/*
Theme Name: Prophetic Profit
Theme URI: https://propheticprofit.org/
Author: Prophetic Profit
Description: An illuminated theme for long-form Islamic writing, with a full Qur'an reader recited by a qari', a tafsir room of thirty-four classical works readable a passage at a time and side by side, fourteen hadith collections readable as narrations or as a book, prayer times, a Qibla compass, a tasbih counter and three hundred and eighty-two adhkar, in eight appearances, each with its own metal.
Version: 14.3.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: propheticprofit
*/


/* ==== BEGIN MAP — written by tools/gen_map.py, do not edit ==== */
/*
   THE MAP OF THIS FILE.

   style.css is one file because a WordPress theme's root style.css
   is what WordPress reads its name and version out of, and because
   one file means one cascade a reader can follow top to bottom.
   It is long, so it carries its own contents.

   The base rules run from the top to the first layer marker below.
   Everything after that is a dated layer, appended in order, and the
   LAST rule for a selector is the one that wins.

   Regenerate with:  python tools/gen_map.py --write

     16,153   v130-layer-10-home.css             v13.0  The home page
     16,258   v130-layer-20-adhkar.css           v13.0  The adhkar page
     16,566   v130-layer-40-reading.css          v13.0  Reading pages: posts and prose
     16,737   v130-layer-50-book.css             v13.0  Book-style reading
     17,193   v130-layer-60-qibla.css            v13.0  The qibla compass
     17,270   v130-layer-65-prayer.css           v13.0  Prayer times
     17,308   v130-layer-70-arabic.css           v13.0  Arabic typography
     17,347   v130-layer-80-emblems.css          v13.0  Emblems and ornaments
     17,367   v131-layer-05-chrome.css           v13.1  Header, nav and page chrome
     17,388   v131-layer-20-tafsir.css           v13.1  The tafsir pages
     17,417   v131-layer-25-tafsir-room.css      v13.1  The tafsir reading room
     17,611   v131-layer-30-hadith.css           v13.1  The hadith pages
     17,653   v131-layer-40-shamail.css          v13.1  The Shama'il
     17,971   v132-layer-10-arabic.css           v13.2  Arabic typography
     18,086   v132-layer-20-hadith.css           v13.2  The hadith pages
     18,267   v132-layer-30-menus.css            v13.2  Menus and drop-downs
     18,324   v132-layer-40-adhkar.css           v13.2  The adhkar page
     18,359   v132-layer-50-tafsir.css           v13.2  The tafsir pages
     18,600   v132-layer-60-prayer.css           v13.2  Prayer times
     18,656   v132-layer-70-qibla.css            v13.2  The qibla compass
     18,722   v132-layer-80-surah-names.css      v13.2  Surah names
     18,791   v132-layer-90-header-phone.css     v13.2  The header, on phones
     18,812   v132-layer-95-tafsir-bar-phone.css v13.2  The tafsir bar, on phones
     18,856   v140-layer-05-mark.css             v14.0  The logo mark
     18,889   v140-layer-10-button.css           v14.0  Buttons
     19,077   v140-layer-15-quran-size.css       v14.0  Qur'an text sizing
     19,191   v140-layer-20-unwan.css            v14.0  The unwan, the title panel above a reading
     19,402   v140-layer-25-chapters.css         v14.0  Chapter lists
     19,470   v140-layer-30-adhkar.css           v14.0  The adhkar page
     19,640   v140-layer-40-tafsir.css           v14.0  The tafsir pages
     19,792   v140-layer-50-aa.css               v14.0  The Aa text-size control
     20,106   v140-layer-60-chrome.css           v14.0  Header, nav and page chrome
     20,332   v140-layer-70-boxes.css            v14.0  Cards and boxes
     20,451   v140-layer-80-tafsir.css           v14.0  The tafsir pages
     20,638   v140-layer-85-unwan.css            v14.0  The unwan, the title panel above a reading
     20,819   v140-layer-90-polish.css           v14.0  Final polish
     20,850   v141-layer-10-text.css             v14.1  Body text
     20,967   v141-layer-20-adhkar.css           v14.1  The adhkar page
     21,137   v141-layer-30-chrome.css           v14.1  Header, nav and page chrome
     21,254   v141-layer-40-button.css           v14.1  Buttons
     21,414   v141-layer-60-tafsir-menu.css      v14.1  The tafsir book menu
     21,449   v141-layer-70-shamail.css          v14.1  The Shama'il
     21,541   v141-layer-80-chapters.css         v14.1  Chapter lists
     21,620   v141-layer-90-picker.css           v14.1  The picker sheet
     21,742   v141-layer-95-hadith-shelf.css     v14.1  The hadith shelf
     21,917   v142-layer-10-ayah-size.css        v14.2  Ayah text sizing
     21,981   v142-layer-20-chrome.css           v14.2  Header, nav and page chrome
     22,118   v142-layer-40-menus.css            v14.2  Menus and drop-downs
     22,175   v142-layer-50-tafsir-shelf.css     v14.2  The tafsir shelf of books
     22,223   v142-layer-60-inline-arabic.css    v14.2  Arabic inside an English sentence
     22,263   v142-layer-70-menu-life.css        v14.2  Menus, lit rather than grey
     22,312   v142-layer-80-qibla-step3.css      v14.2  Qibla step 3: which way to face
     22,330   v142-layer-90-header-centre.css    v14.2  The nav, centred on the page
     22,365   v142-layer-95-writings-and-others.css v14.2  Latest Writings, and the other commentaries
     22,414   v143-layer-00-speed.css            v14.3  Speed: what is skipped, what moves by transform, the cross-fade
     22,530   v143-layer-10-header.css           v14.3  The header, its menus and the drawer
     23,345   v143-layer-20-post.css             v14.3  A post: title block, tools, On this page, reading bar, Aa
     23,975   v143-layer-30-cards.css            v14.3  A post as a card: Latest Writings, topics, Read next, Saved
     24,170   v143-layer-40-tafsir.css           v14.3  The tafsir pages
     24,804   v143-layer-50-tools.css            v14.3  Prayer times and the Qibla by the sun
     25,000   v143-layer-60-quran.css            v14.3  The Qur'an reader: the rhythm between ayat
     25,034   v143-layer-70-hadith-book.css      v14.3  A hadith collection read as a book: the contents and the reading
     25,373   v143-layer-80-adhkar.css           v14.3  The adhkar page: one list per set, and the head of a set
     25,493   v143-layer-90-ink.css              v14.3  Room inside a clipped label for Arabic marks; excerpts in Arabic
*/
/* ==== END MAP ==== */
/* KFGQPC Hafs Smart — the official Uthmani Qur'an typeface from the King
   Fahd Glorious Qur'an Printing Complex, freely licensed for use and
   distribution. The Qur'an text data pairs each word with custom glyph
   codepoints specific to this font, so font-display:block (rather than
   swap) is deliberate: those codepoints render as blank/tofu in any
   other font, and a brief invisible wait followed by the correct
   Uthmani script is far better than visibly flashing broken glyphs. */
@font-face{
  font-family:'KFGQPC Hafs Smart';
  src:url('assets/fonts/hafs-smart.woff2') format('woff2');
  font-weight:normal; font-style:normal; font-display:block;
  /*
   * ═══════════════════════════════════════════════════════════════════
   * v14.0 — THE MISSING size-adjust, AND IT WAS THE WHOLE OF ITEM 1.
   * ═══════════════════════════════════════════════════════════════════
   *
   * "See how in the home page there is such a big difference in text
   *  sizes in Arabic and Eng & Hadith & qur'an? you should not cause such
   *  issues again please, it should be all reasonable!"
   *
   * Every other Arabic face on this site carries a size-adjust — 118% on
   * Scheherazade, 124% on Amiri, 135% on Uthmani, 112% on Amiri Quran —
   * because a browser's own em is not the same fraction of the drawn
   * glyph in any two Arabic fonts, and normalising them is what makes
   * `font-size: 1.4rem` mean one thing across the site. This face, the
   * one every ayah is set in, was the only one without.
   *
   * MEASURED, not guessed. Al-Fātiḥah 1:1 at 200px, the same ayah in
   * three faces:
   *
   *     KFGQPC Hafs Smart (PUA)   1569px wide, no size-adjust
   *     PP Uthmani (Unicode)      1789px wide, at 135%
   *     PP Naskh (Scheherazade)   1859px wide, at 118%
   *
   * So an ayah was rendering at 0.84x the size of a hadith set at the
   * identical font-size — which is exactly the "big difference" on the
   * home page, where the ayah of the day and the hadith of the day sit
   * one above the other at 25.6px each and did not look it.
   *
   * 118% brings it level with Scheherazade, which is the face it is
   * compared against most often (hadith text, adhkār text, quoted prose).
   *
   * EVERY RULE THAT SETS AN AYAH'S SIZE COMES DOWN BY 1/1.18 in the same
   * edit — see v140-layer-15-quran-size at the foot of this file — so the
   * reading pages look exactly as they did and only the RELATIONSHIP
   * between the scripts changes.
   */
  size-adjust:118%;
}

/* =========================================================================
   THE ARABIC FACES — SELF-HOSTED, AND SIZE-ADJUSTED. v13.0.

   "please use bold traditional Arabic except when its ayat then Hafs font
   (or suwar names etc) and make sure its always sized correctly and looks
   visually perfect, not smaller than Eng as usual, across the entire
   website"

   TWO SEPARATE PROBLEMS, ONE MECHANISM.

   1. ARABIC LOOKS SMALLER THAN LATIN AT THE SAME font-size, AND IT IS NOT
      AN ILLUSION. A naskh face spends most of its em on the vowel marks
      above and the descenders below; the letters themselves sit in a
      shallow band on the baseline. Amiri's x-height is 433/1000 where a
      Latin text face is 500-520 and Inter is 727. So 18px of Amiri beside
      18px of Newsreader genuinely reads two sizes down, everywhere on
      this site, on every page.

      The wrong fix is to hand-raise font-size on the forty-odd Arabic
      classes: it has to be redone for every new component, it changes
      line boxes unevenly, and it was already half-done and inconsistent.

      The right fix is `size-adjust` on the @font-face — one number that
      scales the glyphs AND the line box, applies to every rule that names
      the family, and needs nothing per-component. It can only be written
      on an @font-face we own, which is why these are bundled rather than
      loaded from Google.

   2. TRADITIONAL ARABIC WAS ASKED FOR, CANNOT BE SHIPPED, AND v13.1
      STOPS PRETENDING OTHERWISE.

      "Make 100% sure that traditional Arabic is across all devices not
       only pc... (super super super important)"

      Traditional Arabic is a Microsoft/Office face and is not licensed
      for redistribution. Up to v13.0 'PP Naskh' therefore listed it as a
      local() reference FIRST and bundled Amiri behind it. That is exactly
      the fault he reported: the author's PC has Traditional Arabic and
      renders in it, every phone on earth does not and renders in Amiri,
      and the two are different-looking faces. The site had two Arabics.

      v13.1 ships ONE, on every device, with no local() at all:
      SCHEHERAZADE NEW (SIL, Open Font Licence). It is the closest open
      face to Traditional Arabic that exists — the same upright, compact,
      lightly-contrasted naskh with the same short teeth and the same
      undramatic terminals — where Amiri is the Bulaq press cut, which is
      more calligraphic and more ornate. Nobody now sees a different
      Arabic from anybody else, and what everyone sees is the shape that
      was asked for.

      SIZE-ADJUST IS 118%, NOT 124%. Measured, not guessed: Scheherazade's
      alif is 0.705em and its dāl 0.429em against Amiri's 0.696 and 0.397,
      so it runs about 4.7% larger per em and needs correspondingly less
      correction to sit level with the Latin beside it.

      Amiri stays bundled and is still used by name for Qur'anic display
      (--font-quran) and as the last web fallback.

   BOLD IS THE DEFAULT WEIGHT FOR ARABIC HERE. Traditional Arabic is a
   light face and Amiri is a moderate one; at reading size on cream paper
   both look like a watermark beside Newsreader. Every Arabic rule in this
   stylesheet declares font-weight:700, and 700 is a real cut of both
   faces, not a synthesised smear.

   AYAT ARE THE EXCEPTION AND ALWAYS HAVE BEEN. The Qur'an text is
   PUA-encoded for KFGQPC Hafs Smart (see data/quran and the @font-face at
   the top of this file) and renders as tofu in anything else, so it is
   never touched by any of this. Surah names are ordinary Unicode and
   cannot use Hafs Smart — that font contains no Arabic letters at all,
   only ayah glyphs — so they use Amiri Quran, which is the Qur'anic cut
   of the same Bulaq naskh.
   ========================================================================= */

@font-face{
  font-family:'PP Naskh';
  src: url('assets/fonts/scheherazade-400.woff2') format('woff2');
  font-weight:400; font-style:normal; font-display:swap;
  size-adjust:118%;
  unicode-range:U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
@font-face{
  font-family:'PP Naskh';
  src: url('assets/fonts/scheherazade-700.woff2') format('woff2');
  font-weight:700; font-style:normal; font-display:swap;
  size-adjust:118%;
  unicode-range:U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* v14.3 — THE SAME NASKH, FOR ARABIC INSIDE AN ENGLISH LINE.
   Named straight after the Latin face in --font-display, --font-body and
   --font-ui (see the note there), so a quoted ḥadīth in an excerpt or a
   search hit is set in the site's Arabic rather than the device's.
   The same two files, so nothing more is fetched — with one block left
   out of its range: U+FDF0–FDFF, the honorific ligatures. ﷺ in an English
   label was drawn by the device's face at the size of a word; given to
   this one at its 118% it stood a third taller than the capitals and was
   cut off at the top of every one-line label that carries it ("The
   Prophet ﷺ & His Companions" in the Topics menu). Those glyphs go on
   down the stack exactly as they did before. */
@font-face{
  font-family:'PP Naskh Inline';
  src: url('assets/fonts/scheherazade-400.woff2') format('woff2');
  font-weight:400; font-style:normal; font-display:swap;
  size-adjust:118%;
  unicode-range:U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDEF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
@font-face{
  font-family:'PP Naskh Inline';
  src: url('assets/fonts/scheherazade-700.woff2') format('woff2');
  font-weight:700; font-style:normal; font-display:swap;
  size-adjust:118%;
  unicode-range:U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDEF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
@font-face{
  font-family:'Amiri';
  src: url('assets/fonts/amiri-400.woff2') format('woff2');
  font-weight:400; font-style:normal; font-display:swap;
  size-adjust:124%;
  unicode-range:U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
@font-face{
  font-family:'Amiri';
  src: url('assets/fonts/amiri-700.woff2') format('woff2');
  font-weight:700; font-style:normal; font-display:swap;
  size-adjust:124%;
  unicode-range:U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* Amiri Quran carries a 1815/1000 ascender for the vocalisation, so its
   line box is already tall; it needs less of a lift than the text cut and
   more would make every surah name collide with the rule above it. */
@font-face{
  /* KFGQPC Uthmanic Script HAFS — the muṣḥaf hand, as a real Unicode font.
     See the note in tools/ and CLAUDE-NOTES.txt. This is the face every
     surah name, every Bismillah and every Qurʾanic heading is set in from
     v13.1; the PUA word-glyph face ('KFGQPC Hafs Smart') is still what
     the ayah TEXT itself uses and is a different file for a different
     job. */
  font-family:'PP Uthmani';
  src: url('assets/fonts/uthmanic-hafs-400.woff2') format('woff2');
  font-weight:400; font-style:normal; font-display:swap;
  size-adjust:135%;
  unicode-range:U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
}
@font-face{
  font-family:'Amiri Quran';
  src: url('assets/fonts/amiri-quran-400.woff2') format('woff2');
  font-weight:400; font-style:normal; font-display:swap;
  size-adjust:112%;
  unicode-range:U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* v14.3 — ʿAYN AND HAMZAH, DRAWN FOR THIS SITE.
   Literata draws the two half rings of transliteration (ʿ U+02BF, ʾ U+02BE)
   on a half-em body, so "Qurʾān" and "Ibn ʿAbbās" read as two words each.
   These two files hold those two marks and nothing else, on a tight body —
   see tools/gen_ayn_font.py. They lead the serif stacks and, fallback being
   per glyph, are used for those two characters only. Under 500 bytes each. */
@font-face{
  font-family:'PP Ayn';
  src: url('assets/fonts/pp-ayn-400.woff2') format('woff2');
  font-weight:100 550; font-style:normal; font-display:swap;
  unicode-range:U+02BE-02BF;
}
@font-face{
  font-family:'PP Ayn';
  src: url('assets/fonts/pp-ayn-700.woff2') format('woff2');
  font-weight:551 900; font-style:normal; font-display:swap;
  unicode-range:U+02BE-02BF;
}
/* The italics, so the browser never slants the upright marks itself — it
   leans them 14 degrees against Literata Italic's four (gen_ayn_font.py). */
@font-face{
  font-family:'PP Ayn';
  src: url('assets/fonts/pp-ayn-400i.woff2') format('woff2');
  font-weight:100 550; font-style:italic; font-display:swap;
  unicode-range:U+02BE-02BF;
}
@font-face{
  font-family:'PP Ayn';
  src: url('assets/fonts/pp-ayn-700i.woff2') format('woff2');
  font-weight:551 900; font-style:italic; font-display:swap;
  unicode-range:U+02BE-02BF;
}
/* Noto Naskh Arabic is a variable font; Google serves ONE file for the
   whole weight axis, so it is declared once across 400-700 rather than
   twice from the same bytes. */
@font-face{
  font-family:'Noto Naskh Arabic';
  src: url('assets/fonts/noto-naskh-400.woff2') format('woff2');
  font-weight:400 700; font-style:normal; font-display:swap;
  size-adjust:120%;
  unicode-range:U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}

/* =========================================================================
   0. DESIGN TOKENS — eight palettes as of v7.0. Five light (Parchment /
   Linen / Blush / Sea Glass / Sage) and three dark (Graphite / Midnight
   / Obsidian), all sharing one set of role-based variable names, so
   every component below only has to be written once. Colors are stored
   as space-separated R G B triplets so they can be composited with
   alpha via rgb(var(--x) / 0.5).

   Parchment is the default for EVERY reader — see the pre-paint script
   in header.php for why the operating system's dark-mode preference is
   deliberately not consulted.
   ========================================================================= */

:root{
  /* Light is the baseline. Any dark palette overrides this to `dark`
     in its own block, and the pre-paint script sets it inline too so
     it's correct before this stylesheet has even parsed. */
  color-scheme: light;
  /* structural */
  --radius: 14px;
  --radius-sm: 9px;
  --radius-lg: 22px;
  --ease: cubic-bezier(.22,.61,.36,1);
  --header-h: 78px;
  --header-h-static: 78px;

  /* type — Fraunces gives the headings a warm, high-contrast editorial
     voice; Newsreader carries the long-form reading, where its lower
     contrast is gentler on the eye; Inter handles interface chrome.
     Arabic content gets its own dedicated faces so it never has to
     borrow a Latin font: Scheherazade New (a complete, highly legible
     Naskh with full harakat coverage) for general text and hadith, and
     Amiri Quran for accurate Qur'anic typesetting. */
  /*
   * v12.1 — Newsreader is inserted ahead of the system serifs as the
   * fallback. This site writes ḥ ṣ ḍ ṭ ẓ ā ī ū ʿ ʾ constantly — Tafsīr,
   * Sīrah, Adhkār, al-Ṭabarī — and while Fraunces does carry the common
   * ones, anything it lacks was previously being supplied by Georgia,
   * whose colour and axis are noticeably different. Newsreader is already
   * loaded as the body face and is a much closer match, so a substituted
   * letter inside a word no longer shows. Fallback is per glyph: this
   * changes nothing Fraunces already renders.
   */
  /*
   * v12.3 — WHY 'Amiri' IS AT THE END OF ALL FOUR LATIN STACKS.
   *
   * This site writes ﷺ (U+FDFA) in ENGLISH sentences, constantly, and
   * that character exists in no Latin font on earth. "The sīrah tells
   * what he ﷺ did" was rendering the ligature as a tofu box in
   * Fraunces, in Inter and in IBM Plex Mono, on the one glyph the site
   * cares most about getting right.
   *
   * Font fallback in CSS is PER GLYPH, not per element: the browser
   * walks the whole family list for each character and takes the first
   * face that has it. So a face at the end of the list is only ever
   * reached by characters that nothing before it carries — here, ﷺ and
   * the honorific ligatures beside it. Nothing that already rendered
   * changes, and Amiri is loaded on every page anyway.
   */
  /*
   * v14.3 — LITERATA, FOR HEADINGS AND READING BOTH.
   *
   * "Al-Rāzī" was reported with its macrons floating loose, and it was
   * not one title. Drawn side by side at every size and weight, Fraunces
   * puts the bar of ā, ī and ū a whole letter to the right ("Kathir̄",
   * "Adhkar̄") in every heading on the site, and Newsreader leaves the dot
   * on the i under the bar of ī in every paragraph. A site whose own
   * vocabulary is Tafsīr, Ḥadīth, Adhkār and al-Bukhārī cannot be set in
   * either. Literata draws all of them correctly, including ḥ ṣ ḍ ṭ ẓ and
   * ʿ ʾ, in roman and italic.
   *
   * It is also one family where there were two: its optical-size axis
   * gives a title the high-contrast display cut and a paragraph the text
   * cut, automatically, from font-size. Measured against what it
   * replaces: the same x-height as Newsreader at text size (so the Arabic
   * size-adjust calibrated against it still holds) and within 3% of
   * Fraunces' width at heading size (so no title rewraps).
   */
  /* v14.3 — ARABIC THAT NOBODY MARKED STILL GETS THE SITE'S ARABIC. An
     excerpt, a search hit or a title that opens with a ḥadīth carries no
     lang="ar", so its letters fell through these stacks to the first face
     that has Arabic: Times New Roman or Segoe UI on a PC, SF on an iPhone —
     three Arabics, where the note above promises one on every device.
     'PP Naskh Inline' — the site's naskh, under a name of its own — now
     comes straight after the Latin face. Its @font-face is limited to the
     Arabic blocks (unicode-range), so no Latin letter can ever reach it,
     and it is only fetched on a page that has Arabic. ﷺ is left out of it
     on purpose; see its @font-face. */
  --font-display:'PP Ayn', 'Literata', 'PP Naskh Inline', Georgia, 'Times New Roman', 'Amiri', 'Noto Naskh Arabic', serif;
  --font-body:'PP Ayn', 'Literata', 'PP Naskh Inline', Georgia, 'Times New Roman', 'Amiri', 'Noto Naskh Arabic', serif;
  --font-ui:'Inter', 'PP Naskh Inline', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Amiri', 'Noto Naskh Arabic', sans-serif;
  /* v14.3 — THE UTILITY VOICE IS THE INTERFACE SANS. `--font-mono` was IBM
     Plex Mono and set every small label on the site — dates, reading times,
     counts, references, eyebrows — in a typewriter face: "the date used and
     read time in the top is quite ugly!! … dont use such ugly fonts". The
     token keeps its name, because 190 rules read it, and now resolves to
     the interface sans with tabular figures left to each rule. Real code
     (a <code> in a post, a <kbd> hint) reads --font-code, and nothing is
     fetched for it: it is the device's own monospace. */
  --font-mono:var(--font-ui);
  --font-code:ui-monospace, 'SFMono-Regular', Menlo, Consolas, 'Liberation Mono', monospace;
  /* One Arabic family for the whole site — Traditional Arabic where it
     Scheherazade New, bundled, on every device without exception — see
     the long note in the @font-face block above for why this is one face
     now and not two. */
  --font-arabic:'PP Naskh', 'Amiri', 'Noto Naskh Arabic', serif;
  /* THE WEIGHT EVERY ARABIC RULE IN THIS FILE DECLARES — and in v13.2 it
     comes down from 700.

       "on tafsir the text is too bold, across the entire website I dont
        want huge bold text, be reasonable, I want basic nice looking
        bold, it must be similar to the text and font of Qur'an itself so
        its not so weird"

     He is right, and 700 was a decision made when the Arabic face was
     Traditional Arabic — a genuinely light hand that needed the weight
     to hold a page. Scheherazade New is not light: at 400 it has the same
     colour on the page as the Latin beside it, which is what "similar to
     the text and font of Qur'an itself" means, since the muṣḥaf face has
     ONE cut and it is this weight.

     So: 400 is the reading weight and it is the default everywhere.
     --ar-weight-strong is the display weight, and it is used only where
     Arabic is a TITLE — the twenty-one selectors that name
     --font-arabic-display, plus the ʿunwāns. A title in 700 beside body
     text in 400 is "basic nice looking bold"; a whole page in 700 is the
     "huge bold text" he is objecting to. */
  --ar-weight:400;
  --ar-weight-strong:700;
  /* Display Arabic — used ONLY for large titles: the sīrah headings, the
     hadith book names, the page heroes.

     v12.3 — Aref Ruqaa is gone. Ruqʿah is a hand for notes and signage,
     not for the name of a book, and at title size its steep descenders
     and blunt terminals fought every Naskh line under them.

     Traditional Arabic is what was asked for, and it leads. It is a
     Windows/Office face, so it is the one the author actually sees; for
     everyone else Noto Naskh Arabic follows, which is the closest
     web-served cut to it — the same upright, open Naskh with the same
     modest contrast — and unlike Traditional Arabic it ships a real 700.

     BOLD IS NOT OPTIONAL HERE: at 3rem in a regular weight on cream
     paper an upright naskh looks like a watermark. Every rule that uses
     this token declares font-weight:700.

     v13.2 — IT IS AMIRI THAT LEADS THIS ONE NOW.

       "use Amiri Bold on the website too, you decide when to use
        traditional arabic & when to use Amiri based on beauty and bold
        level"

     So the site keeps two Arabic faces and gives each the job it is
     good at, rather than setting everything in one:

       BODY  --font-arabic       Scheherazade New. Upright, compact,
                                 lightly contrasted; made to be read for
                                 an hour. Hadith text, adhkar text,
                                 quoted prose.
       TITLE --font-arabic-display  AMIRI, at 700. A Bulaq naskh with real
                                 stroke contrast and long descenders —
                                 nothing on this site is more beautiful
                                 at 2rem, and it has a true bold, which
                                 Scheherazade's display sizes needed and
                                 never quite carried.
       QUR'AN --font-quran / --font-quran-glyphs   KFGQPC Hafs. Neither of
                                 the other two ever sets scripture. */
  --font-arabic-display:'Amiri', 'PP Naskh', 'Noto Naskh Arabic', serif;
  /* v13.1 — the muṣḥaf hand leads. See the @font-face for 'PP Uthmani'
     above: this is what fixes "the name of the suwar is in Amiri not
     Hafs", and it fixes it everywhere at once rather than in the one
     menu it was reported in. */
  /* v13.2 — the chain stops at the two muṣḥaf cuts. It used to fall
     through to 'PP Naskh' and 'Amiri', so a single missing glyph put an
     ayah into a hand that is not the muṣḥaf's — which is what "all AYAT
     on posts MUST be in Hafs in posts!!" is about. Both faces here are
     bundled, so the fallback is theoretical anyway; removing it makes it
     impossible rather than unlikely. */
  --font-quran:'PP Uthmani', 'Amiri Quran', serif;
  /* Only for the Hafs Smart PUA-encoded ayah glyphs (see data/quran) —
     every other Arabic Qur'an-related text on the site (surah names,
     the Bismillah heading, the pre-existing blog-post "Qur'an verse"
     quote style) is ordinary Unicode text and uses --font-quran or
     --font-arabic above, both of which are proven for standard
     Unicode Quranic typography. */
  --font-quran-glyphs:'KFGQPC Hafs Smart', 'Amiri Quran', 'Amiri', serif;

}

/* ==== BEGIN GENERATED PALETTES — do not edit by hand ==== */
/* Generated by tools/gen_palettes.py. Every value below is checked
   against every other value it is ever painted on — see that file.
   8 palettes x 54 pairs, all passing at emit time. */

/* -------- SAFFRON (slug: saffron) — Gold leaf and Rawḍah green -------- */
:root,
html[data-theme="saffron"]{
  color-scheme: light;
  --bg: 250 238 212;
  --bg-alt: 244 227 192;
  --surface: 251 244 225;
  --text: 34 44 38;
  --text-muted: 84 96 84;
  --heading: 20 70 52;
  --heading-soft: 42 92 72;
  --ink: 13 40 31;
  --ink-soft: 21 54 42;
  --on-ink: 250 242 222;
  --accent: 22 92 68;
  --accent-ui: 18 84 62;
  --accent-light: 234 204 136;
  --accent-2: 132 86 20;
  --accent-3: 30 96 92;
  --shadow: 66 54 18;
  --on-accent: var(--on-ink);
  --gilt-hi: 255 240 200;
  --gilt: 241 200 108;
  --gilt-deep: 200 148 54;
  --gilt-edge: 126 84 22;
  --on-gilt: var(--ink);
  --btn-hi: var(--gilt-hi);
  --btn: var(--gilt);
  --btn-deep: var(--gilt-deep);
  --btn-edge: var(--gilt-edge);
  --on-btn: var(--ink);
  --accent-btn: var(--gilt);
  --mark-hi: 255 240 200;
  --mark-mid: 241 200 108;
  --mark-deep: 126 84 22;
  --mark-pale-a: 255 248 230;
  --mark-pale-b: 246 219 158;
  --mark-dot: 13 40 31;
  --mark-ground-a: 20 52 40;
  --mark-ground-b: 7 22 17;
  --cta: 22 92 68;
  --cta-lift: 38 103 81;
  --cta-deep: 18 77 57;
  --cta-edge: 15 61 45;
  --on-cta: var(--on-accent);
  --cta-ring: var(--gilt-edge);
  --ornament: var(--gilt);
  --wash: 168 120 38;
}

/* -------- FROST (slug: frost) — Pale ice, deep glacier blue -------- */
html[data-theme="frost"]{
  color-scheme: light;
  --bg: 238 246 253;
  --bg-alt: 220 235 249;
  --surface: 249 253 255;
  --text: 28 45 62;
  --text-muted: 80 100 122;
  --heading: 12 38 62;
  --heading-soft: 38 66 92;
  --ink: 10 28 46;
  --ink-soft: 22 44 66;
  --on-ink: 236 246 254;
  --accent: 13 97 148;
  --accent-ui: 11 90 138;
  --accent-light: 150 205 238;
  --accent-2: 116 74 30;
  --accent-3: 10 102 100;
  --shadow: 20 42 66;
  --on-accent: var(--on-ink);
  --gilt-hi: 252 254 255;
  --gilt: 207 226 242;
  --gilt-deep: 146 176 204;
  --gilt-edge: 52 86 118;
  --on-gilt: var(--ink);
  --btn-hi: var(--gilt-hi);
  --btn: var(--gilt);
  --btn-deep: var(--gilt-deep);
  --btn-edge: var(--gilt-edge);
  --on-btn: var(--ink);
  --accent-btn: var(--gilt);
  --mark-hi: 252 254 255;
  --mark-mid: 207 226 242;
  --mark-deep: 52 86 118;
  --mark-pale-a: 254 255 255;
  --mark-pale-b: 223 236 246;
  --mark-dot: 10 28 46;
  --mark-ground-a: 20 42 63;
  --mark-ground-b: 6 15 25;
  --cta: 13 97 148;
  --cta-lift: 30 108 155;
  --cta-deep: 11 81 124;
  --cta-edge: 9 64 98;
  --on-cta: var(--on-accent);
  --cta-ring: var(--gilt-edge);
  --ornament: var(--accent);
  --wash: var(--accent);
}

/* -------- ROSE (slug: rose) — Blush paper, madder crimson -------- */
html[data-theme="rose"]{
  color-scheme: light;
  --bg: 253 238 243;
  --bg-alt: 250 224 233;
  --surface: 255 248 251;
  --text: 58 30 41;
  --text-muted: 116 76 90;
  --heading: 122 12 58;
  --heading-soft: 152 42 88;
  --ink: 74 10 40;
  --ink-soft: 102 26 60;
  --on-ink: 255 241 246;
  --accent: 190 18 88;
  --accent-ui: 178 16 82;
  --accent-light: 250 172 200;
  --accent-2: 142 74 4;
  --accent-3: 90 58 166;
  --shadow: 78 22 48;
  --on-accent: var(--on-ink);
  --gilt-hi: 253 222 212;
  --gilt: 240 178 162;
  --gilt-deep: 204 128 110;
  --gilt-edge: 134 58 52;
  --on-gilt: var(--ink);
  --btn-hi: var(--gilt-hi);
  --btn: var(--gilt);
  --btn-deep: var(--gilt-deep);
  --btn-edge: var(--gilt-edge);
  --on-btn: var(--ink);
  --accent-btn: var(--gilt);
  --mark-hi: 253 222 212;
  --mark-mid: 240 178 162;
  --mark-deep: 134 58 52;
  --mark-pale-a: 254 240 236;
  --mark-pale-b: 245 204 194;
  --mark-dot: 74 10 40;
  --mark-ground-a: 98 24 57;
  --mark-ground-b: 41 6 22;
  --cta: 190 18 88;
  --cta-lift: 195 35 100;
  --cta-deep: 160 15 74;
  --cta-edge: 125 12 58;
  --on-cta: var(--on-accent);
  --cta-ring: var(--gilt-edge);
  --ornament: var(--accent);
  --wash: var(--accent);
}

/* -------- EMERALD (slug: emerald) — Green paper, true emerald -------- */
html[data-theme="emerald"]{
  color-scheme: light;
  --bg: 233 250 240;
  --bg-alt: 213 242 226;
  --surface: 246 253 249;
  --text: 20 48 34;
  --text-muted: 72 106 86;
  --heading: 2 68 45;
  --heading-soft: 16 92 66;
  --ink: 3 46 32;
  --ink-soft: 11 64 46;
  --on-ink: 236 252 242;
  --accent: 0 120 76;
  --accent-ui: 0 104 65;
  --accent-light: 126 228 176;
  --accent-2: 160 68 16;
  --accent-3: 22 86 154;
  --shadow: 10 56 40;
  --on-accent: var(--on-ink);
  --gilt-hi: 252 233 180;
  --gilt: 230 186 106;
  --gilt-deep: 184 138 52;
  --gilt-edge: 96 74 14;
  --on-gilt: var(--ink);
  --btn-hi: var(--gilt-hi);
  --btn: var(--gilt);
  --btn-deep: var(--gilt-deep);
  --btn-edge: var(--gilt-edge);
  --on-btn: var(--ink);
  --accent-btn: var(--gilt);
  --mark-hi: 252 233 180;
  --mark-mid: 230 186 106;
  --mark-deep: 96 74 14;
  --mark-pale-a: 254 245 221;
  --mark-pale-b: 238 209 157;
  --mark-dot: 3 46 32;
  --mark-ground-a: 10 61 44;
  --mark-ground-b: 2 25 18;
  --cta: 0 120 76;
  --cta-lift: 18 129 89;
  --cta-deep: 0 101 64;
  --cta-edge: 0 79 50;
  --on-cta: var(--on-accent);
  --cta-ring: var(--gilt-edge);
  --ornament: var(--accent);
  --wash: var(--accent);
}

/* -------- OBSIDIAN (slug: obsidian) — Near-black with illuminated gold -------- */
html[data-theme="obsidian"]{
  color-scheme: dark;
  --bg: 18 17 15;
  --bg-alt: 26 25 22;
  --surface: 30 29 25;
  --text: 230 226 216;
  --text-muted: 166 160 148;
  --heading: 248 245 238;
  --heading-soft: 218 213 202;
  --ink: 10 10 8;
  --ink-soft: 22 21 18;
  --on-ink: 242 238 230;
  --accent: 216 176 88;
  --accent-ui: 228 190 108;
  --accent-light: 240 214 156;
  --accent-2: 212 130 96;
  --accent-3: 126 176 152;
  --shadow: 0 0 0;
  --on-accent: var(--ink);
  --gilt-hi: 253 229 168;
  --gilt: 238 196 116;
  --gilt-deep: 204 158 70;
  --gilt-edge: 148 106 36;
  --on-gilt: var(--ink);
  --btn-hi: var(--gilt-hi);
  --btn: var(--gilt);
  --btn-deep: var(--gilt-deep);
  --btn-edge: var(--gilt-edge);
  --on-btn: var(--ink);
  --accent-btn: var(--gilt);
  --mark-hi: 253 229 168;
  --mark-mid: 238 196 116;
  --mark-deep: 148 106 36;
  --mark-pale-a: 254 243 216;
  --mark-pale-b: 244 216 163;
  --mark-dot: 10 10 8;
  --mark-ground-a: 20 19 16;
  --mark-ground-b: 6 6 4;
  --cta: 216 176 88;
  --cta-lift: 223 190 118;
  --cta-deep: 194 158 79;
  --cta-edge: 168 137 69;
  --on-cta: var(--on-accent);
  --cta-ring: var(--gilt-edge);
  --ornament: var(--accent);
  --wash: var(--accent);
}

/* -------- MIDNIGHT (slug: midnight) — Sapphire night, moonlight on it -------- */
html[data-theme="midnight"]{
  color-scheme: dark;
  --bg: 11 20 41;
  --bg-alt: 19 31 58;
  --surface: 25 39 70;
  --text: 219 231 248;
  --text-muted: 150 170 200;
  --heading: 238 246 255;
  --heading-soft: 203 219 241;
  --ink: 7 13 29;
  --ink-soft: 15 25 47;
  --on-ink: 232 242 255;
  --accent: 126 182 244;
  --accent-ui: 154 202 250;
  --accent-light: 198 224 252;
  --accent-2: 238 192 132;
  --accent-3: 126 224 214;
  --shadow: 0 0 0;
  --on-accent: var(--ink);
  --gilt-hi: 236 246 255;
  --gilt: 194 219 246;
  --gilt-deep: 136 176 222;
  --gilt-edge: 62 104 158;
  --on-gilt: var(--ink);
  --btn-hi: var(--gilt-hi);
  --btn: var(--gilt);
  --btn-deep: var(--gilt-deep);
  --btn-edge: var(--gilt-edge);
  --on-btn: var(--ink);
  --accent-btn: var(--gilt);
  --mark-hi: 236 246 255;
  --mark-mid: 194 219 246;
  --mark-deep: 62 104 158;
  --mark-pale-a: 246 251 255;
  --mark-pale-b: 215 231 249;
  --mark-dot: 7 13 29;
  --mark-ground-a: 14 23 44;
  --mark-ground-b: 4 7 16;
  --cta: 126 182 244;
  --cta-lift: 149 195 246;
  --cta-deep: 113 164 220;
  --cta-edge: 98 142 190;
  --on-cta: var(--on-accent);
  --cta-ring: var(--gilt-edge);
  --ornament: var(--accent);
  --wash: var(--accent);
}

/* -------- VELVET (slug: velvet) — Deep wine, champagne gold -------- */
html[data-theme="velvet"]{
  color-scheme: dark;
  --bg: 28 14 23;
  --bg-alt: 40 21 33;
  --surface: 46 25 38;
  --text: 240 223 232;
  --text-muted: 186 156 172;
  --heading: 255 240 247;
  --heading-soft: 228 204 218;
  --ink: 17 8 14;
  --ink-soft: 29 15 24;
  --on-ink: 250 235 242;
  --accent: 236 168 192;
  --accent-ui: 244 190 208;
  --accent-light: 248 212 226;
  --accent-2: 238 200 146;
  --accent-3: 158 204 200;
  --shadow: 0 0 0;
  --on-accent: var(--ink);
  --gilt-hi: 252 236 212;
  --gilt: 238 210 170;
  --gilt-deep: 200 166 122;
  --gilt-edge: 136 104 70;
  --on-gilt: var(--ink);
  --btn-hi: var(--gilt-hi);
  --btn: var(--gilt);
  --btn-deep: var(--gilt-deep);
  --btn-edge: var(--gilt-edge);
  --on-btn: var(--ink);
  --accent-btn: var(--gilt);
  --mark-hi: 252 236 212;
  --mark-mid: 238 210 170;
  --mark-deep: 136 104 70;
  --mark-pale-a: 254 246 236;
  --mark-pale-b: 244 225 199;
  --mark-dot: 17 8 14;
  --mark-ground-a: 27 14 22;
  --mark-ground-b: 9 4 8;
  --cta: 236 168 192;
  --cta-lift: 239 184 203;
  --cta-deep: 212 151 173;
  --cta-edge: 184 131 150;
  --on-cta: var(--on-accent);
  --cta-ring: var(--gilt-edge);
  --ornament: var(--accent);
  --wash: var(--accent);
}

/* -------- JUNIPER (slug: juniper) — Garden green night, jade and gold -------- */
html[data-theme="juniper"]{
  color-scheme: dark;
  --bg: 12 30 24;
  --bg-alt: 20 42 34;
  --surface: 24 48 38;
  --text: 222 238 228;
  --text-muted: 157 183 167;
  --heading: 240 252 244;
  --heading-soft: 208 228 214;
  --ink: 7 20 15;
  --ink-soft: 16 32 25;
  --on-ink: 234 248 238;
  --accent: 108 222 168;
  --accent-ui: 135 233 185;
  --accent-light: 176 240 206;
  --accent-2: 237 199 121;
  --accent-3: 241 179 151;
  --shadow: 0 0 0;
  --on-accent: var(--ink);
  --gilt-hi: 250 234 178;
  --gilt: 228 196 112;
  --gilt-deep: 182 150 58;
  --gilt-edge: 120 100 30;
  --on-gilt: var(--ink);
  --btn-hi: var(--gilt-hi);
  --btn: var(--gilt);
  --btn-deep: var(--gilt-deep);
  --btn-edge: var(--gilt-edge);
  --on-btn: var(--ink);
  --accent-btn: var(--gilt);
  --mark-hi: 250 234 178;
  --mark-mid: 228 196 112;
  --mark-deep: 120 100 30;
  --mark-pale-a: 253 246 220;
  --mark-pale-b: 237 216 161;
  --mark-dot: 7 20 15;
  --mark-ground-a: 15 30 24;
  --mark-ground-b: 4 11 8;
  --cta: 108 222 168;
  --cta-lift: 134 228 184;
  --cta-deep: 97 200 151;
  --cta-edge: 84 173 131;
  --on-cta: var(--on-accent);
  --cta-ring: var(--gilt-edge);
  --ornament: var(--accent);
  --wash: var(--accent);
}

/* ==== END GENERATED PALETTES ==== */

@media (prefers-reduced-motion: reduce){
  html:root{ scroll-behavior:auto; }
  *{ animation-duration:0.001ms !important; animation-iteration-count:1 !important; transition-duration:0.001ms !important; }
}

/* Suppresses every transition, site-wide, for the one paint that
   changing data-theme itself causes — see the long comment on
   applyTheme() in assets/main.js. This is what stops a palette switch
   from being hundreds of components' individual hover/focus
   transitions all animating background/color/border-color/box-shadow
   at once. The class is added and removed by that same function, a
   couple of frames apart, so ordinary hover and focus transitions are
   completely unaffected outside of that one moment. */
html.is-switching-theme,
html.is-switching-theme *,
html.is-switching-theme *::before,
html.is-switching-theme *::after{
  transition-property: none !important;
}

/* =========================================================================
   1. RESET & BASE
   ========================================================================= */

*,*::before,*::after{ box-sizing:border-box; }

/* A real, widespread bug found during testing: [hidden] has the same
   CSS specificity as a single class selector, so any element with
   both the `hidden` attribute AND a class that sets its own `display`
   (the near-universal .btn among many others) had that class's
   display value silently win over the browser's built-in
   [hidden]{display:none} — since this stylesheet loads after the
   browser's defaults, and equal-specificity rules resolve by source
   order. Caught it by testing an actual hidden element's computed
   style rather than assuming the attribute "just works". This single
   rule guarantees `hidden` always wins, for every element on the
   site, current and future. */
[hidden]{ display:none !important; }
/* overflow-x:clip on the root reliably contains the off-canvas mobile
   menu (which sits translated off the right edge) so it can never open
   up an empty horizontal scroll strip on phones. */
html{ scroll-behavior:smooth; -webkit-text-size-adjust:100%; overflow-x:clip; }

body{
  margin:0;
  max-width:100%;
  background:rgb(var(--bg));
  color:rgb(var(--text));
  font-family:var(--font-ui);
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  transition:background 0.35s var(--ease), color 0.35s var(--ease);
  overflow-x:clip;
  /* A single long unbroken word, URL, or hashtag anywhere in real content
     (post body, comments, cards) would otherwise overflow its container;
     combined with overflow-x:clip above that overflow was being silently
     cut off — invisible and unreachable — instead of wrapping. This
     makes every long run of text wrap inside its box, inherited
     site-wide, on every screen size. */
  overflow-wrap:break-word;
  word-wrap:break-word;
}

h1,h2,h3,.display{
  font-family:var(--font-display);
  font-weight:600;
  color:rgb(var(--heading));
  margin:0;
  letter-spacing:-0.01em;
}

.eyebrow{
  font-weight:500;
}

a{ color:inherit; text-decoration:none; }
button{ font-family:inherit; cursor:pointer; }
.wrap{ max-width:1220px; margin:0 auto; padding:0 28px; }

/* Anchor-link targets (nav "Subscribe", footer "View all topics", 404/search
   "Browse topics", etc. all jump to these IDs) would otherwise land flush
   under the sticky header, hiding the section's own heading. */
#topics, #writings, #hadith, #essays, #welcome, #support, #subscribe, #comments{
  scroll-margin-top:calc(var(--header-h) + 18px);
}
img,svg{ display:block; max-width:100%; }

.sr-only{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }

a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible{
  outline:2px solid rgb(var(--accent));
  outline-offset:3px;
  border-radius:4px;
}


.bg-texture{
  position:fixed; inset:0; pointer-events:none; z-index:0; opacity:0.5;
  background-image:
    radial-gradient(circle at 12% 8%, rgb(var(--wash) / 0.10), transparent 40%),
    radial-gradient(circle at 88% 18%, rgb(var(--accent-3) / 0.10), transparent 42%),
    radial-gradient(circle at 50% 95%, rgb(var(--accent-2) / 0.06), transparent 45%);
  transition:opacity 0.35s var(--ease);
}
/* A faint paper-grain, reinforcing the "parchment" identity the warm
   palette already suggests with real tactile texture rather than a flat
   wash. Tuned separately for light and dark palettes — multiply reads
   as fine speckling on light parchment tones; on near-black dark
   surfaces multiply has almost nothing left to darken, so dark palettes
   use soft-light instead, which stays visible without washing out. Both
   were checked by rendering and measuring actual pixel variance before
   picking these values, not eyeballed. */
.grain-overlay{
  position:fixed; inset:0; pointer-events:none; z-index:0;
}
@media (prefers-reduced-motion: reduce), (forced-colors: active){
  /* Not motion, but the same audience that benefits from a visually
     quieter page — and forced-colors modes should never see a
     synthetic noise layer fighting the user's chosen palette. */
  .grain-overlay{ display:none; }
}

/* ---- Skip link (accessibility) ---- */
.skip-link{
  position:absolute; top:-60px; left:12px; z-index:300;
  background:rgb(var(--ink)); color:rgb(var(--on-ink));
  padding:12px 22px; border-radius:8px; font-weight:600; font-size:0.85rem;
  transition:top 0.2s var(--ease);
}
.skip-link:focus{ top:12px; outline:2px solid rgb(var(--accent-light)); }

/* =========================================================================
   2. READING PROGRESS BAR (global, most visible on single posts)
   ========================================================================= */

/* =========================================================================
   3. HEADER / NAVIGATION
   ========================================================================= */
/* The frosted background lives on a pseudo-element rather than on the
   header itself. This is deliberate: putting backdrop-filter directly on
   .site-header would make it the containing block for its position:fixed
   descendants, which broke the mobile drawer (it sized against the header
   instead of the viewport). With the blur on ::before, the header no
   longer traps fixed children, and the drawer fills the screen correctly. */
.site-main{ display:block; }
/*
 * v11.5 — THREE COLUMNS, SO THE NAV IS ACTUALLY IN THE MIDDLE.
 *
 * "the header has some design issues... and its not centered properly,
 * and its messy."
 *
 * It was `display:flex; justify-content:space-between` over three
 * children of very different widths. That does not centre anything: it
 * pins the logo left, pins the actions right, and drops the nav wherever
 * the leftover space happens to put it — which moves every time the
 * wordmark, the tagline or the number of icons changes, and moved again
 * when v11.1/v11.3 added Tafsīr and Adhkār. Measured at 1920px before
 * this change, the nav's centre sat 121px left of the page's.
 *
 * A three-track grid with the middle track sized to its content puts the
 * nav on the page's true centre line and keeps it there at every width,
 * whatever the two side columns contain. The columns are placed by
 * number rather than by source order on purpose: below 1180px the nav
 * becomes a fixed-position drawer and leaves the flow entirely, and with
 * explicit `grid-column` the logo and the actions stay in tracks 1 and 3
 * instead of collapsing into 1 and 2.
 */
/* The lockup is the one item allowed to give. */
/* The two auto margins are what centre the nav between the other two.
   `min-width:max-content` keeps it from being squeezed into a wrap. */
/* Every item in the actions row is a fixed-size tap target, and none of
   them may be compressed. */
/*
 * The bar gets a wider measure than the page it sits over.
 *
 * Measured at 1920px with every item present: logo 229 + nav 590 +
 * actions 280. A grid that centres the middle track needs BOTH side
 * tracks to be at least as wide as the widest of the two, so the row
 * needs 280+590+280 = 1150px of content box before the gaps. `.wrap` is
 * 1220px wide with 28px of padding each side, which leaves 1164 — seven
 * pixels of slack, i.e. the nav and the icons were one nav item away
 * from colliding, which is what they had already done at 1200px. This
 * is not a reading column; it is a rule of chrome across the top of the
 * window, and 1360 gives it the room the seven-item nav actually needs.
 */

.logo{ display:flex; align-items:center; gap:12px; flex-shrink:0; min-width:0; }
.logo-text{ min-width:0; }
.logo-text .name, .logo-text .tagline{
  display:block; min-width:0;
  /* v14.3 — clipped sideways only. `hidden` clips both axes, and with a
     line-height of 1 it was cutting the descender off the p of "Prophetic"
     in Literata, whose descenders are longer than Fraunces'. */
  overflow-x:clip; overflow-y:visible; text-overflow:ellipsis; white-space:nowrap;
}
.logo-mark{ width:40px; height:40px; flex-shrink:0; }
.logo-text{ display:flex; flex-direction:column; line-height:1.15; gap:3px; }
.logo-text .name{ font-family:var(--font-display); font-weight:600; font-size:1.28rem; color:rgb(var(--heading)); letter-spacing:-0.005em; line-height:1; }
.logo-text .tagline{ font-family:var(--font-body); font-style:italic; font-size:0.75rem; letter-spacing:0.01em; color:rgb(var(--accent)); text-transform:none; line-height:1.1; }

/*
 * v11.5 — THE ITEM IS THE PILL, NOT THE LABEL.
 *
 * The label and its caret were two separate controls with two separate
 * hover backgrounds and a -6px negative margin pulling them together.
 * Hovering "Qur'an" lit a pill that stopped short of the caret beside
 * it, so every dropdown item read as a button with a stray chevron
 * loose next to it — which is most of what "messy" was pointing at.
 *
 * The <li> now carries the pill and both children are transparent, so
 * one rounded shape lights up for the whole item however you approach
 * it. The caret still remains a real <button> and still toggles the
 * panel on its own, so nothing about the behaviour changes.
 */
/* --accent-ui: the hovered label is text sitting on a tint of its own
   colour. See the note on .lib-row-topic. */
/* The caret is its own small button, separate from the link, so the link
   navigates on click while the caret alone toggles the dropdown —
   appearance reset since, unlike .nav-link (mostly real <a> tags now),
   this always is a genuine <button>. It sits INSIDE the item's pill, so
   it carries no background of its own. */
/* Drawer-only nav items, hidden on desktop.
   v6.3 — this was a REAL, shipping bug, not a theoretical one: written
   as a bare `.nav-mobile-only{display:none}` (specificity 0,1,0) it lost
   outright to `.main-nav > ul > li{display:flex}` above (specificity
   0,1,2), so every drawer-only item stayed visible on desktop. That is
   exactly why "Subscribe" appeared TWICE in the header (once as the
   drawer CTA, once as the real desktop button) and why the old "Saved
   Reflections" text link sat next to its own icon. Verified by reading
   computed styles in a real rendered page at 1280px and 1440px, not by
   eye. Scoped through .site-header (0,2,0) so it wins on structure
   rather than on file order — the same reasoning applied to the mobile
   drawer rules further down. */
/* v8.0 — drawer items that exist ONLY on phones, because the controls they
   stand in for are still present as icons in the bar at wider widths (see
   `is-bar-overflow` in header.php). Same specificity trick as the line
   above and for the same reason: (0,2,0) beats `.main-nav > ul > li`'s
   (0,1,2) on class count, so this wins on structure rather than on where
   it happens to sit in the file. */

/* The drawer's install row is a real <button>, not a link, because
   installing is an action with no URL. .nav-link was written for anchors
   and never reset a button's user-agent chrome, so without this it would
   render as a grey OS button in the middle of a list of plain rows. */
/* The saved count, shown on the drawer row the way .icon-badge shows it on
   the header icon. Sits at the end of the row rather than floating over a
   corner, since a full-width row has somewhere sensible to put it. */


/*
 * v12.1 — AND THE THINGS INSIDE IT MAY NOT SHRINK EITHER.
 *
 * `.header-actions` said flex-shrink:0 about ITSELF, but its children kept
 * the flex default of 1, so the row's min-content width was far smaller
 * than the row actually needs. That is what defeated the grid fix above:
 * `minmax(auto,1fr)` sizes the track to the item's automatic minimum, and
 * the automatic minimum of a flex container is its min-content — which,
 * with shrinkable children, was ~180px for a 319px row. So the track was
 * allowed to be 284px and the buttons spilled 35px over the nav.
 *
 * Measured before and after across 1181-1920px: overlapping at 1185,
 * 1190, 1200 and 1220 before; clear at every width after.
 */
/* Hairline dividers between the three icon groups (reading & discovery |
   worship tools | app & chrome). Purely visual grouping, so they're
   aria-hidden in the markup and disappear on small screens where every
   pixel of the bar is needed. */
/*
 * v12.1 — THE TASBĪḤ BEAD LEAVES THE BAR.
 *
 * "remove the adhkar icon from header on PC version". It was already
 * hidden on phones (the drawer carries a labelled row for it), so with
 * the desktop copy gone it is simply not in the bar at any width — which
 * also gives the actions row back ~50px, and the actions row running out
 * of room is what had been pushing it over the nav.
 *
 * Nothing is lost: /tasbih/ is a top-level nav item (Adhkār), the drawer
 * has its own row, and the counter's saved progress is untouched.
 */
.site-header .header-actions .pp-tasbih-bead{ display:none; }

/* The Kaʿbah glyph is a filled isometric solid rather than a line drawing,
   so at the same box size it reads noticeably heavier than the strokes
   beside it. A hair smaller evens the row out optically. */

/* v12.0 — Prayer Times and Qibla, back in the bar as icons. They are the
   only <a> elements among the icon buttons, so they get the same current
   marking the nav links use: a tint of the accent, not a different
   colour, so the bar never shows two golds at once. */
/* The install button hides itself when there's nothing to install (app
   already installed, or a browser with no install path at all). Uses
   the `hidden` attribute, which is made reliable site-wide by the
   [hidden] rule in the base layer. */
.icon-badge{
  position:absolute; top:-4px; right:-4px; min-width:16px; height:16px; padding:0 4px;
  display:flex; align-items:center; justify-content:center; border-radius:999px;
  background:rgb(var(--accent-2)); color:rgb(var(--on-accent)); font-family:var(--font-mono);
  font-size:0.6rem; font-weight:700; line-height:1; border:2px solid rgb(var(--bg));
}

/* v11.5 — `.search-panel` was the 280px popover that hung off the header
   and could only find blog posts. It is a full command palette now
   (`.pp-cmd`, at the end of this file) and nothing emits this markup;
   its rules are gone rather than left to accumulate, which is the
   lesson of the four hundred lines of dead tafsir CSS this release also
   removed. The <form> keeps `id="searchPanel"` and nothing else. */

/* =========================================================================
   THE APPEARANCE PICKER — rebuilt in v8.0.

   The old picker was a scrolling three-column grid of 44px squares, each
   split diagonally into two of the palette's colours. Two problems with
   that, both of which this replaces rather than tunes:

   1. A diagonal two-tone square does not tell you what a PAGE in that
      palette looks like. Every one of them read as "a dark half and a light
      half", so choosing between ten of them was guesswork.
   2. Each palette had a sentence written to describe it, and that sentence
      lived in `title=` — a tooltip, which does not exist on a touchscreen.
      On a phone, the writing that explained the choice was invisible.

   Now: one row per palette. The swatch is a small rendering of an actual
   page — ground, card, heading bar, two lines of text, accent dot — built
   from the same generated values the palette itself uses. The description
   is real text next to it. And a Light/Dark segment above splits ten
   palettes into a six and a four, so the list is never long.
   ========================================================================= */
.theme-switcher{ position:relative; }
.theme-panel{
  position:absolute; right:0; top:calc(100% + 10px);
  width:330px; max-height:min(78vh, 560px);
  display:flex; flex-direction:column;
  padding:14px 14px 12px;
  opacity:0; visibility:hidden;
  z-index:20;
}
.theme-panel.open{ opacity:1; visibility:visible; }

.theme-panel-head{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:11px; }
.theme-panel-label{
  font-family:var(--font-mono); font-size:0.66rem; letter-spacing:0.1em;
  text-transform:uppercase; color:rgb(var(--text-muted));
}
/* The close button only earns its place on the phone sheet, where there is
   no "click outside the dropdown" gesture that feels deliberate. */
.theme-panel-close{
  display:none; width:34px; height:34px; margin:-6px -4px -6px 0;
  align-items:center; justify-content:center;
  background:transparent; border:none; border-radius:50%;
  color:rgb(var(--text-muted));
}
.theme-panel-close svg{ width:17px; height:17px; }
@media (hover: hover){ .theme-panel-close:hover{ background:rgb(var(--heading) / 0.07); color:rgb(var(--heading)); } }

/* ---- the Light / Dark segment ---- */
.theme-mode{
  position:relative; display:grid; grid-template-columns:1fr 1fr; gap:0;
  padding:3px; margin-bottom:12px;
  background:rgb(var(--heading) / 0.06); border-radius:999px;
}
/* The sliding thumb is one element moved with a transform rather than a
   background on whichever button is active, so the movement is animatable
   and costs no repaint. */
.theme-mode-thumb{
  position:absolute; top:3px; left:3px; width:calc(50% - 3px); height:calc(100% - 6px);
  border-radius:999px; background:rgb(var(--surface));
  box-shadow:0 1px 3px rgb(var(--shadow) / 0.18), 0 0 0 1px rgb(var(--heading) / 0.06);
  transition:transform 0.28s var(--ease);
}
.theme-panel[data-mode="dark"] .theme-mode-thumb{ transform:translateX(100%); }
.theme-mode-btn{
  position:relative; z-index:1;
  display:flex; align-items:center; justify-content:center; gap:7px;
  min-height:36px; padding:0 10px;
  background:transparent; border:none; border-radius:999px;
  font-family:var(--font-ui); font-size:0.8rem; font-weight:600;
  color:rgb(var(--text-muted));
  transition:color 0.2s var(--ease);
}
.theme-mode-btn svg{ width:14px; height:14px; flex-shrink:0; }
.theme-mode-btn[aria-pressed="true"]{ color:rgb(var(--heading)); }

/* ---- the list ---- */
.theme-panel-body{ overflow-y:auto; margin:0 -4px; padding:0 4px; }
.theme-options{ display:flex; flex-direction:column; gap:3px; }
.theme-option{
  display:flex; align-items:center; gap:12px; width:100%;
  padding:8px 10px 8px 8px; text-align:left;
  border-radius:12px; border:1px solid transparent; background:transparent;
}
@media (hover: hover){ .theme-option:hover{ background:rgb(var(--wash) / 0.07); } }
.theme-option[aria-pressed="true"]{
  border-color:rgb(var(--wash) / 0.35); background:rgb(var(--wash) / 0.08);
}

/* ---- the miniature page ----
   Painted entirely from the --sw-* custom properties emitted by
   tools/gen_palettes.py for this palette, so it shows the real colours of
   the theme it applies and cannot drift from them. */
.theme-preview{
  position:relative; flex-shrink:0;
  width:52px; height:40px; border-radius:9px; overflow:hidden;
  background:var(--sw-bg);
  border:1px solid var(--sw-edge);
  transition:box-shadow 0.2s var(--ease);
}
.theme-preview-card{
  position:absolute; inset:6px 5px 5px 6px;
  display:flex; flex-direction:column; gap:3px;
  padding:4px; border-radius:4px;
  background:var(--sw-surface);
  box-shadow:0 1px 2px rgb(0 0 0 / 0.08);
}
.theme-preview-bar{ height:4px; width:74%; border-radius:1px; background:var(--sw-head); }
.theme-preview-line{ height:2px; width:100%; border-radius:1px; background:var(--sw-text); opacity:0.55; }
.theme-preview-line.is-short{ width:62%; }
.theme-preview-dot{
  position:absolute; right:4px; bottom:4px; width:9px; height:9px; border-radius:50%;
  background:var(--sw-accent); box-shadow:0 0 0 1.5px var(--sw-bg);
}

.theme-option-text{ display:flex; flex-direction:column; gap:1px; min-width:0; flex:1; }
.theme-option-name{ font-size:0.86rem; font-weight:600; color:rgb(var(--heading)); line-height:1.25; }
.theme-option-blurb{
  font-size:0.72rem; line-height:1.35; color:rgb(var(--text-muted));
}
.theme-option-tick{
  flex-shrink:0; width:20px; height:20px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:rgb(var(--accent)); color:rgb(var(--on-accent));
  opacity:0; transform:scale(0.7);
  transition:opacity 0.18s var(--ease), transform 0.18s var(--ease);
}
.theme-option-tick svg{ width:12px; height:12px; }
.theme-option[aria-pressed="true"] .theme-option-tick{ opacity:1; transform:scale(1); }

/* The grab handle and backdrop only exist on the phone sheet. */
.theme-sheet-grip{ display:none; }
.theme-sheet-backdrop{
  position:fixed; inset:0; z-index:99;
  background:rgb(var(--ink) / 0.42);
  -webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px);
  opacity:0; visibility:hidden; transition:opacity 0.3s var(--ease), visibility 0.3s;
}
body.theme-sheet-open .theme-sheet-backdrop{ opacity:1; visibility:visible; }

/* The appearance-picker swatch values. Regenerated alongside the palettes by
   tools/gen_palettes.py — these are the ONLY hardcoded colours left in the
   stylesheet, because a swatch has to show a palette without that palette
   being active. They were hand-copied before v7.1, and after that release's
   palette rebuild every one of them advertised a colour the site no longer
   used: the picker was showing eight swatches that did not match the eight
   themes they applied. Generating them is what makes that impossible. */
/* ==== BEGIN GENERATED SWATCHES — do not edit by hand ==== */
.theme-option[data-swatch="saffron"]{ --sw-bg:rgb(250 238 212); --sw-surface:rgb(251 244 225); --sw-head:rgb(20 70 52); --sw-text:rgb(84 96 84); --sw-accent:rgb(22 92 68); --sw-edge:rgb(20 70 52 / 0.16); }
.theme-option[data-swatch="frost"]{ --sw-bg:rgb(238 246 253); --sw-surface:rgb(249 253 255); --sw-head:rgb(12 38 62); --sw-text:rgb(80 100 122); --sw-accent:rgb(13 97 148); --sw-edge:rgb(12 38 62 / 0.16); }
.theme-option[data-swatch="rose"]{ --sw-bg:rgb(253 238 243); --sw-surface:rgb(255 248 251); --sw-head:rgb(122 12 58); --sw-text:rgb(116 76 90); --sw-accent:rgb(190 18 88); --sw-edge:rgb(122 12 58 / 0.16); }
.theme-option[data-swatch="emerald"]{ --sw-bg:rgb(233 250 240); --sw-surface:rgb(246 253 249); --sw-head:rgb(2 68 45); --sw-text:rgb(72 106 86); --sw-accent:rgb(0 120 76); --sw-edge:rgb(2 68 45 / 0.16); }
.theme-option[data-swatch="obsidian"]{ --sw-bg:rgb(18 17 15); --sw-surface:rgb(30 29 25); --sw-head:rgb(248 245 238); --sw-text:rgb(166 160 148); --sw-accent:rgb(216 176 88); --sw-edge:rgb(248 245 238 / 0.16); }
.theme-option[data-swatch="midnight"]{ --sw-bg:rgb(11 20 41); --sw-surface:rgb(25 39 70); --sw-head:rgb(238 246 255); --sw-text:rgb(150 170 200); --sw-accent:rgb(126 182 244); --sw-edge:rgb(238 246 255 / 0.16); }
.theme-option[data-swatch="velvet"]{ --sw-bg:rgb(28 14 23); --sw-surface:rgb(46 25 38); --sw-head:rgb(255 240 247); --sw-text:rgb(186 156 172); --sw-accent:rgb(236 168 192); --sw-edge:rgb(255 240 247 / 0.16); }
.theme-option[data-swatch="juniper"]{ --sw-bg:rgb(12 30 24); --sw-surface:rgb(24 48 38); --sw-head:rgb(240 252 244); --sw-text:rgb(157 183 167); --sw-accent:rgb(108 222 168); --sw-edge:rgb(240 252 244 / 0.16); }
/* ==== END GENERATED SWATCHES ==== */

.btn{
  display:inline-flex; align-items:center; gap:8px;
  padding:12px 22px; border-radius:999px; font-size:0.88rem; font-weight:600;
  border:1px solid transparent;
}
.btn-primary{
  /* The base declaration only. The gilded surface — gradient, edge,
     burnish, press — is described once, in section "THE ACTION COLOUR"
     near the foot of this file, so there is one place to read and one
     place to change. v12.3 left two competing definitions here and the
     later one silently won; that is why this one is now deliberately
     thin rather than deleted (plenty of markup still keys off it). */
  background:rgb(var(--gilt));
  color:rgb(var(--on-gilt));
}
.btn-primary:disabled{ opacity:0.55; cursor:default; transform:none; }
.btn-sm{ padding:9px 16px; font-size:0.8rem; }

.hp-field{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }

/* =========================================================================
   4. HERO
   ========================================================================= */
.hero{ position:relative; z-index:1; }
.hero-frame{
  position:relative; border:1px solid rgb(var(--ornament) / 0.35);
  text-align:center; overflow:hidden;
  background:
    radial-gradient(ellipse 60% 50% at 50% 0%, rgb(var(--ornament) / 0.08), transparent 70%),
    linear-gradient(180deg, rgb(var(--surface) / 0.55), rgb(var(--surface) / 0));
}
/* Two oversized copies of the site's own logo mark, bled off opposite
   corners at very low opacity — ties the hero back to the brand mark
   instead of a generic gradient, without competing with the text.
   Asymmetric placement (different sizes, opposite corners) reads as
   more considered than a mirrored, perfectly symmetric pair. */
.hero-watermark{ position:absolute; color:rgb(var(--accent)); opacity:0.05; pointer-events:none; z-index:0; }
.hero-watermark-1{ transform:rotate(12deg); }
.hero-watermark-2{ transform:rotate(-18deg); }
.corner{ position:absolute; color:rgb(var(--accent)); }
.corner.tr{ transform:scaleX(-1); }
.corner.bl{ transform:scaleY(-1); }
.corner.br{ transform:scale(-1,-1); }

.hero-content{ margin:0 auto; position:relative; z-index:1; }
.hero .eyebrow{ display:block; }
.hero h1{ font-size:clamp(2.4rem, 6vw, 3.7rem); letter-spacing:-0.01em; }

/* A calm, elegant tagline: a single line of italic display serif, no
   flanking rules or dots — it sits quietly under the wordmark. */
.hero .sub{
  display:block; text-align:center;
  font-family:var(--font-display); font-style:italic; font-weight:500;
  letter-spacing:0;
  color:rgb(var(--accent)); text-transform:none;
}

.hero p.desc{ color:rgb(var(--text-muted)); margin-left:auto; margin-right:auto; }
.hero-ctas{ display:flex; justify-content:center; flex-wrap:wrap; }

.hero-stats{ display:flex; align-items:center; justify-content:center; flex-wrap:wrap; }
.hero-stat{ display:flex; flex-direction:column; align-items:center; gap:2px; }
.hero-stat-num{ font-family:var(--font-display); font-weight:600; color:rgb(var(--heading)); line-height:1; }
.hero-stat-label{ font-family:var(--font-mono); letter-spacing:0.06em; text-transform:uppercase; color:rgb(var(--text-muted)); }
.hero-stat-divider{ width:1px; background:rgb(var(--heading) / 0.15); }

/* =========================================================================
   5. REVEAL / SECTION SHELL
   ========================================================================= */

section{ position:relative; z-index:1; }
/* v12.5 — padding-BLOCK, not the shorthand.
   `.wrap` sets `padding: 0 28px` and every one of these sections is also
   a `.wrap`; the shorthand here therefore reset the horizontal padding to
   zero on all of them. Measured at 1440px: the breadcrumb trail (a .wrap
   that is not a .section-pad) began at x=133 and the page content under
   it began at x=105 — twenty-eight pixels of misalignment on every
   archive, every collection, every tool page. Reported as "the
   navigation Home > … bar is also weirdly placed". */
.section-pad{ padding-block:72px; }
.section-header{ display:flex; align-items:flex-end; justify-content:space-between; margin-bottom:36px; gap:20px; flex-wrap:wrap; }
.section-header h2{ margin-top:6px; }
.view-all{ font-size:0.85rem; font-weight:600; color:rgb(var(--accent)); display:inline-flex; align-items:center; gap:6px; }
.view-all svg{ width:14px; height:14px; transition:transform 0.2s var(--ease); }
@media (hover: hover){ .view-all:hover svg{ transform:translateX(4px); } }

/* =========================================================================
   6. SPOTLIGHT (featured post + reflection)
   ========================================================================= */
/* align-items:start (not stretch) lets the reflection card size itself
   to its own content instead of stretching to match the featured post. */
.spotlight-grid{ display:grid; grid-template-columns:1.5fr 1fr; gap:26px; align-items:start; }

.featured-card{
  border-radius:20px; overflow:hidden;
  background:linear-gradient(155deg, rgb(var(--surface)) 0%, rgb(var(--surface)) 55%, rgb(var(--heading) / 0.035) 130%);
  box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5), 0 10px 30px -12px rgb(var(--shadow) / 0.25); border:1px solid rgb(var(--heading) / 0.06);
  transition:box-shadow 0.35s var(--ease), transform 0.35s var(--ease); display:flex; flex-direction:column;
}
@media (hover: hover){
  .featured-card:hover{ box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5), 0 24px 50px -18px rgb(var(--shadow) / 0.4); transform:translateY(-4px); }
}
.featured-cover{
  height:230px; overflow:hidden;
}
.featured-cover img{ width:100%; height:100%; object-fit:cover; }
.tag-chip{
  display:inline-block; font-family:var(--font-mono); font-size:0.66rem; letter-spacing:0.06em;
  text-transform:uppercase; padding:5px 11px; border-radius:999px; font-weight:500;
}
/* v8.0 — the gold chip's LABEL is now --accent-ui, not --accent.
   --accent is the fill token: it is tuned to be dark enough to carry white
   text on top of it. --accent-ui is the same colour tuned for the opposite
   job, being read AS text against the page. This chip is a foreground use
   and had been using the fill value, which is precisely the confusion the
   three-way accent split was introduced to end — it was simply never
   applied here. Measured on a rendered page it failed at 4.14:1 on
   Parchment, 4.29:1 on Graphite and 4.07:1 on Midnight.

   The 14% background tint stays on --accent-ui too, so the chip keeps
   reading as one colour rather than a wash of one and a label of another. */
.tag-gold{ background:rgb(var(--wash) / 0.14); color:rgb(var(--accent-ui)); }
.tag-rust{ background:rgb(var(--accent-2) / 0.14); color:rgb(var(--accent-2)); }
.tag-sage{ background:rgb(var(--accent-3) / 0.14); color:rgb(var(--accent-3)); }

.featured-body{ padding:26px 28px 28px; display:flex; flex-direction:column; gap:12px; flex:1; }
.featured-body h3{ font-size:1.75rem; line-height:1.25; }
.featured-body h3 a{ transition:color 0.2s var(--ease); }
@media (hover: hover){ .featured-body h3 a:hover{ color:rgb(var(--accent)); } }
.featured-body p{ color:rgb(var(--text-muted)); font-size:0.95rem; margin:0; line-height:1.65; }

/* On covers with no featured image, a single centred logo watermark
   sits over the gradient — calm, branded, and far quieter than the old
   tiled geometry. */
.cover-ornament{
  position:absolute; inset:0; margin:auto;
  width:44%; max-width:132px; aspect-ratio:1 / 1; height:auto;
  pointer-events:none;
}
.featured-cover .cover-ornament{ width:34%; max-width:150px; }

/* -------- "moment to reflect" card — self-sized, richer treatment -------- */
.reflection-card{
  position:relative; overflow:hidden;
  background:rgb(var(--ink)); color:rgb(var(--on-ink)); border-radius:22px; padding:30px 30px 26px;
  display:flex; flex-direction:column;
  box-shadow:0 20px 50px -20px rgb(var(--shadow) / 0.45);
  border:1px solid rgb(var(--on-ink) / 0.08);
  transition:background 0.35s var(--ease), color 0.35s var(--ease), border-color 0.35s var(--ease);
}
.reflection-card:focus-visible{ outline:2px solid rgb(var(--accent-light)); outline-offset:3px; }
/* a quiet two-tone glow behind the content, echoing the site's own
   bg-texture treatment so the card reads as part of the same design
   language rather than a plain flat box */
.reflection-glow{
  position:absolute; inset:0; pointer-events:none; opacity:0.9;
  background:
    radial-gradient(circle at 8% -10%, rgb(var(--accent-light) / 0.20), transparent 48%),
    radial-gradient(circle at 100% 115%, rgb(var(--accent-3) / 0.16), transparent 50%);
}
/* a large, quiet quotation glyph sitting behind the text — a common,
   elegant editorial cue that this is a quoted line, not a headline */
.reflection-card::after{
  position:absolute; top:-0.28em; right:0.22em;
  font-family:var(--font-display); font-size:7em; line-height:1; font-weight:600;
  color:rgb(var(--on-ink) / 0.06); pointer-events:none;
}
.reflection-head{ position:relative; display:flex; align-items:center; }
.reflection-head .eyebrow{ display:inline-flex; align-items:center; gap:8px; color:rgb(var(--accent-light)); font-size:0.68rem; }
.reflection-star{ width:15px; height:15px; color:rgb(var(--accent-light)); flex-shrink:0; }
.quote-text{
  position:relative;
  font-family:var(--font-display); font-style:italic; font-weight:500; font-size:1.2rem; line-height:1.55;
  flex:1; margin:16px 0 0; transition:opacity 0.35s ease, transform 0.35s ease;
}
.quote-text.fade{ opacity:0; transform:translateY(4px); }
.reflection-controls{ position:relative; display:flex; align-items:center; justify-content:space-between; gap:18px; }
.reflection-progress{ flex:1; min-width:0; display:flex; flex-direction:column; gap:7px; }
.reflection-count{ font-family:var(--font-mono); font-size:0.66rem; letter-spacing:0.06em; color:rgb(var(--on-ink) / 0.55); }
.reflection-track{ height:3px; border-radius:999px; background:rgb(var(--on-ink) / 0.14); overflow:hidden; max-width:180px; }
.reflection-fill{ height:100%; width:0%; border-radius:999px; transition:width 0.4s var(--ease); }
.arrow-pair{ display:flex; gap:8px; flex-shrink:0; }
.arrow-btn{
  width:32px; height:32px; border-radius:50%; border:1px solid rgb(var(--on-ink) / 0.22); background:rgb(var(--on-ink) / 0.04);
  color:rgb(var(--on-ink)); display:flex; align-items:center; justify-content:center; transition:background 0.2s var(--ease), border-color 0.2s var(--ease), transform 0.2s var(--ease);
}
@media (hover: hover){
  .arrow-btn:hover{ background:rgb(var(--accent-light) / 0.18); border-color:rgb(var(--accent-light)); transform:translateY(-1px); }
}
.arrow-btn:active{ transform:translateY(0); }
.arrow-btn svg{ width:13px; height:13px; }


/* =========================================================================
   7. TOPICS
   ========================================================================= */
.topics-grid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(240px, 1fr)); gap:22px; }

.topic-tile{
  display:block; border:1px solid rgb(var(--heading) / 0.07); border-radius:20px;
  background:linear-gradient(155deg, rgb(var(--surface)) 0%, rgb(var(--surface)) 55%, rgb(var(--heading) / 0.035) 130%);
  box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5);
  padding:0; transition:transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
  position:relative; overflow:hidden;
}
.topic-tile-inner{ position:relative; padding:28px 24px; z-index:1; }
.topic-tile::before{
  content:''; position:absolute; inset:0; opacity:0; transition:opacity 0.35s var(--ease);
  background:radial-gradient(circle at 85% -10%, rgb(var(--tile-accent, var(--accent)) / 0.16), transparent 60%);
}
@media (hover: hover){
  .topic-tile:hover{ transform:translateY(-7px); box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5), 0 24px 50px -18px rgb(var(--shadow) / 0.35); border-color:rgb(var(--tile-accent, var(--accent)) / 0.4); }
  .topic-tile:hover::before{ opacity:1; }
}
.topic-tile:nth-of-type(3n+2){ --tile-accent: var(--accent-2); }
.topic-tile:nth-of-type(3n+3){ --tile-accent: var(--accent-3); }

.topic-icon{
  width:48px; height:48px; border-radius:14px; background:rgb(var(--tile-accent, var(--accent)) / 0.12);
  display:flex; align-items:center; justify-content:center; color:rgb(var(--tile-accent, var(--accent))); margin-bottom:18px;
  transition:background 0.3s var(--ease), transform 0.3s var(--ease), color 0.3s var(--ease);
}
@media (hover: hover){
  .topic-tile:hover .topic-icon{ background:rgb(var(--tile-accent, var(--accent))); color:rgb(var(--on-accent)); transform:rotate(-6deg) scale(1.07); }
}
.topic-icon svg{ width:23px; height:23px; }
.topic-tile h3{ font-size:1.28rem; margin-bottom:7px; line-height:1.3; }
.topic-tile p{ color:rgb(var(--text-muted)); font-size:0.87rem; margin:0 0 16px; line-height:1.55; }
.topic-count{ font-family:var(--font-mono); font-size:0.7rem; color:rgb(var(--text-muted)); display:flex; align-items:center; gap:6px; }
.topic-count svg{ width:12px; height:12px; transition:transform 0.25s var(--ease); }
@media (hover: hover){
  .topic-tile:hover .topic-count svg{ transform:translateX(4px); color:rgb(var(--tile-accent, var(--accent))); }
}

.topic-tile.is-placeholder{
  background:transparent; box-shadow:none; border-style:dashed; border-color:rgb(var(--heading) / 0.18); cursor:default;
}
.topic-tile.is-placeholder::before{ display:none; }
@media (hover: hover){ .topic-tile.is-placeholder:hover{ transform:none; box-shadow:none; border-color:rgb(var(--heading) / 0.28); } }
.topic-tile.is-placeholder .topic-icon{ background:rgb(var(--heading) / 0.06); color:rgb(var(--text-muted)); }
@media (hover: hover){
  .topic-tile.is-placeholder:hover .topic-icon{ transform:none; background:rgb(var(--heading) / 0.06); color:rgb(var(--text-muted)); }
}
.topic-tile.is-placeholder .topic-count{ color:rgb(var(--accent)); font-weight:600; }

/* =========================================================================
   8. WELCOME / VALUE-PROP CARDS
   ========================================================================= */
.welcome-grid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(240px, 1fr)); gap:24px; }
.welcome-card{
  border:1px solid rgb(var(--heading) / 0.08); border-radius:var(--radius);
  background:linear-gradient(155deg, rgb(var(--surface)) 0%, rgb(var(--surface)) 55%, rgb(var(--heading) / 0.035) 130%);
  box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5);
  padding:36px 30px; text-align:center; transition:transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
}
@media (hover: hover){
  .welcome-card:hover{ transform:translateY(-6px); box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5), 0 20px 45px -18px rgb(var(--shadow) / 0.3); border-color:rgb(var(--wash) / 0.3); }
}
.welcome-icon{
  width:54px; height:54px; border-radius:50%; background:rgb(var(--wash) / 0.12); color:rgb(var(--accent));
  display:flex; align-items:center; justify-content:center; margin:0 auto 18px; transition:transform 0.3s var(--ease);
}
@media (hover: hover){ .welcome-card:hover .welcome-icon{ transform:scale(1.08); } }
.welcome-icon svg{ width:24px; height:24px; }
.welcome-card h3{ font-size:1.2rem; margin-bottom:9px; }
.welcome-card p{ color:rgb(var(--text-muted)); font-size:0.92rem; margin:0; line-height:1.6; }

/* =========================================================================
   9. ARTICLES GRID
   ========================================================================= */

/* =========================================================================
   10. ESSAYS LIST
   ========================================================================= */
.essays-list{ display:grid; grid-template-columns:1fr 1fr; gap:2px 32px; }
.essay-link{
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  padding:16px 4px; border-bottom:1px solid rgb(var(--heading) / 0.08);
  font-size:0.97rem; font-weight:500; color:rgb(var(--heading-soft));
  transition:color 0.2s var(--ease), padding-left 0.2s var(--ease);
}
.essay-link svg{ width:14px; height:14px; flex-shrink:0; color:rgb(var(--accent)); opacity:0; transform:translateX(-4px); transition:opacity 0.2s var(--ease), transform 0.2s var(--ease); }
@media (hover: hover){
  .essay-link:hover{ color:rgb(var(--accent)); padding-left:8px; }
  .essay-link:hover svg{ opacity:1; transform:translateX(0); }
}

/* =========================================================================
   11. NEWSLETTER
   ========================================================================= */
.newsletter-band{ color:rgb(var(--on-ink)); padding:58px 48px; text-align:center; transition:background 0.35s var(--ease), color 0.35s var(--ease); }
.newsletter-band::before{
  content:''; position:absolute; inset:0;
  background-image: radial-gradient(circle at 20% 30%, rgb(var(--wash) / 0.18), transparent 40%), radial-gradient(circle at 82% 70%, rgb(var(--accent-3) / 0.16), transparent 40%);
}
.newsletter-inner{ position:relative; max-width:520px; margin:0 auto; }
.newsletter-band h2{ color:rgb(var(--on-ink)); font-size:2.05rem; }
.newsletter-band p{ color:rgb(var(--on-ink) / 0.75); margin-top:10px; font-size:0.95rem; }
.newsletter-form{ display:flex; gap:10px; margin-top:26px; flex-wrap:wrap; justify-content:center; }
.newsletter-form input[type="email"]{
  flex:1; min-width:220px; padding:13px 18px; border-radius:999px; border:1px solid rgb(var(--on-ink) / 0.25);
  background:rgb(var(--on-ink) / 0.06); color:rgb(var(--on-ink)); font-family:var(--font-ui); font-size:0.92rem;
  transition:border-color 0.2s var(--ease), background 0.2s var(--ease);
}
.newsletter-form input[type="email"]::placeholder{ color:rgb(var(--on-ink) / 0.5); }
.newsletter-form input[type="email"]:focus{ outline:none; border-color:rgb(var(--accent-light)); background:rgb(var(--on-ink) / 0.1); }
.form-note{ font-size:0.74rem; color:rgb(var(--on-ink) / 0.55); margin-top:14px; }
.form-message{ font-size:0.85rem; margin-top:14px; color:rgb(var(--accent-light)); min-height:1.2em; font-weight:500; }
.form-message.is-error{ color:#e2a798; }

/* =========================================================================
   12. FOOTER (3 columns: brand / topics / site)
   ========================================================================= */
.site-footer{ color:rgb(var(--on-ink) / 0.75); padding:58px 0 calc(28px + env(safe-area-inset-bottom)); margin-top:20px; transition:background 0.35s var(--ease), color 0.35s var(--ease); }
/* v11.5 — five tracks: the brand, then Topics, Read, Practise and
   Site. The fourth column was added when the Hadith list of
   fourteen books was split into two shorter, named sections. */
.footer-grid{ display:grid; grid-template-columns:1.2fr 0.85fr 1fr 0.85fr 0.85fr; gap:32px; }
.footer-brand .logo-text .name{ color:rgb(var(--on-ink)); }
.footer-brand p{ font-size:0.88rem; margin-top:14px; max-width:280px; color:rgb(var(--on-ink) / 0.6); line-height:1.6; }
.footer-social{ display:flex; gap:8px; margin-top:18px; }
.footer-social a{
  width:34px; height:34px; border-radius:50%; border:1px solid rgb(var(--on-ink) / 0.2);
  display:flex; align-items:center; justify-content:center; color:rgb(var(--on-ink) / 0.7);
  transition:background 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
}
@media (hover: hover){
  .footer-social a:hover{ background:rgb(var(--accent-light)); border-color:rgb(var(--accent-light)); color:rgb(var(--ink)); }
}
.footer-social svg{ width:15px; height:15px; }
.footer-col h4{ font-family:var(--font-mono); font-size:0.7rem; letter-spacing:0.1em; text-transform:uppercase; color:rgb(var(--accent-light)); margin:0 0 16px; font-weight:500; }
.footer-col ul{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:11px; }
.footer-col a{ font-size:0.88rem; }
.footer-bottom{ border-top:1px solid rgb(var(--on-ink) / 0.1); margin-top:46px; padding-top:22px; display:flex; justify-content:space-between; flex-wrap:wrap; gap:10px; font-size:0.76rem; color:rgb(var(--on-ink) / 0.45); }

/* =========================================================================
   13. BACK TO TOP
   ========================================================================= */
.back-top{
  position:fixed; right:calc(24px + env(safe-area-inset-right)); bottom:calc(24px + env(safe-area-inset-bottom)); width:44px; height:44px; border-radius:50%;
  background:rgb(var(--ink)); color:rgb(var(--on-ink)); display:flex; align-items:center; justify-content:center;
  border:none; box-shadow:0 20px 45px -18px rgb(var(--shadow) / 0.4); opacity:0; visibility:hidden; transform:translateY(10px);
  z-index:90;
}
.back-top.show{ opacity:1; visibility:visible; transform:translateY(0); }
@media (hover: hover){ .back-top:hover{ background:rgb(var(--accent)); color:rgb(var(--on-accent)); } }
.back-top svg{ width:16px; height:16px; }

/* =========================================================================
   14. BREADCRUMBS
   ========================================================================= */
/* v11.5 — the trail carries its own `.wrap` now and the layout moved to
   section 6 of the v11.5 layer at the end of this file. What is left
   here is the colour, which nothing later overrides. */
.breadcrumbs a{ color:rgb(var(--text-muted)); }

/* =========================================================================
   15. 404 / SEARCH EMPTY STATES
   ========================================================================= */
.not-found-shell{ max-width:560px; margin:0 auto; text-align:center; padding:60px 20px; }
.not-found-icon{ width:52px; height:52px; color:rgb(var(--accent)); margin:0 auto 20px; opacity:0.8; }
.not-found-shell h1{ font-size:clamp(1.8rem,4vw,2.5rem); margin-top:4px; }
.not-found-shell p{ color:rgb(var(--text-muted)); margin-top:14px; line-height:1.7; }
.not-found-search{ display:flex; gap:10px; margin:28px 0; flex-wrap:wrap; justify-content:center; }
.not-found-search input{
  flex:1; min-width:220px; padding:13px 18px; border-radius:999px; border:1px solid rgb(var(--heading) / 0.18);
  background:rgb(var(--surface)); color:rgb(var(--text)); font-family:var(--font-ui); font-size:0.92rem;
}
.not-found-search input:focus{ outline:none; border-color:rgb(var(--accent)); }
.not-found-links{ display:flex; gap:10px; justify-content:center; flex-wrap:wrap; margin-bottom:36px; }
.not-found-recent{ text-align:left; margin-top:36px; padding-top:28px; border-top:1px solid rgb(var(--heading) / 0.1); }

/* =========================================================================
   16. ENTRY CONTENT (article & page prose) + ARABIC / QUR'AN TYPOGRAPHY
   ========================================================================= */
.entry-content{
  font-family:var(--font-body); font-size:1.09rem; line-height:1.8; color:rgb(var(--text));
}

/* =========================================================================
   READABLE POSTS ON EVERY APPEARANCE BUT THE DEFAULT — v11.0

   THE PROBLEM. A colour picked by hand in the editor is checked against
   exactly one background: Parchment, the palette that was open while
   writing. This site has nine others, four of them dark. Black body text
   chosen on cream is invisible on Obsidian; a pale yellow heading chosen
   for emphasis vanishes on Ivory. The reader has no way to fix it and no
   way to know why.

   WHY v10.2's ATTEMPT DIDN'T WORK. It matched only `.has-text-color` —
   the CLASS WordPress adds when a colour comes from the theme palette.
   But a custom colour picked from the editor's colour wheel, and every
   colour on older or pasted content, is written as an INLINE STYLE
   (`style="color:#000"`), which carries no class at all. That is the
   common case, so the rule almost never fired. Inline styles also beat
   any normal stylesheet rule, so `!important` is required here — it is
   the one place on this site where it is the correct tool rather than a
   shortcut.

   WHAT IT DOES NOW. On every palette EXCEPT the default, one calm,
   readable colour replaces whatever was set: `--text` for body copy,
   `--heading` for headings — both already proven against that palette's
   own background by tools/gen_palettes.py. Inline backgrounds are
   neutralised in the same pass, because leaving a hand-picked background
   under corrected text just moves the collision.

   PARCHMENT IS UNTOUCHED, deliberately and permanently. It is what every
   post was written and proofed against, so on the default appearance a
   post renders exactly as its author intended, down to the colour.

   `[style*="color"]` also matches `background-color`, which is fine and
   in fact wanted: an element carrying a hand-set background is exactly
   one whose text colour should be re-derived too. Buttons and the
   theme's own Qur'an blocks are excluded — a button's two colours were
   chosen as a pair, and correcting one half without the other makes it
   worse rather than better.
   ========================================================================= */
html[data-flatten="1"] .entry-content [style*="color"]:not(.wp-block-button__link):not(.quran-text):not(.quran-text *),
html[data-flatten="1"] .entry-content .has-text-color:not(.wp-block-button__link),
html[data-flatten="1"] .entry-content font[color]{
  color: rgb(var(--text)) !important;
}
html[data-flatten="1"] .entry-content h1[style*="color"],
html[data-flatten="1"] .entry-content h2[style*="color"],
html[data-flatten="1"] .entry-content h3[style*="color"],
html[data-flatten="1"] .entry-content h4[style*="color"],
html[data-flatten="1"] .entry-content h5[style*="color"],
html[data-flatten="1"] .entry-content h6[style*="color"],
html[data-flatten="1"] .entry-content h1.has-text-color,
html[data-flatten="1"] .entry-content h2.has-text-color,
html[data-flatten="1"] .entry-content h3.has-text-color,
html[data-flatten="1"] .entry-content h4.has-text-color,
html[data-flatten="1"] .entry-content h5.has-text-color,
html[data-flatten="1"] .entry-content h6.has-text-color{
  color: rgb(var(--heading)) !important;
}
/* Strong/em/mark/links inside a corrected run follow it, rather than
   keeping an inherited inline colour of their own. */
html[data-flatten="1"] .entry-content [style*="color"] strong,
html[data-flatten="1"] .entry-content [style*="color"] em,
html[data-flatten="1"] .entry-content [style*="color"] span:not([style*="color"]){
  color: inherit !important;
}
/* A link keeps being a link — the accent, which is contrast-checked on
   every palette, not the body colour. */
html[data-flatten="1"] .entry-content a[style*="color"],
html[data-flatten="1"] .entry-content a.has-text-color{
  color: rgb(var(--accent-ui)) !important;
}
html[data-flatten="1"] .entry-content [style*="background"]:not(.wp-block-button__link):not(img):not(figure),
html[data-flatten="1"] .entry-content .has-background:not(.wp-block-button__link){
  background-color: rgb(var(--bg-alt)) !important;
}
.entry-content h1, .entry-content h2, .entry-content h3, .entry-content h4{
  font-family:var(--font-display); color:rgb(var(--heading)); margin:1.5em 0 0.55em; line-height:1.3;
}
.entry-content h2{ font-size:1.6rem; }
.entry-content h3{ font-size:1.3rem; }
.entry-content p{ margin:0 0 1.3em; }
.entry-content a{ color:rgb(var(--accent)); text-decoration:underline; text-decoration-color:rgb(var(--wash) / 0.4); text-underline-offset:3px; transition:color 0.2s var(--ease), text-decoration-color 0.2s var(--ease); }
@media (hover: hover){ .entry-content a:hover{ color:rgb(var(--accent-2)); text-decoration-color:currentColor; } }
.entry-content img{ max-width:100%; height:auto; border-radius:16px; margin:1.6em 0; cursor:zoom-in; }
.entry-content blockquote{
  background:rgb(var(--wash) / 0.06); font-weight:500;
  border-radius:0 12px 12px 0;
}
.entry-content ul, .entry-content ol{ margin:0 0 1.3em; padding-left:1.4em; }
.entry-content li{ margin-bottom:0.45em; }
.entry-content hr{ border:none; border-top:1px solid rgb(var(--heading) / 0.15); margin:2.2em 0; }

/* -- inline image alignment (classic WordPress alignleft/alignright,
   plus figure/figcaption for captioned images) -- */
.entry-content .alignleft{ float:left; margin:0.4em 1.6em 1em 0; max-width:42%; }
.entry-content .alignright{ float:right; margin:0.4em 0 1em 1.6em; max-width:42%; }
.entry-content .aligncenter{ margin-left:auto; margin-right:auto; float:none; }
.entry-content .alignleft img, .entry-content .alignright img{ margin:0; }
.entry-content figure{ margin:1.6em 0; }
.entry-content figure.alignleft, .entry-content figure.alignright{ margin-top:0.4em; }
.entry-content figcaption{
  font-family:var(--font-ui); font-size:0.78rem; color:rgb(var(--text-muted)); text-align:center;
  margin-top:8px; line-height:1.5;
}
.entry-content::after{ content:''; display:table; clear:both; }

/* -- tables & code, for completeness on posts that use them -- */
.entry-content table{ width:100%; border-collapse:collapse; margin:1.8em 0; font-size:0.92em; }
.entry-content th, .entry-content td{ padding:10px 14px; border:1px solid rgb(var(--heading) / 0.12); text-align:left; }
.entry-content th{ background:rgb(var(--bg-alt)); font-weight:600; color:rgb(var(--heading)); }
.entry-content tr:nth-child(even) td{ background:rgb(var(--heading) / 0.02); }
.entry-content code{ font-family:var(--font-code); font-size:0.85em; background:rgb(var(--heading) / 0.07); padding:0.15em 0.4em; border-radius:4px; }
.entry-content pre{ background:rgb(var(--ink)); color:rgb(var(--on-ink)); padding:20px 22px; border-radius:12px; overflow-x:auto; margin:1.8em 0; }
.entry-content pre code{ background:none; padding:0; color:inherit; }

/* -- general Arabic prose (hadith text, ayah citations, attributions) -- */
.entry-content :lang(ar),
.arabic-text{
  font-family:var(--font-arabic); font-weight: var(--ar-weight);
  direction:rtl;
  unicode-bidi:isolate;
  font-size:1.2em;
  line-height:2.15;
  color:rgb(var(--heading-soft));
}

/* -- .quran-text / "Qur'an Verse" block style: Amiri Quran, Uthmani-style -- */
.quran-text,
.is-style-quran-verse{
  display:block;
  font-family:var(--font-quran) !important;
  direction:rtl;
  unicode-bidi:isolate;
  text-align:center;
  font-size:1.55em;
  line-height:2.4;
  color:rgb(var(--heading));
  background:rgb(var(--wash) / 0.055);
  border:1px solid rgb(var(--wash) / 0.22);
  border-radius:var(--radius);
  padding:28px 34px;
  margin:1.9em 0;
  position:relative;
}
.quran-text::before,
.is-style-quran-verse::before{
  content:'\FD3F'; /* ornate right parenthesis — traditionally opens an ayah in RTL flow */
  color:rgb(var(--accent)); opacity:0.7; font-size:0.6em; display:block; margin-bottom:4px;
}
.quran-text::after,
.is-style-quran-verse::after{
  content:'\FD3E'; /* ornate left parenthesis — closes the ayah */
  color:rgb(var(--accent)); opacity:0.7; font-size:0.6em; display:block; margin-top:2px;
}
.quran-text cite,
.is-style-quran-verse cite{
  display:block; direction:ltr; font-family:var(--font-mono); font-style:normal;
  font-size:0.42em; letter-spacing:0.08em; text-transform:uppercase; color:rgb(var(--text-muted));
  margin-top:10px;
}

/* -- inline variant: used when JS auto-detects a { }-bracketed ayah
   sitting inside an ordinary Arabic paragraph (the site's own citation
   convention) — same Amiri Quran face, none of the standalone block's
   box/border/ornaments, so it reads naturally mid-sentence -- */
.quran-text.quran-text--inline,
.is-style-quran-verse.quran-text--inline{
  display:inline; text-align:inherit; font-size:1.08em; line-height:inherit;
  background:none; border:none; padding:0; margin:0; color:inherit;
}
.quran-text.quran-text--inline::before, .quran-text.quran-text--inline::after,
.is-style-quran-verse.quran-text--inline::before, .is-style-quran-verse.quran-text--inline::after{
  content:none;
}

/* -- one-tap ayah copying, injected by JS next to standalone Qur'an
   blocks only (never the inline variant, which sits mid-sentence) -- */
.ayah-copy-btn{
  display:inline-flex; align-items:center; justify-content:center; width:30px; height:30px; margin-top:10px;
  border-radius:50%; border:1px solid rgb(var(--wash) / 0.3); background:rgb(var(--surface)); color:rgb(var(--accent));
  transition:background 0.2s var(--ease), color 0.2s var(--ease), transform 0.2s var(--ease);
}
@media (hover: hover){ .ayah-copy-btn:hover{ background:rgb(var(--accent)); color:rgb(var(--on-accent)); transform:scale(1.08); } }
.ayah-copy-btn svg{ width:14px; height:14px; }
.ayah-copy-btn.copied{ background:rgb(var(--accent-3)); color:rgb(var(--on-accent)); border-color:rgb(var(--accent-3)); }

/* =========================================================================
   17. COMMENTS
   ========================================================================= */
.comments-shell{ margin-top:56px; padding-top:40px; border-top:1px solid rgb(var(--heading) / 0.1); }
.comments-title{ font-size:1.5rem; margin-bottom:24px; }
.pp-comment-list{ list-style:none; margin:0; padding:0; }
.pp-comment-list .children{ list-style:none; margin:20px 0 0 30px; padding:0; border-left:2px solid rgb(var(--heading) / 0.08); padding-left:24px; }
.pp-comment{ display:flex; gap:14px; margin-bottom:28px; }
.pp-comment-avatar img{ border-radius:50%; display:block; }
.pp-comment-body{ flex:1; min-width:0; }
.pp-comment-meta{ display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; margin-bottom:6px; }
.pp-comment-author{ font-weight:600; color:rgb(var(--heading)); font-size:0.92rem; font-family:var(--font-display); }
.pp-comment-date a{ font-family:var(--font-mono); font-size:0.7rem; color:rgb(var(--text-muted)); }
@media (hover: hover){ .pp-comment-date a:hover{ color:rgb(var(--accent)); } }
.pp-comment-pending{ font-size:0.78rem; font-style:italic; color:rgb(var(--accent-2)); margin:2px 0 8px; }
.pp-comment-text{ font-size:0.94rem; line-height:1.7; color:rgb(var(--text)); font-family:var(--font-body); }
.pp-comment-text p{ margin:0 0 0.8em; }
.pp-comment-reply a{
  display:inline-block; margin-top:8px; font-size:0.76rem; font-weight:600; color:rgb(var(--accent));
  padding:5px 12px; border:1px solid rgb(var(--wash) / 0.35); border-radius:999px; transition:background 0.2s var(--ease), color 0.2s var(--ease);
}
@media (hover: hover){ .pp-comment-reply a:hover{ background:rgb(var(--accent)); color:rgb(var(--on-accent)); } }
.comments-closed-note{ color:rgb(var(--text-muted)); font-style:italic; font-size:0.9rem; }
.comment-form-shell{ margin-top:40px; padding-top:32px; border-top:1px solid rgb(var(--heading) / 0.1); }
.comments-form-title{ font-size:1.3rem; margin-bottom:18px; }
.comment-form-author, .comment-form-email{ display:inline-block; width:calc(50% - 7px); vertical-align:top; }
.comment-form-author{ margin-right:14px; }
@media (max-width:600px){ .comment-form-author.comment-form-author, .comment-form-email.comment-form-email{ width:100%; margin-right:0; } }
.comment-respond input[type="text"], .comment-respond input[type="email"], .comment-respond input[type="url"], .comment-respond textarea{
  width:100%; padding:12px 14px; border-radius:10px; border:1px solid rgb(var(--heading) / 0.18);
  font-family:var(--font-ui); background:rgb(var(--surface)); color:rgb(var(--text)); margin-bottom:14px;
}
.comment-respond textarea{ resize:vertical; min-height:120px; }

/* =========================================================================
   18. AUTHOR CARD + "READ NEXT" RELATED SECTION
   ========================================================================= */
.author-card{
  display:flex; gap:18px; align-items:center; margin-top:44px; padding:26px;
  background:rgb(var(--bg-alt)); border-radius:var(--radius); border:1px solid rgb(var(--heading) / 0.08);
}
.author-avatar{ border-radius:50%; flex-shrink:0; }
.author-card-body h3{ font-size:1.15rem; margin:2px 0 6px; }
.author-card-body p{ font-size:0.88rem; color:rgb(var(--text-muted)); margin:0; line-height:1.6; }
@media (max-width:480px){ .author-card{ flex-direction:column; text-align:center; } }

.related-section{ margin-top:56px; padding-top:40px; border-top:1px solid rgb(var(--heading) / 0.1); }

/* =========================================================================
   19. SCROLL-SYNCED MINI TITLE / PROGRESS BAR (single posts)
   ========================================================================= */

/* =========================================================================
   20. SINGLE POST — reading rail (actions + table of contents)
   ========================================================================= */


/* heart-pulse micro-interaction on Like */
@keyframes heartPulse{
  0%{ transform:scale(1); }
  30%{ transform:scale(1.35); }
  55%{ transform:scale(0.92); }
  100%{ transform:scale(1); }
}

.rail-fontsize{
  display:flex; align-items:center; gap:6px; margin-top:2px; padding:6px 8px;
  border:1px solid rgb(var(--heading) / 0.1); border-radius:10px;
}
.rail-fontsize span{ font-size:0.7rem; color:rgb(var(--text-muted)); font-family:var(--font-mono); flex:1; }
/* v11.5 — these held "A−" and "A+" in a 26px box at 0.72rem with no
   `white-space` and no centring, so both glyphs wrapped onto two lines
   inside the circle and the control read as four stacked characters.
   Wide enough for two glyphs, told not to wrap, and centred. */
.rail-fontsize button{
  min-width:30px; height:26px; padding:0 4px;
  display:inline-flex; align-items:center; justify-content:center;
  white-space:nowrap; line-height:1;
  border-radius:7px; border:1px solid rgb(var(--heading) / 0.12); background:rgb(var(--surface));
  color:rgb(var(--heading)); font-family:var(--font-ui); font-size:0.72rem; font-weight:700;
  transition:background 0.2s var(--ease), border-color 0.2s var(--ease);
}
@media (hover: hover){ .rail-fontsize button:hover{ background:rgb(var(--wash) / 0.12); border-color:rgb(var(--wash) / 0.4); } }


/* =========================================================================
   21. ARTICLE HEADER / META (single.php)
   ========================================================================= */
.article-cover-full{ border-radius:var(--radius-lg); overflow:hidden; margin-bottom:36px; }
.article-cover-full img{ width:100%; height:auto; display:block; }
.article-footer-nav{ margin-top:48px; display:flex; justify-content:space-between; gap:16px; flex-wrap:wrap; }

/* =========================================================================
   22. PAGINATION
   ========================================================================= */
.pagination, .navigation.pagination{ display:flex; gap:10px; flex-wrap:wrap; }
.pagination .page-numbers{
  display:inline-flex; align-items:center; justify-content:center; min-width:38px; height:38px; padding:0 10px;
  border-radius:8px; border:1px solid rgb(var(--heading) / 0.15); font-size:0.85rem; font-weight:500; color:rgb(var(--heading-soft));
  transition:background 0.2s var(--ease), color 0.2s var(--ease), border-color 0.2s var(--ease);
}
.pagination .page-numbers.current{
  background:rgb(var(--ink)); color:rgb(var(--on-ink)); border-color:rgb(var(--ink));
}
@media (hover: hover){
  .pagination .page-numbers:hover{
    background:rgb(var(--ink)); color:rgb(var(--on-ink)); border-color:rgb(var(--ink));
  }
}

/* =========================================================================
   23. SAVED REFLECTIONS PAGE
   ========================================================================= */
.saved-remove{
  align-items:center; justify-content:center;
}
@media (hover: hover){ .saved-remove:hover{ color:rgb(var(--on-accent)); transform:scale(1.08); } }

/* =========================================================================
   24. LIGHTBOX (in-article images)
   ========================================================================= */
.pp-lightbox{
  position:fixed; inset:0; z-index:250; background:rgba(10,10,10,0.92);
  display:flex; align-items:center; justify-content:center; padding:40px;
  opacity:0; visibility:hidden; transition:opacity 0.25s ease, visibility 0.25s;
}
.pp-lightbox.show{ opacity:1; visibility:visible; }
.pp-lightbox img{ max-width:100%; max-height:100%; border-radius:8px; box-shadow:0 30px 80px rgba(0,0,0,0.5); cursor:default; }
.pp-lightbox-close{
  position:absolute; top:20px; right:20px; width:44px; height:44px; border-radius:50%;
  background:rgba(255,255,255,0.1); border:1px solid rgba(255,255,255,0.3); color:#fff;
  display:flex; align-items:center; justify-content:center; transition:background 0.2s ease;
}
@media (hover: hover){ .pp-lightbox-close:hover{ background:rgba(255,255,255,0.2); } }
.pp-lightbox-close svg{ width:18px; height:18px; }

/* =========================================================================
   25. HADITH COLLECTION (v3.1) — header dropdown, index/collection/single
   pages. Arabic hadith text intentionally uses --font-arabic (Amiri),
   NOT --font-quran (Amiri Quran) or the .quran-text ornamentation —
   hadith is not scripture, and shouldn't borrow the Qur'an-specific
   ornate-parenthesis convention reserved for ayat elsewhere in the site.
   ========================================================================= */

/* ---- header dropdown: richer 2x2 card grid ---- */
/* --accent-ui: this line appears inside .quran-menu-resume, whose panel is
   a 10% accent tint. See the note on .lib-row-topic. */
/* ---- Qur'an nav dropdown additions ---- */

/* ---- /hadith/ index page ---- */
.hadith-grid{ display:grid;  }
.hadith-collection-icon{
  align-items:center; justify-content:center; margin-bottom:16px;
}
.hadith-collection-card h3{ margin-bottom:8px; }

/* ---- /hadith/{collection}/ browse page ---- */
.hadith-book-header{
  flex-wrap:wrap;
}
.hadith-book-icon{
  flex-shrink:0;
}
.hadith-book-meta .eyebrow{ font-family:var(--font-arabic); font-weight: var(--ar-weight); direction:rtl; text-transform:none; letter-spacing:0; display:block; }.hadith-book-author{ margin-top:6px; }
.hadith-book-author span[lang="ar"]{ font-family:var(--font-arabic); font-weight: var(--ar-weight); }

/* v13.2 — the toolbar and its two fields: v132-layer-20-hadith. */
.hadith-result-count{ font-size:0.82rem; color:rgb(var(--text-muted)); margin-bottom:18px; }
.hadith-result-count a{ color:rgb(var(--accent)); font-weight:600; }

.hadith-list{ display:flex; flex-direction:column; }
.hadith-card{
  display:flex; align-items:flex-start; gap:16px; background:rgb(var(--surface));
}
@media (hover: hover){
  .hadith-card:hover{ background:rgb(var(--wash) / 0.05);  }
}
.hadith-card-num{
  border-radius:50%;
  display:flex; align-items:center; justify-content:center; font-family:var(--font-mono); font-weight:600; flex-shrink:0;
}
.hadith-card-body{ flex:1; min-width:0; }
.hadith-card-chapter{ font-family:var(--font-mono); text-transform:uppercase; }
.hadith-card-narrator{ font-style:italic; color:rgb(var(--text-muted)); }
/* v12.1 — the Arabic on a listing card. Leads, because that is what the
   book is; sized so a card stays a card and does not become a page. */
.hadith-card-ar{
  direction: rtl; unicode-bidi: isolate; text-align: right;
  margin: 0 0 8px;
}
.hadith-card-excerpt{ font-family:var(--font-body); margin:0; }
.hadith-card-arrow{ width:15px; height:15px; color:rgb(var(--text-muted)); flex-shrink:0; margin-top:8px; transition:transform 0.2s var(--ease), color 0.2s var(--ease); }
@media (hover: hover){ .hadith-card:hover .hadith-card-arrow{ transform:translateX(3px); color:rgb(var(--accent)); } }

/* =========================================================================
   THE COLLECTION PAGE, ILLUMINATED — v11.1

   The page you land on when you open a book was the plainest thing on
   the site: a grey rounded box for a header, a pill search, a native
   <select> for twenty chapters, and a flat column of near-identical
   cards with a small circle of a number. Nothing about it said you had
   opened Riyāḍ aṣ-Ṣāliḥīn rather than a list of search results, and
   the chapter list — the actual way anyone navigates a hadith book —
   was hidden inside a dropdown.

   It now opens like a book: a ruled gold panel naming the work in
   Arabic and English, the chapters as a browsable rail rather than a
   dropdown, and cards with real typographic hierarchy.
   ========================================================================= */
/* The gold rule across the head, as on the adhkār ʿunwān and the covers. */
.hadith-book-header::before{
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg,
    rgb(var(--wash) / 0) 0%, rgb(var(--wash) / 0.85) 22%,
    rgb(var(--wash) / 0.85) 78%, rgb(var(--wash) / 0) 100%);
}
.hadith-book-meta .eyebrow{
  font-size: 1.35rem; line-height: 1.6; color: rgb(var(--accent-ui));
}/* ---- the cards ---- */
.hadith-list{ gap: var(--sp-3); }
.hadith-card{
  padding: var(--sp-5) var(--sp-5);
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  box-shadow: var(--e1);
  transition: background var(--dur) var(--ease-soft),
              border-color var(--dur) var(--ease-soft),
              box-shadow var(--dur) var(--ease-soft);
}
/* No translateX on hover — a whole column of cards sliding sideways
   under the cursor is movement without meaning, and it made the list
   feel unsteady while scanning it. */
@media (hover: hover){
  .hadith-card:hover{
    transform: none;
    border-color: rgb(var(--wash) / 0.4);
    box-shadow: var(--e2);
  }
}
.hadith-card-num{
  width: 38px; height: 38px;
  background: transparent;
  border: 1px solid rgb(var(--wash) / 0.4);
  color: rgb(var(--accent-ui));
  font-size: 0.8rem;
}
@media (hover: hover){ .hadith-card:hover .hadith-card-num{ background: rgb(var(--wash) / 0.12); } }
.hadith-card-chapter{
  font-size: var(--fs-2xs); letter-spacing: var(--track-caps);
  color: rgb(var(--accent-ui));
}
.hadith-card-narrator{ font-size: var(--fs-xs); margin: 5px 0 4px; }
.hadith-card-excerpt{
  font-size: 1.02rem; line-height: 1.72; color: rgb(var(--text));
}

/* =========================================================================
   A LEGIBILITY FLOOR ON PHONES — v11.1

   Audited on a real 375px viewport: ten distinct classes were rendering
   text between 10.2px and 10.9px — chips, eyebrows, counts, stat
   labels. Each is defensible on a desktop as a micro-label; together,
   on a phone held at arm's length, they are the difference between a
   site that reads and one that squints. Uppercase mono at 10px is the
   worst case of all, because caps have no ascenders or descenders to
   help the eye.

   Nothing here changes the desktop; it only puts a floor under the
   smallest tier where the screen is small.
   ========================================================================= */
@media (max-width:600px){
  .eyebrow{ font-size: 0.76rem; letter-spacing: 0.12em; }
  .tag-chip{ font-size: 0.72rem; padding: 5px 10px; }
  .hero-stat-label,
.hadith-home-count,
.reflection-count,
.theme-panel-label,
.card-meta,
.adhkar-card-source { font-size: 0.72rem; }
}

@media (max-width:600px){
  .hadith-book-header{ padding: var(--sp-6) var(--sp-4); }
  .hadith-card{ padding: var(--sp-4); gap: var(--sp-3); }
  .hadith-card-num{ width: 34px; height: 34px; font-size: 0.74rem; }
  .hadith-card-excerpt{ font-size: 0.96rem; }
}

/* ---- /hadith/{collection}/{n}/ single hadith page ---- */
.hadith-single-header{ text-align:center; margin-bottom:28px; }
.hadith-single-header h1{ font-size:clamp(1.4rem,3vw,1.8rem); margin-top:10px; }
.hadith-single-num{ font-family:var(--font-mono); font-size:0.6em; color:rgb(var(--text-muted)); font-weight:400; }
.hadith-single-chapter-ar{ direction:rtl; margin-top:6px; }

.hadith-arabic{
  direction:rtl; unicode-bidi:isolate; text-align:right;
  background:rgb(var(--bg-alt)); border:1px solid rgb(var(--heading) / 0.1);
  border-radius:var(--radius-lg); padding:32px 36px; margin:0 0 30px;
}
.hadith-english{ margin-bottom:28px; }
/* v12.0 — the Arabic card holds one <p> per real paragraph now instead of
   one text node full of <br>s, so the spacing between paragraphs has to
   be declared rather than inherited from a line break. */
.hadith-arabic-p{ margin:0; }
.hadith-arabic-p + .hadith-arabic-p{ margin-top:0.85em; }
.hadith-text + .hadith-text{ margin-top:1em; }
.hadith-text-missing{
  font-style:italic; color:rgb(var(--text-muted)); font-size:1rem;
}
.hadith-note-label{
  font-size:0.85rem; font-style:italic; color:rgb(var(--text-muted));
  padding:14px 18px; margin:0 0 24px; border-left:2px solid rgb(var(--wash) / 0.3);
  background:rgb(var(--bg-alt) / 0.5); border-radius:0 var(--radius) var(--radius) 0;
}
.hadith-narrator{ font-family:var(--font-body); font-style:italic; color:rgb(var(--text-muted)); font-size:0.98rem; margin:0 0 10px; }
.hadith-text{ font-family:var(--font-body); font-size:1.12rem; line-height:1.85; color:rgb(var(--text)); margin:0; }

.hadith-actions{ display:flex; gap:10px; flex-wrap:wrap; margin-bottom:40px; padding-top:20px; border-top:1px solid rgb(var(--heading) / 0.08); }
.hadith-action-btn{ width:auto; flex-direction:row; padding:10px 18px; border:1px solid rgb(var(--heading) / 0.15); border-radius:999px; }
@media (hover: hover){ .hadith-action-btn:hover{ transform:none; border-color:rgb(var(--wash) / 0.4); } }
.hadith-action-btn.copied{ color:rgb(var(--accent-3)); border-color:rgb(var(--accent-3) / 0.4); }
.hadith-ic-check{ display:none; }
.hadith-action-btn.copied .hadith-ic-copy{ display:none; }
.hadith-action-btn.copied .hadith-ic-check{ display:block; }
#hadithSave[aria-pressed="true"]{ color:rgb(var(--accent)); border-color:rgb(var(--wash) / 0.4); background:rgb(var(--wash) / 0.08); }

.hadith-pager{ display:flex; align-items:center; justify-content:space-between; gap:14px; padding-top:24px; border-top:1px solid rgb(var(--heading) / 0.08); }
.hadith-pager-link{
  display:flex; align-items:center; gap:8px; font-size:0.86rem; font-weight:600; color:rgb(var(--heading-soft));
  transition:color 0.2s var(--ease); max-width:38%;
}
@media (hover: hover){ .hadith-pager-link:hover{ color:rgb(var(--accent)); } }
.hadith-pager-link svg{ width:14px; height:14px; flex-shrink:0; color:rgb(var(--accent)); }
.hadith-pager-prev{ text-align:left; }
.hadith-pager-next{ text-align:right; flex-direction:row-reverse; margin-left:auto; }
.hadith-pager-label{ display:block; font-family:var(--font-mono); font-size:0.6rem; letter-spacing:0.06em; text-transform:uppercase; color:rgb(var(--text-muted)); font-weight:500; }
.hadith-pager-collection{ font-size:0.78rem; color:rgb(var(--text-muted)); font-weight:500; flex-shrink:0; }
@media (hover: hover){ .hadith-pager-collection:hover{ color:rgb(var(--accent)); } }

/* =========================================================================
   25. MOBILE
   Hardened for v3.0: locked body scroll behind the mobile drawer (see
   .no-scroll, toggled by JS), safe-area padding for notched phones,
   ≥44px tap targets throughout, and a horizontally-scrollable fallback
   for the article rail's mobile toolbar so it can never overflow or
   wrap awkwardly regardless of how many actions it holds.
   ========================================================================= */

/* Scroll lock while the drawer is open. JS pins the body with
   position:fixed and a negative top offset (the reliable iOS technique),
   then restores the exact scroll position on close. */
html.no-scroll{ overflow:hidden; }
body.no-scroll{ position:fixed; left:0; right:0; width:100%; overflow:hidden; overscroll-behavior:none; }

@media (max-width:1100px){
  /* v9.0 — WHICH PART OF THE RAIL SCROLLS.
     Through v8.0 the whole strip was one horizontal scroller, and the
     "Contents" toggle sat at the end of it. v8.0 narrowed that toggle to
     bring it back on screen at 375px, but the fix was arithmetic rather
     than structural: it held only until the row grew again. Measured at
     320px with the Listen button added, Contents began at x=227 and ran
     to 323 — three pixels past the edge of the screen, inside a
     container that scrolls, which is the exact failure v8.0 set out to
     end. Any future control would have re-broken it.
     So the scroller is now the ACTIONS alone. Contents is a sibling
     outside it, pinned and unshrinkable, and therefore on screen at
     every width no matter how many buttons the rail grows. */
  .rail-fontsize.rail-fontsize{ margin-top:0; flex-shrink:0; }
  .rail-fontsize button{ min-width:34px; min-height:34px; }
  /* Pinned outside the scroller (see above), so this no longer competes
     for width with the buttons and cannot be pushed off the edge.
     `position:static` is deliberate: the panel below is anchored to the
     whole rail instead, because this element is now only as wide as the
     word "Contents" and a panel that width would be unreadable. A
     sticky element is a positioned one, so .article-rail is already a
     containing block and nothing else is needed to make that work. */
/* the sticky rail toolbar already fills this role on mobile */
}

@media (max-width:960px){
  .spotlight-grid.spotlight-grid{ grid-template-columns:1fr; }
  .topics-grid.topics-grid{ grid-template-columns:repeat(2,1fr); }
  .footer-grid.footer-grid{ grid-template-columns:1fr 1fr; }
  .footer-brand{ grid-column:1 / -1; }
}

/*
 * v11.5 — ONE COMPACT STEP BETWEEN THE FULL BAR AND THE DRAWER, AND THE
 * ARITHMETIC IT IS DERIVED FROM.
 *
 * v11.3 added a second, undocumented header breakpoint that contradicted
 * the first, and v11.4 rightly removed it. This is not that: it is a
 * single, stated, measured step, and the numbers are here so the next
 * person can check them rather than re-guess them.
 *
 * At the full sizes the centred row needs 2×280 (actions) + 590 (nav) +
 * 32 (gaps) = 1182px of content box. Below 1300px the window stops
 * providing it. Trimming the nav's horizontal padding by 2px an item and
 * the icon buttons by 2px takes the requirement to 2×254 + 562 + 24 =
 * 1070, which the narrowest desktop width this block has to serve
 * (1181px, one pixel above the drawer) provides with 55px to spare.
 *
 * Nothing is hidden here and nothing moves: it is the same row, set one
 * notch tighter, so the step is invisible rather than a second layout.
 */

@media (max-width:1180px){
  /* ---- Mobile navigation drawer (v4: sits directly under the header,
     fills to the bottom, no top gap; smooth slide; robust scroll lock
     handled in JS). Moved from 760px to 1100px in v5.0 (too many nav
     items), then to 1180px in v5.3 once Prayer Times joined Qibla as a
     second always-visible header icon, widening the full desktop row
     enough that 1100px stopped being enough room — measured via direct
     bisection, not guessed. ---- */

  /* v11.5 — the desktop item-pill (see `.main-nav > ul > li` in the
     header block) must not follow the nav into the drawer: a 999px
     radius on a full-width row with a hairline under it reads as a
     misdrawn box. Same specificity as the rule it undoes, and later in
     the file, plus one extra class on the plain-state rule so it also
     beats it on structure. */
  /* The caret button becomes the full-height accordion toggle in the
     drawer, with its own slim chevron (unrelated to the desktop
     .nav-caret, which is hidden here) that rotates on open. */
  /* Re-shown in the drawer. Three classes (0,3,0) so it beats the
     base .site-header .nav-mobile-only (0,2,0) on specificity rather
     than on appearing later in the file — see the note there. */
  /* in-drawer dropdown: a tidy indented accordion, never a floating box.
     Every selector below is deliberately scoped through .main-nav (or
     another always-true ancestor) so it wins on CSS SPECIFICITY, not on
     appearing later in the file. A same-specificity, order-dependent
     override is fragile: if any caching, minification, or "optimize
     CSS" plugin on the live site ever reorders rules — several popular
     ones do — the desktop absolute-positioned mega-panel could win
     again and the drawer would look exactly like this: text clipped at
     the left edge, huge gaps, misaligned rows. Scoping through an
     ancestor class makes the mobile rule structurally win regardless of
     file order, so this can't come back from a caching quirk. */
  /* v8.0 — 44px, not 40px. Everything below 1180px is a touch device (a
     tablet, or a large phone in landscape), and 40px was under the minimum
     target size on every one of them. There is room: measured at 861px —
     the widest point at which the full icon row is shown — the row needs
     690px of the 805px available. */
  .logo-text .tagline{ display:none; }
}

/* =========================================================================
   v8.0 — WHERE THE BAR SHEDS ITS SECONDARY CONTROLS.

   Split out from the phone block below because these are two different
   questions with two different answers. THIS is "does the full eight-control
   row still fit?", and measured against a real render the answer is no below
   861px. The block below is "is there room for the wordmark beside the
   buttons?", which only becomes a problem 240px further down.

   Between 621 and 860px the drawer is already in use for navigation, so the
   five secondary controls have a labelled home to move into.
   ========================================================================= */

/* =========================================================================
   v8.0 — TOUCH TARGETS OUTSIDE THE HEADER.

   The header was the worst offender by a distance (28px), but a measured
   sweep of nine pages found controls elsewhere sitting at 24-36px: the
   reflection arrows, the topic filter chips, the reading rail's text-size
   buttons, the prayer format toggles and every .btn-sm.

   Two conditions, because "is this a touch target?" is not the same
   question as "is the screen narrow?":

     max-width: 860px   catches phones and portrait tablets. Matches the
                        header breakpoint above, so the whole chrome changes
                        character at one place rather than two.
     pointer: coarse    catches touch devices too wide for that — an iPad in
                        landscape is 1024px and every target on it is still a
                        fingertip.

   Sized individually from the measured list rather than by sweeping every
   button to 44px, which would have broken the two-up rows several of them
   sit in.
   ========================================================================= */
@media (max-width:860px), (pointer: coarse){
  /* Every selector is doubled (0,2,0). This block sits early in the file, and
     several of these components are re-declared later by the v7.1 elevation
     pass at plain single-class specificity — `.prayer-format-btn{min-height:
     36px}` among them, which silently won on source order and held those
     toggles at 36px through the first pass of this very fix. */
  /* .btn before .btn-sm: they are the same specificity, so within this
     block the later one wins, and the small variant must be the later one. */
  .btn.btn{ min-height:46px; padding:12px 20px; }
  .btn-sm.btn-sm{ min-height:44px; padding:11px 18px; }

  .arrow-btn.arrow-btn{ width:44px; height:44px; }
  .lib-chip.lib-chip{ min-height:44px; }
  .shuffle-btn.shuffle-btn{ min-height:44px; display:inline-flex; align-items:center; }
  .view-all.view-all{ min-height:44px; display:inline-flex; align-items:center; }
  .prayer-format-btn.prayer-format-btn{ min-height:44px; }
  .prayer-link-btn.prayer-link-btn{ min-height:44px; display:inline-flex; align-items:center; }
  .qibla-compass-link.qibla-compass-link{ min-height:44px; }
  .rail-fontsize button{ min-width:44px; min-height:44px; }
}

@media (max-width:760px){
  .hero-frame.hero-frame{ padding:44px 22px; }
  .topics-grid.topics-grid{ grid-template-columns:1fr; }
  .footer-grid.footer-grid{ grid-template-columns:1fr; gap:30px; }
  .newsletter-band.newsletter-band{ padding:42px 22px; }
  .essays-list.essays-list{ grid-template-columns:1fr; }
  /* v8.0 — the old `.hero-stats{gap:16px}` that sat here is gone. The
     phone layout of this row is now a three-column grid with gap:0 and
     real hairline borders (see "THE HERO STATS ROW" further down, same
     breakpoint). Leaving a second same-specificity gap declaration in
     the file meant the two could only be told apart by source order,
     which is precisely the kind of thing a CSS-reordering cache plugin
     breaks. One rule owns this row now. */
  .quran-text.quran-text, .is-style-quran-verse.is-style-quran-verse{ font-size:1.25em; padding:22px 18px; }
  .entry-content .alignleft.alignleft, .entry-content .alignright.alignright{ float:none; max-width:100%; margin:1em 0; }
  .not-found-links{ flex-direction:column; align-items:stretch; }
  .not-found-links .btn{ justify-content:center; }
  .hadith-grid.hadith-grid{ grid-template-columns:1fr; }
  .hadith-book-header.hadith-book-header{ flex-direction:column; text-align:center; padding:24px 20px; }
  .hadith-book-header .btn{ width:100%; justify-content:center; }
  .hadith-card.hadith-card{ padding:14px 16px; gap:12px; }
  .hadith-arabic.hadith-arabic{ font-size:1.15em; padding:22px 20px; line-height:1.95; }
  .hadith-pager.hadith-pager{ flex-wrap:wrap; justify-content:center; text-align:center; }
  .hadith-pager-link.hadith-pager-link{ max-width:100%; }
  .hadith-pager-next.hadith-pager-next{ margin-left:0; }
  .hadith-pager-collection{ order:-1; flex-basis:100%; text-align:center; margin-bottom:8px; }
}

/* =========================================================================
   THE PHONE HEADER — rebuilt in v8.0.

   Every previous release solved "the header row does not fit on a phone"
   by making the row smaller. By v7.1 that had bottomed out at seven 28x28px
   icon buttons and a 32px menu button with 1px between them: measured on a
   real 375px render, every single control in the bar was under the 44px
   minimum touch target, and the site's own name had been deleted from the
   header entirely to make room for them.

   v8.0 solves it by making the row SHORTER instead. Five of the eight
   controls move into the drawer, where they get text labels (see the
   `is-bar-overflow` note in header.php). What remains — search, appearance,
   menu — gets 42px targets, real spacing, and the wordmark back.

   The measured budget at 375px: 335px of content width, of which the three
   buttons and their gaps take 138px and the logo lockup takes ~176px. That
   is ~21px of slack, and the logo is allowed to shrink into it rather than
   overflow, so the row cannot break however long the site title gets.
   ========================================================================= */
@media (max-width:620px){

  /* THE WORDMARK RETURNS. Only the italic tagline is dropped — that is the
     line that genuinely does not earn its width on a phone. The name is the
     brand and reads as the "home" affordance, which a bare 26px glyph did
     not. It is allowed to shrink and ellipsise rather than push the row
     wide, so no title length can ever break the header again. */

  /*
   * v11.4 — THE THREE THAT STAY, ACTUALLY ENFORCED.
   *
   * A REAL BUG, found by measuring: this comment has said "the three
   * that stay" — search, appearance, menu — since v8.0, but the rule
   * beneath it only ever SIZED `.icon-btn` at 44px; nothing here hid
   * the other two icon-btns that had joined the bar since (Install,
   * added for the PWA prompt, and the tasbīḥ bead). Both stayed
   * visible on every phone, which is how "Prophetic Profit" — 117px of
   * text — ended up squeezed into a 57px gap alongside five 42px
   * buttons at 375px and rendered as "Prop…". The design intent this
   * comment states was simply never wired up for two of the five
   * icons it was written to describe.
   *
   * Both have full, labelled rows already in the drawer — Install's is
   * right below (`.pp-install-drawer-item`) and the tasbīḥ counter has
   * its own drawer row — so hiding the bar copies here loses no
   * function, exactly as it already worked for Surprise/Saved/Prayer
   * Times/Qibla before v11.4 removed those entirely.
   */
  .site-header .header-actions .pp-tasbih-bead { display:none; }


  /* Search stops being a 280px card hanging off one button and becomes the
     width of the screen. It was anchored with `right:-12px`, which was
     measured against a header row that no longer exists — with the bar
     rebuilt, a fixed-width popover pinned to a moved button is exactly the
     kind of thing that ends up half off the edge. Full width has no anchor
     to get wrong, and gives the field room to actually show a query. */

  /* =====================================================================
     THE APPEARANCE PANEL BECOMES A BOTTOM SHEET.

     It was a 294px-wide dropdown anchored to a 28px button near the right
     edge of the screen, nudged back on with `right:-12px`. A list of ten
     things you scroll and tap is a sheet, not a dropdown, and a sheet has
     no anchor to get wrong.

     Every selector here is doubled (0,2,0) so it beats the frosted-panel
     rules in the elevation section further down the file on SPECIFICITY
     rather than on source order — those set `transform` on both
     .theme-panel and .theme-panel.open, and a CSS-reordering cache plugin
     moving them after this block would otherwise put the sheet back into
     a scaled dropdown transform and leave it off-screen.

     Note it is position:fixed inside .site-header, which is also fixed.
     That works because the header deliberately carries no transform or
     backdrop-filter of its own (both would make it the containing block —
     see the note on .site-header::before), and because the header's
     auto-hide transform is suppressed while any header popover is open
     (headerPopoverOpen() in main.js).
     ===================================================================== */
  .theme-panel.theme-panel{
    position:fixed; left:0; right:0; bottom:0; top:auto;
    width:auto; max-width:none; max-height:min(82vh, 640px);
    padding:8px 16px calc(16px + env(safe-area-inset-bottom, 0px));
    border-radius:var(--radius-lg) var(--radius-lg) 0 0;
    border-left:none; border-right:none; border-bottom:none;
    box-shadow:0 -18px 50px -18px rgb(var(--shadow) / 0.5);
    transform:translateY(100%); transform-origin:center bottom;
    transition:transform 0.34s cubic-bezier(0.4, 0, 0.2, 1), visibility 0.34s;
    /* Also a child of .site-header, so the same caveat applies as for
       .main-nav: this orders it inside the header, not against the
       page. The recitation bar is lowered out of the way instead. */
    opacity:1; z-index:99;
  }
  .theme-panel.theme-panel.open{ transform:translateY(0); }

  .theme-sheet-grip{
    display:block; width:38px; height:4px; border-radius:999px;
    background:rgb(var(--heading) / 0.18); margin:4px auto 10px;
  }
  .theme-panel-close{ display:flex; }

  /* Roomier rows: this is the one place on the site a reader deliberately
     compares ten things side by side, and it is worth the height. */
  .theme-mode-btn{ min-height:42px; font-size:0.85rem; }
  .theme-option{ padding:10px 12px 10px 10px; gap:13px; }
  .theme-preview{ width:58px; height:44px; }
  .theme-option-name{ font-size:0.92rem; }
  .theme-option-blurb{ font-size:0.76rem; }
}


@media (max-width:420px){
  .wrap.wrap{ padding:0 20px; }
  /* Previously this also had to re-declare `.header-inner`'s padding
     entirely (`padding:12px 20px`) to undo the shorthand collision
     fixed at the root now (see the long comment on `.header-inner`
     above) — that collision was silently stripping the header's
     vertical padding on phones ≤420px, squashing the whole bar to the
     height of its tallest button (measured: 45px at 360px versus 85px
     at 430px, a visible, jarring difference). With the collision fixed
     at the source, only the vertical size actually needs to change
     here, and only in longhand, so it can't reopen the same collision
     for horizontal padding. --header-h is measured from the real
     element at runtime, so everything built on the header's height
     follows this automatically. */
  .hero.hero h1{ font-size:clamp(2rem, 9vw, 2.6rem); }
  .btn.btn{ padding:11px 18px; }
}

/*
 * z-index 96 — BELOW the header, and that is not negotiable.
 *
 * v10.2 raised this to 111 to stop the docked recitation bar (110)
 * showing through the dimmed backdrop. It fixed that and broke
 * something far worse, because of a stacking context that is easy to
 * miss: the mobile menu (.main-nav) lives INSIDE .site-header, and
 * .site-header is `position:fixed; z-index:100`. A z-index on a child
 * of that is resolved *within* the header's context — so the drawer
 * cannot rise above 100 relative to the page no matter what number it
 * is given. Putting the overlay at 111 therefore painted it ON TOP OF
 * the open menu, and since the overlay carries backdrop-filter:blur,
 * the menu came out blurred and unusable. Reported exactly that way.
 *
 * The overlay belongs under the header. The recitation bar is dealt
 * with where the actual conflict is — see body.no-scroll .qa-bar below.
 */

/* =========================================================================
   27. v3.2 ADDITIONS
   ========================================================================= */

/* ---- Spotlight: latest post full-width, reflection on its own row ---- */
.spotlight-solo{ margin-bottom:26px; }
.featured-card.is-wide{ flex-direction:column; }
@media (min-width:861px){
  .featured-card.is-wide.is-wide{ flex-direction:row; align-items:stretch; }
  .featured-card.is-wide .featured-cover{ width:46%; min-width:46%; height:auto; min-height:300px; }
  .featured-card.is-wide .featured-body{ width:54%; justify-content:center; padding:34px 38px; }
  .featured-card.is-wide .featured-body h3{ font-size:2rem; }
}

/* ---- Hadith of the Day banner (homepage) ---- */
.hadith-day{
  position:relative; margin:8px 0 0; padding:34px 36px; overflow:hidden;
  border-radius:var(--radius-lg); border:1px solid rgb(var(--wash) / 0.32);
  background:
    radial-gradient(circle at 88% -10%, rgb(var(--wash) / 0.12), transparent 46%),
    linear-gradient(180deg, rgb(var(--surface) / 0.7), rgb(var(--surface) / 0.25));
}
/* Compact variant used on the homepage — a smaller, quieter banner. */
.hadith-day.is-compact{ padding:24px 28px; }
.hadith-day.is-compact .hadith-day-arabic{ font-size:clamp(1.25rem, 2.8vw, 1.6rem); line-height:1.95; margin:0 0 12px; }
.hadith-day.is-compact .hadith-day-en{ font-size:clamp(1rem, 1.9vw, 1.1rem); line-height:1.6; }
.hadith-day.is-compact .hadith-day-head{ margin-bottom:12px; }
.hadith-day.is-compact .hadith-day-foot{ margin-top:16px; }
.hadith-day-head{ display:flex; align-items:center; gap:10px; margin-bottom:16px; }
.hadith-day-head .eyebrow{ margin:0; }
.hadith-day-head svg{ width:17px; height:17px; }
.hadith-day-arabic{
  font-family:var(--font-arabic); font-weight: var(--ar-weight); direction:rtl; text-align:right;
  font-size:clamp(1.4rem, 3.4vw, 2rem); line-height:2.05; color:rgb(var(--heading));
  margin:0 0 18px;
}
.quran-day-arabic{ font-family:var(--font-quran-glyphs); }
.hadith-day-en{ font-family:var(--font-body); font-size:clamp(1.05rem, 2.2vw, 1.22rem); line-height:1.62; color:rgb(var(--text)); margin:0; max-width:70ch; }
.hadith-day-narr{ color:rgb(var(--text-muted)); font-style:italic; }
.hadith-day-foot{ display:flex; align-items:center; justify-content:space-between; gap:16px; flex-wrap:wrap; margin-top:20px; }
.hadith-day-ref{ font-family:var(--font-mono); font-size:0.74rem; letter-spacing:0.04em; color:rgb(var(--accent)); text-transform:uppercase; }
.hadith-day-ref a{ color:inherit; }
@media (hover: hover){ .hadith-day-ref a:hover{ text-decoration:underline; } }
.hadith-day-link{ font-size:0.85rem; font-weight:600; color:rgb(var(--accent)); display:inline-flex; align-items:center; gap:6px; }
.hadith-day-link svg{ width:14px; height:14px; transition:transform 0.2s var(--ease); }
@media (hover: hover){ .hadith-day-link:hover svg{ transform:translateX(4px); } }

/* ---- Homepage "From the Hadith Collections" cards ---- */
.hadith-home-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:18px; }
.hadith-home-card{
  display:flex; flex-direction:column; gap:8px; padding:22px 20px; border-radius:var(--radius);
  background:linear-gradient(155deg, rgb(var(--surface)) 0%, rgb(var(--surface)) 55%, rgb(var(--heading) / 0.035) 130%);
  border:1px solid rgb(var(--heading) / 0.07);
  box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5), 0 8px 26px -18px rgb(var(--shadow) / 0.4);
  transition:transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
}
@media (hover: hover){
  .hadith-home-card:hover{ transform:translateY(-4px); border-color:rgb(var(--wash) / 0.3); box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5), 0 22px 44px -22px rgb(var(--shadow) / 0.5); }
}
.hadith-home-icon{ width:42px; height:42px; border-radius:12px; display:grid; place-items:center; background:rgb(var(--wash) / 0.12); color:rgb(var(--accent)); margin-bottom:4px; }
.hadith-home-icon svg{ width:22px; height:22px; }
.hadith-home-arabic{ font-family:var(--font-arabic); font-weight: var(--ar-weight); direction:rtl; font-size:1.32rem; color:rgb(var(--heading)); line-height:1.4; }
.hadith-home-title{ font-family:var(--font-display); font-weight:600; font-size:1.06rem; color:rgb(var(--heading)); }
.hadith-home-blurb{ font-size:0.82rem; color:rgb(var(--text-muted)); line-height:1.5; flex:1; }
.hadith-home-count{ font-family:var(--font-mono); font-size:0.68rem; letter-spacing:0.05em; text-transform:uppercase; color:rgb(var(--accent)); display:inline-flex; align-items:center; gap:6px; }
.hadith-home-count svg{ width:13px; height:13px; transition:transform 0.2s var(--ease); }
@media (hover: hover){ .hadith-home-card:hover .hadith-home-count svg{ transform:translateX(3px); } }

/* ---- Homepage recommended-essays cards + shuffle ---- */
.essay-rec-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:20px; }
.essay-rec{
  display:flex; flex-direction:column; gap:10px; padding:22px 22px 20px; border-radius:var(--radius);
  background:linear-gradient(155deg, rgb(var(--surface)) 0%, rgb(var(--surface)) 55%, rgb(var(--heading) / 0.035) 130%);
  border:1px solid rgb(var(--heading) / 0.07);
  box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5), 0 8px 26px -18px rgb(var(--shadow) / 0.4);
  transition:transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
  min-height:170px;
}
@media (hover: hover){
  .essay-rec:hover{ transform:translateY(-4px); border-color:rgb(var(--wash) / 0.3); box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5), 0 22px 44px -22px rgb(var(--shadow) / 0.5); }
}
.essay-rec .tag-chip{ align-self:flex-start; }
.essay-rec h3{ font-size:1.18rem; line-height:1.3; }
@media (hover: hover){ .essay-rec h3 a:hover{ color:rgb(var(--accent)); } }
.essay-rec p{ color:rgb(var(--text-muted)); font-size:0.88rem; line-height:1.55; margin:0; flex:1; }
.essay-rec .card-meta{ margin-top:6px; }
.shuffle-btn{
  display:inline-flex; align-items:center; gap:8px; padding:9px 16px; border-radius:999px;
  font-size:0.82rem; font-weight:600; color:rgb(var(--accent));
  background:rgb(var(--wash) / 0.1); border:1px solid rgb(var(--wash) / 0.24);
  transition:background 0.2s var(--ease), transform 0.2s var(--ease);
}
@media (hover: hover){ .shuffle-btn:hover{ background:rgb(var(--wash) / 0.18); transform:translateY(-1px); } }
.shuffle-btn svg{ width:15px; height:15px; transition:transform 0.5s var(--ease); }
.shuffle-btn.spin svg{ transform:rotate(360deg); }

/* =========================================================================
   THE TOPICS PAGE (page-topics.php) — v7.0
   Replaces the old separate Essays library. Two halves: a grid of topic
   cards, then the complete library of every writing underneath, with
   search / topic filter / sort over it.
   ========================================================================= */

.topics-page{ padding-top:26px; }

.topics-hero{ max-width:64ch; margin:0 0 40px; }
.topics-hero h1{
  font-size:clamp(2.1rem, 6vw, 3.3rem); line-height:1.06; margin:8px 0 14px;
  letter-spacing:-0.02em;
}
.topics-hero-sub{ color:rgb(var(--text-muted)); font-size:1.02rem; line-height:1.65; margin:0; }

/* ---- Topic cards ---- */
.topic-card-grid{
  display:grid; grid-template-columns:repeat(auto-fill, minmax(272px, 1fr));
  gap:18px; margin-bottom:74px;
}
.topic-card{
  --card-accent: var(--accent);
  position:relative; display:flex; flex-direction:column; gap:14px;
  padding:26px 24px 20px; border-radius:var(--radius-lg); overflow:hidden;
  background:rgb(var(--surface)); border:1px solid rgb(var(--heading) / 0.10);
  transition:transform 0.32s var(--ease), box-shadow 0.32s var(--ease), border-color 0.32s var(--ease);
}
/* Rotates the three accent roles across the grid so a long list of
   cards has rhythm instead of reading as one solid block of gold. */
.topic-card:nth-child(3n+2){ --card-accent: var(--accent-2); }
.topic-card:nth-child(3n+3){ --card-accent: var(--accent-3); }
.topic-card::before{
  content:''; position:absolute; inset:0 0 auto; height:3px;
  background:linear-gradient(90deg, rgb(var(--card-accent)), rgb(var(--card-accent) / 0));
  opacity:0.75; transition:opacity 0.32s var(--ease);
}
.topic-card::after{
  content:''; position:absolute; inset:0; pointer-events:none; opacity:0;
  background:radial-gradient(130% 90% at 100% 0%, rgb(var(--card-accent) / 0.10), transparent 62%);
  transition:opacity 0.32s var(--ease);
}
.topic-card:focus-visible{
  transform:translateY(-5px);
  border-color:rgb(var(--card-accent) / 0.38);
  box-shadow:0 22px 44px -20px rgb(var(--shadow) / 0.32);
}
@media (hover: hover){
  .topic-card:hover{
    transform:translateY(-5px);
    border-color:rgb(var(--card-accent) / 0.38);
  }
}
.topic-card:focus-visible::after{ opacity:1; }
@media (hover: hover){
  .topic-card:hover::after{ opacity:1; }
  .topic-card:hover::before{ opacity:1; }
}

.topic-card-icon{
  width:46px; height:46px; flex:0 0 auto; border-radius:13px;
  display:grid; place-items:center;
  background:rgb(var(--card-accent) / 0.12); color:rgb(var(--card-accent));
  transition:background 0.32s var(--ease), color 0.32s var(--ease), transform 0.32s var(--ease);
}
.topic-card-icon svg{ width:23px; height:23px; }
@media (hover: hover){
  .topic-card:hover .topic-card-icon{
    background:rgb(var(--card-accent)); color:rgb(var(--on-accent)); transform:rotate(-5deg) scale(1.06);
  }
}

.topic-card-body{ display:block; flex:1 1 auto; }
.topic-card-name{
  display:block; font-family:var(--font-display); font-size:1.2rem; font-weight:600;
  line-height:1.28; color:rgb(var(--heading)); margin-bottom:7px; letter-spacing:-0.01em;
}
.topic-card-desc{ display:block; color:rgb(var(--text-muted)); font-size:0.885rem; line-height:1.58; }

.topic-card-foot{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding-top:14px; border-top:1px solid rgb(var(--heading) / 0.08);
}
.topic-card-count{ font-family:var(--font-mono); font-size:0.7rem; color:rgb(var(--text-muted)); letter-spacing:0.02em; }
.topic-card-arrow{ width:15px; height:15px; color:rgb(var(--card-accent)); transition:transform 0.28s var(--ease); }
@media (hover: hover){ .topic-card:hover .topic-card-arrow{ transform:translateX(5px); } }

/* ---- The complete library ---- */
.library-head{ margin-bottom:22px; }
.library-head h2{ font-size:clamp(1.6rem, 4vw, 2.15rem); margin:6px 0 0; }

.library-controls{
  display:flex; gap:12px; align-items:center; flex-wrap:wrap; margin-bottom:16px;
}
.library-search{ position:relative; flex:1 1 320px; min-width:0; margin:0; }
.library-search input{
  width:100%; padding:13px 42px 13px 46px; border-radius:999px; font-size:0.95rem;
  font-family:var(--font-ui); color:rgb(var(--text));
  background:rgb(var(--surface)); border:1px solid rgb(var(--heading) / 0.16);
  transition:border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.library-search input:focus{ outline:none; border-color:rgb(var(--accent)); box-shadow:0 0 0 3px rgb(var(--accent) / 0.16); }
.library-search > svg{ position:absolute; left:17px; top:50%; transform:translateY(-50%); width:18px; height:18px; color:rgb(var(--text-muted)); pointer-events:none; }
.library-search-clear{
  position:absolute; right:8px; top:50%; transform:translateY(-50%);
  width:30px; height:30px; border-radius:50%; display:grid; place-items:center;
  background:rgb(var(--heading) / 0.07); color:rgb(var(--text-muted)); border:0; cursor:pointer;
  transition:background 0.2s var(--ease), color 0.2s var(--ease);
}
@media (hover: hover){ .library-search-clear:hover{ background:rgb(var(--heading) / 0.14); color:rgb(var(--heading)); } }
.library-search-clear svg{ width:14px; height:14px; }

.library-sort select{
  appearance:none; -webkit-appearance:none;
  padding:13px 38px 13px 18px; border-radius:999px; font-size:0.88rem;
  font-family:var(--font-ui); font-weight:500; color:rgb(var(--heading)); cursor:pointer;
  background-color:rgb(var(--surface)); border:1px solid rgb(var(--heading) / 0.16);
  background-image:linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position:calc(100% - 20px) calc(50% + 1px), calc(100% - 15px) calc(50% + 1px);
  background-size:5px 5px, 5px 5px; background-repeat:no-repeat;
  transition:border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.library-sort select:focus{ outline:none; border-color:rgb(var(--accent)); box-shadow:0 0 0 3px rgb(var(--accent) / 0.16); }

/* Topic filter chips. Horizontally scrollable rather than wrapping on a
   phone, so the row stays one line tall instead of eating half the
   screen before the reader has seen a single title. */
.library-chips{
  display:flex; gap:8px; flex-wrap:wrap; margin-bottom:18px;
}
.lib-chip{
  display:inline-flex; align-items:center; gap:7px; cursor:pointer;
  padding:8px 14px; border-radius:999px; font-family:var(--font-ui);
  font-size:0.815rem; font-weight:500; line-height:1; white-space:nowrap;
  color:rgb(var(--text-muted)); background:transparent;
  border:1px solid rgb(var(--heading) / 0.15);
  transition:background 0.2s var(--ease), color 0.2s var(--ease), border-color 0.2s var(--ease);
}
@media (hover: hover){ .lib-chip:hover{ color:rgb(var(--heading)); border-color:rgb(var(--heading) / 0.32); } }
.lib-chip-n{
  font-family:var(--font-mono); font-size:0.66rem; opacity:0.7;
  padding:2px 5px; border-radius:5px; background:rgb(var(--heading) / 0.07);
}
.lib-chip.is-active{
  background:rgb(var(--ink)); color:rgb(var(--on-ink)); border-color:rgb(var(--ink));
}
.lib-chip.is-active .lib-chip-n{ background:rgb(var(--on-ink) / 0.16); opacity:0.85; }

.library-count{ font-family:var(--font-mono); font-size:0.74rem; color:rgb(var(--text-muted)); margin:0 0 14px; }

.library-list{ display:grid; grid-template-columns:1fr 1fr; gap:0 40px; align-content:start; }
/* In the grouped views a heading has to break the flow across the whole
   width, which a two-column grid can't do — so those views go to one
   column, where a heading reads as a heading. */
.library-list.is-grouped{ grid-template-columns:1fr; }

.lib-heading{
  font-family:var(--font-display); font-size:1.18rem; font-weight:600;
  color:rgb(var(--accent)); letter-spacing:0.01em;
  padding:26px 0 8px; margin-bottom:4px;
  border-bottom:1px solid rgb(var(--wash) / 0.22);
}
.lib-heading:first-child{ padding-top:2px; }

.lib-row{
  display:flex; justify-content:space-between;
  min-width:0; flex-wrap:wrap;
  padding:13px 8px; border-bottom:1px solid rgb(var(--heading) / 0.07);
  border-radius:8px;
  transition:background 0.18s var(--ease), padding-left 0.18s var(--ease);
}
@media (hover: hover){
  .lib-row:hover{ background:rgb(var(--wash) / 0.06); padding-left:14px; }
  .lib-row:hover .lib-row-title{ color:rgb(var(--accent)); }
}
.lib-row-title{
  font-family:var(--font-display); font-size:1.03rem; line-height:1.38;
  color:rgb(var(--heading)); min-width:0; transition:color 0.18s var(--ease);
}
.lib-row-meta{
  display:flex; align-items:center; gap:9px; flex-shrink:0;
  font-family:var(--font-mono); font-size:0.66rem; color:rgb(var(--text-muted)); white-space:nowrap;
}
/* v8.0 — --accent-ui, not --accent, for the same reason as .tag-gold: this
   is a label READ on a tint of its own colour, which is a foreground job.
   Measured on a rendered Topics page it was 4.09:1 on Parchment. --accent
   is fine as a foreground on plain page backgrounds (it clears 4.64:1 on
   every palette) — it is specifically on a tint of ITSELF that it stops
   being, because the tint lifts the background toward the text. */
.lib-row-topic{
  padding:2px 7px; border-radius:5px; background:rgb(var(--wash) / 0.10);
  color:rgb(var(--accent-ui)); font-weight:500;
}
.library-empty{ color:rgb(var(--text-muted)); padding:32px 0; font-size:0.95rem; }

/* ---- Saved Reflections cards (remove button) ---- */
.saved-card{ position:relative; }
.saved-remove{
  position:absolute; top:10px; right:10px; z-index:3; width:34px; height:34px;
  display:grid; place-items:center; border-radius:9px; border:none;
  background:rgb(var(--ink) / 0.55); color:rgb(var(--on-ink)); backdrop-filter:blur(4px);
  opacity:0; transform:translateY(-4px); transition:opacity 0.2s var(--ease), transform 0.2s var(--ease), background 0.2s var(--ease);
}
.saved-remove:focus-visible{ opacity:1; transform:translateY(0); }
@media (hover: hover){
  .saved-card:hover .saved-remove{ opacity:1; transform:translateY(0); }
  .saved-remove:hover{ background:rgb(var(--accent-2)); }
}
.saved-remove svg{ width:16px; height:16px; }
@media (hover:none){ .saved-remove.saved-remove{ opacity:1; transform:none; } }

/* ---- Save toast (confirmation on single posts) ---- */
.pp-toast{
  position:fixed; left:50%; bottom:26px; transform:translate(-50%, 20px);
  z-index:200; display:flex; align-items:center; gap:10px;
  padding:12px 20px; border-radius:999px; font-size:0.86rem; font-weight:600;
  color:rgb(var(--on-ink)); background:rgb(var(--ink));
  box-shadow:0 18px 44px -16px rgb(var(--shadow) / 0.6);
  opacity:0; visibility:hidden; transition:opacity 0.25s var(--ease), transform 0.25s var(--ease);
}
.pp-toast.show{ opacity:1; visibility:visible; transform:translate(-50%, 0); }
.pp-toast svg{ width:17px; height:17px; color:rgb(var(--accent-light)); }

/* ---- Resume-reading banner (single posts) ---- */

/* ---- Zen / theatre reading mode (single posts) ---- */
/* Zen mode hides the surrounding chrome with display:none so it leaves
   the layout entirely — no reserved boxes, no empty gaps. Only the
   article itself (and the exit button) remain. */

@media (max-width:960px){
  .hadith-home-grid.hadith-home-grid{ grid-template-columns:repeat(2,1fr); }
  .essay-rec-grid.essay-rec-grid{ grid-template-columns:repeat(2,1fr); }
  .library-list.library-list{ grid-template-columns:minmax(0,1fr); }
}
@media (max-width:760px){
  .hadith-day.hadith-day{ padding:26px 22px; }
  .hadith-home-grid.hadith-home-grid{ grid-template-columns:1fr; }
  .essay-rec-grid.essay-rec-grid{ grid-template-columns:1fr; }
}

/* =========================================================================
   28. PRINT
   Browser-native printing (Ctrl/Cmd+P) still produces a clean, chrome-
   free printout even without a dedicated Print button in the UI.
   ========================================================================= */
@media print{
  .article-rail,
.site-footer,
.back-top,
.reading-progress,
.bg-texture,
.theme-panel,
.pp-cmd,
.article-footer-nav,
.hero-ctas,
.rail-toggle,
.mini-bar,
.skip-link {
    display:none !important;
  }
  body{ background:#fff !important; color:#000 !important; }
  .article-grid{ display:block !important; }
  .article-main{ max-width:100% !important; }
  .entry-content{ font-size:12pt !important; color:#000 !important; }
  .entry-content a{ color:#000 !important; text-decoration:underline !important; }
  .quran-text, .is-style-quran-verse{ background:none !important; border:1px solid #999 !important; }
}

/* =========================================================================
   29. v3.3 ADDITIONS — small polish
   ========================================================================= */

/* small polish */
.topics-empty{ color:rgb(var(--text-muted)); grid-column:1 / -1; }


/* =========================================================================
   30. PRAYER TIMES & QIBLA (v5.0, split into separate pages in v5.1)
   Entirely client-calculated — no external service. A location panel,
   a live-updating "next prayer" countdown ring, today's six times, and
   a Qibla compass that becomes a live device-orientation compass on
   phones that support it (falling back gracefully to a static bearing
   everywhere else).
   ========================================================================= */
.prayer-app{ display:flex; flex-direction:column; gap:22px; }

.prayer-panel{
  background:linear-gradient(155deg, rgb(var(--surface)) 0%, rgb(var(--surface)) 55%, rgb(var(--heading) / 0.035) 130%);
  padding:28px 30px; min-width:0;
}

/* ---- location ---- */
.prayer-location-row{ display:flex; align-items:center; justify-content:space-between; gap:16px; flex-wrap:wrap; }
.prayer-location-info{ display:flex; flex-direction:column; gap:3px; min-width:0; }
.prayer-location-label{ font-family:var(--font-mono); font-size:0.66rem; letter-spacing:0.08em; text-transform:uppercase; color:rgb(var(--text-muted)); }
.prayer-location-name{ font-family:var(--font-display); font-size:1.2rem; font-weight:600; color:rgb(var(--heading)); overflow-wrap: break-word; }
.prayer-status{ font-size:0.86rem; color:rgb(var(--text-muted)); margin:14px 0 0; min-height:1.4em; }
.prayer-location-controls{ display:flex; align-items:center; gap:16px; flex-wrap:wrap; margin-top:14px; position:relative; }
.prayer-select{
  padding:10px 34px 10px 14px; border-radius:999px; border:1px solid rgb(var(--heading) / 0.16);
  background:rgb(var(--bg-alt)) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23787878' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 10px center / 14px 14px;
  color:rgb(var(--text)); font-family:var(--font-ui); font-size:0.86rem; appearance:none; max-width:100%; min-width:0;
}
/* padding (not just line-height) so the touch target clears 24px —
   measured at 176x15 before this. */
.prayer-link-btn{
  display:inline-block; font-size:0.84rem; font-weight:600; color:rgb(var(--accent));
  text-decoration:underline; text-underline-offset:3px; background:none; border:none;
  padding:7px 2px; line-height:1.3; cursor:pointer;
}
.prayer-manual-form{ display:flex; gap:10px; flex-wrap:wrap; margin-top:16px; padding-top:16px; border-top:1px solid rgb(var(--heading) / 0.08); }
.prayer-input{
  flex:1; min-width:140px; padding:10px 14px; border-radius:999px; border:1px solid rgb(var(--heading) / 0.16);
  background:rgb(var(--bg-alt)); color:rgb(var(--text)); font-family:var(--font-ui); font-size:0.86rem;
}
.prayer-input:focus{ outline:none; border-color:rgb(var(--accent)); }

/* ---- main two-column layout ---- */

/* ---- countdown ring ---- */
.prayer-countdown{ width:132px; height:132px; margin:0 auto 26px; }
.prayer-ring{ width:100%; height:100%; transform:rotate(-90deg); }
.prayer-ring-track{ fill:none; stroke-width:7; }
.prayer-ring-fill{
  fill:none; stroke-width:7;
  stroke-dasharray:339.29; stroke-dashoffset:339.29; transition:stroke-dashoffset 0.6s var(--ease);
}
.prayer-countdown-text{
  position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px; text-align:center; padding:0 10px;
}
/* 0.62rem measured 9.92px — this line names the NEXT prayer, which is the
   single most-read thing on the page, so it was the wrong place to be the
   smallest text on the site. 0.7rem is 11.2px. */
.prayer-countdown-label{ font-family:var(--font-mono); font-size:0.7rem; letter-spacing:0.04em; color:rgb(var(--text-muted)); text-transform:uppercase; }
.prayer-countdown-label span{ color:rgb(var(--accent)); font-weight:700; text-transform:none; font-family:var(--font-ui); }
.prayer-countdown-value{ font-weight:600; color:rgb(var(--heading)); }

/* ---- six prayer cards ---- */
.prayer-grid{ display:grid; grid-template-columns:repeat(6, minmax(0,1fr)); }
.prayer-card{
  display:flex; flex-direction:column; align-items:center; border-radius:14px; min-width:0;
  border:1px solid rgb(var(--heading) / 0.08); background:rgb(var(--bg-alt) / 0.5);
  transition:border-color 0.25s var(--ease), background 0.25s var(--ease), transform 0.25s var(--ease);
}
.prayer-card.is-sunrise{ opacity:0.72; }
.prayer-card.is-sunrise .prayer-card-time{ font-weight:500; }
.prayer-card.is-next{
  border-color:rgb(var(--wash) / 0.5); background:rgb(var(--wash) / 0.09); transform:translateY(-3px);
  box-shadow:0 14px 30px -18px rgb(var(--accent) / 0.5);
}
.prayer-card.is-next .prayer-card-name, .prayer-card.is-next .prayer-card-ar{ color:rgb(var(--heading)); }


.prayer-settings{
  margin-top:22px; padding-top:18px; border-top:1px solid rgb(var(--heading) / 0.08);
}
.prayer-settings-row{ display:flex; gap:20px; flex-wrap:wrap; }
.prayer-setting{ display:flex; flex-direction:column; gap:5px; font-size:0.76rem; color:rgb(var(--text-muted)); flex:1; min-width:180px; }
.prayer-setting .prayer-select{ width:100%; }
/* The method picker carries 28 entries with long names, so it gets
   noticeably more room than the two short pickers beside it. */
.prayer-setting-wide{ flex:2.2 1 300px; }
.prayer-select-sm{ padding:8px 30px 8px 12px; font-size:0.8rem; }
.prayer-input-sm{ padding:8px 12px; font-size:0.8rem; width:100%; }
.prayer-setting-hint{ font-size:0.71rem; line-height:1.5; color:rgb(var(--text-muted)); opacity:0.85; }

.prayer-method-note{
  margin:12px 0 0; font-size:0.78rem; line-height:1.6;
  color:rgb(var(--text-muted)); max-width:72ch;
  padding-left:11px; border-left:2px solid rgb(var(--wash) / 0.35);
}
.prayer-subrow{ margin-top:16px; }

/* ---- Extra markers (Imsak, midnight, last third) ---- */
.prayer-extras{
  display:flex; gap:8px; flex-wrap:wrap;
}
.prayer-extra{
  display:inline-flex; align-items:baseline; gap:7px;
  padding:6px 11px; border-radius:999px; background:rgb(var(--heading) / 0.045);
}
.prayer-extra-name{ font-family:var(--font-mono); font-size:0.62rem; letter-spacing:0.04em; text-transform:uppercase; color:rgb(var(--text-muted)); }
.prayer-extra-ar{ font-family:var(--font-arabic); font-weight: var(--ar-weight); font-size:0.9rem; color:rgb(var(--text-muted)); opacity:0.75; }
.prayer-extra-time{ font-family:var(--font-ui); font-weight:600; font-size:0.79rem; color:rgb(var(--heading-soft)); font-variant-numeric:tabular-nums; }

/* ---- Fine-tuning ---- */
.prayer-tune{ margin-top:16px; }
.prayer-tune-panel{
  margin-top:12px; padding:16px 18px; border-radius:var(--radius);
  background:rgb(var(--heading) / 0.035); border:1px solid rgb(var(--heading) / 0.08);
}
.prayer-tune-intro{ margin:0 0 12px; font-size:0.78rem; color:rgb(var(--text-muted)); }
.prayer-tune-grid{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(112px, 1fr)); gap:10px;
}
.prayer-tune-item{ display:flex; flex-direction:column; gap:4px; font-size:0.7rem; color:rgb(var(--text-muted)); }
.prayer-tune-input{
  width:100%; padding:7px 9px; border-radius:var(--radius-sm); font-size:0.82rem;
  font-family:var(--font-ui); font-variant-numeric:tabular-nums; text-align:center;
  color:rgb(var(--text)); background:rgb(var(--surface));
  border:1px solid rgb(var(--heading) / 0.16);
}
.prayer-tune-input:focus{ outline:none; border-color:rgb(var(--accent)); box-shadow:0 0 0 3px rgb(var(--accent) / 0.15); }
.prayer-tune-reset{ margin-top:12px; }

/* ---- v10.2 — the hero moment, matching the Qibla page's own (see
   "THE QIBLA PAGE ITSELF" further down): the largest type on the page
   answers the one question everyone opened it for, with a soft glow
   behind the dial so it reads as an instrument rather than a stat in a
   box. Settings moved out into their own quiet panel entirely — see
   .prayer-settings-panel below — so this one stays about today only. ---- */
.prayer-hero-panel{
  position:relative; overflow:hidden;
  padding:40px 30px 32px;
  box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5), var(--e4);
}
.prayer-hero-panel::before{
  content:''; position:absolute; top:-16%; left:50%;
  width:min(520px, 140%); height:min(420px, 130%);
  transform:translateX(-50%);
  background:radial-gradient(circle at 50% 32%,
    rgb(var(--ornament) / 0.12) 0%, rgb(var(--ornament) / 0.04) 40%, transparent 70%);
  pointer-events:none;
}
.prayer-hero-panel > *{ position:relative; z-index:1; }

.prayer-hero-panel .prayer-countdown{
  width:min(58vw, 226px); height:min(58vw, 226px);
  margin:6px auto 30px;
}
.prayer-hero-panel .prayer-ring-track{ stroke-width:5; }
.prayer-hero-panel .prayer-ring-fill{ stroke-width:5; }
/* ---- v11.1: the clock, laid out instead of flowed -------------------
   "4h 34m 04s" written as one string into a circle wrapped, leaving a
   stranded "04s" jammed against the ring. Each part is its own element
   now, sized by how much it matters: hours and minutes carry it, the
   seconds are small and quiet, and the label and Arabic name sit above
   in their own rows. Nothing wraps because nothing has to flow. ---- */
.prayer-hero-panel .prayer-countdown-text{
  gap: 0; padding: 0 14px;
}
.prayer-hero-panel .prayer-countdown-label{
  font-family: var(--font-mono); font-size: 0.62rem;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: rgb(var(--text-muted)); line-height: 1;
}
.prayer-countdown-name{
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--fs-base); line-height: 1.25; margin-top: 4px;
  color: rgb(var(--accent-ui));
}
.prayer-countdown-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 0.92rem; line-height: 1.35;
  color: rgb(var(--text-muted)); margin-bottom: 6px;
}
.prayer-hero-panel .prayer-countdown-value{
  display: flex; align-items: baseline; justify-content: center; gap: 1px;
  /* Tabular figures: this ticks every second, and a proportional face
     would shuffle width and jitter the whole dial as it changes. */
  font-variant-numeric: tabular-nums;
  color: rgb(var(--heading));
  line-height: 1;
}
.prayer-countdown-value .pc-num{
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.7rem, 1.3rem + 1.6vw, 2.35rem);
  letter-spacing: -0.02em;
}
.prayer-countdown-value .pc-unit{
  font-family: var(--font-ui); font-weight: 500;
  font-size: 0.82rem; color: rgb(var(--text-muted));
  margin: 0 5px 0 1px;
}
.prayer-countdown-value .pc-sec{
  font-family: var(--font-mono); font-size: 0.74rem;
  color: rgb(var(--text-muted)); margin-left: 3px;
  align-self: flex-end; padding-bottom: 3px;
}

/* ---- v10.2 — calculation settings, now their own panel rather than
   folded into the hero card, so "what's happening today" and "how it's
   worked out" read as two different kinds of thing rather than one
   long form. ---- */
.prayer-settings-panel{ padding-top:26px; }
.prayer-settings-title{
  display:flex; align-items:center; gap:10px;
  margin:0 0 22px; font-family:var(--font-display); font-size:1.05rem; font-weight:600;
  color:rgb(var(--heading-soft));
}
.prayer-settings-title svg{ width:18px; height:18px; flex-shrink:0; color:rgb(var(--accent)); }
.prayer-settings-panel .prayer-settings{ margin-top:0; padding-top:0; border-top:none; }

/* ---- v11.0: THE TIMES THEMSELVES, LEGIBLE AT LAST ----------------------
   Measured on a real page before changing anything: the prayer NAMES
   were rendering at 9.92px and the TIMES at 13.76px, inside cards
   186px wide and 99px tall. The six numbers that are the entire reason
   this page exists were the smallest type on it, floating in cards with
   room to spare. That is what "even the clock super bad" meant.

   The time is now the largest thing in its cell, set in tabular figures
   so the row cannot jitter as minutes tick over; the name is a proper
   small-caps label above it; and the Arabic sits quietly beneath. Same
   grid, same states — the type just does its job. ---------------------- */
.prayer-card{ padding: 15px 8px; gap: 3px; justify-content: center; }
.prayer-card-name{
  font-family: var(--font-mono);
  font-size: 0.74rem; letter-spacing: 0.07em;
  text-transform: uppercase; color: rgb(var(--text-muted));
  margin-top: 0; order: 1;
}
.prayer-card-time{
  font-family: var(--font-display);
  font-weight: 600; letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
  color: rgb(var(--heading)); line-height: 1.15;
  order: 2;
}
.prayer-card-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 0.95rem;
  color: rgb(var(--text-muted)); line-height: 1.4;
  order: 3;
}
.prayer-card.is-next .prayer-card-time{ color: rgb(var(--accent-ui)); }
.prayer-card.is-past{ opacity: 0.52; }
.prayer-card.is-past .prayer-card-time{ font-weight: 500; }

@media (max-width:600px){
  .prayer-card{ padding: 13px 6px; }
  .prayer-card-name{ font-size: 0.68rem; }
  .prayer-card-ar{ font-size: 0.88rem; }
}
@media (max-width:380px){
  .prayer-hero-panel .prayer-grid{ grid-template-columns: repeat(2, minmax(0,1fr)); }
}

/* ---- Qibla compass ---- */
.qibla-hero-panel{ display:flex; flex-direction:column; align-items:center; gap:10px; padding:44px 30px 38px; }
.qibla-hero-panel .eyebrow{ align-self:center; }
.qibla-compass{
  position:relative; width:clamp(180px, 34vw, 220px); aspect-ratio:1/1; margin:14px 0 6px;
  border-radius:50%; background:radial-gradient(circle, rgb(var(--bg-alt)), rgb(var(--surface)));
  box-shadow:inset 0 0 0 1px rgb(var(--heading) / 0.1), 0 20px 40px -24px rgb(var(--shadow) / 0.4);
}
/* No transition on transform: v6.4 moved rotation smoothing into JS
   (a per-frame, wraparound-aware exponential ease — see
   assets/qibla.js). A CSS transition here on top of that would stack a
   second, slower layer of smoothing under the first, dragging the
   needle's response into a sluggish, rubber-band feel instead of a
   crisp one. */
.qibla-rose{ position:absolute; inset:0; }
.qibla-tick{
  position:absolute; font-family:var(--font-mono); font-size:0.72rem; font-weight:700; color:rgb(var(--text-muted));
}
.qibla-compass-lg .qibla-tick{ font-size:0.85rem; }
.qibla-tick-minor{
  position:absolute; width:5px; height:5px; border-radius:50%; background:rgb(var(--heading) / 0.16); transform:translate(-50%, -50%);
}
.qibla-n{ top:8px; left:50%; transform:translateX(-50%); color:rgb(var(--heading)); font-weight:800; }
.qibla-e{ right:8px; top:50%; transform:translateY(-50%); }
.qibla-s{ bottom:8px; left:50%; transform:translateX(-50%); }
.qibla-w{ left:8px; top:50%; transform:translateY(-50%); }
.qibla-compass-lg .qibla-n{ top:14px; }
.qibla-compass-lg .qibla-e{ right:14px; }
.qibla-compass-lg .qibla-s{ bottom:14px; }
.qibla-compass-lg .qibla-w{ left:14px; }
.qibla-kaaba{
  position:absolute; inset:0; margin:auto; width:30px; height:30px; display:flex; align-items:center; justify-content:center;
  color:rgb(var(--heading)); pointer-events:none;
}
.qibla-kaaba svg{ width:22px; height:22px; }
.qibla-compass-lg .qibla-kaaba svg{ width:30px; height:30px; }
.qibla-arrow{
  position:absolute; left:50%; top:50%; width:4px; height:44%;
  transform-origin:50% 100%; /* pivot at the compass's exact center */
  transform:translate(-50%, -100%) rotate(var(--qibla-rot, 0deg));
  /* Same reasoning as .qibla-rose above: rotation smoothing now lives
     in JS, so stacking a 0.5s CSS transition on top would make the
     arrow visibly lag half a second behind where the phone actually
     is. */
  pointer-events:none;
}
.qibla-arrow svg{
  position:absolute; top:-4px; left:50%; transform:translateX(-50%); width:22px; height:22px; color:rgb(var(--accent));
  filter:drop-shadow(0 2px 6px rgb(var(--accent) / 0.5));
}
.qibla-compass-lg .qibla-arrow svg{ width:28px; height:28px; top:-6px; }
.qibla-arrow::after{
  content:''; position:absolute; left:50%; top:16px; bottom:0; width:2px; transform:translateX(-50%);
  background:linear-gradient(rgb(var(--accent)), rgb(var(--wash) / 0.15)); border-radius:2px;
}
/* The bearing is the single most important number on this page, so v7.0
   gives it the weight of a headline rather than of a caption. */
.qibla-degrees{
  margin-top:10px;
  font-variant-numeric:tabular-nums;
}
.qibla-live-note{ font-size:0.8rem; color:rgb(var(--text-muted)); margin:6px 0 0; max-width:38ch; }
.qibla-step-lead{
  font-size:0.86rem; color:rgb(var(--text-muted)); margin:2px 0 0; max-width:46ch; line-height:1.6;
}

/* ---- The sun panel (v7.0) ---- */


.prayer-disclaimer{
  font-size:0.78rem; color:rgb(var(--text-muted)); line-height:1.65; max-width:70ch;
  padding-top:18px; border-top:1px solid rgb(var(--heading) / 0.08);
}

@media (max-width:640px){
  .prayer-panel.prayer-panel{ padding:22px 18px; }
  /* v11.0 — was `.prayer-times-panel .prayer-grid`. That panel was
     renamed to .prayer-hero-panel when the page was split in two, and
     this rule was left pointing at a class that no longer exists, so
     the six-column grid stayed six columns on a phone. */
  .prayer-hero-panel .prayer-grid{ grid-template-columns:repeat(3, minmax(0,1fr)); gap:8px; }
  .prayer-card.prayer-card{ padding:12px 4px; }
  .prayer-location-row.prayer-location-row{ flex-direction:column; align-items:flex-start; }
  .prayer-location-row .btn{ width:100%; justify-content:center; }
  .prayer-settings-row.prayer-settings-row{ flex-direction:column; gap:14px; }
}

/* =========================================================================
   31. PWA INSTALL / NOTIFICATION BANNERS (v5.3)
   Small, unobtrusive, dismissible cards anchored to the bottom of the
   screen — never a blocking modal. Uses the same card language
   (surface, shadow, accent) as the rest of the site rather than
   introducing a new visual style just for these two prompts.
   ========================================================================= */
/* v11.0 — the prompt redrawn as a quiet illuminated card: a gold rule
   across the top the way a manuscript panel is ruled, the site's own
   shamsa as the icon, and a calmer entrance. The behaviour changed at
   the same time and matters more than the paint — it no longer appears
   on a first visit at all, and the two prompts can never stack. See
   assets/pwa-install.js. */
.pp-inline-ic{ width:14px; height:14px; vertical-align:-2px; color:rgb(var(--accent)); }
/* A real 40px tap target, matching every other icon-only control on the
   site — was 24px, well under the 44px guideline, and the one thing on
   this card that used a plain glyph (&times;) instead of the site's own
   icon set, which is why it looked bolted on. */


/* =========================================================================
   32. PRAYER TIMES & QIBLA — v5.4 additions
   Live clock, searchable city input, time-format toggle, tomorrow's
   Fajr, share/print actions, and a GPS accuracy note.
   ========================================================================= */

/* the city field is a text input now (searchable via a native
   datalist), not a <select> — swap the dropdown chevron for a search
   icon so it doesn't look like a broken select */
.prayer-search-input{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='11' cy='11' r='7' fill='none' stroke='%23787878' stroke-width='2'/%3E%3Cpath stroke='%23787878' stroke-width='2' stroke-linecap='round' d='M21 21l-4.3-4.3'/%3E%3C/svg%3E");
  background-position:right 12px center; background-size:15px 15px;
}
/* v12.2 — `.prayer-live-clock` is gone with its element. The live clock
   moved into the hero panel as `.prayer-clock-time`; it was a 12px
   caption beside the city name, which is not where anybody looks for the
   time. */
.prayer-panel-actions{ display:flex; gap:10px; flex-wrap:wrap; margin-top:18px; }
.prayer-setting-toggle{ min-width:auto; flex:0 0 auto; }
.prayer-format-toggle{
  gap:2px;
}
.prayer-accuracy-note{ font-family:var(--font-mono); font-size:0.72rem; color:rgb(var(--text-muted)); margin-top:2px; }
.prayer-share-btn{ margin-top:16px; }

@media (max-width:480px){
  .prayer-panel-actions{ flex-direction:column; }
  .prayer-panel-actions .btn{ width:100%; justify-content:center; }
}

/* =========================================================================
   33. QUR'AN — v6.0
   A deliberately calm, spacious reading experience: generous whitespace,
   the official Uthmani typeface at real size, and every interactive
   element (search, goals, bookmarking) kept quiet until it's needed.
   ========================================================================= */
.section-pad-sm{ padding-block:28px; }

/* ---- Fihrist hero ---- */
.quran-hero-frame{ position:relative; }

/* ---- Reading goal card ---- */
.quran-goal-card{
  border-radius:var(--radius-lg); padding:26px 28px;
  background:linear-gradient(155deg, rgb(var(--surface)) 0%, rgb(var(--surface)) 55%, rgb(var(--heading) / 0.035) 130%);
  box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5), 0 8px 26px -18px rgb(var(--shadow) / 0.35);
  border:1px solid rgb(var(--heading) / 0.07);
}
.quran-goal-empty{ display:flex; align-items:center; justify-content:space-between; gap:20px; flex-wrap:wrap; }
.quran-goal-empty-text h3{ font-size:1.2rem; margin:4px 0 6px; }
.quran-goal-empty-text p{ color:rgb(var(--text-muted)); font-size:0.9rem; max-width:46ch; }
.quran-goal-active{ display:flex; align-items:center; gap:20px; }
.quran-goal-ring{ width:64px; height:64px; flex-shrink:0; transform:rotate(-90deg); }
.quran-goal-ring .prayer-ring-fill{ stroke-dasharray:339.3; stroke-dashoffset:339.3; transition:stroke-dashoffset 0.6s var(--ease); }
.quran-goal-info{ flex:1; min-width:0; display:flex; flex-direction:column; gap:3px; }
.quran-goal-info strong{ font-family:var(--font-display); font-size:1.3rem; color:rgb(var(--heading)); }
.quran-goal-sub{ font-size:0.82rem; color:rgb(var(--text-muted)); }

/* ---- Search ---- */
.quran-search-box{
  display:flex; align-items:center; gap:12px; padding:16px 20px; border-radius:999px;
  background:rgb(var(--surface)); border:1px solid rgb(var(--heading) / 0.14);
  box-shadow:0 12px 30px -20px rgb(var(--shadow) / 0.3);
  transition:border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.quran-search-box:focus-within{ border-color:rgb(var(--wash) / 0.5); box-shadow:0 12px 30px -18px rgb(var(--accent) / 0.3); }
.quran-search-ic{ color:rgb(var(--text-muted)); flex-shrink:0; }
.quran-search-box input{
  flex:1; min-width:0; border:none; background:transparent; font-family:var(--font-ui); font-size:0.98rem; color:rgb(var(--text));
}
.quran-search-box input:focus{ outline:none; }
.quran-search-hint{ font-size:0.76rem; color:rgb(var(--text-muted)); flex-shrink:0; white-space:nowrap; }
.quran-search-results{
  margin-top:14px; border-radius:var(--radius); border:1px solid rgb(var(--heading) / 0.1);
  background:rgb(var(--surface)); box-shadow:0 20px 45px -24px rgb(var(--shadow) / 0.35);
  max-height:60vh; overflow-y:auto;
}
.quran-search-result{
  display:block; padding:16px 20px; border-bottom:1px solid rgb(var(--heading) / 0.06);
  transition:background 0.15s var(--ease);
}
.quran-search-result:last-child{ border-bottom:none; }
@media (hover: hover){ .quran-search-result:hover{ background:rgb(var(--wash) / 0.06); } }
.quran-search-result-ref{ font-family:var(--font-mono); font-size:0.72rem; color:rgb(var(--heading-soft)); letter-spacing:0.03em; margin-bottom:6px; display:block; }
.quran-search-result-ar{ font-family:var(--font-arabic); font-weight: var(--ar-weight); direction:rtl; font-size:1.2rem; color:rgb(var(--heading)); line-height:1.9; margin-bottom:4px; }
.quran-search-result-en{ font-size:0.88rem; color:rgb(var(--text-muted)); line-height:1.6; }
.quran-search-result mark{ background:rgb(var(--wash) / 0.25); color:inherit; border-radius:3px; padding:0 1px; }
.quran-search-empty{ padding:30px 20px; text-align:center; color:rgb(var(--text-muted)); font-size:0.9rem; }
.pp-saved-row-actions{ display:flex; gap:16px; margin-top:8px; }
.prayer-city-results{ position:absolute; z-index:30; width:100%; margin-top:6px; max-height:280px; }
.prayer-city-result{ width:100%; text-align:left; font-family:var(--font-ui); color:rgb(var(--text)); font-size:0.92rem; cursor:pointer; }

/* ---- Browse tabs ---- */
.quran-tabs{ display:flex; gap:8px; margin-bottom:32px; border-bottom:1px solid rgb(var(--heading) / 0.1); }
.quran-tab{
  padding:12px 6px; margin-bottom:-1px; border:none; border-bottom:2px solid transparent; background:transparent;
  font-family:var(--font-display); font-size:1rem; font-weight:600; color:rgb(var(--text-muted));
  transition:color 0.2s var(--ease), border-color 0.2s var(--ease); margin-right:22px;
}
.quran-tab-sub{ font-family:var(--font-ui); font-weight:400; font-size:0.78rem; opacity:0.75; }
@media (hover: hover){ .quran-tab:hover{ color:rgb(var(--heading)); } }
.quran-tab.is-active{ color:rgb(var(--heading-soft)); border-bottom-color:rgb(var(--accent)); }
.quran-tab-panel{ display:none; }
.quran-tab-panel.is-active{ display:block; }

/* ---- Surah grid (Fihrist) ---- */
.quran-surah-grid{ display:grid; grid-template-columns:repeat(auto-fill, minmax(260px, 1fr)); gap:16px; }
.quran-surah-card{
  display:flex; align-items:center; gap:14px; padding:18px 20px; border-radius:16px; min-width:0;
  background:linear-gradient(155deg, rgb(var(--surface)) 0%, rgb(var(--surface)) 55%, rgb(var(--heading) / 0.035) 130%);
  box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5); border:1px solid rgb(var(--heading) / 0.07);
  transition:transform 0.25s var(--ease), box-shadow 0.25s var(--ease), border-color 0.25s var(--ease);
}
@media (hover: hover){
  .quran-surah-card:hover{ transform:translateY(-4px); box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5), 0 20px 42px -22px rgb(var(--shadow) / 0.4); border-color:rgb(var(--wash) / 0.3); }
}
.quran-surah-num{
  width:34px; height:34px; flex-shrink:0; border-radius:50%; border:1.5px solid rgb(var(--wash) / 0.4);
  display:flex; align-items:center; justify-content:center; font-family:var(--font-mono); font-size:0.8rem; color:rgb(var(--heading-soft));
}
.quran-surah-info{ flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.quran-surah-translit{ font-family:var(--font-display); font-weight:600; color:rgb(var(--heading)); overflow-wrap: break-word; }
.quran-surah-meta{ font-size:0.76rem; color:rgb(var(--text-muted)); }
.quran-surah-ar{ font-family:var(--font-arabic); font-weight: var(--ar-weight); direction:rtl; flex-shrink:0; }

/* ---- Juz'/Hizb unit grid ---- */
.quran-unit-grid{ display:grid; grid-template-columns:repeat(auto-fill, minmax(120px, 1fr)); gap:12px; }
.quran-unit-card{
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px; padding:20px 10px; border-radius:14px;
  background:rgb(var(--surface)); border:1px solid rgb(var(--heading) / 0.07);
  transition:transform 0.2s var(--ease), box-shadow 0.2s var(--ease), border-color 0.2s var(--ease);
}
@media (hover: hover){
  .quran-unit-card:hover{ transform:translateY(-3px); box-shadow:0 16px 34px -22px rgb(var(--shadow) / 0.4); border-color:rgb(var(--wash) / 0.3); }
}
.quran-unit-num{ font-family:var(--font-display); font-size:1.5rem; font-weight:600; color:rgb(var(--heading-soft)); }
.quran-unit-label{ font-size:0.76rem; color:rgb(var(--text-muted)); }

/* ---- Surah reading page: header ---- */
.quran-reader{ max-width:760px; padding-top:24px; }
.quran-surah-header{ text-align:center; padding-bottom:30px; border-bottom:1px solid rgb(var(--heading) / 0.08); margin-bottom:8px; }
.quran-surah-header-top{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:28px; }
.quran-surah-nav-btn{
  display:flex; align-items:center; gap:6px; font-size:0.82rem; font-weight:600; color:rgb(var(--text-muted));
  padding:8px 10px; border-radius:999px; transition:color 0.2s var(--ease), background 0.2s var(--ease); min-width:0;
}
.quran-surah-nav-btn span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:22vw; }
@media (hover: hover){ .quran-surah-nav-btn:hover{ color:rgb(var(--heading-soft)); background:rgb(var(--wash) / 0.08); } }
.quran-surah-nav-index{ padding:8px; }
.quran-surah-header-num{
  display:inline-flex; align-items:center; justify-content:center; width:38px; height:38px; border-radius:50%;
  border:1.5px solid rgb(var(--wash) / 0.4); color:rgb(var(--heading-soft)); font-family:var(--font-mono); font-size:0.85rem; margin-bottom:16px;
}
.quran-surah-header-ar{ direction:rtl; color:rgb(var(--heading));  }
.quran-surah-header-en{ font-family:var(--font-display); font-size:1.15rem; font-weight:600; color:rgb(var(--heading-soft)); margin-bottom:14px; }
.quran-surah-header-en span{ font-weight:400; font-style:italic; color:rgb(var(--text-muted)); }
.quran-surah-header-meta{ display:flex; align-items:center; justify-content:center; gap:10px; font-size:0.82rem; color:rgb(var(--text-muted)); }

/* ---- Reading controls ----
   The Qur'an page's reading options. Since v14.0 they open from the Aa
   button (assets/aa.js, v140-layer-50-aa.css). The fixed side rail that
   held them, its toggle, and every rule that placed it or moved the
   arrow out of its way were taken out in v14.3: the rail is never shown,
   but those rules still set where the arrow sat on this page. */

.quran-rail-panel{
  position:absolute; right:0; bottom:calc(100% + 12px);
  display:flex; flex-direction:column; align-items:center;
  -webkit-backdrop-filter:blur(12px); backdrop-filter:blur(12px);
  border:1px solid rgb(var(--heading) / 0.12);
  box-shadow:0 22px 50px -18px rgb(var(--shadow) / 0.48);

  /* The clamp that makes "it disappears" impossible. Whatever the panel
     grows to hold, it stops at the top of the usable viewport and
     scrolls inside itself instead of running off the screen. */
  max-height:calc(100dvh - var(--header-h, 68px) - 130px);
  overflow-y:auto; overscroll-behavior:contain;
  scrollbar-width:thin;

  opacity:0; visibility:hidden;
  transform:translateY(8px) scale(0.97); transform-origin:bottom right;
  transition:opacity 0.2s var(--ease), transform 0.22s var(--ease), visibility 0.22s;
}
.quran-rail-panel::-webkit-scrollbar{ width:4px; }
.quran-rail-panel::-webkit-scrollbar-thumb{ background:rgb(var(--heading) / 0.2); border-radius:2px; }

.quran-rail-label{
  font-family:var(--font-mono); text-transform:uppercase;
  line-height:1;
}

/* Vertical segmented control. The sliding indicator moves on translateY
   and animates its height, mirroring the horizontal version it replaced. */


.quran-rail-font{ display:flex; flex-direction:column; align-items:center; gap:6px; }
.quran-rail-font-btn{
  border:1px solid rgb(var(--heading) / 0.12);
  color:rgb(var(--heading-soft)); font-family:var(--font-display);
  font-size:0.85rem; font-weight:600; line-height:1;
  display:flex; align-items:center; justify-content:center;
  transition:background 0.2s var(--ease), color 0.2s var(--ease), border-color 0.2s var(--ease);
}
@media (hover: hover){
  .quran-rail-font-btn:hover:not(:disabled){ background:rgb(var(--accent)); color:rgb(var(--on-accent)); border-color:rgb(var(--accent)); }
}
.quran-rail-font-btn:disabled{ opacity:0.35; cursor:default; }
/* A small stack of dots showing which size step you're on — the old bar
   gave no feedback at all once you hit the largest or smallest size. */
.quran-rail-steps{ display:flex; flex-direction:column; gap:3px; align-items:center; }
.quran-rail-step{ width:5px; height:5px; border-radius:50%; background:rgb(var(--heading) / 0.18); transition:background 0.2s var(--ease); }
.quran-rail-step.is-on{ background:rgb(var(--accent)); }

@media (prefers-reduced-motion: reduce){
  
  .quran-rail-panel{ transition:opacity 0.14s linear; }
}

.quran-share-row{ text-align:center; margin:28px 0; }

/* ---- Bismillah ---- */
.quran-bismillah{
  text-align:center; direction:rtl;
  position:relative;
}
.quran-bismillah::after{
  content:''; position:absolute; bottom:0; left:50%; transform:translateX(-50%);
  height:1px; background:linear-gradient(90deg, transparent, rgb(var(--wash) / 0.5), transparent);
}

/* ---- Ayat ---- */
.quran-ayat{ display:flex; flex-direction:column; }
.quran-ayah{
  padding:16px 4px; border-bottom:1px solid rgb(var(--heading) / 0.06); position:relative;
  scroll-margin-top:calc(var(--header-h) + 70px);
}
.quran-ayah:last-child{ border-bottom:none; }
.quran-ayah.is-target-flash{ background:rgb(var(--wash) / 0.1); }
.quran-ayah-ar{
  font-family:var(--font-quran-glyphs); direction:rtl; text-align:right;
  line-height:2.15; color:rgb(var(--heading));
}
.quran-ayah-en{ font-family:var(--font-body); font-size:var(--quran-font-size-en, 1.05rem); line-height:1.85; color:rgb(var(--text)); max-width:64ch; }
.quran-ayah-en-num{ color:rgb(var(--text-muted)); font-size:0.85em; }
.quran-ayah-actions{
  display:flex; gap:6px; margin-top:14px; opacity:0; transition:opacity 0.2s var(--ease);
}
.quran-ayah:focus-within .quran-ayah-actions,
.quran-ayah:has(.quran-ayah-save[aria-pressed="true"]) .quran-ayah-actions{ opacity:1; }
@media (hover: hover){ .quran-ayah:hover .quran-ayah-actions{ opacity:1; } }
.quran-ayah-action{
  width:32px; height:32px; border-radius:50%; border:1px solid rgb(var(--heading) / 0.12); background:rgb(var(--surface));
  color:rgb(var(--text-muted)); display:flex; align-items:center; justify-content:center;
  transition:background 0.2s var(--ease), color 0.2s var(--ease), border-color 0.2s var(--ease);
}
@media (hover: hover){
  .quran-ayah-action:hover{ background:rgb(var(--accent)); color:rgb(var(--on-accent)); border-color:rgb(var(--accent)); }
}
.quran-ayah-copy{ position:relative; }
.quran-ic-check{ display:none; }
.quran-ayah-copy.is-copied{ background:rgb(var(--accent)); color:rgb(var(--on-accent)); border-color:rgb(var(--accent)); }
.quran-ayah-copy.is-copied .quran-ic-copy{ display:none; }
.quran-ayah-copy.is-copied .quran-ic-check{ display:block; }
.quran-ayah-save[aria-pressed="true"]{ background:rgb(var(--accent)); color:rgb(var(--on-accent)); border-color:rgb(var(--accent)); }
.quran-ayah:has(.quran-ayah-save[aria-pressed="true"]){ background:rgb(var(--wash) / 0.05); }

/* view-mode toggling */

/* ---- Section markers (Juz'/Hizb dividers) — v11.4 ----------------------
   "strange gaps in Qur'an" — real, and measured. Consecutive ayat sit
   flush (0 margin; the ~32px rhythm between them comes entirely from
   each row's own 16px top/bottom padding). A juz'/hizb marker used to
   add a further 20px margin on both of its own sides on top of that,
   for a combined gap of roughly 90px around it — nearly three times the
   normal rhythm — while looking like a thin line of 11px caps text with
   nothing to justify that much silence around it. It read as broken
   spacing, not as a labelled break.

   Two changes: the surrounding gap is trimmed to something proportionate
   rather than accidental, and the label itself is given enough visual
   weight — a bordered pill on its own tinted rule — to make the pause
   self-evidently intentional instead of looking like a gap a bug left
   behind. */
.quran-section-marker{
  display:flex; align-items:center; gap:14px; margin:14px 0;
  color:rgb(var(--accent-ui)); font-family:var(--font-mono);
  font-size:0.7rem; letter-spacing:0.05em; text-transform:uppercase;
}
.quran-section-marker::before, .quran-section-marker::after{ content:''; flex:1; height:1px; background:rgb(var(--wash) / 0.22); }
.quran-section-marker span{
  flex:0 0 auto;
  padding:5px 14px;
  border-radius:999px;
  border:1px solid rgb(var(--wash) / 0.3);
  background:rgb(var(--wash) / 0.08);
  white-space:nowrap;
}

.quran-surah-footer{ display:flex; align-items:center; justify-content:space-between; gap:14px; padding-top:36px; }

@media (max-width:640px){
  .quran-surah-nav-btn span{ display:none; }
  .quran-goal-empty{ flex-direction:column; align-items:flex-start; }
  .quran-goal-empty .btn{ width:100%; justify-content:center; }
  
  .quran-rail-font-btn{ width:34px; height:30px; font-size:0.8rem; }
  .quran-ayah-ar{ font-size:var(--quran-font-size-mobile, 1.6rem); line-height:2; }
  .quran-ayah-en{ font-size:var(--quran-font-size-en-mobile, 0.95rem); }
  .quran-surah-header-ar{ font-size:clamp(2rem, 10vw, 2.8rem); }
  .quran-surah-footer .btn span, .quran-surah-footer .btn{ font-size:0.85rem; }
}

/* ---- Reading goal form (built inline by JS when "Set a goal" / "Edit goal" is clicked) ---- */
.quran-goal-form{ margin-top:20px; padding-top:20px; border-top:1px dashed rgb(var(--heading) / 0.12); display:flex; flex-direction:column; gap:14px; }
.quran-goal-form-row{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
.quran-goal-form-row > span:first-child{ font-size:0.85rem; color:rgb(var(--text-muted)); min-width:100px; }
.quran-goal-form-actions{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; }

/* =========================================================================
   34. QIBLA CAMERA AR VIEW — v6.2
   A full-screen live camera backdrop with the same direction math
   already used by the 2D compass, overlaid as a glowing reticle. Not
   true markerless AR (no floating 3D object anchored in space) — a
   camera feed for real-world context plus a directional overlay, which
   is what every major Qibla-finder app actually does under the hood.
   ========================================================================= */

.qibla-mode-row{ display:flex; flex-direction:column; align-items:center; gap:12px; margin-top:14px; width:100%; }

/* The camera entry point — v6.4. Previously a plain .btn.btn-primary
   sitting flush against a secondary button, no more inviting to tap
   than anything else on the page, for what is genuinely the best
   experience this feature offers. Now a standout card: a real
   camera-lens badge, a two-line pitch instead of three words, and a
   slow breathing glow that draws the eye without being obnoxious. */
.qibla-camera-cta{
  position:relative; width:100%; max-width:420px; display:flex; align-items:center; gap:16px;
  padding:18px 20px; border-radius:20px; border:none; text-align:left; cursor:pointer;
  /* Two layers, deliberately separated: the vivid two-tone gradient
     underneath for richness, and a flat, ALWAYS-ON dark scrim above it
     (multiply blend) purely so the text is guaranteed readable no
     matter which two palette colours land in the gradient. Verified
     numerically against every accent/accent-2 pair across all 16
     palettes: 0.42 opacity (raised from 0.38 in v6.5 when the new
     Obsidian theme's gold accent — bright by design, so it reads as
     true gold rather than bronze — measured 4.46 against the previous
     value) keeps contrast at 4.98:1 or better in the worst case,
     comfortably past the 4.5:1 minimum, across every palette. This
     scrim is static — the sheen animation below lives on a SEPARATE
     ::before layer precisely so an oversized, sliding highlight can
     never uncover part of the button and let the contrast dip
     mid-animation. */
  background:
    linear-gradient(rgb(0 0 0 / 0.42), rgb(0 0 0 / 0.42)),
    linear-gradient(135deg, rgb(var(--accent)) 0%, rgb(var(--accent-2)) 100%);
  background-blend-mode:multiply, normal;
  color:#fff; overflow:hidden;
  box-shadow:0 14px 30px -12px rgb(var(--accent) / 0.55), 0 2px 8px rgb(var(--shadow) / 0.15);
  transition:transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.qibla-camera-cta::before{
  /* Purely decorative — a slow-drifting sheen, like light catching a
     lens. Deliberately NOT relied on for contrast (see the scrim on the
     element itself above), so its animation can move freely without
     ever affecting readability. */
  content:''; position:absolute; inset:-40% -60%; z-index:0;
  background:linear-gradient(115deg, transparent 30%, rgb(255 255 255 / 0.14) 45%, transparent 60%);
  animation:qiblaCtaSheen 5s ease-in-out infinite;
}
@keyframes qiblaCtaSheen{
  0%, 100%{ transform:translateX(-30%); }
  50%{ transform:translateX(30%); }
}
@media (hover: hover){
  .qibla-camera-cta:hover{ transform:translateY(-2px); box-shadow:0 20px 38px -14px rgb(var(--accent) / 0.62), 0 4px 10px rgb(var(--shadow) / 0.18); }
}
.qibla-camera-cta:active{ transform:translateY(0) scale(0.99); }

.qibla-camera-cta-badge{
  position:relative; z-index:1; flex-shrink:0; width:52px; height:52px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  backdrop-filter:blur(4px);
}
.qibla-camera-cta-badge svg{ width:24px; height:24px; position:relative; z-index:1; }
.qibla-camera-cta-ring{
  position:absolute; inset:-6px; border-radius:50%; border:1.6px solid rgb(255 255 255 / 0.45);
  animation:qiblaCtaRing 2.6s var(--ease) infinite;
}
@keyframes qiblaCtaRing{
  0%{ transform:scale(0.85); opacity:0.9; }
  70%{ transform:scale(1.22); opacity:0; }
  100%{ transform:scale(1.22); opacity:0; }
}

.qibla-camera-cta-text{ position:relative; z-index:1; display:flex; flex-direction:column; gap:3px; min-width:0; flex:1; }
.qibla-camera-cta-title{ font-family:var(--font-display); font-size:1.08rem; font-weight:650; line-height:1.2; }
.qibla-camera-cta-sub{ font-size:0.8rem; line-height:1.4; }
.qibla-camera-cta-arrow{
  position:relative; z-index:1; flex-shrink:0; width:18px; height:18px;
  transform:rotate(90deg); transition:transform 0.25s var(--ease);
}
@media (hover: hover){ .qibla-camera-cta:hover .qibla-camera-cta-arrow{ transform:rotate(90deg) translateX(3px); } }

/* The plain-compass fallback is intentionally quiet — a text link, not
   a competing button, so the eye has exactly one obvious first choice. */
.qibla-compass-link{
  display:inline-flex; align-items:center; gap:7px; border:none; background:none; cursor:pointer;
  font-size:0.83rem; color:rgb(var(--text-muted)); padding:4px 2px;
  transition:color 0.2s var(--ease);
}
.qibla-compass-link svg{ flex-shrink:0; opacity:0.7; }
@media (hover: hover){ .qibla-compass-link:hover{ color:rgb(var(--accent)); } }
.qibla-compass-link[hidden]{ display:none; }

.qibla-camera-view{
  inset:0;
  align-items:center; justify-content:center;
}
@keyframes qiblaCamFadeIn{ from{ opacity:0; } to{ opacity:1; } }
#qiblaCameraVideo{
  inset:0;
}

.qibla-camera-close{
  top:calc(20px + env(safe-area-inset-top)); right:20px;
}

/* =========================================================================
   v12.1 — THE CALIBRATION BAND ON THE CAMERA VIEW

   Shown only while the heading cannot be trusted. It sits under the top
   chips and above the reticle, so it never covers the thing the reader is
   aiming, and it is opacity+transform only so appearing and disappearing
   costs nothing on a screen that is already decoding a video stream.
   ========================================================================= */
.qibla-cam-warn{
  position: absolute; z-index: 6;
  top: 64px; left: 12px; right: 12px;
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 13px;
  border-radius: var(--radius);
  border: 1px solid rgb(255 255 255 / 0.22);
  background: rgb(20 16 10 / 0.72);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  color: #fff;
  opacity: 0; transform: translateY(-8px); pointer-events: none;
  transition: opacity 0.24s var(--ease-soft), transform 0.24s var(--ease-out-expo);
}
.qibla-cam-warn.is-on{ opacity: 1; transform: none; }
.qibla-cam-warn-ic{
  width: 18px; height: 18px; flex-shrink: 0; margin-top: 1px;
  fill: none; stroke: #f0c96a; stroke-width: 1.8;
}
.qibla-cam-warn-text{
  font-family: var(--font-ui); font-size: 0.76rem; line-height: 1.5;
  color: rgb(255 255 255 / 0.86);
}
.qibla-cam-warn-text strong{
  display: block; font-size: 0.84rem; font-weight: 700;
  color: #fff; margin-bottom: 2px;
}

/* The reticle while the heading is not trusted: amber rather than green,
   and never the "locked on" treatment. */
.qibla-camera-reticle.is-unreliable .qibla-camera-crosshair{
  border-color: rgb(240 201 106 / 0.85);
}
.qibla-camera-reticle.is-unreliable .qibla-camera-pointer{ opacity: 0.45; }
.qibla-camera-reticle.is-unreliable.is-aligned{ /* cannot happen; stated so it stays impossible */
  filter: none;
}

@media (prefers-reduced-motion: reduce){
  .qibla-cam-warn{ transition: none; }
}

.qibla-camera-overlay{
  padding-bottom:calc(40px + env(safe-area-inset-bottom));
}

.qibla-camera-reticle{
  display:flex; align-items:center; justify-content:center;
}
.qibla-camera-reticle::after{
  /* fixed "you are here" center dot, independent of rotation */
  content:''; position:absolute; width:8px; height:8px; border-radius:50%;
  background:rgb(255 255 255 / 0.85); box-shadow:0 0 10px rgb(255 255 255 / 0.6);
}
.qibla-camera-pointer svg{
  width:34px; height:34px; margin-top:14px; color:#fff;
  filter:drop-shadow(0 2px 8px rgb(0 0 0 / 0.5));
  transition:color 0.3s var(--ease);
}
.qibla-camera-kaaba{
  position:absolute; width:30px; height:30px; border-radius:8px;
  background:rgb(255 255 255 / 0.12); backdrop-filter:blur(6px);
  display:flex; align-items:center; justify-content:center; color:rgb(255 255 255 / 0.55);
  opacity:0; transition:opacity 0.35s var(--ease);
}

.qibla-camera-reticle.is-aligned .qibla-camera-pointer svg{ color:rgb(var(--accent-light)); }
.qibla-camera-reticle.is-aligned .qibla-camera-kaaba{ opacity:1; color:rgb(var(--accent-light)); }
@keyframes qiblaCamPulse{
  0%, 100%{ opacity:0.5; transform:scale(1); }
  50%{ opacity:0.9; transform:scale(1.05); }
}


.qibla-camera-error{
  display:flex;
  max-width:320px; border-radius:var(--radius-lg);
  backdrop-filter:blur(14px); border:1px solid rgb(255 255 255 / 0.15);
}
.qibla-camera-error svg{ color:rgb(var(--accent-light)); opacity:0.8; }


/* =========================================================================
   36. INSTALL SHEET — v6.3
   Opened by the permanent header install button on any platform where
   the browser gives us no native install dialog (iOS/iPadOS Safari,
   Firefox), so that button is never dead. On Chrome/Edge/Android/Windows
   the native prompt is used instead and this never appears.
   ========================================================================= */
.pp-install-sheet-wrap{
  position:fixed; inset:0; z-index:200; display:flex; align-items:center; justify-content:center;
  padding:20px; background:rgb(var(--ink) / 0.45); backdrop-filter:blur(3px);
  opacity:0; transition:opacity 0.26s var(--ease);
}
.pp-install-sheet-wrap.in{ opacity:1; }
.pp-install-sheet{
  position:relative; width:min(430px, 100%); max-height:calc(100vh - 40px); overflow-y:auto;
  background:rgb(var(--surface)); color:rgb(var(--text));
  border:1px solid rgb(var(--heading) / 0.1); border-radius:var(--radius);
  box-shadow:0 30px 70px -24px rgb(var(--shadow) / 0.55);
  padding:26px 24px 22px; transform:translateY(14px) scale(0.98);
  transition:transform 0.3s var(--ease);
}
.pp-install-sheet-wrap.in .pp-install-sheet{ transform:translateY(0) scale(1); }
.pp-install-sheet-close{
  position:absolute; top:12px; right:12px; width:32px; height:32px; border-radius:50%;
  display:flex; align-items:center; justify-content:center; border:none; background:transparent;
  color:rgb(var(--text-muted)); transition:background 0.2s var(--ease), color 0.2s var(--ease);
}
@media (hover: hover){ .pp-install-sheet-close:hover{ background:rgb(var(--heading) / 0.08); color:rgb(var(--heading)); } }
.pp-install-sheet-close svg{ width:16px; height:16px; }
.pp-install-sheet-head{ display:flex; align-items:flex-start; gap:14px; margin-bottom:20px; padding-right:28px; }
.pp-install-sheet-icon{ flex-shrink:0; width:42px; height:42px; }
.pp-install-sheet-icon svg{ width:100%; height:100%; }
.pp-install-sheet h3{
  font-family:var(--font-display); font-size:1.12rem; font-weight:600;
  color:rgb(var(--heading)); margin:0 0 5px; line-height:1.25;
}
.pp-install-sheet-head p{ font-size:0.86rem; line-height:1.5; color:rgb(var(--text-muted)); margin:0; }
.pp-install-steps{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:12px; }
.pp-install-steps li{ display:flex; align-items:flex-start; gap:12px; font-size:0.9rem; line-height:1.5; }
.pp-install-step-n{
  flex-shrink:0; width:24px; height:24px; border-radius:50%;
  background:rgb(var(--accent)); color:rgb(var(--on-accent));
  display:flex; align-items:center; justify-content:center;
  font-family:var(--font-mono); font-size:0.75rem; margin-top:1px;
}
.pp-install-steps b{ color:rgb(var(--heading)); font-weight:600; }
.pp-install-note{
  margin:18px 0 0; padding-top:14px; border-top:1px dashed rgb(var(--heading) / 0.14);
  font-size:0.78rem; line-height:1.5; color:rgb(var(--text-muted));
}
@media (prefers-reduced-motion: reduce){
  .pp-install-sheet-wrap, .pp-install-sheet{ transition:opacity 0.15s linear; transform:none; }
}

/* =========================================================================
   37. NEXT 30 DAYS TIMETABLE — v6.3
   One dataset, two presentations. Above 720px it's a real aligned table
   with a sticky header row, which is what a timetable wants to be. Below
   that a phone can't show seven columns legibly, so each day becomes a
   card and each time carries its own label — the same trick a good
   responsive table uses, rather than shrinking the type until it can't
   be read or forcing a sideways scroll.
   ========================================================================= */
.prayer-month-panel{ margin-top:18px; }
.prayer-month-head{
  display:flex; align-items:flex-start; justify-content:space-between; gap:16px;
  padding-bottom:16px; margin-bottom:4px; border-bottom:1px solid rgb(var(--heading) / 0.1);
}
.prayer-month-title{
  font-family:var(--font-display); font-size:1.08rem; font-weight:600;
  color:rgb(var(--heading)); margin:0 0 4px;
}
.prayer-month-sub{ display:block; font-size:0.78rem; color:rgb(var(--text-muted)); line-height:1.45; }
.prayer-month-scroll{ margin:0 -4px; }
.prayer-month-table{ display:flex; flex-direction:column; }

.prayer-month-row{
  display:grid; grid-template-columns:minmax(104px, 1.35fr) repeat(6, minmax(0, 1fr));
  align-items:center; gap:4px; padding:9px 8px; border-radius:10px;
  border-bottom:1px solid rgb(var(--heading) / 0.055);
}
.prayer-month-row:last-child{ border-bottom:none; }
.prayer-month-row-head{
  position:sticky; top:calc(var(--header-h) + 4px); z-index:5;
  background:rgb(var(--surface)); border-bottom:1px solid rgb(var(--heading) / 0.14);
  font-family:var(--font-mono); font-size:0.68rem; letter-spacing:0.06em; text-transform:uppercase;
  color:rgb(var(--text-muted)); border-radius:0;
}
.prayer-month-row-head span{ text-align:center; }
.prayer-month-row-head .prayer-month-day{ text-align:left; }

.prayer-month-day{ display:flex; flex-direction:column; gap:1px; line-height:1.25; }
.prayer-month-dow{ font-size:0.72rem; color:rgb(var(--text-muted)); text-transform:uppercase; letter-spacing:0.04em; }
.prayer-month-date{ font-size:0.9rem; font-weight:600; color:rgb(var(--heading)); }
.prayer-month-hijri{ font-size:0.7rem; color:rgb(var(--accent)); }
.prayer-month-cell{
  text-align:center; font-family:var(--font-mono); font-size:0.82rem;
  color:rgb(var(--text)); font-variant-numeric:tabular-nums;
}

.prayer-month-row.is-friday{ background:rgb(var(--wash) / 0.045); }
.prayer-month-row.is-today{
  background:rgb(var(--wash) / 0.12); box-shadow:inset 0 0 0 1px rgb(var(--accent) / 0.3);
}
.prayer-month-row.is-today .prayer-month-date,
.prayer-month-row.is-today .prayer-month-cell{ color:rgb(var(--heading)); font-weight:600; }

.prayer-month-foot{
  display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap;
  padding-top:14px; margin-top:10px; border-top:1px solid rgb(var(--heading) / 0.1);
  font-size:0.78rem; color:rgb(var(--text-muted));
}
.prayer-month-legend{ display:inline-flex; align-items:center; gap:7px; }
.prayer-month-dot{
  width:11px; height:11px; border-radius:3px; background:rgb(var(--wash) / 0.25);
  box-shadow:inset 0 0 0 1px rgb(var(--accent) / 0.5);
}

@media (max-width:720px){
  /* Card-per-day. Each time labels itself from data-label, so no column
     header is needed and nothing has to be scrolled sideways. */
  .prayer-month-row-head{ display:none; }
  .prayer-month-row{
    grid-template-columns:repeat(3, minmax(0, 1fr));
    gap:8px 6px; padding:13px 12px; margin-bottom:8px;
    border:1px solid rgb(var(--heading) / 0.09); border-radius:14px;
  }
  .prayer-month-day{
    grid-column:1 / -1; flex-direction:row; align-items:baseline; gap:8px; flex-wrap:wrap;
    padding-bottom:8px; margin-bottom:2px; border-bottom:1px dashed rgb(var(--heading) / 0.12);
  }
  .prayer-month-dow{ order:1; }
  .prayer-month-date{ order:0; font-size:0.95rem; }
  .prayer-month-hijri{ order:2; margin-left:auto; }
  .prayer-month-cell{
    display:flex; flex-direction:column; align-items:center; gap:2px;
    font-size:0.85rem; padding:4px 2px;
  }
  .prayer-month-cell::before{
    content:attr(data-label);
    font-family:var(--font-body); font-size:0.66rem; letter-spacing:0.04em; text-transform:uppercase;
    color:rgb(var(--text-muted));
  }
}

@media print{
  /* A printed timetable should be the whole point of the page, not one
     panel among many. */
  .prayer-month-panel{ break-inside:auto; }
  .prayer-month-row{ break-inside:avoid; }
  .prayer-month-row-head{ position:static; }
  .prayer-month-foot, .prayer-month-head .prayer-link-btn{ display:none; }
}

/* =========================================================================
   38. QIBLA — accuracy, calibration & guidance — v6.3
   The direction maths was always right; this is the layer that helps
   someone actually trust and use it. An uncalibrated phone compass can
   be tens of degrees out with nothing on screen to suggest it, so
   accuracy is shown honestly and calibration is taught with a moving
   picture rather than a sentence.
   ========================================================================= */
.qibla-intro{ color:rgb(var(--text-muted)); margin-top:10px; max-width:60ch; line-height:1.6; }

.qibla-step{ position:relative; }
.qibla-step-badge{
  /* Text is --heading, not --accent. Accent-on-accent-tint measured
     between 2.79 and 4.39 against composited backgrounds across the
     light palettes, i.e. below the 4.5 AA minimum for text this size in
     five of them. The tint carries the accent identity; the heading
     colour carries the legibility. */
  border:1px solid rgb(var(--wash) / 0.28);
}

/* ---- accuracy indicator ---- */
.qibla-status-bar{
  width:100%; margin-bottom:18px;
}
.qibla-accuracy{ display:inline-flex; align-items:center; gap:9px; font-size:0.8rem; color:rgb(var(--text-muted)); }
.qibla-accuracy-bars{ display:inline-flex; align-items:flex-end; gap:2.5px; height:14px; }
.qibla-accuracy-bars span{
  width:4px; border-radius:1.5px; background:rgb(var(--heading) / 0.18);
  transition:background 0.3s var(--ease), height 0.3s var(--ease);
}
.qibla-accuracy-bars span:nth-child(1){ height:6px; }
.qibla-accuracy-bars span:nth-child(2){ height:10px; }
.qibla-accuracy-bars span:nth-child(3){ height:14px; }
.qibla-accuracy[data-level="good"] .qibla-accuracy-bars span{ background:#2f9e6b; }
.qibla-accuracy[data-level="fair"] .qibla-accuracy-bars span:nth-child(-n+2){ background:#d79a2b; }
.qibla-accuracy[data-level="poor"] .qibla-accuracy-bars span:nth-child(1){ background:#cf5a4a; }
.qibla-accuracy[data-level="good"] .qibla-accuracy-text{ color:#2f9e6b; }
.qibla-accuracy[data-level="fair"] .qibla-accuracy-text{ color:#b57d18; }
.qibla-accuracy[data-level="poor"] .qibla-accuracy-text{ color:#cf5a4a; }
.qibla-accuracy[data-level="poor"] .qibla-accuracy-bars span:nth-child(1){ animation:qiblaPulseBar 1.4s var(--ease) infinite; }
@keyframes qiblaPulseBar{ 0%,100%{ opacity:1; } 50%{ opacity:0.35; } }

.qibla-recalibrate-btn{
  text-decoration:underline; text-underline-offset:3px; text-decoration-thickness:1px;
}

.qibla-aligned-msg{
  justify-content:center;
}
.qibla-aligned-msg::before{ content:'\2713'; font-size:1.05rem; }
.qibla-compass.is-aligned{ filter:drop-shadow(0 0 18px rgb(47 158 107 / 0.4)); }

/* ---- how to hold your phone ---- */
.qibla-howto-panel{ margin-top:18px; }
.qibla-howto-title{
  font-family:var(--font-display); font-size:1.02rem; font-weight:600;
  color:rgb(var(--heading)); margin:0 0 18px;
}
.qibla-howto-item{ text-align:center; align-items:center; }
.qibla-howto-fig{
  width:100%; max-width:150px; border-radius:14px; padding:8px;
  background:rgb(var(--heading) / 0.035); border:1px solid rgb(var(--heading) / 0.07);
}
.qibla-howto-fig svg{ width:100%; height:auto; display:block; overflow:visible; }
.qibla-howto-text strong{ display:block; font-size:0.9rem; color:rgb(var(--heading)); margin-bottom:5px; }
.qibla-howto-text span{ display:block; font-size:0.8rem; line-height:1.55; color:rgb(var(--text-muted)); }

.qfig-shadow{ fill:rgb(var(--heading) / 0.1); }
.qfig-phone-flat rect{ fill:rgb(var(--surface)); stroke:rgb(var(--heading) / 0.5); stroke-width:1.6; }
.qfig-phone-flat .qfig-screen{ fill:rgb(var(--accent) / 0.14); stroke:none; }
.qfig-needle{ fill:rgb(var(--accent)); stroke:none; }
.qfig-level{ stroke:rgb(var(--accent) / 0.5); stroke-width:1.4; stroke-dasharray:4 4; fill:none; }
.qfig-ring{ fill:none; stroke:rgb(var(--heading) / 0.28); stroke-width:1.6; }
.qfig-magnet{ fill:none; stroke:rgb(var(--heading) / 0.3); stroke-width:1.6; stroke-linecap:round; }
.qfig-cross path{ stroke:#cf5a4a; stroke-width:2.2; stroke-linecap:round; fill:none; }
.qfig-person circle{ fill:rgb(var(--accent) / 0.25); stroke:rgb(var(--accent)); stroke-width:1.5; }
.qfig-person path{ stroke:rgb(var(--accent)); stroke-width:1.8; stroke-linecap:round; fill:none; }
.qfig-turn-arc{ fill:none; stroke:rgb(var(--accent)); stroke-width:1.8; stroke-linecap:round; stroke-dasharray:3 3.5; }
.qfig-turn-head{ fill:rgb(var(--accent)); }
.qfig-label{
  fill:rgb(var(--text-muted)); font-family:var(--font-mono); font-size:8px;
  letter-spacing:0.04em; text-transform:uppercase;
}

/* ---- calibration sheet ---- */
.qibla-calibrate{
  position:fixed; inset:0; display:flex; align-items:center; justify-content:center;
  padding:20px; background:rgb(var(--ink) / 0.5); backdrop-filter:blur(4px);
  opacity:0; transition:opacity 0.26s var(--ease);
}
.qibla-calibrate.in{ opacity:1; }
.qibla-calibrate-card{
  position:relative; width:min(440px, 100%); max-height:calc(100vh - 40px); overflow-y:auto;
  background:rgb(var(--surface)); border:1px solid rgb(var(--heading) / 0.1);
  border-radius:var(--radius); box-shadow:0 30px 70px -24px rgb(var(--shadow) / 0.55);
  padding:28px 24px 22px; text-align:center;
  transform:translateY(14px) scale(0.98); transition:transform 0.3s var(--ease);
}
.qibla-calibrate.in .qibla-calibrate-card{ transform:translateY(0) scale(1); }
.qibla-calibrate-close{
  position:absolute; top:12px; right:12px; width:32px; height:32px; border-radius:50%;
  display:flex; align-items:center; justify-content:center; border:none; background:transparent;
  color:rgb(var(--text-muted)); transition:background 0.2s var(--ease), color 0.2s var(--ease);
}
@media (hover: hover){ .qibla-calibrate-close:hover{ background:rgb(var(--heading) / 0.08); color:rgb(var(--heading)); } }
.qibla-calibrate-close svg{ width:16px; height:16px; }
.qibla-calibrate-card h3{
  font-family:var(--font-display); font-size:1.18rem; font-weight:600;
  color:rgb(var(--heading)); margin:0 0 10px; padding:0 24px;
}
.qibla-calibrate-lead{ font-size:0.88rem; line-height:1.6; color:rgb(var(--text-muted)); margin:0 0 6px; }

/* The figure-eight — v6.4 rebuild. A big phone that visibly TILTS
   and TURNS in 3D as it sweeps the loop, rather than a small flat icon
   sliding along a line. The path, the phone's motion, and the
   direction chevrons are all generated from one shared parametric
   formula (a lemniscate: x=sin(t), y=sin(t)cos(t)) rather than drawn
   by hand, so the guide track drawn underneath and the phone's actual
   travel can never visually disagree. */
.qibla-figure8{ margin:10px 0 16px; display:flex; flex-direction:column; align-items:center; gap:12px; }
.q8-stage{
  position:relative; width:222px; height:134px; perspective:600px;
  filter:drop-shadow(0 10px 18px rgb(var(--shadow) / 0.16));
}
.q8-guide{ position:absolute; inset:0; width:100%; height:100%; overflow:visible; }
.q8-guide-track{
  /* v12.2 — 0.32 → 0.22. The track is the road, not the traffic: now
     that a lit trail runs it, the static line only has to say where the
     shape goes when the animation is between passes. */
  fill:none; stroke:rgb(var(--accent) / 0.22); stroke-width:2.5; stroke-linecap:round; stroke-linejoin:round;
}
/*
 * THE TRAIL — v12.2. A comet a quarter of the path long, running the
 * figure of eight in step with the phone above it.
 *
 * The keyframes below are GENERATED from @keyframes q8Roll's own
 * translate3d values: the cumulative distance the phone has travelled at
 * each frame, expressed as a fraction of the whole path, becomes the
 * dash offset at that frame. So the light is where the phone is at every
 * moment, including through the slow parts at the ends of the loops
 * where a linear animation would visibly run ahead of it.
 *
 * `pathLength="100"` on the path (see page-qibla.php) is what lets the
 * dash array and offset be written as plain percentages instead of in
 * user units that would have to be remeasured if the shape changed.
 */
.q8-trail{
  fill:none;
  stroke:rgb(var(--accent));
  stroke-width:3.4; stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:24 76;
  animation:q8Trail 6s linear infinite;
  filter:drop-shadow(0 0 5px rgb(var(--accent) / 0.55));
}
.q8-chevron{
  fill:none; stroke:rgb(var(--accent) / 0.6); stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round;
}
.q8-start-ring{
  fill:none; stroke:rgb(var(--accent)); stroke-width:1.6; opacity:0.5;
  animation:q8Pulse 1.8s var(--ease) infinite;
  transform-box:fill-box; transform-origin:center;
}
.q8-start-dot{ fill:rgb(var(--accent)); }
@keyframes q8Pulse{
  0%{ transform:scale(1); opacity:0.55; }
  70%{ transform:scale(2.6); opacity:0; }
  100%{ transform:scale(2.6); opacity:0; }
}

/* The phone: a real 3D element (perspective on the parent + preserve-3d
   here) so rotateX/rotateY genuinely foreshorten it as it turns, rather
   than faking tilt with a 2D skew. This is what makes the "roll your
   wrist" motion actually read at a glance. */
.q8-phone-wrap{
  position:absolute; top:50%; left:50%; width:0; height:0;
  transform-style:preserve-3d;
}
.q8-phone{
  position:absolute; top:0; left:0;
  animation:q8Roll 6s ease-in-out infinite;
  transform-style:preserve-3d;
}
.q8-phone-body{
  position:relative; width:38px; height:62px; border-radius:9px;
  background:linear-gradient(155deg, rgb(var(--surface)), rgb(var(--bg-alt)));
  border:1.6px solid rgb(var(--accent));
  box-shadow:0 3px 10px rgb(var(--shadow) / 0.3), inset 0 1px 0 rgb(255 255 255 / 0.4);
  display:flex; align-items:center; justify-content:center;
}
.q8-phone-notch{
  position:absolute; top:4px; left:50%; transform:translateX(-50%);
  width:12px; height:2.5px; border-radius:2px; background:rgb(var(--wash) / 0.4);
}
.q8-phone-screen{
  width:28px; height:46px; border-radius:5px;
  background:rgb(var(--wash) / 0.14);
  display:flex; align-items:center; justify-content:center;
}
.q8-compass-mini{
  width:17px; height:17px; color:rgb(var(--accent));
  animation:q8CompassSpin 6s linear infinite;
}
/* The mini compass glyph on the phone's screen spins opposite the
   phone's own yaw so it always looks like it's still finding north —
   a small touch that reinforces WHY the motion matters, not just what
   it looks like. */
@keyframes q8CompassSpin{ from{ transform:rotate(0deg); } to{ transform:rotate(-360deg); } }

@keyframes q8Roll{
  0%{ transform:translate(-50%,-50%) translate3d(0.00px,0.00px,0) rotateY(0.00deg) rotateX(0.00deg) rotateZ(0.00deg); }
  2.083%{ transform:translate(-50%,-50%) translate3d(10.18px,5.95px,0) rotateY(-5.48deg) rotateX(2.85deg) rotateZ(1.55deg); }
  4.167%{ transform:translate(-50%,-50%) translate3d(20.19px,11.50px,0) rotateY(-10.87deg) rotateX(5.50deg) rotateZ(3.00deg); }
  6.25%{ transform:translate(-50%,-50%) translate3d(29.85px,16.26px,0) rotateY(-16.07deg) rotateX(7.78deg) rotateZ(4.24deg); }
  8.333%{ transform:translate(-50%,-50%) translate3d(39.00px,19.92px,0) rotateY(-21.00deg) rotateX(9.53deg) rotateZ(5.20deg); }
  10.417%{ transform:translate(-50%,-50%) translate3d(47.48px,22.22px,0) rotateY(-25.57deg) rotateX(10.63deg) rotateZ(5.80deg); }
  12.5%{ transform:translate(-50%,-50%) translate3d(55.15px,23.00px,0) rotateY(-29.70deg) rotateX(11.00deg) rotateZ(6.00deg); }
  14.583%{ transform:translate(-50%,-50%) translate3d(61.88px,22.22px,0) rotateY(-33.32deg) rotateX(10.63deg) rotateZ(5.80deg); }
  16.667%{ transform:translate(-50%,-50%) translate3d(67.55px,19.92px,0) rotateY(-36.37deg) rotateX(9.53deg) rotateZ(5.20deg); }
  18.75%{ transform:translate(-50%,-50%) translate3d(72.06px,16.26px,0) rotateY(-38.80deg) rotateX(7.78deg) rotateZ(4.24deg); }
  20.833%{ transform:translate(-50%,-50%) translate3d(75.34px,11.50px,0) rotateY(-40.57deg) rotateX(5.50deg) rotateZ(3.00deg); }
  22.917%{ transform:translate(-50%,-50%) translate3d(77.33px,5.95px,0) rotateY(-41.64deg) rotateX(2.85deg) rotateZ(1.55deg); }
  25%{ transform:translate(-50%,-50%) translate3d(78.00px,0.00px,0) rotateY(-42.00deg) rotateX(0.00deg) rotateZ(0.00deg); }
  27.083%{ transform:translate(-50%,-50%) translate3d(77.33px,-5.95px,0) rotateY(-41.64deg) rotateX(-2.85deg) rotateZ(-1.55deg); }
  29.167%{ transform:translate(-50%,-50%) translate3d(75.34px,-11.50px,0) rotateY(-40.57deg) rotateX(-5.50deg) rotateZ(-3.00deg); }
  31.25%{ transform:translate(-50%,-50%) translate3d(72.06px,-16.26px,0) rotateY(-38.80deg) rotateX(-7.78deg) rotateZ(-4.24deg); }
  33.333%{ transform:translate(-50%,-50%) translate3d(67.55px,-19.92px,0) rotateY(-36.37deg) rotateX(-9.53deg) rotateZ(-5.20deg); }
  35.417%{ transform:translate(-50%,-50%) translate3d(61.88px,-22.22px,0) rotateY(-33.32deg) rotateX(-10.63deg) rotateZ(-5.80deg); }
  37.5%{ transform:translate(-50%,-50%) translate3d(55.15px,-23.00px,0) rotateY(-29.70deg) rotateX(-11.00deg) rotateZ(-6.00deg); }
  39.583%{ transform:translate(-50%,-50%) translate3d(47.48px,-22.22px,0) rotateY(-25.57deg) rotateX(-10.63deg) rotateZ(-5.80deg); }
  41.667%{ transform:translate(-50%,-50%) translate3d(39.00px,-19.92px,0) rotateY(-21.00deg) rotateX(-9.53deg) rotateZ(-5.20deg); }
  43.75%{ transform:translate(-50%,-50%) translate3d(29.85px,-16.26px,0) rotateY(-16.07deg) rotateX(-7.78deg) rotateZ(-4.24deg); }
  45.833%{ transform:translate(-50%,-50%) translate3d(20.19px,-11.50px,0) rotateY(-10.87deg) rotateX(-5.50deg) rotateZ(-3.00deg); }
  47.917%{ transform:translate(-50%,-50%) translate3d(10.18px,-5.95px,0) rotateY(-5.48deg) rotateX(-2.85deg) rotateZ(-1.55deg); }
  50%{ transform:translate(-50%,-50%) translate3d(0.00px,0.00px,0) rotateY(0.00deg) rotateX(0.00deg) rotateZ(0.00deg); }
  52.083%{ transform:translate(-50%,-50%) translate3d(-10.18px,5.95px,0) rotateY(5.48deg) rotateX(2.85deg) rotateZ(1.55deg); }
  54.167%{ transform:translate(-50%,-50%) translate3d(-20.19px,11.50px,0) rotateY(10.87deg) rotateX(5.50deg) rotateZ(3.00deg); }
  56.25%{ transform:translate(-50%,-50%) translate3d(-29.85px,16.26px,0) rotateY(16.07deg) rotateX(7.78deg) rotateZ(4.24deg); }
  58.333%{ transform:translate(-50%,-50%) translate3d(-39.00px,19.92px,0) rotateY(21.00deg) rotateX(9.53deg) rotateZ(5.20deg); }
  60.417%{ transform:translate(-50%,-50%) translate3d(-47.48px,22.22px,0) rotateY(25.57deg) rotateX(10.63deg) rotateZ(5.80deg); }
  62.5%{ transform:translate(-50%,-50%) translate3d(-55.15px,23.00px,0) rotateY(29.70deg) rotateX(11.00deg) rotateZ(6.00deg); }
  64.583%{ transform:translate(-50%,-50%) translate3d(-61.88px,22.22px,0) rotateY(33.32deg) rotateX(10.63deg) rotateZ(5.80deg); }
  66.667%{ transform:translate(-50%,-50%) translate3d(-67.55px,19.92px,0) rotateY(36.37deg) rotateX(9.53deg) rotateZ(5.20deg); }
  68.75%{ transform:translate(-50%,-50%) translate3d(-72.06px,16.26px,0) rotateY(38.80deg) rotateX(7.78deg) rotateZ(4.24deg); }
  70.833%{ transform:translate(-50%,-50%) translate3d(-75.34px,11.50px,0) rotateY(40.57deg) rotateX(5.50deg) rotateZ(3.00deg); }
  72.917%{ transform:translate(-50%,-50%) translate3d(-77.33px,5.95px,0) rotateY(41.64deg) rotateX(2.85deg) rotateZ(1.55deg); }
  75%{ transform:translate(-50%,-50%) translate3d(-78.00px,0.00px,0) rotateY(42.00deg) rotateX(0.00deg) rotateZ(0.00deg); }
  77.083%{ transform:translate(-50%,-50%) translate3d(-77.33px,-5.95px,0) rotateY(41.64deg) rotateX(-2.85deg) rotateZ(-1.55deg); }
  79.167%{ transform:translate(-50%,-50%) translate3d(-75.34px,-11.50px,0) rotateY(40.57deg) rotateX(-5.50deg) rotateZ(-3.00deg); }
  81.25%{ transform:translate(-50%,-50%) translate3d(-72.06px,-16.26px,0) rotateY(38.80deg) rotateX(-7.78deg) rotateZ(-4.24deg); }
  83.333%{ transform:translate(-50%,-50%) translate3d(-67.55px,-19.92px,0) rotateY(36.37deg) rotateX(-9.53deg) rotateZ(-5.20deg); }
  85.417%{ transform:translate(-50%,-50%) translate3d(-61.88px,-22.22px,0) rotateY(33.32deg) rotateX(-10.63deg) rotateZ(-5.80deg); }
  87.5%{ transform:translate(-50%,-50%) translate3d(-55.15px,-23.00px,0) rotateY(29.70deg) rotateX(-11.00deg) rotateZ(-6.00deg); }
  89.583%{ transform:translate(-50%,-50%) translate3d(-47.48px,-22.22px,0) rotateY(25.57deg) rotateX(-10.63deg) rotateZ(-5.80deg); }
  91.667%{ transform:translate(-50%,-50%) translate3d(-39.00px,-19.92px,0) rotateY(21.00deg) rotateX(-9.53deg) rotateZ(-5.20deg); }
  93.75%{ transform:translate(-50%,-50%) translate3d(-29.85px,-16.26px,0) rotateY(16.07deg) rotateX(-7.78deg) rotateZ(-4.24deg); }
  95.833%{ transform:translate(-50%,-50%) translate3d(-20.19px,-11.50px,0) rotateY(10.87deg) rotateX(-5.50deg) rotateZ(-3.00deg); }
  97.917%{ transform:translate(-50%,-50%) translate3d(-10.18px,-5.95px,0) rotateY(5.48deg) rotateX(-2.85deg) rotateZ(-1.55deg); }
  100%{ transform:translate(-50%,-50%) translate3d(0.00px,0.00px,0) rotateY(0.00deg) rotateX(0.00deg) rotateZ(0.00deg); }
}
@keyframes q8Trail{
  0%{ stroke-dashoffset:100.00; }
  2.083%{ stroke-dashoffset:96.95; }
  4.167%{ stroke-dashoffset:93.99; }
  6.25%{ stroke-dashoffset:91.21; }
  8.333%{ stroke-dashoffset:88.66; }
  10.417%{ stroke-dashoffset:86.39; }
  12.5%{ stroke-dashoffset:84.40; }
  14.583%{ stroke-dashoffset:82.65; }
  16.667%{ stroke-dashoffset:81.07; }
  18.75%{ stroke-dashoffset:79.57; }
  20.833%{ stroke-dashoffset:78.07; }
  22.917%{ stroke-dashoffset:76.55; }
  25%{ stroke-dashoffset:75.00; }
  27.083%{ stroke-dashoffset:73.45; }
  29.167%{ stroke-dashoffset:71.93; }
  31.25%{ stroke-dashoffset:70.43; }
  33.333%{ stroke-dashoffset:68.93; }
  35.417%{ stroke-dashoffset:67.35; }
  37.5%{ stroke-dashoffset:65.60; }
  39.583%{ stroke-dashoffset:63.61; }
  41.667%{ stroke-dashoffset:61.34; }
  43.75%{ stroke-dashoffset:58.79; }
  45.833%{ stroke-dashoffset:56.01; }
  47.917%{ stroke-dashoffset:53.05; }
  50%{ stroke-dashoffset:50.00; }
  52.083%{ stroke-dashoffset:46.95; }
  54.167%{ stroke-dashoffset:43.99; }
  56.25%{ stroke-dashoffset:41.21; }
  58.333%{ stroke-dashoffset:38.66; }
  60.417%{ stroke-dashoffset:36.39; }
  62.5%{ stroke-dashoffset:34.40; }
  64.583%{ stroke-dashoffset:32.65; }
  66.667%{ stroke-dashoffset:31.07; }
  68.75%{ stroke-dashoffset:29.57; }
  70.833%{ stroke-dashoffset:28.07; }
  72.917%{ stroke-dashoffset:26.55; }
  75%{ stroke-dashoffset:25.00; }
  77.083%{ stroke-dashoffset:23.45; }
  79.167%{ stroke-dashoffset:21.93; }
  81.25%{ stroke-dashoffset:20.43; }
  83.333%{ stroke-dashoffset:18.93; }
  85.417%{ stroke-dashoffset:17.35; }
  87.5%{ stroke-dashoffset:15.60; }
  89.583%{ stroke-dashoffset:13.61; }
  91.667%{ stroke-dashoffset:11.34; }
  93.75%{ stroke-dashoffset:8.79; }
  95.833%{ stroke-dashoffset:6.01; }
  97.917%{ stroke-dashoffset:3.05; }
  100%{ stroke-dashoffset:0.00; }
  100%{ stroke-dashoffset:0; }
}@keyframes q8PassLit{
  0%{ background:rgb(var(--accent)); transform:scale(1.35); }
  30%{ background:rgb(var(--heading) / 0.16); transform:scale(1); }
  100%{ background:rgb(var(--heading) / 0.16); transform:scale(1); }
}

.qibla-calibrate-steps{
  list-style:none; margin:0 0 18px; padding:0; display:flex; flex-direction:column; gap:11px; text-align:left;
}
.qibla-calibrate-steps li{ font-size:0.85rem; line-height:1.5; }
.qibla-cal-n{
  flex-shrink:0; width:22px; height:22px; border-radius:50%;
  background:rgb(var(--accent)); color:rgb(var(--on-accent));
  display:flex; align-items:center; justify-content:center;
  font-family:var(--font-mono); font-size:0.72rem; margin-top:1px;
}
.qibla-calibrate-live{
  display:flex; justify-content:center; margin-bottom:16px; padding:9px 12px; border-radius:999px;
  background:rgb(var(--heading) / 0.04); border:1px solid rgb(var(--heading) / 0.08);
}
.qibla-calibrate-card .btn-primary{ width:100%; justify-content:center; }
.qibla-calibrate-note{
  margin:16px 0 0; padding-top:14px; border-top:1px dashed rgb(var(--heading) / 0.14);
  font-size:0.76rem; line-height:1.55; color:rgb(var(--text-muted)); text-align:left;
}

/* ---- camera view additions ---- */
.qibla-camera-top{
  top:calc(16px + env(safe-area-inset-top)); left:16px;
}
.qibla-accuracy-oncam{
  padding:7px 13px; border-radius:999px; background:rgb(0 0 0 / 0.55);
  backdrop-filter:blur(8px); color:#fff;
}
.qibla-accuracy-oncam .qibla-accuracy-text{ color:#fff; }
.qibla-accuracy-oncam .qibla-accuracy-bars span{ background:rgb(255 255 255 / 0.3); }
@media (hover: hover){ .qibla-cam-calibrate:hover{ background:rgb(0 0 0 / 0.75); } }

/* One unambiguous instruction, large enough to read at arm's length. */
.qibla-camera-turn{
  animation:qiblaTurnNudge 1.8s var(--ease) infinite;
}
@keyframes qiblaTurnNudge{
  0%,100%{ transform:translate(-50%, -50%) translateY(-132px) scale(1); }
  50%{ transform:translate(-50%, -50%) translateY(-132px) scale(1.045); }
}

@media (max-width:760px){
  .qibla-howto-grid{ grid-template-columns:1fr; gap:18px; }
  .qibla-howto-item{
    flex-direction:row; align-items:center; text-align:left; gap:14px;
  }
  .qibla-howto-fig{ width:96px; flex-shrink:0; }
  .qibla-status-bar{ justify-content:center; }
}

@media (prefers-reduced-motion: reduce){
  .q8-phone{ animation:none; top:50%; left:50%; transform:translate(-50%,-50%); }
  /* The trail stops moving but stays drawn, so the shape is still
     stated — reduced motion means no animation, not no information. */
  .q8-trail{ animation:none; stroke-dasharray:none; opacity:0.85; }
  .q8-compass-mini{ animation:none; }
  .q8-start-ring{ animation:none; opacity:0.35; }
  .q8-pass-dot{ animation:none !important; }
  .q8-pass-dot[data-pass="1"]{ background:rgb(var(--accent)); }
  .qibla-camera-turn{ animation:none; }
  .qibla-accuracy[data-level="poor"] .qibla-accuracy-bars span:nth-child(1){ animation:none; }
  .qibla-calibrate, .qibla-calibrate-card{ transition:opacity 0.15s linear; transform:none; }
}

/* =========================================================================
   30. PHONES — the v7.0 mobile pass
   =========================================================================
   Everything above this point was designed on a wide screen and then
   narrowed. This section starts from the opposite end: what a person
   holding a phone in one hand actually needs.

   Deliberately placed last in the file so these rules win on order as
   well as on their media query, and written with doubled class names
   (`.topics-grid.topics-grid`) wherever an earlier mobile block already
   styles the same element, so specificity carries the override rather
   than file position — the same reasoning as the nav-drawer block
   further up, and for the same reason: a minifying or "optimize CSS"
   plugin that reorders rules must not be able to undo any of this.
   ========================================================================= */

@media (max-width: 760px) {

  /* ---- Nothing may ever scroll sideways -----------------------------
     A single over-wide element (a table, a code block, a long unbroken
     URL in a post) makes the WHOLE page slide horizontally, which on a
     phone feels like the site is broken. The base rule on html and body
     is `overflow-x: clip`, which contains that.

     v14.3 — THIS BLOCK USED TO SAY `overflow-x: hidden` ON BOTH, and that
     was the reason "the tafsir bar sometimes isnt fully sticking to the top
     header" on every phone. `hidden` on <body> makes the body a scroll
     container of its own (its overflow-y computes to `auto`), and a sticky
     element sticks to the nearest scroll container — a body that never
     scrolls. So on a phone the tafsīr bar, the book's running head and
     every other sticky bar simply scrolled away with the page. `clip`
     hides the same overflow without creating a scroll container. */
  .site-main img,
  .site-main table,
  .site-main pre { max-width: 100%; }
  .site-main pre { overflow-x: auto; }
  .site-main table { display: block; overflow-x: auto; }

  /* ---- Reading ------------------------------------------------------
     The single biggest thing a phone needs from a site that exists to be
     read: slightly larger type, more line height, and less horizontal
     padding stealing the measure. 17px with 1.75 line-height puts a
     comfortable 38–42 characters on a line at typical phone widths. */
  .entry-content,
.page-content {
    font-size: 1.06rem;
    line-height: 1.78;
  }
  .entry-content p { margin-bottom: 1.3em; }
  .entry-content h2 { font-size: 1.5rem; line-height: 1.25; margin-top: 1.9em; }
  .entry-content h3 { font-size: 1.24rem; line-height: 1.3; margin-top: 1.6em; }
  .entry-content blockquote { padding-left: 16px; margin-left: 0; margin-right: 0; }

  /* Long words and pasted URLs break instead of forcing the page wide. */
  .entry-content,
.lib-row-title,
.topic-card-name,
.card h3 {
    overflow-wrap: break-word;
    word-break: break-word;
  }

  /* ---- Vertical rhythm ----------------------------------------------
     Desktop section padding on a phone means a lot of scrolling past
     nothing. Tightened, but not so far that sections run together. */
  .section-pad.section-pad { padding-top: 44px; padding-bottom: 44px; }
  .section-header.section-header { margin-bottom: 22px; gap: 10px; }
  .section-header h2 { font-size: clamp(1.5rem, 6.4vw, 1.9rem); line-height: 1.18; }

  /* ---- Tap targets ---------------------------------------------------
     v8.0 — moved out of this block, to "TOUCH TARGETS OUTSIDE THE HEADER"
     earlier in the file. Two reasons.

     It belongs at a wider breakpoint: this block stops at 760px, so a
     portrait iPad at 768px got none of it, and an iPad in landscape at
     1024px got none of it either — both are touch devices where every
     one of these is hit with a fingertip.

     And it was in conflict with the new block. Both declared `.btn-sm`
     at (0,2,0); this one sat later in the file and won on source order,
     holding it at 42px against the 44px the other asked for. One rule
     owns tap targets now, and it is the one with both conditions. */

  /* =====================================================================
     TOPICS ON A PHONE
     ---------------------------------------------------------------------
     This is the thing that was specifically called out as unclear, and
     the fix isn't a tweak — it's a different component.

     A "topic tile" is a card: an icon, a heading, a sentence of
     description, and a count, in a box. At desktop widths, several sit
     side by side and the eye takes in the whole set at once, which is
     what makes a card grid work. Stacked one per row on a phone, each
     one is around 200px tall, so nine topics is roughly two thousand
     pixels of scrolling — five full screens — to see a list of nine
     short names. The set can never be perceived as a set, and the
     description text that justified the card's height on desktop is
     precisely what's burying the names on a phone.

     So on a phone they stop being cards and become rows: icon, name,
     count, chevron, about 66px each. Nine of them is one screen. The
     descriptions are dropped rather than shrunk — at this size they are
     what's in the way, and the topic names were written to stand on
     their own.
     ===================================================================== */
  .topics-grid.topics-grid,
  .topic-card-grid.topic-card-grid {
    grid-template-columns: 1fr;
    gap: 0;
    border-top: 1px solid rgb(var(--heading) / 0.09);
  }

  .topic-tile.topic-tile,
  .topic-card.topic-card {
    display: block;
    border: 0;
    border-bottom: 1px solid rgb(var(--heading) / 0.09);
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    padding: 0;
    transform: none;
  }
  @media (hover: hover){
    .topic-tile.topic-tile:hover,
    .topic-card.topic-card:hover { transform: none; box-shadow: none; }
  }
  .topic-card.topic-card::before,
  .topic-card.topic-card::after,
  .topic-tile.topic-tile::before { display: none; }

  /* One grid per row: [icon] [name + count] [chevron] */
  .topic-tile .topic-tile-inner,
  .topic-card.topic-card {
    display: grid;
    grid-template-columns: 40px 1fr 16px;
    align-items: center;
    gap: 14px;
    padding: 14px 2px;
    min-height: 66px;
  }

  .topic-icon, .topic-card-icon {
    width: 40px; height: 40px; margin: 0; border-radius: 11px;
    background: rgb(var(--card-accent, var(--accent)) / 0.12);
    color: rgb(var(--card-accent, var(--accent)));
  }
  .topic-icon svg, .topic-card-icon svg { width: 20px; height: 20px; }
  @media (hover: hover){
    .topic-tile:hover .topic-icon,
    .topic-card:hover .topic-card-icon { transform: none; }
  }

  .topic-tile h3,
  .topic-card-name.topic-card-name {
    font-size: 1.02rem;
    line-height: 1.3;
    margin: 0 0 2px;
    font-weight: 600;
  }

  /* The descriptions are the height. On a phone they go. */
  .topic-tile p,
  .topic-card-desc.topic-card-desc { display: none; }

  .topic-card-body { display: contents; }

  .topic-count,
  .topic-card-foot.topic-card-foot {
    padding: 0;
    border: 0;
    display: block;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    color: rgb(var(--text-muted));
  }
  /* The count sits under the name, in the middle column; the arrow gets
     the third column to itself. */
  .topic-card-foot.topic-card-foot { grid-column: 2; grid-row: 2; margin-top: -2px; }
  .topic-card.topic-card { grid-template-rows: auto auto; align-content: center; }
  .topic-card-icon { grid-row: 1 / 3; }
  .topic-card-name { grid-column: 2; grid-row: 1; }
  .topic-card-arrow { grid-column: 3; grid-row: 1 / 3; width: 15px; height: 15px; opacity: 0.5; }
  @media (hover: hover){ .topic-card:hover .topic-card-arrow { transform: none; } }
  .topic-count svg { display: none; }

  /* =====================================================================
     v8.0 — THE HOME PAGE TOPIC ROWS GOT THE SAME PLACEMENT.

     The rule above placed every child of .topic-card explicitly, and left
     every child of .topic-tile — the home page's version of the same row —
     to the grid's automatic placement. Those two components have different
     markup: .topic-card has a separate .topic-card-arrow element for the
     third column, while .topic-tile keeps its arrow INSIDE .topic-count.

     So auto-placement put .topic-count itself into column three: the 14–16px
     strip reserved for a chevron. "17 writings" cannot fit in 14px, so it
     wrapped one character per line and rendered as a vertical stack of
     letters down the right edge of every topic on the home page. It is the
     most visible thing wrong with the site on a phone.

     Every child is now placed by hand, exactly as .topic-card's are.
     ===================================================================== */
  .topic-tile .topic-tile-inner { grid-template-rows: auto auto; align-content: center; }
  .topic-tile .topic-icon { grid-column: 1; grid-row: 1 / 3; }
  .topic-tile h3 { grid-column: 2; grid-row: 1; }
  .topic-tile .topic-count { grid-column: 2; grid-row: 2; margin-top: -2px; }

  /* The chevron the third column exists for. .topic-count's own <svg> is a
     descendant of .topic-count, so it cannot be placed in a different grid
     column than its parent — hence it stays hidden (above) and the row's
     chevron is drawn here instead, at the same size and weight as
     .topic-card-arrow on the Topics page so the two components match. */
  .topic-tile .topic-tile-inner::after {
    content: '';
    grid-column: 3; grid-row: 1 / 3;
    justify-self: end; align-self: center;
    width: 7px; height: 7px; margin-right: 2px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    border-radius: 1px;
    transform: rotate(-45deg);
    opacity: 0.42;
  }

  /* =====================================================================
     THE LIBRARY (Topics page)
     ===================================================================== */
  .topics-hero { margin-bottom: 28px; }
  .topic-card-grid.topic-card-grid { margin-bottom: 44px; }

  .library-controls { gap: 10px; }
  .library-search { flex: 1 1 100%; }
  .library-sort { flex: 1 1 100%; }
  .library-sort select { width: 100%; }

  /* The filter chips scroll sideways in their own strip rather than
     wrapping. Nine wrapped chips is four stacked rows — most of a phone
     screen spent on filters before a single title is visible. One
     scrolling line keeps the list itself above the fold. The edge fade
     and the partially-visible chip at the right are what tell a reader
     there is more to the side; a neatly-clipped row reads as complete. */
  .library-chips.library-chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding: 2px 24px 10px 0;
    margin-right: -20px;
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 34px), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 34px), transparent);
  }
  .library-chips.library-chips::-webkit-scrollbar { display: none; }
  .lib-chip { scroll-snap-align: start; }

  .lib-row { padding: 14px 6px; gap: 3px 10px; }
  @media (hover: hover){ .lib-row:hover { padding-left: 6px; } }
  .lib-row-title { font-size: 1rem; flex: 1 1 100%; }
  /* v8.0 — 0.63rem measured 10.08px, and this line (topic · date · reading
     time) repeats under all ~100 titles, so it was the largest single block
     of sub-11px text anywhere on the site. 0.7rem is 11.2px and still reads
     as secondary against the 16px title above it.

     It has to be allowed to WRAP to carry the extra width. The base rule is
     `flex-shrink:0; white-space:nowrap`, which was survivable at 10px but
     at 11.2px pushed the row 27px past the right edge of a 320px screen
     behind the longest topic name ("The Prophet ﷺ & His Companions").
     Wrapping, plus a topic chip that can ellipsise, means no topic name
     length can do that again. */
  .lib-row-meta {
    font-size: 0.7rem; gap: 5px 8px;
    flex-wrap: wrap; flex-shrink: 1; min-width: 0;
  }
  .lib-row-topic {
    min-width: 0; max-width: 100%;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }

  /* =====================================================================
     PRAYER TIMES & QIBLA
     ===================================================================== */
  .prayer-settings-row.prayer-settings-row { gap: 14px; }
  .prayer-setting.prayer-setting { flex: 1 1 100%; min-width: 0; }
  .prayer-setting-toggle.prayer-setting-toggle { flex: 0 0 auto; }
  .prayer-select-sm.prayer-select-sm { padding: 11px 32px 11px 12px; font-size: 0.86rem; }
  .prayer-method-note { font-size: 0.76rem; }
  .prayer-extras { gap: 6px; }
  .prayer-extra { padding: 5px 9px; }
  .prayer-tune-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  .qibla-howto-grid.qibla-howto-grid { grid-template-columns: 1fr; gap: 18px; }
  .qibla-howto-item { flex-direction: row; text-align: left; align-items: center; gap: 14px; }
  .qibla-howto-fig { max-width: 84px; flex: 0 0 84px; }

  /* =====================================================================
     THE HOMEPAGE
     ===================================================================== */
  .hero .corner { display: none; }
  .hero-ctas .btn { flex: 1 1 auto; justify-content: center; }
  /* =====================================================================
     v8.0 — THE HERO STATS ROW.

     This was `flex: 1 1 40%` on a wrapping flex row with the dividers set
     to display:none. Three items at a 40% basis means two fit on the first
     line and the third is left alone on the second, where `flex-grow`
     stretches it to the full width — so the phone showed a lopsided
     2-then-1-full-width block, with the hidden dividers still counted as
     flex items contributing gaps between them.

     A three-column grid is the shape this always wanted: three equal
     columns that stay three equal columns, separated by real hairlines
     instead of by elements that had to be hidden. The numbers sit on one
     baseline because every cell starts at the top of the same row, no
     matter how many lines its label takes.
     ===================================================================== */
  .hero-stats.hero-stats {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0;
    align-items: start;
    margin-top: 30px;
    padding: 16px 0 4px;
    border-top: 1px solid rgb(var(--heading) / 0.1);
  }
  /* The dividers were markup standing in for a border. The border does it
     properly: it cannot be left with a stale gap, and it disappears by
     itself on the first column. */
  .hero-stat-divider { display: none; }
  .hero-stat {
    padding: 0 4px;
    border-left: 1px solid rgb(var(--heading) / 0.1);
    gap: 4px;
  }
  .hero-stat:first-child { border-left: none; }
  .hero-stat-num { font-size: 1.42rem; }
  /* Deliberately the SAME 0.64rem the desktop label uses, not smaller. An
     earlier draft of this grid shrank it to 0.56rem (8.96px measured) to
     force each label onto one line; that is below anything else on the
     site and traded the bug for an unreadable one. Two tidy lines at the
     site's own label size is the better answer — the columns are equal
     width, so the labels wrap evenly instead of raggedly. */
  .hero-stat-label {
    font-size: 0.64rem;
    letter-spacing: 0.04em;
    line-height: 1.4;
    text-align: center;
    text-wrap: balance;
  }

  .newsletter-band.newsletter-band { padding: 30px 20px; }
  .newsletter-form.newsletter-form { flex-direction: column; gap: 10px; }
  .newsletter-form input, .newsletter-form .btn { width: 100%; }

  .welcome-grid.welcome-grid { gap: 14px; }

  /* The footer's four columns become two, which reads far better than
     one very long stack of links. */
  .footer-grid.footer-grid { grid-template-columns: 1fr 1fr; gap: 26px 20px; }
  .footer-brand { grid-column: 1 / -1; }
  .footer-col ul li a { display: inline-block; padding: 4px 0; }
}

/* ---- Small phones (≤ 400px) ---- */
@media (max-width: 400px) {
  .topic-tile .topic-tile-inner,
  .topic-card.topic-card { grid-template-columns: 36px 1fr 14px; gap: 12px; }
  .topic-icon, .topic-card-icon { width: 36px; height: 36px; }
  .topic-tile h3, .topic-card-name.topic-card-name { font-size: 0.97rem; }
  .prayer-tune-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer-grid.footer-grid { grid-template-columns: 1fr; }
}

/* =========================================================================
   31. TOPIC ARCHIVE HEADER + TOPIC SWITCHER (v7.0)
   A category page is a topic page: it leads with the topic's own icon and
   description, and ends by offering every other topic, so browsing never
   dead-ends and force a trip back through the menu to change subject.
   ========================================================================= */

.page-lede{
  color:rgb(var(--text-muted)); margin-top:10px; max-width:64ch; line-height:1.7;
}
.archive-desc{ color:rgb(var(--text-muted)); margin-top:8px; max-width:640px; }

.topic-archive-head{
  display:flex; gap:20px; align-items:flex-start; margin-bottom:36px;
  padding-bottom:26px; border-bottom:1px solid rgb(var(--heading) / 0.09);
}
.topic-archive-icon{
  flex:0 0 auto; width:58px; height:58px; border-radius:16px; display:grid; place-items:center;
  background:linear-gradient(145deg, rgb(var(--wash) / 0.18), rgb(var(--wash) / 0.05));
  color:rgb(var(--accent));
}
.topic-archive-icon svg{ width:29px; height:29px; }
.topic-archive-head h1{
  font-size:clamp(1.8rem, 5.4vw, 2.7rem); line-height:1.08; letter-spacing:-0.02em;
  margin:6px 0 10px;
}
.topic-archive-desc{
  color:rgb(var(--text-muted)); font-size:1rem; line-height:1.65; margin:0 0 12px; max-width:60ch;
}
.topic-archive-count{
  font-family:var(--font-mono); font-size:0.7rem; letter-spacing:0.05em; text-transform:uppercase;
  color:rgb(var(--accent));
}

.topic-switch{
  margin-top:56px; padding-top:28px; border-top:1px solid rgb(var(--heading) / 0.09);
}
.topic-switch-label{
  display:block; font-family:var(--font-mono); font-size:0.68rem; letter-spacing:0.08em;
  text-transform:uppercase; color:rgb(var(--text-muted)); margin-bottom:14px;
}
.topic-switch-chips{ display:flex; flex-wrap:wrap; gap:9px; }
.topic-switch-chips .lib-chip{ text-decoration:none; }
.lib-chip-all{
  background:rgb(var(--wash) / 0.10); border-color:rgb(var(--wash) / 0.32);
  color:rgb(var(--accent)); font-weight:600;
}
.lib-chip-all svg{ width:13px; height:13px; }
@media (hover: hover){ .lib-chip-all:hover{ background:rgb(var(--wash) / 0.18); color:rgb(var(--accent-ui)); } }

@media (max-width:760px){
  .topic-archive-head{ gap:14px; margin-bottom:26px; padding-bottom:20px; }
  .topic-archive-icon{ width:46px; height:46px; border-radius:13px; }
  .topic-archive-icon svg{ width:23px; height:23px; }
  .topic-archive-desc{ font-size:0.92rem; }
  .topic-switch{ margin-top:40px; }
}


/* =========================================================================
   40. v7.1 — THE ELEVATION LAYER
   -------------------------------------------------------------------------
   v7.0 shipped eight palettes that were carefully chosen and correctly
   contrast-checked, and then spent them on a flat page. Colour was doing
   all the work; nothing above it described DEPTH. Every panel on the site
   had its own hand-written box-shadow, no two of them agreeing, and the
   result read as a well-chosen palette rather than as a designed object.

   This section adds the layer that was missing. It changes no palette
   value — every colour in section 0 is untouched, and all eight themes
   keep the exact contrast ratios that were measured for them. What it adds
   is a vocabulary the rest of the stylesheet can speak in:

     · a six-step shadow ladder, derived from each palette's own --shadow
       so it stays in the palette's colour family rather than going grey
     · named surface roles (raised / sunken / glass / hairline)
     · one modular type scale, fluid between 380px and 1280px viewports
     · one spacing scale
     · four motion curves, including a real spring

   Dark palettes override the ladder's alphas at the bottom of this
   section: an ambient shadow that reads as depth on parchment is
   invisible on obsidian, where depth has to come from a light rim
   instead. Same token names, inverted physics.
   ========================================================================= */

:root{
  /* ---- MOTION -----------------------------------------------------------
     --ease was already here and is left alone, so nothing that currently
     uses it changes behaviour. The four below are new.
     --spring overshoots slightly and settles: it is for things that
     APPEAR (sheets, menus, cards on hover). It must never be used on
     anything continuously driven by a sensor — see the note on
     .qibla-rose about why compass needles get their smoothing in JS. */
  --spring: cubic-bezier(.34, 1.56, .64, 1);
  --ease-out-expo: cubic-bezier(.16, 1, .3, 1);
  --ease-soft: cubic-bezier(.4, 0, .2, 1);
  --dur-fast: 140ms;
  --dur: 240ms;
  --dur-slow: 420ms;

  /* ---- ELEVATION LADDER -------------------------------------------------
     Two shadows per step: a tight contact shadow that grounds the element,
     and a wider ambient one that gives it height. Both are composited from
     the palette's own --shadow triplet, so a warm parchment page casts a
     warm shadow and a cool sea-glass page casts a cool one — a grey shadow
     over a warm background is one of the most reliable ways to make a
     design look unfinished.
     The alphas are deliberately low. Six clearly distinguishable steps at
     low opacity read as a real surface hierarchy; two heavy ones read as
     drop-shadow. */
  --e0: none;
  --e1:
    0 1px 2px rgb(var(--shadow) / 0.055),
    0 1px 1px rgb(var(--shadow) / 0.04);
  --e2:
    0 2px 4px -1px rgb(var(--shadow) / 0.06),
    0 4px 10px -2px rgb(var(--shadow) / 0.07);
  --e3:
    0 4px 8px -2px rgb(var(--shadow) / 0.07),
    0 10px 22px -6px rgb(var(--shadow) / 0.10);
  --e4:
    0 8px 16px -4px rgb(var(--shadow) / 0.08),
    0 20px 44px -12px rgb(var(--shadow) / 0.14);
  --e5:
    0 14px 28px -8px rgb(var(--shadow) / 0.10),
    0 34px 72px -20px rgb(var(--shadow) / 0.18);
  /* For anything that floats over the whole page — sheets, drawers, the
     method picker. Heavier on purpose: it has to separate from a scrim. */
  --e-overlay:
    0 24px 48px -12px rgb(var(--shadow) / 0.22),
    0 60px 120px -30px rgb(var(--shadow) / 0.30);

  /* Accent-tinted glow, for the one primary action on a screen. */

  /* ---- SURFACE ROLES ----------------------------------------------------
     --surface already existed as "the colour of a card". These describe
     what a surface IS relative to the page, which is what components
     actually need to ask for. */
  --surface-raised: var(--surface);
  --surface-sunken: var(--bg-alt);
  /* A hairline that is a tint of the palette's ink rather than a grey
     border — the difference between a card that belongs to the page and
     one that was pasted onto it. */
  --hairline: rgb(var(--ink) / 0.09);
  --hairline-strong: rgb(var(--ink) / 0.16);
  --hairline-faint: rgb(var(--ink) / 0.05);

  /* Frosted surfaces. Backdrop-filter is progressively enhanced below —
     the fallback is simply a more opaque background, which is why the
     alpha here is only trusted when blur is known to be supported. */
  --glass-bg: rgb(var(--surface) / 0.72);
  --glass-bg-strong: rgb(var(--surface) / 0.88);
  --glass-border: rgb(255 255 255 / 0.5);
  --glass-blur: saturate(180%) blur(20px);
  --scrim: rgb(var(--shadow) / 0.42);

  /* ---- FAILURE ----------------------------------------------------------
     v11.5 — `--danger` was USED (`.tafsir-tool.is-failed`) and never
     DECLARED. It happened to work because that one call site carried a
     fallback triplet inline, which is exactly the kind of thing that is
     correct today and wrong the second time somebody reaches for the
     token. tools/verify.py has been reporting it since v11.0.

     Declared here rather than per palette because it is not a palette
     colour: it is the one hue on this site that must NOT harmonise with
     the page. A muted brick, warm enough to sit beside the golds without
     shouting, and light enough at 0.55 alpha to stay visible on the four
     dark grounds. It is only ever used for a border or a tint, never for
     text, so it is not held to a text-contrast ratio. */
  --danger: 176 62 48;

  /* ---- ACCENT, AS A FOREGROUND ------------------------------------------
     --accent-ui is DECLARED BY EACH PALETTE, not here.

     It used to default to `var(--accent)` in this block, which was an
     outright bug once the palettes started defining it themselves: this
     :root comes later in the file than the palette :root at equal
     specificity, so this default silently overwrote the tuned Parchment
     value for every reader on the default theme. (The data-theme palettes
     escaped it only because their selector is more specific — which is the
     kind of accident that makes a bug look intermittent.)

     The token's PURPOSE, which is what belongs in a comment here:

       --accent        a FILL. Deep enough that --on-accent clears 4.5:1
                       on top of it. Buttons, badges, the countdown ring.
       --accent-ui     the same hue as a FOREGROUND on the page. Clears
                       4.5:1 against --bg, so it is safe for link text and
                       small labels, not just for icons.
       --accent-light  for INK surfaces — the footer, the newsletter band,
                       the camera overlay — where the other two are too
                       dark to read.

     One value cannot satisfy all three, which is why there are three. See
     _gen_palettes.py, which asserts every one of those relationships for
     every palette before emitting anything. */

  /* ---- FOCUS ------------------------------------------------------------
     One ring, used everywhere, visible against every palette because it is
     the accent at full strength plus a contrasting inner halo of the page
     colour underneath it. */
  /* --accent-ui, not --accent, and at full opacity rather than 0.85.
     A focus ring is a non-text UI component and needs 3:1 against what
     surrounds it; the Emerald palette's raw accent measures 2.93:1 on its
     own page background, and dropping it to 0.85 alpha lowered that
     further. Since --accent-ui exists precisely to be "the accent, safe as
     a foreground", the ring should have been asking for it all along.
     Worst case across the eight palettes is now 3.35:1 (Emerald). */
  --ring: 0 0 0 2px rgb(var(--bg)), 0 0 0 4.5px rgb(var(--accent-ui));

  /* ---- TYPE SCALE -------------------------------------------------------
     A 1.25 (major third) ratio, fluid between a 380px and a 1280px
     viewport. Fluid rather than stepped at breakpoints because headline
     sizes that jump at 768px are the most visible way a responsive site
     announces it was designed at one width and adapted to the others.
     Every clamp minimum is >= 0.69rem so nothing becomes unreadable on a
     small phone, and body text never goes below 1rem. */
  --fs-2xs: clamp(0.69rem, 0.66rem + 0.13vw, 0.75rem);
  --fs-xs:  clamp(0.75rem, 0.72rem + 0.14vw, 0.82rem);
  --fs-sm:  clamp(0.84rem, 0.80rem + 0.17vw, 0.92rem);
  --fs-base:clamp(1rem,    0.97rem + 0.16vw, 1.08rem);
  --fs-md:  clamp(1.09rem, 1.03rem + 0.28vw, 1.22rem);
  --fs-lg:  clamp(1.24rem, 1.13rem + 0.48vw, 1.5rem);
  --fs-xl:  clamp(1.45rem, 1.26rem + 0.83vw, 1.9rem);
  --fs-2xl: clamp(1.75rem, 1.4rem + 1.5vw, 2.5rem);
  --fs-3xl: clamp(2.1rem,  1.5rem + 2.6vw, 3.25rem);
  --fs-4xl: clamp(2.5rem,  1.5rem + 4.3vw, 4.25rem);

  /* Optical letter-spacing: large display type needs negative tracking to
     stop it reading as loose, small uppercase UI type needs positive. */
  --track-display: -0.021em;
  --track-tight: -0.012em;
  --track-caps: 0.085em;

  /* ---- SPACING ----------------------------------------------------------
     A 4px base, doubling loosely. */
  /* v12.2 — 7 and 9 filled in. The scale went 6, 8, 10 with two gaps in
     it, so every rule that wanted 28px or 36px either reached for a
     token that resolves to nothing (silently: an undefined custom
     property makes the whole declaration invalid and the property falls
     back to its inherited value, which is almost never what was meant)
     or wrote a raw pixel value and left the scale. tools/verify.py
     catches the first kind; nothing catches the second. */
  --sp-1: 4px;   --sp-2: 8px;   --sp-3: 12px;  --sp-4: 16px;
  --sp-5: 20px;  --sp-6: 24px;  --sp-7: 28px;  --sp-8: 32px;
  --sp-9: 36px;  --sp-10: 40px;
  --sp-12: 48px; --sp-16: 64px; --sp-20: 80px; --sp-24: 96px;

  /* Radii — the existing three, plus the two the new components need. */
  --radius-xs: 6px;
  --radius-xl: 28px;
  --radius-pill: 999px;
}

/* -------------------------------------------------------------------------
   DARK PALETTES — the same tokens, inverted physics.
   On a dark surface a black shadow is invisible, so elevation has to be
   carried by a light rim along the top edge of the element (mimicking a
   light source above) plus a much deeper, softer ambient shadow to
   separate it from the background. Hairlines invert to a tint of white for
   the same reason. Component code never has to know which case it is in.
   ------------------------------------------------------------------------- */
html[data-scheme="dark"]{
  --e1:
    inset 0 1px 0 rgb(255 255 255 / 0.035),
    0 1px 2px rgb(0 0 0 / 0.30);
  --e2:
    inset 0 1px 0 rgb(255 255 255 / 0.045),
    0 3px 8px -2px rgb(0 0 0 / 0.42);
  --e3:
    inset 0 1px 0 rgb(255 255 255 / 0.055),
    0 8px 20px -6px rgb(0 0 0 / 0.5);
  --e4:
    inset 0 1px 0 rgb(255 255 255 / 0.07),
    0 16px 38px -12px rgb(0 0 0 / 0.6);
  --e5:
    inset 0 1px 0 rgb(255 255 255 / 0.085),
    0 28px 64px -20px rgb(0 0 0 / 0.7);
  --e-overlay:
    inset 0 1px 0 rgb(255 255 255 / 0.09),
    0 30px 60px -15px rgb(0 0 0 / 0.75),
    0 70px 130px -40px rgb(0 0 0 / 0.85);

  --hairline: rgb(255 255 255 / 0.085);
  --hairline-strong: rgb(255 255 255 / 0.15);
  --hairline-faint: rgb(255 255 255 / 0.045);

  --glass-bg: rgb(var(--surface) / 0.7);
  --glass-bg-strong: rgb(var(--surface) / 0.88);
  --glass-border: rgb(255 255 255 / 0.1);
  --scrim: rgb(0 0 0 / 0.62);

  --glow-accent: 0 10px 34px -10px rgb(var(--accent) / 0.55);
}

/* Blur is expensive and not universal. Rather than assume it, the frosted
   look is applied only where it is supported; everywhere else the same
   components get a solid surface, which is a perfectly good design and not
   a degraded one. */
@supports not (backdrop-filter: blur(1px)){
  :root{
    --glass-bg: rgb(var(--surface) / 0.97);
    --glass-bg-strong: rgb(var(--surface) / 0.99);
  }
}

/* =========================================================================
   41. v7.1 — GLOBAL POLISH
   Applied to the primitives everything else is built out of, so the
   improvement reaches pages this changelog never mentions by name.
   ========================================================================= */

/* One focus ring for the entire site. :focus-visible rather than :focus so
   it appears for keyboard users and not on every mouse click — the reason
   so many sites end up deleting focus styles altogether and breaking
   keyboard access in the process. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible{
  outline: none;
  box-shadow: var(--ring);
  border-radius: var(--radius-sm);
  transition: box-shadow var(--dur-fast) var(--ease-soft);
}

/* Headings get the optical tracking the scale above defines. Sizes are
   left to the existing rules so nothing reflows unexpectedly; this is
   purely the letterfit. */
h1, .h1{ letter-spacing: var(--track-display); }
h2, h3, .h2, .h3{ letter-spacing: var(--track-tight); }

/* Selection in the palette's own accent rather than the browser's blue. */
::selection{ background: rgb(var(--wash) / 0.22); color: rgb(var(--heading)); }

/* Scrollbars, on the browsers that allow styling them. Thin, in-palette,
   and quiet against their own track. */
@supports (scrollbar-color: auto){
  html{ scrollbar-color: rgb(var(--ink) / 0.22) transparent; scrollbar-width: thin; }
}
::-webkit-scrollbar{ width: 10px; height: 10px; }
::-webkit-scrollbar-track{ background: transparent; }
::-webkit-scrollbar-thumb{
  background: rgb(var(--ink) / 0.18); border-radius: var(--radius-pill);
  border: 3px solid transparent; background-clip: content-box;
}
@media (hover: hover){ ::-webkit-scrollbar-thumb:hover{ background: rgb(var(--ink) / 0.32); background-clip: content-box; } }

/* ---- BUTTONS ------------------------------------------------------------
   The primary button was a flat accent rectangle. It is now a surface with
   a light top rim, a real shadow, and a press state that actually depresses
   — the three things that make a button feel like a physical control. */
.btn{
  font-family: var(--font-ui);
  letter-spacing: -0.005em;
  transition:
    transform var(--dur-fast) var(--ease-soft),
    box-shadow var(--dur) var(--ease-soft),
    background-color var(--dur) var(--ease-soft),
    border-color var(--dur) var(--ease-soft),
    color var(--dur) var(--ease-soft);
}
/* v13.0 — the three .btn-primary rules that were here are GONE, not
   overridden. They set a generic elevation ladder and a 16%-white inset
   that fought the gilded surface described in "THE ACTION COLOUR" near
   the foot of this file: whichever won depended on source order, which is
   how v12.3 shipped two competing buttons. There is now exactly one
   definition of the primary button in this stylesheet. */
@media (hover: hover){ .btn-ghost:hover{ box-shadow: var(--e2); } }

/* ---- CARDS & PANELS -----------------------------------------------------
   Every card class on the site pointed at its own bespoke shadow. They all
   now resolve to the same ladder, which is the single change that does the
   most to make separate pages look like one product. */
.card,
.topic-card,
.value-card,
.hadith-card,
.quran-card,
.saved-card,
.author-card {
  border: 1px solid var(--hairline);
  box-shadow: var(--e2);
  transition:
    transform var(--dur) var(--ease-out-expo),
    box-shadow var(--dur) var(--ease-out-expo),
    border-color var(--dur) var(--ease-soft);
}
@media (hover: hover){
  .card:hover,
  .topic-card:hover,
  .value-card:hover,
  .hadith-card:hover,
  .quran-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--e4);
    border-color: var(--hairline-strong);
  }
}

/* Panels are containers, not targets — they get depth but never lift on
   hover, because a 600px settings panel that jumps when the pointer
   crosses it is noise, not feedback. */
.prayer-panel{
  border: 1px solid var(--hairline);
  box-shadow: var(--e3);
  border-radius: var(--radius-lg);
  transition: box-shadow var(--dur) var(--ease-soft), border-color var(--dur) var(--ease-soft);
}

/* ---- FORM CONTROLS ------------------------------------------------------ */
.prayer-select,
.prayer-input,
input[type="text"],
input[type="search"],
input[type="email"],
input[type="number"],
select,
textarea{
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--e1);
  transition:
    border-color var(--dur) var(--ease-soft),
    box-shadow var(--dur) var(--ease-soft),
    background-color var(--dur) var(--ease-soft);
}
@media (hover: hover){
  .prayer-select:hover,
  .prayer-input:hover,
  input[type="text"]:hover,
  input[type="search"]:hover,
  select:hover{ border-color: rgb(var(--wash) / 0.5); }
}
.prayer-select:focus-visible,
.prayer-input:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible{ border-color: rgb(var(--accent-ui)); }

/* Reduced motion is honoured globally rather than component by component,
   which is how the previous version kept missing cases. Transitions are
   shortened rather than removed outright — an instant state change with no
   transition at all can be MORE disorienting, and the guidance is to reduce
   motion, not to eliminate feedback. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.05ms !important;
    scroll-behavior: auto !important;
  }
  @media (hover: hover){
    .card:hover,
    .topic-card:hover,
    .value-card:hover,
    .hadith-card:hover,
    .quran-card:hover,
    .btn-primary:hover,
    .btn-ghost:hover { transform: none; }
  }
}


/* =========================================================================
   42. v7.1 — NAVIGATION
   -------------------------------------------------------------------------
   Two separate problems, one on each side of the 1180px breakpoint.

   DESKTOP. The dropdowns worked but looked like plain white boxes with a
   list in them. They now sit on a frosted surface with a real overlay
   shadow, arrive with a spring, carry a titled header row so you know what
   you opened, and animate their rows in on a short stagger. The active
   page is finally marked in the bar — previously there was no way to tell
   from the nav which section you were in.

   MOBILE. The drawer slid in from the right against the bare page with no
   scrim, which is why it never felt like a layer: nothing dimmed behind
   it, so it read as content that had appeared rather than as a panel over
   the page. It now has a scrim, sectioned groups with labels, 52px touch
   targets throughout (unchanged — they were already right), and a
   staggered entrance. The accordion chevron animation is kept from v7.0
   because it was good.

   Everything here is scoped through .site-header or .main-nav for the same
   reason the v6.3 comments give: winning on structure rather than on file
   order survives CSS minifiers that reorder rules.
   ========================================================================= */

/* ---- The bar itself -----------------------------------------------------
   A slightly stronger frost, and a shadow that appears on scroll from the
   ladder rather than from a one-off value. */

/* ---- Nav links ----------------------------------------------------------
   The underline is replaced with a soft filled pill, which reads better at
   small sizes and gives the active state somewhere to live. */
/*
 * v11.5 — THE NAV ::after IS GONE FROM THE MARKUP'S POINT OF VIEW.
 *
 * It had been an underline (v3), then a current-section dot (v7.1), then
 * held at scale(0) (v9.1), then `content:none !important` in a THIRD
 * place (v11.0) — three separate blocks in this file whose only job was
 * to undo the second one. The pseudo-element is simply not declared any
 * more: `.nav-link` has no ::after at all, so there is nothing to
 * suppress and nothing for a later rule to bring back.
 *
 * The current section is marked the way it has actually been marked
 * since v9.1: a filled pill behind the label, which is legible at every
 * width and in all ten palettes.
 */

/*
 * v12.0 — THE CARET IS PART OF THE ITEM, SO IT TAKES THE ITEM'S COLOUR.
 *
 * A dropdown nav item is TWO controls: an <a> that navigates and a
 * <button> that opens the panel. The current-section pill above is
 * painted on the <a> alone, so on /quran/, /tafsir/ and /hadith/ the
 * label went `--accent-ui` inside a tinted pill while the caret beside
 * it — a sibling, outside the anchor — stayed `--heading-soft`. The
 * result was a coloured word with a visibly darker arrow welded to it,
 * and the pill stopping halfway through the shape. That is the "weird
 * different colour on these small arrows".
 *
 * Hover was never wrong because hover is declared on the <li>. This
 * mirrors it: when the item is current, the <li> carries the pill and
 * BOTH children take the accent, so the two halves can never disagree.
 * The pill on the <a> is dropped to transparent so the two tints do not
 * stack into a darker patch behind the label only.
 */
/* The caret's own 0.6 opacity is what made it read as a third, greyer
   colour again even once it inherited the accent. At rest inside a
   current item it sits at the same weight as the label. */

/* ---- Dropdown panels ----------------------------------------------------
   The frost + overlay shadow is what turns these from "a white box" into
   "a surface floating above the page". */

/* A small pointer joining the panel to its trigger. Drawn as a rotated
   square on ::before so it inherits the panel's own frosted background and
   border, and therefore stays correct in all eight palettes automatically. */

/* Rows: a leading icon well, a lift on hover, and an arrow that slides in
   from nothing so the row has a visible affordance without carrying a
   permanently-visible chevron on all twelve of them. */


/* Panel header row — new. A dropdown with twelve surahs in it needs to say
   what it is; without a title the panel is just a list that appeared. */


/* Staggered row entrance. Six steps is enough to read as a cascade without
   the last item arriving noticeably late; rows past the sixth simply share
   the sixth delay rather than compounding into a slow reveal. */
@keyframes navRowIn{
  from{ opacity: 0; transform: translateY(6px); }
  to{ opacity: 1; transform: translateY(0); }
}

/* ---- Header icon buttons ------------------------------------------------ */

/* ---- Search & theme panels ---------------------------------------------
   Brought onto the same frosted-surface treatment as the mega panels, so
   every layer that opens from the header looks like the same material. */
.theme-panel{
  border-radius: var(--radius-lg);
  border: 1px solid var(--glass-border);
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  box-shadow: var(--e-overlay);
  transform: translateY(-8px) scale(0.97);
  transform-origin: top right;
  transition:
    opacity var(--dur) var(--ease-out-expo),
    transform var(--dur) var(--spring),
    visibility var(--dur);
}
.theme-panel.open{ transform: translateY(0) scale(1); }
.theme-option{
  transition:
    background-color var(--dur-fast) var(--ease-soft),
    border-color var(--dur-fast) var(--ease-soft),
    transform var(--dur) var(--spring);
}
.theme-preview{ box-shadow: var(--e1); }
@media (hover: hover){ .theme-option:hover .theme-preview{ box-shadow: var(--e3); } }

/* =========================================================================
   43. v7.1 — THE MOBILE DRAWER
   The breakpoint is 1180px to match the v5.3 measurement referenced in
   section 25; changing it here would desynchronise the drawer from the
   .menu-toggle that opens it.
   ========================================================================= */
@media (max-width:1180px){

  /* ---- Scrim ------------------------------------------------------------
     There is already a scrim: `.overlay`, emitted once at the end of
     header.php and shown/hidden by main.js alongside the drawer. It was
     doing its job but reading as a flat grey wash — a hard-coded
     `rgb(var(--ink) / 0.5)` that ignored the palette's own shadow colour
     and blurred by only 2px, which is under the threshold at which a
     backdrop blur actually registers as depth rather than as a smudge.
     Re-pointed at the --scrim token (which the dark palettes already
     override) and given a blur strong enough to see. No new element: a
     second scrim would have been a duplicate of a working one and a
     second thing to keep in sync with the open/close logic. */

  /* ---- The panel --------------------------------------------------------
     Frosted, with the overlay shadow and a rounded leading edge so it
     reads as a card sliding in rather than as the right-hand third of the
     screen changing colour. */

  /* ---- Group labels -----------------------------------------------------
     New. The drawer was one undifferentiated column of nine items; the
     eye had nothing to anchor to. Emitted by header.php as list items
     with aria-hidden, since they label sections visually and the nav
     already has a proper accessible name. */

  /* ---- Rows -------------------------------------------------------------
     Same 52px target as v7.0 (it was correct), now with a rounded hover
     surface and a leading accent bar on the current page. */
  /* v12.0 — in the drawer the current row is marked by the accent bar and
     tint on the LINK, which is the full width of the row. The desktop
     item-level pill would sit underneath that and read as a second,
     darker band behind the caret only, so it is switched off here; the
     caret still takes the accent colour so the row is one colour. */

  /* ---- Accordion contents ----------------------------------------------- */
  /* The desktop panel's pointer must not survive into the accordion, where
     there is no trigger for it to point at. */
  /* Rows animate on the desktop panel only. In the accordion they are
     already inside an element that expands, and animating both at once
     reads as a stutter. */

  /* ---- Staggered entrance for the drawer's own rows ---------------------
     Keyed off `.main-nav.open` — the class main.js actually toggles — and
     not off a body-level flag, because the body only ever gets
     `no-scroll`, which is also set by the lightbox and the install sheet.
     Hanging the drawer's animation off that would have made every row in
     the (closed) nav replay its entrance whenever an unrelated overlay
     opened. */
  @keyframes drawerRowIn{
    from{ opacity: 0; transform: translateX(14px); }
    to{ opacity: 1; transform: translateX(0); }
  }

  /* ---- The toggle -------------------------------------------------------
     Two bars that cross into an X. The markup keeps its single <svg>
     icon for the no-CSS case; these bars are drawn on pseudo-elements
     over it and the svg is hidden, so no template change is required. */

}


/* =========================================================================
   44. v7.1 — THE PICKER SHEET
   -------------------------------------------------------------------------
   Styling for assets/picker.js, used by both the location chooser and the
   calculation-method chooser.

   Two presentations of one component:
     · <=720px — a sheet anchored to the bottom edge, rising into place,
       capped at 88% of the small viewport height. This is the pattern
       phones have taught people to expect for "choose one of these", and
       critically it keeps the list within thumb reach instead of putting
       it under the top of the screen where nothing can be tapped
       one-handed.
     · >720px — a centred modal, because a bottom sheet on a 27" monitor is
       a phone pattern wearing a costume.

   Height uses `dvh` where supported. On mobile browsers `vh` resolves
   against the LARGE viewport — the one that exists only when the URL bar
   is hidden — so a `max-height:88vh` sheet is roughly 10% taller than the
   screen for as long as the URL bar is showing, and its last row and any
   bottom padding sit below the fold with no indication they exist. This is
   the same class of bug as the Qibla camera view fixed in section 46.
   ========================================================================= */

.pp-picker{
  position: fixed; inset: 0; z-index: 600;
  display: flex; align-items: flex-end; justify-content: center;
  /* Not `hidden` — the element must stay in the layout tree so its
     children can transition. Pointer events are what actually make it
     inert while closed. */
  pointer-events: none;
}
.pp-picker.is-open{ pointer-events: auto; }

.pp-picker-scrim{
  position: absolute; inset: 0;
  background: var(--scrim);
  -webkit-backdrop-filter: blur(6px) saturate(120%);
  backdrop-filter: blur(6px) saturate(120%);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-soft);
}
.pp-picker.is-open .pp-picker-scrim{ opacity: 1; }

.pp-picker-sheet{
  position: relative;
  display: flex; flex-direction: column;
  width: 100%;
  max-height: 88vh;
  max-height: 88dvh;
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-border);
  border-bottom: none;
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  box-shadow: var(--e-overlay);
  /* The sheet starts fully off the bottom edge. translateY(100%) rather
     than a fixed pixel offset so it is correct at every sheet height. */
  transform: translateY(100%);
  transition: transform var(--dur-slow) var(--ease-out-expo);
  overflow: hidden;
}
.pp-picker.is-open .pp-picker-sheet{ transform: translateY(0); }

/* The grab handle. Non-interactive — this sheet is dismissed by the close
   button, the scrim, or Escape, and a handle that looks draggable but
   isn't would be a worse lie than no handle. It is here purely because a
   bottom sheet without one doesn't read as a bottom sheet. */
.pp-picker-grab{
  flex-shrink: 0;
  width: 38px; height: 4px;
  margin: 10px auto 2px;
  border-radius: var(--radius-pill);
  background: rgb(var(--ink) / 0.2);
}

/* ---- Head --------------------------------------------------------------- */
.pp-picker-head{
  flex-shrink: 0;
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5) var(--sp-3);
}
.pp-picker-head-text{ min-width: 0; }
.pp-picker-title{
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 600;
  letter-spacing: var(--track-tight);
  color: rgb(var(--heading));
  line-height: 1.2;
}
.pp-picker-sub{
  margin: 5px 0 0;
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  line-height: 1.45;
  color: rgb(var(--text-muted));
}
.pp-picker-close{
  flex-shrink: 0;
  /* 44px is the accessibility floor for a touch target, and this is the
     only way out of the sheet on a phone that doesn't involve reaching for
     the scrim. It is not a place to save space. */
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-pill);
  background: rgb(var(--surface) / 0.6);
  color: rgb(var(--heading-soft));
  cursor: pointer;
  transition:
    background-color var(--dur-fast) var(--ease-soft),
    color var(--dur-fast) var(--ease-soft),
    transform var(--dur-fast) var(--ease-soft);
}
.pp-picker-close svg{ width: 17px; height: 17px; }
@media (hover: hover){ .pp-picker-close:hover{ background: rgb(var(--ink) / 0.08); color: rgb(var(--heading)); } }
.pp-picker-close:active{ transform: scale(0.92); }

/* ---- Search ------------------------------------------------------------- */
.pp-picker-search{
  flex-shrink: 0;
  position: relative;
  display: flex; align-items: center;
  margin: 0 var(--sp-5) var(--sp-3);
  padding: 0 var(--sp-3);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-sm);
  background: rgb(var(--bg) / 0.75);
  transition: border-color var(--dur) var(--ease-soft), box-shadow var(--dur) var(--ease-soft);
}
.pp-picker-search-ic{
  flex-shrink: 0; width: 17px; height: 17px;
  color: rgb(var(--text-muted)); opacity: 0.8;
}
.pp-picker-input{
  flex: 1; min-width: 0;
  /* 48px keeps the field itself a comfortable target, and 16px is the
     threshold below which iOS Safari zooms the whole page on focus — a
     jarring, hard-to-undo jump that makes a search field feel broken. The
     font-size here is deliberately not on the fluid scale for that reason:
     it must never resolve below 16px at any viewport width. */
  height: 48px;
  padding: 0 var(--sp-2);
  border: none; background: transparent; box-shadow: none;
  font-family: var(--font-ui);
  font-size: 16px;
  color: rgb(var(--text));
}
.pp-picker-input:focus{ outline: none; }
@media (hover: hover){ .pp-picker-input:hover{ border: none; } }
/* The native clear affordance duplicates the one below it and can't be
   styled to match anything. */
.pp-picker-input::-webkit-search-cancel-button{ -webkit-appearance: none; appearance: none; }
.pp-picker-clear{
  flex-shrink: 0;
  width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  border: none; border-radius: 50%;
  background: rgb(var(--ink) / 0.1);
  color: rgb(var(--heading-soft));
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft);
}
.pp-picker-clear svg{ width: 13px; height: 13px; }
@media (hover: hover){ .pp-picker-clear:hover{ background: rgb(var(--ink) / 0.18); } }

.pp-picker-status{
  flex-shrink: 0;
  margin: 0 var(--sp-5) var(--sp-2);
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  color: rgb(var(--text-muted));
  display: flex; align-items: center; gap: 8px;
}
/* A small spinner, so "Searching worldwide…" is visibly in progress rather
   than a line of text that may or may not be stale. */
.pp-picker-status::before{
  content: '';
  width: 12px; height: 12px; flex-shrink: 0;
  border: 2px solid rgb(var(--wash) / 0.25);
  border-top-color: rgb(var(--accent-ui));
  border-radius: 50%;
  animation: ppPickerSpin 0.7s linear infinite;
}
@keyframes ppPickerSpin{ to{ transform: rotate(360deg); } }

/* ---- List --------------------------------------------------------------- */
.pp-picker-list{
  flex: 1; min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 0 var(--sp-3) calc(var(--sp-5) + env(safe-area-inset-bottom));
}
.pp-picker-group-label{
  top: 0; z-index: 1;
  /* Sticky headings need an opaque backing or the rows scroll visibly
     through the text. The blur keeps it consistent with the sheet. */
}

.pp-picker-row{
  position: relative;
  width: 100%;
  /* 56px, comfortably past the 44px minimum — these rows hold two lines of
     text and are tapped while scrolling a long list, where a near-miss is
     costly because it selects the wrong city rather than doing nothing. */
  min-height: 56px;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  text-align: left;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft);
}
.pp-picker-row.is-active{ background: rgb(var(--wash) / 0.09); }
@media (hover: hover){ .pp-picker-row:hover{ background: rgb(var(--wash) / 0.09); } }
/* Pressed feedback is a background and opacity change only — deliberately
   nothing that alters the row's bounds. A row that scales under the finger
   in a scrolling list makes the whole list feel like it is wobbling. */
.pp-picker-row:active{ background: rgb(var(--wash) / 0.16); }
.pp-picker-row:focus-visible{ box-shadow: var(--ring); }

.pp-picker-row-main{ display: flex; flex-direction: column; gap: 2px; }
.pp-picker-row-title-line{ flex-wrap: wrap; }
.pp-picker-row-title{
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: rgb(var(--heading));
  letter-spacing: -0.006em;
}
.pp-picker-row-note{
  font-family: var(--font-ui);
  font-size: var(--fs-2xs);
  color: rgb(var(--text-muted));
  opacity: 0.85;
  line-height: 1.45;
}
.pp-picker-row-aside{
  flex-shrink: 0;
  white-space: nowrap;
}
.pp-picker-row-badge{
  flex-shrink: 0;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* The tick occupies its space whether or not it is visible, so choosing a
   different row never re-flows the text beside it. */
.pp-picker-row-tick{
  flex-shrink: 0;
  width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  color: rgb(var(--accent-ui));
  opacity: 0;
  transform: scale(0.7);
  transition: opacity var(--dur-fast) var(--ease-soft), transform var(--dur) var(--spring);
}
.pp-picker-row-tick svg{ width: 17px; height: 17px; }
.pp-picker-row.is-selected .pp-picker-row-tick{ opacity: 1; transform: scale(1); }
.pp-picker-row.is-selected .pp-picker-row-title{ color: rgb(var(--accent-ui)); }
/* Selection is marked by the tick AND by weight, not by colour alone —
   colour on its own fails for anyone who can't distinguish it from the
   surrounding text. */
.pp-picker-row.is-selected{ background: rgb(var(--wash) / 0.07); }

/* A featured row (the recommended method, the detected location) gets a
   leading accent bar so it is distinguishable from the rows below it
   without relying on the badge's colour to carry the whole message. */
.pp-picker-row.is-featured{
  background: rgb(var(--wash) / 0.06);
  box-shadow: inset 3px 0 0 rgb(var(--accent) / 0.8);
}
.pp-picker-row.is-featured.is-active{ background: rgb(var(--wash) / 0.13); }
@media (hover: hover){ .pp-picker-row.is-featured:hover{ background: rgb(var(--wash) / 0.13); } }

.pp-picker-empty{
  margin: 0;
  padding: var(--sp-10) var(--sp-5);
  text-align: center;
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: rgb(var(--text-muted));
}

/* ---- Desktop: centred modal --------------------------------------------- */
@media (min-width: 721px){
  .pp-picker{ align-items: center; padding: var(--sp-6); }
  .pp-picker-sheet{
    width: min(560px, 100%);
    max-height: min(680px, 84vh);
    max-height: min(680px, 84dvh);
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-xl);
    /* Rises a short distance and scales in, rather than sliding the full
       height of the screen — a modal that travels 600px on a desktop reads
       as slow no matter how fast the easing is. */
    transform: translateY(16px) scale(0.97);
    opacity: 0;
    transition:
      transform var(--dur) var(--spring),
      opacity var(--dur) var(--ease-soft);
  }
  .pp-picker.is-open .pp-picker-sheet{ transform: translateY(0) scale(1); opacity: 1; }
  .pp-picker-grab{ display: none; }
  .pp-picker-head{ padding-top: var(--sp-5); }
}

/* Anything that opens a picker sits under it, never over it. */
.pp-picker{ isolation: isolate; }

@media (prefers-reduced-motion: reduce){
  .pp-picker-sheet{ transform: none !important; opacity: 1 !important; }
  .pp-picker-status::before{ animation: none; }
}

/* =========================================================================
   45. v7.1 — SKIP LINK
   -------------------------------------------------------------------------
   A UX audit pass flagged "no skip link on nav-heavy pages" as a likely
   gap. It was wrong about this codebase: header.php has emitted one since
   before v7.0 and section 1 styles it correctly, including the detail most
   implementations get wrong (moved off-screen with a position offset
   rather than `display:none`, which would remove it from the
   accessibility tree and make it unfocusable — a skip link that cannot be
   reached).

   Left as a note rather than silently doing nothing, because "the audit
   said add one" is exactly the kind of prompt that produces a second,
   competing `.skip-link` rule further down the cascade that breaks the
   working one. The single addition below is the focus ring, so the link
   matches the site-wide ring introduced in section 41 instead of keeping
   its own one-off outline.
   ========================================================================= */
.skip-link:focus-visible{
  outline: none;
  box-shadow: var(--e4), var(--ring);
}


/* =========================================================================
   46. v7.1 — QIBLA: THE CAMERA VIEW, REBUILT
   -------------------------------------------------------------------------
   THE HEIGHT BUG, which is what "the camera is very long vertically" was.

   `position:fixed; inset:0` does not mean "the visible screen" on a mobile
   browser. It resolves against the LARGE viewport — the one that only
   exists once the URL bar has scrolled away. While the URL bar is showing,
   a fixed inset:0 element is roughly 10-15% taller than the screen, and
   everything anchored to its bottom edge sits below the fold. On this
   screen that was the degrees readout and part of the hint; the close
   button, anchored to the top, sat under the browser chrome.

   Fixed in three layers, deliberately, because no single one of them is
   universally supported:

     1. `height:100%` as the baseline everywhere.
     2. `100svh` — the SMALL viewport, i.e. the screen with the browser
        chrome visible. Always fits. Never crops. This is the correct
        choice for a fixed overlay, where `dvh` would make the element
        resize mid-gesture as the URL bar animates, and a viewfinder that
        changes size while you are aiming it is worse than one that is
        slightly short.
     3. JS pins the exact height to `visualViewport.height` where that
        exists (see syncCameraViewport in assets/qibla.js), which is the
        only value that is correct on iOS in every state including
        pinch-zoom.

   The other half of "very long vertically" was the picture, not the
   element — a landscape camera stream cropped into a portrait window under
   object-fit:cover. That is fixed in JS by requesting a stream shaped like
   the window and sizing the element to the frame that actually arrives;
   see cameraConstraints() and sizeCameraVideo().
   ========================================================================= */

body.qibla-camera-lock{
  /* position:fixed rather than overflow:hidden. `overflow:hidden` on body
     does not stop scrolling behind a fixed overlay on iOS at all, which is
     why the page underneath used to move while the camera was open. The
     scroll offset is preserved and restored in JS. */
  position: fixed;
  left: 0; right: 0; width: 100%;
  overflow: hidden;
}

.qibla-camera-view{
  position: fixed;
  top: 0; left: 0;
  width: 100%;
  height: 100%;
  height: 100svh;
  /* inset:0 is deliberately NOT used — see the header comment. */
  right: auto; bottom: auto;
  z-index: 500;
  background: #000;
  display: block;
  overflow: hidden;
  animation: qiblaCamFadeIn var(--dur) var(--ease-soft);
}

/* The video is positioned and sized entirely from JS (sizeCameraVideo), so
   that the frame's true aspect ratio is preserved and only the overflow is
   cropped. object-fit is left as a fallback for the brief moment before
   metadata arrives, and for the case where videoWidth never becomes
   readable. */
#qiblaCameraVideo{
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  /* A dark backdrop behind the frame, so the letterboxed edges during the
     first frames read as intentional rather than as a rendering fault. */
  background: #000;
}

.qibla-camera-scrim{
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(180deg,
      rgb(0 0 0 / 0.62) 0%,
      rgb(0 0 0 / 0.15) 18%,
      transparent 34%,
      transparent 60%,
      rgb(0 0 0 / 0.3) 78%,
      rgb(0 0 0 / 0.78) 100%);
  pointer-events: none;
}

/* ---- State machine ------------------------------------------------------
   One attribute drives all of it. See the note in page-qibla.php for why
   this replaced four independent `hidden` writes. */
.qibla-camera-view .qibla-camera-loading,
.qibla-camera-view .qibla-camera-error{ display: none; }

.qibla-camera-view[data-state="loading"] .qibla-camera-loading{ display: flex; }
.qibla-camera-view[data-state="loading"] .qibla-camera-overlay,
.qibla-camera-view[data-state="loading"] .qibla-camera-top,
.qibla-camera-view[data-state="loading"] .qibla-camera-turn{ display: none; }

.qibla-camera-view[data-state="error"] .qibla-camera-error{ display: flex; }
.qibla-camera-view[data-state="error"] .qibla-camera-overlay,
.qibla-camera-view[data-state="error"] .qibla-camera-top,
.qibla-camera-view[data-state="error"] .qibla-camera-turn,
.qibla-camera-view[data-state="error"] #qiblaCameraVideo,
.qibla-camera-view[data-state="error"] .qibla-camera-scrim{ display: none; }

/* ---- Loading ------------------------------------------------------------ */
.qibla-camera-loading{
  position: absolute; inset: 0; z-index: 3;
  flex-direction: column; align-items: center; justify-content: center;
  gap: var(--sp-4);
  padding: var(--sp-8);
  text-align: center;
  color: #fff;
}
.qibla-camera-loading p{
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 600;
}
.qibla-camera-loading-sub{
  max-width: 300px;
  font-family: var(--font-ui) !important;
  font-size: var(--fs-xs) !important;
  font-weight: 400 !important;
  line-height: 1.55;
  color: rgb(255 255 255 / 0.7);
}
.qibla-camera-spinner{
  width: 34px; height: 34px;
  border: 2.5px solid rgb(255 255 255 / 0.2);
  border-top-color: #fff;
  border-radius: 50%;
  animation: qiblaCamSpin 0.8s linear infinite;
}
@keyframes qiblaCamSpin{ to{ transform: rotate(360deg); } }

/* ---- Chrome -------------------------------------------------------------
   Everything fixed to an edge respects the safe area, so nothing lands
   under a notch, a status bar, or the home indicator. */
.qibla-camera-close{
  position: absolute; z-index: 4;
  top: calc(var(--sp-4) + env(safe-area-inset-top));
  right: calc(var(--sp-4) + env(safe-area-inset-right));
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid rgb(255 255 255 / 0.28);
  background: rgb(0 0 0 / 0.42);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  transition: background-color var(--dur) var(--ease-soft), transform var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .qibla-camera-close:hover{ background: rgb(0 0 0 / 0.62); } }
.qibla-camera-close:active{ transform: scale(0.92); }

.qibla-camera-top{
  position: absolute; z-index: 4;
  top: calc(var(--sp-4) + env(safe-area-inset-top));
  left: calc(var(--sp-4) + env(safe-area-inset-left));
  /* Stops short of the close button rather than running under it. */
  right: calc(var(--sp-4) + 44px + var(--sp-3) + env(safe-area-inset-right));
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
}

.qibla-cam-calibrate{
  display: inline-flex; align-items: center; gap: 6px;
  /* 40px tall and generously padded: this is a small control on a screen
     being held up at arm's length. */
  min-height: 40px;
  padding: 0 var(--sp-3);
  border-radius: var(--radius-pill);
  border: 1px solid rgb(255 255 255 / 0.3);
  background: rgb(0 0 0 / 0.42);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  color: #fff;
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  font-weight: 600;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease-soft), transform var(--dur-fast) var(--ease-soft);
}
.qibla-cam-calibrate svg{ width: 14px; height: 14px; }
.qibla-cam-calibrate:active{ transform: scale(0.95); }

/* ---- Turn indicator -----------------------------------------------------
   Class-driven, not `hidden`-driven. See page-qibla.php. Because it now
   fades rather than being removed from layout, it also no longer shifts
   anything around it when it appears. */
.qibla-camera-turn{
  position: absolute; z-index: 4;
  top: 50%; left: 50%;
  transform: translate(-50%, calc(-50% - min(46vw, 172px)));
  display: flex; align-items: center; gap: var(--sp-2);
  padding: 10px var(--sp-4);
  border-radius: var(--radius-pill);
  background: rgb(0 0 0 / 0.5);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 1px solid rgb(255 255 255 / 0.18);
  color: #fff;
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  font-weight: 600;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease-soft);
}
.qibla-camera-turn.is-visible{ opacity: 1; }
.qibla-turn-icon{ width: 17px; height: 17px; transition: transform var(--dur) var(--spring); }
.qibla-camera-turn.is-left .qibla-turn-icon{ transform: scaleX(-1); }

/* ---- Reticle ------------------------------------------------------------ */
.qibla-camera-overlay{
  position: absolute; z-index: 2;
  inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--sp-5);
  padding: calc(var(--sp-16) + env(safe-area-inset-top)) var(--sp-5)
           calc(var(--sp-10) + env(safe-area-inset-bottom));
  pointer-events: none;
}

.qibla-camera-reticle{
  position: relative;
  width: min(72vw, 260px); height: min(72vw, 260px);
  border-radius: 50%;
  border: 1.5px solid rgb(255 255 255 / 0.34);
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.2), inset 0 0 60px rgb(0 0 0 / 0.22);
  transition:
    border-color var(--dur-slow) var(--ease-soft),
    box-shadow var(--dur-slow) var(--ease-soft),
    transform var(--dur-slow) var(--spring);
}
.qibla-camera-reticle::before{
  content: ''; position: absolute; inset: 10px;
  border-radius: 50%;
  border: 1px dashed rgb(255 255 255 / 0.16);
}

/* The fixed crosshair — "where you are pointing". New in v7.1: without a
   static reference, the reticle was a needle rotating against a moving
   camera feed and nothing indicated which part of it meant dead ahead. */
.qibla-camera-crosshair{
  position: absolute; top: 50%; left: 50%;
  width: 22px; height: 22px;
  margin: -11px 0 0 -11px;
}
.qibla-camera-crosshair::before,
.qibla-camera-crosshair::after{
  content: ''; position: absolute; background: rgb(255 255 255 / 0.85);
  box-shadow: 0 0 6px rgb(0 0 0 / 0.6);
}
.qibla-camera-crosshair::before{ left: 50%; top: 0; bottom: 0; width: 1.5px; margin-left: -0.75px; }
.qibla-camera-crosshair::after{ top: 50%; left: 0; right: 0; height: 1.5px; margin-top: -0.75px; }

/* The rotating element. Rotation is written from JS every frame; there is
   deliberately NO transition on transform here, for the same reason as
   .qibla-rose — a CSS transition on a value that is already being smoothed
   in JS produces a needle that lags the phone and then overshoots. */
.qibla-camera-pointer{
  position: absolute; inset: 0;
  display: flex; align-items: flex-start; justify-content: center;
}
.qibla-camera-pointer-arrow{
  display: flex; align-items: center; justify-content: center;
  width: 46px; height: 46px;
  margin-top: -23px;                     /* sits astride the ring */
  border-radius: 50%;
  background: rgb(0 0 0 / 0.42);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border: 1.5px solid rgb(255 255 255 / 0.5);
  transition: background-color var(--dur-slow) var(--ease-soft), border-color var(--dur-slow) var(--ease-soft);
}
.qibla-camera-pointer-arrow svg{
  width: 24px; height: 24px; color: #fff;
  filter: drop-shadow(0 1px 4px rgb(0 0 0 / 0.5));
  transition: color var(--dur-slow) var(--ease-soft);
}
/* The Ka'bah glyph rides the same rotating element, just inside the ring,
   so it points where the arrow points instead of sitting inert in the
   middle as it did before. */
.qibla-camera-pointer-kaaba{
  position: absolute; top: 34px; left: 50%;
  width: 30px; height: 30px; margin-left: -15px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 9px;
  background: rgb(255 255 255 / 0.14);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  color: rgb(255 255 255 / 0.6);
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-soft), color var(--dur-slow) var(--ease-soft);
}
.qibla-camera-pointer-kaaba svg{ width: 18px; height: 18px; }

/* Aligned. Marked by colour, by a glow, by a scale change, by the Ka'bah
   glyph appearing AND by the hint text changing — never by colour alone,
   which would leave anyone who can't distinguish it with no signal that
   they had arrived. */
.qibla-camera-reticle.is-aligned{
  border-color: rgb(var(--accent-light) / 0.95);
  box-shadow:
    0 0 0 1px rgb(var(--accent) / 0.35),
    0 0 50px 8px rgb(var(--accent) / 0.4);
  transform: scale(1.035);
}
.qibla-camera-reticle.is-aligned .qibla-camera-pointer-arrow{
  background: rgb(var(--wash) / 0.85);
  border-color: rgb(var(--accent-light));
}
.qibla-camera-reticle.is-aligned .qibla-camera-pointer-arrow svg{ color: #fff; }
.qibla-camera-reticle.is-aligned .qibla-camera-pointer-kaaba{ opacity: 1; color: #fff; }
.qibla-camera-reticle.is-aligned::before{ animation: qiblaCamPulse 1.8s ease-in-out infinite; }
@keyframes qiblaCamPulse{
  0%, 100%{ opacity: 0.45; transform: scale(1); }
  50%{ opacity: 0.9; transform: scale(1.035); }
}

.qibla-camera-hint{
  margin: 0; padding: 0 var(--sp-5);
  color: #fff;
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 600;
  text-align: center;
  letter-spacing: var(--track-tight);
  text-shadow: 0 2px 14px rgb(0 0 0 / 0.65);
}
.qibla-camera-degrees{
  margin: 0;
  padding: 8px var(--sp-4);
  border-radius: var(--radius-pill);
  background: rgb(0 0 0 / 0.42);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid rgb(255 255 255 / 0.14);
  color: rgb(255 255 255 / 0.9);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  /* Reserves its own line height so the layout does not jump when the
     text empties on alignment. */
  min-height: 1.3em;
}
.qibla-camera-degrees:empty{ opacity: 0; }

/* ---- Error --------------------------------------------------------------
   A real screen rather than a card floating over a dead camera feed: at
   this point there is nothing behind it worth showing. */
.qibla-camera-error{
  position: absolute; inset: 0; z-index: 5;
  flex-direction: column; align-items: center; justify-content: center;
  gap: var(--sp-4);
  padding: var(--sp-8);
  text-align: center;
  color: #fff;
  background: rgb(var(--bg) / 0.06);
}
.qibla-camera-error-ic{
  width: 42px; height: 42px;
  color: rgb(var(--accent-light));
  opacity: 0.9;
}
.qibla-camera-error p{
  margin: 0; max-width: 340px;
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: rgb(255 255 255 / 0.88);
}
.qibla-camera-error-actions{ display: flex; gap: var(--sp-3); margin-top: var(--sp-2); }

@media (prefers-reduced-motion: reduce){
  .qibla-camera-reticle.is-aligned::before{ animation: none; }
  .qibla-camera-view{ animation: none; }
  .qibla-camera-spinner{ animation-duration: 1.4s !important; }
}

/* =========================================================================
   47. v7.1 — QIBLA: THE CALIBRATION SHEET
   The figure-eight animation from v6.4 is kept — it was good, and it is
   the clearest way to show a motion nobody can picture from a sentence.
   What is added is the part that was missing: a ring that reflects what
   the sensor is actually reporting. See the long comment above
   calNoteOrientation() in assets/qibla.js.
   ========================================================================= */
.qibla-cal-progress{
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-3);
  margin: var(--sp-4) 0 var(--sp-2);
}

.qibla-cal-ring-wrap{
  position: relative;
  width: 96px; height: 96px;
  display: flex; align-items: center; justify-content: center;
}
.qibla-cal-ring{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  /* Rotated so the fill begins at twelve o'clock rather than at three,
     which is where an SVG circle's path actually starts. */
  transform: rotate(-90deg);
}
.qibla-cal-ring-track{
  fill: none;
  stroke: rgb(var(--ink) / 0.12);
  stroke-width: 7;
}
.qibla-cal-ring-fill{
  fill: none;
  stroke: rgb(var(--accent));
  stroke-width: 7;
  stroke-linecap: round;
  /* dasharray and dashoffset are both set from JS, computed from the same
     radius constant, so they cannot drift apart from the markup. The
     transition is what makes the ring sweep rather than snap between the
     discrete steps the bin counter produces. */
  transition: stroke-dashoffset var(--dur-slow) var(--ease-out-expo), stroke var(--dur) var(--ease-soft);
}
.qibla-cal-percent{
  position: relative; z-index: 1;
  font-family: var(--font-mono);
  font-size: var(--fs-md);
  font-weight: 500;
  color: rgb(var(--heading));
  transition: opacity var(--dur) var(--ease-soft);
}
.qibla-cal-ring-tick{
  position: absolute; z-index: 2;
  width: 38px; height: 38px;
  color: rgb(var(--accent-ui));
  opacity: 0;
  transform: scale(0.5);
  transition: opacity var(--dur) var(--ease-soft), transform var(--dur-slow) var(--spring);
}

.qibla-cal-state{
  margin: 0;
  max-width: 300px;
  text-align: center;
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  line-height: 1.55;
  color: rgb(var(--text-muted));
}

/* Complete: the percentage gives way to a tick, the ring turns solid, and
   the figure-eight animation stops — it has nothing left to demonstrate. */
.qibla-calibrate.is-complete .qibla-cal-percent{ opacity: 0; }
.qibla-calibrate.is-complete .qibla-cal-ring-tick{ opacity: 1; transform: scale(1); }
.qibla-calibrate.is-complete .qibla-cal-state{
  color: rgb(var(--accent-ui));
  font-weight: 600;
}
.qibla-calibrate.is-complete .q8-phone-wrap{ animation-play-state: paused; }
.qibla-calibrate.is-complete .qibla-figure8{ opacity: 0.35; transition: opacity var(--dur-slow) var(--ease-soft); }

/* No magnetometer: hide the whole apparatus rather than showing a ring
   that can never fill. */
.qibla-calibrate.is-unsupported .qibla-figure8,
.qibla-calibrate.is-unsupported .qibla-cal-ring-wrap,
.qibla-calibrate.is-unsupported .qibla-calibrate-steps,
.qibla-calibrate.is-unsupported .qibla-calibrate-live{ display: none; }
.qibla-calibrate.is-unsupported .qibla-cal-state{
  max-width: 380px;
  font-size: var(--fs-sm);
  color: rgb(var(--text));
}

/* =========================================================================
   48. v7.1 — THE CHOICE BUTTON
   The control that opens a picker sheet. Used for the city on both pages
   and for the calculation method on Prayer Times. A row, not a select: it
   has room for a label, the current value, and an icon, and it is a
   comfortable target at any size.
   ========================================================================= */
.pp-choice{
  display: flex; align-items: center; gap: var(--sp-3);
  width: 100%;
  min-height: 56px;
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius);
  background: rgb(var(--surface));
  box-shadow: var(--e1);
  text-align: left;
  cursor: pointer;
  transition:
    border-color var(--dur) var(--ease-soft),
    box-shadow var(--dur) var(--ease-soft),
    background-color var(--dur) var(--ease-soft),
    transform var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){
  .pp-choice:hover{
    border-color: rgb(var(--wash) / 0.5);
    box-shadow: var(--e2);
  }
}
/* Press feedback that does not move anything around it. */
.pp-choice:active{ transform: scale(0.994); box-shadow: var(--e1); }
.pp-choice:focus-visible{ outline: none; box-shadow: var(--ring); border-color: rgb(var(--accent-ui)); }

.pp-choice-ic{
  flex-shrink: 0;
  width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm);
  background: rgb(var(--wash) / 0.1);
  color: rgb(var(--accent-ui));
}
.pp-choice-ic svg{ width: 19px; height: 19px; }

.pp-choice-text{
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
}
.pp-choice-label{
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.pp-choice-value{
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  color: rgb(var(--text-muted));
  /* A long method name must truncate rather than wrap the button to three
     lines and shift the settings grid around it. */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pp-choice-value-lg{
  font-size: var(--fs-sm);
  font-weight: 600;
  color: rgb(var(--heading));
  letter-spacing: -0.006em;
}
.pp-choice-chev{
  flex-shrink: 0;
  width: 16px; height: 16px;
  color: rgb(var(--text-muted));
  opacity: 0.7;
  transition: transform var(--dur) var(--spring), opacity var(--dur) var(--ease-soft);
}
@media (hover: hover){ .pp-choice:hover .pp-choice-chev{ transform: translateY(2px); opacity: 1; } }

.pp-choice-sm{ min-height: 52px; padding: 10px var(--sp-3); }
.pp-choice-sm .pp-choice-ic{ width: 32px; height: 32px; }
.pp-choice-sm .pp-choice-ic svg{ width: 16px; height: 16px; }

/* The caption above the method button, replacing the <span> that used to
   be inside a <label>. */
.prayer-setting-caption{
  display: block;
  margin-bottom: 7px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}


/* =========================================================================
   49. v7.1 — THE QIBLA PAGE ITSELF
   -------------------------------------------------------------------------
   The page was a stack of four panels of identical visual weight, each
   introduced by a small "Step N" pill. Nothing on it looked like the main
   event, which is a problem when the main event is a compass — the one
   thing every visitor came for.

   The compass panel is now a hero: bigger dial, the bearing rendered as
   the largest thing on the page, and a soft radial ground beneath it so it
   reads as an instrument rather than as a diagram in a box. The other
   panels stay quiet on purpose.
   ========================================================================= */

.qibla-app{
  display: flex; flex-direction: column;
  gap: var(--sp-5);
  max-width: 720px;
  margin: 0 auto;
}

.qibla-step-badge{
  display: inline-flex; align-items: center;
  padding: 5px 12px;
  margin-bottom: var(--sp-3);
  border-radius: var(--radius-pill);
  background: rgb(var(--wash) / 0.1);
  color: rgb(var(--accent-ui));
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* ---- The hero compass --------------------------------------------------- */
.qibla-hero-panel{
  position: relative;
  overflow: hidden;
  text-align: center;
  padding-bottom: var(--sp-8);
  box-shadow: var(--e4);
}
/* A soft radial ground under the dial. Sits behind everything (z-index on
   the children rather than a negative one here, which would put it behind
   the panel's own background). */
.qibla-hero-panel::before{
  content: '';
  position: absolute; top: -10%; left: 50%;
  width: min(560px, 130%); height: min(560px, 130%);
  transform: translateX(-50%);
  background: radial-gradient(circle at 50% 40%,
    rgb(var(--ornament) / 0.11) 0%,
    rgb(var(--ornament) / 0.04) 38%,
    transparent 68%);
  pointer-events: none;
}
.qibla-hero-panel > *{ position: relative; z-index: 1; }

.qibla-compass-lg{
  width: min(74vw, 300px);
  height: min(74vw, 300px);
  margin: var(--sp-5) auto var(--sp-4);
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 42%, rgb(var(--surface)) 0%, rgb(var(--bg-alt)) 100%);
  border: 1px solid var(--hairline-strong);
  box-shadow:
    var(--e3),
    inset 0 2px 12px rgb(var(--shadow) / 0.07);
}

.qibla-degrees{
  display: block;
  font-family: var(--font-display);
  /* The largest single piece of type on the page. It is the answer. */
  font-size: var(--fs-2xl);
  font-weight: 600;
  letter-spacing: var(--track-display);
  color: rgb(var(--heading));
  line-height: 1.05;
}
.qibla-degrees-note{
  display: block;
  margin-top: 5px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.qibla-distance{
  display: block;
  margin-top: var(--sp-3);
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  color: rgb(var(--text-muted));
}

.qibla-aligned-msg{
  display: inline-flex; align-items: center; gap: 7px;
  margin: var(--sp-4) auto 0;
  padding: 9px var(--sp-4);
  border-radius: var(--radius-pill);
  background: rgb(var(--wash) / 0.13);
  border: 1px solid rgb(var(--wash) / 0.3);
  color: rgb(var(--accent-ui));
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  font-weight: 600;
}

/* ---- Accuracy bar ------------------------------------------------------- */
.qibla-status-bar{
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); flex-wrap: wrap;
  padding: 10px var(--sp-3);
  border-radius: var(--radius-sm);
  background: rgb(var(--bg-alt) / 0.7);
  border: 1px solid var(--hairline);
}
.qibla-recalibrate-btn{
  min-height: 36px;
  padding: 0 var(--sp-3);
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline-strong);
  background: rgb(var(--surface));
  color: rgb(var(--heading-soft));
  font-family: var(--font-ui);
  font-size: var(--fs-2xs);
  font-weight: 600;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease-soft), border-color var(--dur) var(--ease-soft), transform var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .qibla-recalibrate-btn:hover{ border-color: rgb(var(--wash) / 0.5); color: rgb(var(--accent-ui)); } }
.qibla-recalibrate-btn:active{ transform: scale(0.96); }

/* ---- The sun panel ------------------------------------------------------
   Given a distinctly warmer treatment than the panels around it, because
   it is the one method on this page that no sensor can get wrong and the
   page's own copy says so. It should not look like a footnote. */

/* ---- "Holding your phone" ----------------------------------------------- */
.qibla-howto-grid{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--sp-4);
}
.qibla-howto-item{
  display: flex; flex-direction: column; gap: var(--sp-3);
  padding: var(--sp-4);
  border-radius: var(--radius-sm);
  background: rgb(var(--bg-alt) / 0.55);
  border: 1px solid var(--hairline-faint);
}

/* =========================================================================
   50. v7.1 — THE REST OF THE SITE
   The elevation layer applied to the components each page is built from,
   so the improvement is not confined to the two pages this release is
   named for.
   ========================================================================= */

/* ---- Section headers ---------------------------------------------------- */
.eyebrow{
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: rgb(var(--accent-ui));
}
.section-header h2{
  font-size: var(--fs-2xl);
  letter-spacing: var(--track-display);
  line-height: 1.12;
}

/* ---- Cards -------------------------------------------------------------- */
.value-card { border-radius: var(--radius); }

/* ---- Back to top -------------------------------------------------------- */
.back-to-top{
  box-shadow: var(--e3);
  border: 1px solid var(--hairline-strong);
  transition: transform var(--dur) var(--spring), box-shadow var(--dur) var(--ease-soft), opacity var(--dur) var(--ease-soft);
}
@media (hover: hover){ .back-to-top:hover{ transform: translateY(-3px); box-shadow: var(--e4); } }

/* ---- Prayer times panels ------------------------------------------------ */
.prayer-countdown-value{
  font-family: var(--font-mono);
  font-size: var(--fs-xl);
  letter-spacing: -0.02em;
}
.prayer-format-toggle{
  display: inline-flex;
  padding: 3px;
  border-radius: var(--radius-pill);
  background: rgb(var(--ink) / 0.07);
  border: 1px solid var(--hairline);
}
.prayer-format-btn{
  min-height: 36px;
  padding: 0 var(--sp-4);
  border: none;
  border-radius: var(--radius-pill);
  background: transparent;
  color: rgb(var(--text-muted));
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  font-weight: 600;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease-soft), color var(--dur) var(--ease-soft), box-shadow var(--dur) var(--ease-soft);
}
.prayer-format-btn.is-active{
  background: rgb(var(--surface));
  color: rgb(var(--heading));
  box-shadow: var(--e1);
}


/* =========================================================================
   52. v7.1 — COMPONENT TOKENS
   -------------------------------------------------------------------------
   The third layer of the three-layer scheme. Sections 0 and 40 supply the
   primitives (raw palette triplets) and the semantics (--surface, --accent-ui,
   --e3, --fs-lg). This layer names what individual COMPONENTS ask for, so a
   component's appearance can be retuned in one line here instead of hunting
   through the rules that draw it.

   The rule this enforces: nothing below section 52 may contain a raw colour
   or a raw shadow. Everything resolves through a token.
   ========================================================================= */
:root{
  /* Cards */
  --card-bg: rgb(var(--surface));
  --card-border: var(--hairline);
  --card-border-hover: rgb(var(--wash) / 0.3);
  --card-shadow: var(--e2);
  --card-shadow-hover: var(--e4);
  --card-radius: var(--radius);
  --card-lift: -3px;

  /* Ornament — the hairline rules, flourishes and gradient edges below */
  --ornament: rgb(var(--wash) / 0.28);
  --ornament-soft: rgb(var(--wash) / 0.14);
  --ornament-faint: rgb(var(--wash) / 0.07);

  /* Prayer grid */
  --prayer-row-bg: transparent;
  --prayer-row-bg-next: rgb(var(--wash) / 0.1);
  --prayer-row-bg-past: rgb(var(--ink) / 0.03);
  --prayer-row-radius: var(--radius-sm);

  /* Reading */
  --rule-weight: 1px;
}/* ---- Section headers ----------------------------------------------------
   The eyebrow gets a short leading rule, which does more for the sense of
   a designed page than any amount of decoration elsewhere: it gives every
   section the same optical starting point. */
.section-header .eyebrow::before{
  opacity: 0.75;
}

/* ---- Hero -------------------------------------------------------------
   Deliberately minimal. An earlier v7.1 draft added CSS corner brackets on
   ::before/::after and set `border-color: transparent`. Both were wrong:
   front-page.php already renders four real .corner SVGs inside the frame,
   so the brackets were a SECOND set of corner decorations drawn over the
   first, and the transparent border removed the 1px accent outline the
   frame is built around. The frame keeps its own border and gradient. */
/* =========================================================================
   THE FRONTISPIECE — v11.1

   See the note in front-page.php for what changed and why. These are
   the parts that are new: the gold rule at the head of the panel, the
   mark sitting on it, and the ayah block.
   ========================================================================= */
.hero-frame::after{
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  background: linear-gradient(90deg,
    rgb(var(--ornament) / 0) 0%, rgb(var(--ornament) / 0.85) 20%,
    rgb(var(--ornament) / 0.85) 80%, rgb(var(--ornament) / 0) 100%);
  pointer-events: none; z-index: 2;
}/* A short centred rule with a lozenge at its middle, above and below
   the ayah — the way a panel is closed off in a manuscript. */
.hero-rule{
  display: block; position: relative;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgb(var(--ornament) / 0.6), transparent);
}
.hero-rule::after{
  content: ''; position: absolute; top: 50%; left: 50%;
  width: 5px; height: 5px; transform: translate(-50%, -50%) rotate(45deg);
  background: rgb(var(--ornament) / 0.75);
}
.hero-ayah{
  font-family: var(--font-quran-glyphs), var(--font-quran), var(--font-arabic);
  direction: rtl; unicode-bidi: isolate;
  color: rgb(var(--heading));
}
.hero-ayah-en{
  font-family: var(--font-body); font-style: italic;
  color: rgb(var(--text));
}
.hero-ayah-ref{
  margin: 0;
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--accent-ui));
}
/* The counters are archive facts, not an invitation — quieter, and
   below everything that is. */

@media (max-width:600px){
  .hero-mark{ width: 54px; height: 54px; }
  .hero-mark svg{ width: 29px; height: 29px; }
  .hero-rule{ margin: var(--sp-4) auto; width: 88px; }
}

.hero-frame{
  box-shadow: var(--e2);
}

/* =========================================================================
   51. v7.1 — PHONES
   A pass over everything this release touched, at 380px and at 430px.
   Every rule here exists because something specific was wrong at those
   widths, not as a precaution.
   ========================================================================= */
@media (max-width: 760px){

  /* The picker sheet's own bottom padding has to clear the home indicator
     as well as its own inset, or the last row sits under it. */
  .pp-picker-list{
    padding-bottom: calc(var(--sp-8) + env(safe-area-inset-bottom));
  }

  /* The method button's value is the longest string on the settings panel
     ("Moonsighting Committee — Shafaq Ahmer (red)"). Two lines is fine on
     a phone; three pushes the row below it off the fold. */
  .pp-choice-value-lg{
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  /* Settings stack rather than sitting in a cramped 3-up row. */
  .prayer-settings-row{
    grid-template-columns: 1fr;
    display: grid;
    gap: var(--sp-4);
  }
  .prayer-setting-wide{ grid-column: 1; }

  /* The Qibla dial gets the width it needs; at 380px the old fixed
     260px left barely any margin either side. */
  .qibla-compass-lg{
    width: min(78vw, 280px);
    height: min(78vw, 280px);
    margin-top: var(--sp-4);
  }
  .qibla-app{ gap: var(--sp-4); }
  .qibla-howto-grid{ grid-template-columns: 1fr; }

  /* The turn indicator is positioned relative to the reticle's radius,
     which shrinks with the viewport — recomputed here so it doesn't
     overlap the ring on a small screen. */
  .qibla-camera-turn{
    transform: translate(-50%, calc(-50% - min(48vw, 158px)));
    font-size: var(--fs-xs);
    padding: 9px var(--sp-3);
  }

  /* Panels lose some inner padding but never their touch targets. */
  .prayer-panel{ padding: var(--sp-4); border-radius: var(--radius); }
  .qibla-hero-panel{ padding-bottom: var(--sp-6); }

  .pp-picker-head{ padding: var(--sp-3) var(--sp-4) var(--sp-2); }
  .pp-picker-search{ margin: 0 var(--sp-4) var(--sp-2); }
  .pp-picker-list{ padding-left: var(--sp-2); padding-right: var(--sp-2); }
  .pp-picker-status{ margin: 0 var(--sp-4) var(--sp-2); }
}

@media (max-width: 400px){
  /* v8.0 — the `.logo-text .name{font-size:1.12rem}` that sat here is gone.
     The phone wordmark is owned entirely by the ≤620px header block now
     (0.98rem, ellipsising, hidden below 353px). This rule was (0,2,0)
     against that block's (0,3,0), so it was already losing — but a stale
     declaration that only loses on specificity is one cache plugin away
     from winning, and it set a LARGER size than the row has room for. */
  .qibla-step-badge{ font-size: 0.7rem; padding: 4px 10px; }
  .qibla-degrees{ font-size: var(--fs-xl); }
  .pp-choice{ padding: var(--sp-3); gap: var(--sp-2); }
  .pp-choice-ic{ width: 34px; height: 34px; }
}

/* Landscape phones. The picker sheet at 88dvh on a 380px-tall landscape
   screen leaves room for the header and about one and a half rows, so it
   becomes a near-fullscreen layer with a tighter head instead. */
@media (max-height: 480px) and (orientation: landscape){
  .pp-picker-sheet{
    max-height: 96dvh;
    border-radius: var(--radius) var(--radius) 0 0;
  }
  .pp-picker-grab{ margin: 6px auto 0; }
  .pp-picker-head{ padding: var(--sp-2) var(--sp-4); }
  .pp-picker-sub{ display: none; }
  .pp-picker-row{ min-height: 48px; }

  /* The camera overlay's vertical stack does not fit; the reticle shrinks
     and the readouts move in beside it rather than under it. */
  .qibla-camera-reticle{ width: min(52vh, 200px); height: min(52vh, 200px); }
  .qibla-camera-overlay{ gap: var(--sp-3); padding-top: var(--sp-8); }
  .qibla-camera-turn{ transform: translate(-50%, calc(-50% - min(34vh, 128px))); }
}

/* =========================================================================
   54. v7.1 — CARDS, PROPERLY
   -------------------------------------------------------------------------
   Every card on the site was a rounded rectangle with a border and a
   shadow. They are now given the two things that separate a designed card
   from a default one: an edge that responds, and media that behaves.
   ========================================================================= */
/* .topic-card is again absent on purpose: it already sets its own
   background, border, radius and overflow, and re-declaring them here
   only risks fighting the --card-accent system layered on top of it. */
.featured-card,
.value-card,
.hadith-card,
.quran-card {
  position: relative;
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: var(--card-radius);
  box-shadow: var(--card-shadow);
  overflow: hidden;
  isolation: isolate;
}

/* A light sweep along the top edge — the single cheapest way to make a
   flat surface read as a lit object. Present at rest, brighter on hover.
   Drawn on a pseudo-element so it never interferes with the card's own
   background or its border radius. */
/* NOTE the absence of .topic-card here, which is deliberate and was a
   real bug in an earlier v7.1 draft.

   .topic-card::before was ALREADY in use, since v6: it draws the coloured
   bar across the top of each topic card, rotating through --accent,
   --accent-2 and --accent-3 down the grid so a long list of topics has
   rhythm instead of reading as one solid block of gold. Adding this rule
   with .topic-card in the list replaced that bar with a white sweep on
   every card and silently deleted the entire rotation.

   Topic cards get the same lit-edge treatment from ::after instead, a
   few rules down. Everything else here has no existing ::before. */
.featured-card::before,
.value-card::before,
.hadith-card::before,
.quran-card::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgb(255 255 255 / 0.5) 22%, rgb(255 255 255 / 0.5) 78%, transparent);
  opacity: 0.5;
  transition: opacity var(--dur) var(--ease-soft);
  pointer-events: none; z-index: 2;
}
@media (hover: hover){
  .featured-card:hover::before,
  .value-card:hover::before,
  .hadith-card:hover::before,
  .quran-card:hover::before { opacity: 1; }
}

/* The topic card's lit edge, on the pseudo-element that is actually free.
   ::before is its accent bar (see above) and ::after is its hover glow,
   both pre-existing — so this rides on the card's own box-shadow instead,
   which needs no pseudo-element at all and cannot collide with anything. */
.topic-card{
  box-shadow: var(--card-shadow), inset 0 1px 0 rgb(255 255 255 / 0.4);
}
@media (hover: hover){
  .topic-card:hover{
    box-shadow: var(--card-shadow-hover), inset 0 1px 0 rgb(255 255 255 / 0.55);
  }
}
html[data-scheme="dark"] .topic-card{
  box-shadow: var(--card-shadow), inset 0 1px 0 rgb(255 255 255 / 0.06);
}

@media (hover: hover){
  .featured-card:hover,
  .topic-card:hover,
  .value-card:hover,
  .hadith-card:hover,
  .quran-card:hover {
    transform: translateY(var(--card-lift));
    box-shadow: var(--card-shadow-hover);
    border-color: var(--card-border-hover);
  }
}

/* Topic cards get their icon in a tinted well that warms on hover, rather
   than a bare glyph sitting on the card. */
.topic-card svg{ transition: transform var(--dur-slow) var(--spring); }
@media (hover: hover){ .topic-card:hover svg{ transform: scale(1.1) rotate(-4deg); } }

/* Card media. The real class names here are .article-cover (the grid card,
   template-parts/content-card.php) and .featured-cover (the homepage
   spotlight, front-page.php) — an earlier draft of this section invented
   .card-media and .spotlight-media, which exist nowhere in the theme and
   would have been dead rules that looked like they were doing something.

   The image zoom itself already shipped in v3 and is not re-declared; what
   is added is the easing (the original used the generic 0.6s var(--ease),
   which on a scale transform reads as sluggish) and a gradient scrim so
   that a cover photo can never leave the tag chip sitting on a light patch
   of the image with nothing behind it. */
.featured-cover {
  position: relative;
  background: rgb(var(--bg-alt));
}
.featured-cover img {
  transition: transform var(--dur-slow) var(--ease-out-expo);
}
@media (hover: hover){ .featured-card:hover .featured-cover img{ transform: scale(1.035); } }

/* A soft scrim at the foot of the cover — only where there is a real
   image, since the fallback gradient covers are already controlled. */
.featured-cover:has(img)::after {
  content: ''; position: absolute; inset: auto 0 0 0; height: 45%;
  background: linear-gradient(180deg, transparent, rgb(0 0 0 / 0.28));
  pointer-events: none;
}

/* The ornament on a coverless card, which was a flat centred logo. Given
   a little presence and a slow drift on hover so a card with no photo
   still feels like it was designed rather than left empty. */
.cover-ornament{
  opacity: 0.16;
  transition: opacity var(--dur-slow) var(--ease-soft), transform var(--dur-slow) var(--spring);
}
@media (hover: hover){ .featured-card:hover .cover-ornament { opacity: 0.26; transform: scale(1.08) rotate(6deg); } }

/* =========================================================================
   55. v7.1 — THE PRAYER GRID
   -------------------------------------------------------------------------
   Six times of day, previously rendered as six identical cells. The one
   question anyone opens this page to answer — which prayer is next — was
   answered only by the separate countdown above it.

   Three states now, distinguished by weight and by a marker, never by
   colour alone:
     past     recedes
     next     raised, accented, with a leading bar and a live label
     upcoming normal
   ========================================================================= */
.prayer-grid > *{
  position: relative;
  border-radius: var(--prayer-row-radius);
  background: var(--prayer-row-bg);
  transition:
    background-color var(--dur) var(--ease-soft),
    box-shadow var(--dur) var(--ease-soft),
    opacity var(--dur) var(--ease-soft);
}

.prayer-grid > .is-past{
  background: var(--prayer-row-bg-past);
  /* 0.70, not the 0.62 this was first written at. Measured against the
     tinted cell, 0.62 put the body text at 3.97-4.19:1 across the light
     palettes — under AA. 0.70 clears 4.5:1 on all eight with margin, and
     the cell still reads as clearly receded because the tint and the
     absence of the marker are doing that work too. Fading text is a
     tempting way to say "this is past" and a very easy way to make it
     unreadable. */
}

.prayer-grid > .is-next{
  opacity: 1;
}
/* The next prayer's NAME stays in the heading colour rather than taking
   the accent. Measured: --accent-ui on the 10%-accent-tinted cell reaches
   only 2.85:1 on the Parchment palette and 3.06:1 on Emerald — under the
   4.5:1 a small bold label needs. Tinting text that already sits on a
   tinted background is how contrast quietly disappears.

   Nothing is lost by this. The cell is already identified as "next" four
   other ways — the background tint, the leading accent bar, the pulsing
   dot, and the heavier weight below — so the accent was the one signal
   that was both redundant AND the only one that could fail. */
.prayer-grid > .is-next .prayer-card-name{
  color: rgb(var(--heading));
  font-weight: 700;
}
/* A quiet pulsing dot on the next prayer. Continuous animation is
   reserved for status indicators, which is exactly what this is. */
.prayer-grid > .is-next::after{
  content: '';
  position: absolute; top: 10px; right: 10px;
  width: 7px; height: 7px; border-radius: 50%;
  background: rgb(var(--accent));
  box-shadow: 0 0 0 0 rgb(var(--accent) / 0.55);
  animation: prayerPulse 2.4s var(--ease-soft) infinite;
}
@keyframes prayerPulse{
  0%{ box-shadow: 0 0 0 0 rgb(var(--accent) / 0.5); }
  70%{ box-shadow: 0 0 0 9px rgb(var(--accent) / 0); }
  100%{ box-shadow: 0 0 0 0 rgb(var(--accent) / 0); }
}

/* The countdown ring, given real presence — it is the page's headline. */
.prayer-countdown{ position: relative; }
.prayer-ring-track{ stroke: rgb(var(--ink) / 0.1); }
.prayer-ring-fill{
  stroke: rgb(var(--accent));
  stroke-linecap: round;
  filter: drop-shadow(0 0 6px rgb(var(--accent) / 0.35));
}
.prayer-countdown-value{
  font-variant-numeric: tabular-nums;
  /* Tabular figures matter more here than anywhere else on the site: a
     countdown re-rendering every second with proportional digits jitters
     horizontally as the numbers change width. */
}

/* =========================================================================
   56. v7.1 — READING
   -------------------------------------------------------------------------
   The part of the site people actually spend their time in. Nothing here
   is decorative; every rule is about the eye moving down a column of text
   for twenty minutes without tiring.
   ========================================================================= */

/* =====================================================================
   NO DROP CAP. DO NOT ADD ONE. — permanent, v7.1
   ---------------------------------------------------------------------
   v7.1 added an opening drop cap here (a `::first-letter` rule setting
   the first character of every post at 3.1em, floated left). It was
   removed at the site owner's explicit instruction, and the instruction
   was explicit that it must not come back: post body text opens as plain
   body text, exactly like every other paragraph.

   This block is left in place, as a comment, precisely so that the next
   person to look at the "Reading" section — including a future me — sees
   that the absence of a drop cap is a DECISION and not an oversight
   waiting to be helpfully corrected. It has now been added and removed
   more than once. It stays removed.

   If a first-letter treatment is ever genuinely wanted again, it needs
   to be asked for first.
   ===================================================================== */

/* Blockquotes: a weighted rule and optical hanging, rather than a grey box. */
.entry-content blockquote{
  position: relative;
  margin: var(--sp-8) 0;
  padding: var(--sp-2) 0 var(--sp-2) var(--sp-6);
  border-left: 2px solid var(--ornament);
  font-family: var(--font-body);
  font-size: 1.06em;
  font-style: italic;
  color: rgb(var(--heading-soft));
}
.entry-content blockquote p:last-child{ margin-bottom: 0; }

/* Arabic and Qur'anic text. The line-height increase is not cosmetic:
   vowelled Naskh carries marks well above and below the baseline, and at
   Latin line spacing the harakat of one line collide with the next. */
.entry-content [lang="ar"],
.quran-text,
.hadith-arabic{
  line-height: 2.15;
  letter-spacing: 0;
  word-spacing: 0.02em;
}

/* Links in prose: an underline that sits below the descenders and
   thickens on hover, instead of the browser default cutting through them. */
.entry-content a:not(.btn){
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: rgb(var(--wash) / 0.45);
  transition: text-decoration-color var(--dur) var(--ease-soft), text-decoration-thickness var(--dur) var(--ease-soft);
}
@media (hover: hover){
  .entry-content a:not(.btn):hover{
    text-decoration-thickness: 2px;
    text-decoration-color: rgb(var(--accent));
  }
}

/* Reading measure. 68 characters is the middle of the 45-75 range that
   reads most comfortably; the site was previously setting a pixel width,
   which drifts away from that as the font size changes. */
.entry-content > p,
.entry-content > ul,
.entry-content > ol,
.entry-content > blockquote{
  max-width: 68ch;
}

/* =========================================================================
   57. v7.1 — FOOTER & NEWSLETTER
   ========================================================================= */
/* The footer is an INK surface — dark panel, light text — and has been
   since v3. An earlier v7.1 draft replaced its background with a light
   gradient and left `color: rgb(var(--on-ink) / 0.75)` untouched, which
   put light text on a light background: the footer's text disappeared
   entirely on all five light palettes. The background is restored; only
   the top edge is new. */
.site-footer{
  position: relative;
  background: rgb(var(--ink));
  border-top: none;
}
/* A hairline of accent along the very top edge, brightest in the middle —
   ties the foot of every page back to the palette. */
.site-footer::before{
  content: ''; position: absolute; top: -1px; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--ornament) 50%, transparent);
}

/* Also an INK surface (`color: rgb(var(--on-ink))`). The same draft gave
   it a light --surface background while leaving the light text in place,
   which is the single most visible bug of that pass: the subscribe band
   sits on the home page, so its heading, body copy and label all became
   invisible on every light palette. The ink background is restored and
   the accent glow is composited ON TOP of it, where it belongs. */
.newsletter-band{
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  box-shadow: var(--e3);
  background:
    radial-gradient(ellipse 70% 100% at 50% 0%, rgb(var(--wash) / 0.16), transparent 68%),
    rgb(var(--ink));
}

/* =========================================================================
   58. v7.1 — MICRO-INTERACTIONS
   -------------------------------------------------------------------------
   The guidance is one to two animated elements per view, 150-300ms,
   motion that carries meaning. Everything here is a state change the
   reader caused; nothing animates on its own except the two live status
   indicators (the next-prayer dot and the compass alignment ring), which
   are indicating live status and are the documented exception.
   ========================================================================= */

/* Reveal on scroll. The existing .reveal/.in-view mechanism is kept — this
   only refines the motion, from a plain fade to a short rise with the
   expo curve, which reads as arriving rather than appearing. */
.reveal{
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity var(--dur-slow) var(--ease-out-expo),
    transform var(--dur-slow) var(--ease-out-expo);
}
.reveal.in-view{ opacity: 1; transform: none; }

/* Anything in a grid that reveals gets a short stagger, so a row of three
   cards arrives as a row rather than as three simultaneous events. */
.topics-grid .reveal:nth-child(2) { transition-delay: 70ms; }
.topics-grid .reveal:nth-child(3) { transition-delay: 140ms; }
.topics-grid .reveal:nth-child(n+4) { transition-delay: 200ms; }

/* Link underline that grows from the left on the nav and footer. */
.footer-col a{
  position: relative;
  text-decoration: none;
  transition: color var(--dur) var(--ease-soft);
}
.footer-col a::after{
  content: ''; position: absolute; left: 0; bottom: -2px;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur) var(--ease-out-expo);
}
/* --accent-light, not --accent-ui. The -ui variant is darkened to be
   legible on the PAGE background; the footer is a dark ink panel, where
   darkening is exactly the wrong direction. */
@media (hover: hover){
  .footer-col a:hover{ color: rgb(var(--accent-light)); }
  .footer-col a:hover::after{ transform: scaleX(1); }
}

/* Buttons get a brief inward press. Kept at 0.985 — enough to feel, not
   enough to look like the button is being squashed. */
.btn:active { transition-duration: 60ms; }

/* The one thing the whole reduced-motion block above cannot cover: two
   continuous indicators that must keep indicating. Slowed rather than
   stopped, so they still read as live without being a motion trigger. */
@media (prefers-reduced-motion: reduce){
  .prayer-grid > .is-next::after{ animation-duration: 6s !important; }
  .reveal{ opacity: 1 !important; transform: none !important; }
}

/* =========================================================================
   59. v7.1 — DARK PALETTE CORRECTIONS
   -------------------------------------------------------------------------
   Three of the effects above assume light falls from above onto a light
   surface. On the dark palettes they need inverting, not merely dimming —
   a white top-edge sweep at 0.5 alpha on obsidian is a visible white line,
   not a highlight.
   ========================================================================= */
html[data-scheme="dark"] :is(.article-card, .topic-card, .value-card, .hadith-card, .quran-card)::before{
  background: linear-gradient(90deg, transparent, rgb(255 255 255 / 0.13) 25%, rgb(255 255 255 / 0.13) 75%, transparent);
  opacity: 0.8;
}

/* The card's own surface is barely distinguishable from the page on the
   darkest palettes, so it is lifted a step rather than relying on a
   shadow that has nothing to fall on. */
html[data-scheme="dark"] :is(.article-card, .topic-card, .value-card, .hadith-card, .quran-card, .prayer-panel){
  background: rgb(var(--surface));
  border-color: rgb(255 255 255 / 0.1);
}

/* The past-prayer tint is drawn from --ink, which on a dark palette IS
   light — so the "receding" state was reading as brighter than the
   others. Inverted. */
html[data-scheme="dark"]{
  --prayer-row-bg-past: rgb(0 0 0 / 0.22);
}

/* =========================================================================
   58. v10.1 — THE LISTENING PLAYER IS GONE
   -------------------------------------------------------------------------
   Through v10.0 a docked player bar read every post aloud, with a wide
   invitation card under the byline and a highlight on the paragraph being
   spoken. All of it has been removed — the markup, the script, the server
   side, and the ~250 lines of CSS that used to sit here.

   Nothing replaces it. The Qur'an reader's own recitation bar is a
   different component and lives further down this file, under the v9.1
   heading; it was never part of this.
   ========================================================================= */

/* ---- page.php, which had been four inline style attributes ------------- */
.page-shell{ max-width:760px; margin-inline:auto; }
.page-header{ margin-bottom:28px; }
.page-header h1{ font-size:var(--fs-3xl); line-height:1.15; }
.page-cover{ border-radius:var(--radius-lg); overflow:hidden; margin-bottom:34px; }
.page-cover img{ width:100%; height:auto; display:block; }


/* =========================================================================
   v9.1 — THE QUR'AN READER'S AUDIO, THE TASBIH, AND A ROUND OF FIXES

   Appended rather than woven in, for the reason the v8.0 block earlier in
   this file gives: everything here either introduces a new component or
   deliberately overrides an older rule, and both are clearer as one dated
   layer than as edits scattered through seven thousand lines. Where a rule
   below overrides an earlier one it says which, and why.
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. THE ACTIVE-TAB DOT — v11.5 deleted the pseudo-element itself, so the
   two blocks that used to sit here (v9.1's scale(0), v10.0's
   `content:none !important`) have nothing left to suppress and are gone.
   See the note beside `.site-header .nav-link.is-current`.
   ------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------
   2. THE HEADER, AND WHAT PINS ITSELF TO IT

   `--header-live` is the header's height while it is on screen and zero
   once it has slid away. assets/main.js toggles .pp-header-hidden on the
   root as the page scrolls; anything sticky reads this instead of
   --header-h, so it travels with the header rather than hanging in space
   beneath a bar that is no longer there.
   ------------------------------------------------------------------------- */


/* -------------------------------------------------------------------------
   3. THE TASBIH BEAD IN THE BAR

   A fourth control in a row that v8.0 measured down to about twenty spare
   pixels at 375px. Paid for by taking the buttons from 44px to 42px and
   the gaps from 6px to 5px — which keeps every target above the 40px both
   platforms treat as the practical floor — and by letting the wordmark go
   at 400px rather than 353px. The mark alone still reads as "home", and a
   counter you can reach beats three characters of a site name you are
   already looking at.
   ------------------------------------------------------------------------- */
.pp-tasbih-bead{ position:relative; }
.pp-tasbih-bead svg{ transition: transform var(--dur) var(--spring); }
@media (hover: hover){ .pp-tasbih-bead:hover svg{ transform: rotate(-12deg) scale(1.06); } }
.pp-tasbih-bead.is-pulsing svg{ animation: ppBeadPulse 420ms var(--spring); }
@keyframes ppBeadPulse{
  0%{ transform: scale(1); }
  40%{ transform: scale(1.22) rotate(-8deg); }
  100%{ transform: scale(1) rotate(0); }
}
.pp-tasbih-bead-count{
  position:absolute; top:-2px; right:-2px;
  min-width:17px; height:17px; padding:0 4px;
  display:flex; align-items:center; justify-content:center;
  border-radius: var(--radius-pill);
  background: rgb(var(--accent)); color: rgb(var(--on-ink));
  font-family: var(--font-mono); font-size:0.6rem; font-weight:500;
  line-height:1; pointer-events:none;
  box-shadow: 0 0 0 2px rgb(var(--bg));
}
@media (prefers-reduced-motion: reduce){
  .pp-tasbih-bead.is-pulsing svg{ animation:none; }
}

/* v11.2 — REMOVED. This block hid the wordmark below 400px, silently
   overriding the measured `max-width:353px` rule far above (same
   specificity, later in the file, so this won). The consequence was that
   on every phone narrower than 400px — which is most phones — the site's
   name was missing from the header entirely and a 30px roundel stood in
   for it. The 353px breakpoint shows its arithmetic and is correct; this
   was a duplicate that contradicted it. See section 6a at the end of
   this file. */

/* ---- the popover the bead opens ---- */
.pp-tasbih-pop{
  position:fixed; top:calc(var(--header-h) + 8px); right:16px; z-index:120;
  width:min(280px, calc(100vw - 32px));
  padding: var(--sp-4);
  border-radius: var(--radius-lg);
  border:1px solid var(--glass-border);
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  box-shadow: var(--e-overlay);
  opacity:0; visibility:hidden;
  transform: translateY(-10px) scale(0.97); transform-origin: top right;
  transition: opacity var(--dur) var(--ease-out-expo),
              transform var(--dur) var(--spring),
              visibility var(--dur);
}
.pp-tasbih-pop.is-open{ opacity:1; visibility:visible; transform:translateY(0) scale(1); }
.pp-tasbih-pop-head{ display:flex; align-items:center; gap:var(--sp-2); margin-bottom: var(--sp-3); }
.pp-tasbih-pick{
  flex:1; min-width:0;
  font-family: var(--font-ui); font-size: var(--fs-xs);
  padding:7px 9px; border-radius: var(--radius-sm);
  border:1px solid var(--hairline-strong);
  background: rgb(var(--surface)); color: rgb(var(--heading));
}
.pp-tasbih-x{
  width:30px; height:30px; flex-shrink:0;
  display:grid; place-items:center;
  border:none; background:transparent; border-radius:50%;
  color: rgb(var(--text-muted)); cursor:pointer;
}
@media (hover: hover){ .pp-tasbih-x:hover{ background: rgb(var(--ink) / 0.06); color: rgb(var(--heading)); } }
.pp-tasbih-x svg{ width:16px; height:16px; }

.pp-tasbih-dial{
  position:relative; display:block; width:150px; height:150px;
  margin:0 auto; padding:0; border:none; background:transparent;
  cursor:pointer; -webkit-tap-highlight-color:transparent;
  touch-action: manipulation; user-select:none;
}
.pp-tasbih-dial:active{ transform: scale(0.965); }
.pp-tasbih-ring{ width:100%; height:100%; transform: rotate(-90deg); }
.pp-tasbih-ring-track{ fill:none; stroke: rgb(var(--ink) / 0.09); stroke-width:8; }
.pp-tasbih-ring-fill{
  fill:none; stroke: rgb(var(--accent)); stroke-width:8; stroke-linecap:round;
  transition: stroke-dashoffset var(--dur) var(--ease-soft);
}
.pp-tasbih-dial-num{
  position:absolute; inset:0; display:grid; place-items:center;
  font-family: var(--font-display); font-size:2.4rem; font-weight:600;
  color: rgb(var(--heading)); line-height:1;
  transform: translateY(-6px);
  font-variant-numeric: tabular-nums;
}
.pp-tasbih-dial-of{
  position:absolute; left:0; right:0; bottom:34px; text-align:center;
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  color: rgb(var(--text-muted));
}
.pp-tasbih-ar{
  margin: var(--sp-2) 0 var(--sp-3); text-align:center;
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size:1.24rem; line-height:1.9;
  color: rgb(var(--heading));
}
.pp-tasbih-pop-foot{ display:flex; align-items:center; gap:var(--sp-2); flex-wrap:wrap; justify-content:center; }
.pp-tasbih-mini{
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight:500;
  padding:6px 10px; border-radius: var(--radius-pill);
  border:1px solid var(--hairline-strong); background:transparent;
  color: rgb(var(--text-muted)); cursor:pointer; text-decoration:none;
  transition: color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .pp-tasbih-mini:hover{ color: rgb(var(--accent-ui)); border-color: rgb(var(--wash) / 0.45); } }
.pp-tasbih-more{ color: rgb(var(--accent-ui)); border-color: rgb(var(--wash) / 0.35); }
.pp-tasbih-pop.is-complete .pp-tasbih-ring-fill{ animation: ppRingDone 620ms var(--ease-out-expo); }
@keyframes ppRingDone{ 0%{ opacity:1; } 45%{ opacity:0.25; } 100%{ opacity:1; } }

@media (max-width:520px){
  /* A sheet rather than a dangling panel, for the reason the appearance
     picker became one in v8.0: a 280px popover hanging off a 42px button
     near the right edge of a phone is a hit-target problem wearing a
     menu's clothes. */
  .pp-tasbih-pop{
    top:auto; right:0; left:0; bottom:0;
    width:100%; max-width:none;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    border-bottom:none;
    transform: translateY(16px) scale(1); transform-origin: bottom center;
    padding-bottom: calc(var(--sp-5) + env(safe-area-inset-bottom));
  }
  .pp-tasbih-pop.is-open{ transform: translateY(0); }
}

/* -------------------------------------------------------------------------
   4. THE TASBIH PAGE
   ------------------------------------------------------------------------- */
.tasbih-app{
  display:grid; grid-template-columns: minmax(0,1.25fr) minmax(0,1fr);
  gap: var(--sp-8); align-items:start;
}
.tasbih-stage{
  display:flex; flex-direction:column; align-items:center; gap: var(--sp-5);
  padding: var(--sp-8) var(--sp-6);
  background: rgb(var(--surface));
  border:1px solid var(--hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--e1);
}
.tasbih-dhikr{ text-align:center; min-height:112px; }
.tasbih-ar{
  margin:0 0 var(--sp-2);
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.1rem);
  line-height:2; color: rgb(var(--heading));
}
.tasbih-translit{
  /* v12.1 — body face, for the reason given on .adhkar-card-tr: a
     display italic is the wrong cut for a line of dense transliteration
     that is being read aloud. */
  margin:0; font-family: var(--font-body); font-style:italic;
  font-size: var(--fs-sm); color: rgb(var(--accent-ui)); line-height:1.7;
}
.tasbih-en{ margin:4px 0 0; font-family: var(--font-ui); font-size: var(--fs-xs); color: rgb(var(--text-muted)); }
.tasbih-source{
  margin:8px 0 0; font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); color: rgb(var(--text-muted) / 0.85);
  max-width: 44ch; margin-inline: auto;
}

.tasbih-dial{
  position:relative; display:block;
  width: min(280px, 68vw); height: min(280px, 68vw);
  padding:0; border:none; background:transparent; cursor:pointer;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
  user-select:none;
  transition: transform 120ms var(--ease-soft);
}
.tasbih-dial::before{
  /* The tappable face, separate from the ring so the ring can animate
     independently of the press. */
  content:''; position:absolute; inset:14%;
  border-radius:50%;
  background: radial-gradient(circle at 50% 38%, rgb(var(--surface)), rgb(var(--bg-alt)));
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.5),
    0 10px 30px -14px rgb(var(--shadow) / 0.5);
  transition: box-shadow var(--dur) var(--ease-soft);
}
.tasbih-dial:active{ transform: scale(0.975); }
.tasbih-dial:focus-visible{ outline:2px solid rgb(var(--accent)); outline-offset:6px; border-radius:50%; }
.tasbih-ring{ position:relative; width:100%; height:100%; transform: rotate(-90deg); }
.tasbih-ring-track{ fill:none; stroke: rgb(var(--ink) / 0.08); stroke-width:9; }
.tasbih-ring-fill{
  fill:none; stroke: rgb(var(--accent)); stroke-width:9; stroke-linecap:round;
  transition: stroke-dashoffset 260ms var(--ease-out-expo);
}
.tasbih-num{
  position:absolute; inset:0; display:grid; place-items:center;
  font-family: var(--font-display); font-weight:600;
  line-height:1;
  color: rgb(var(--heading));
  font-variant-numeric: tabular-nums;
}
.tasbih-of{
  position:absolute; left:0; right:0; text-align:center;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: rgb(var(--text-muted));
}
.tasbih-pulse{
  position:absolute; inset:14%; border-radius:50%;
  border:2px solid rgb(var(--wash) / 0.6);
  opacity:0; pointer-events:none;
}
.tasbih-dial.is-counting .tasbih-pulse{ animation: ppTasbihPulse 420ms var(--ease-out-expo); }
.tasbih-dial.is-complete .tasbih-pulse{ animation: ppTasbihDone 760ms var(--ease-out-expo); }
@keyframes ppTasbihPulse{
  0%{ opacity:0.75; transform: scale(0.94); }
  100%{ opacity:0; transform: scale(1.1); }
}
@keyframes ppTasbihDone{
  0%{ opacity:0.9; transform: scale(0.9); border-width:3px; }
  60%{ opacity:0.45; transform: scale(1.16); }
  100%{ opacity:0; transform: scale(1.26); }
}
@media (prefers-reduced-motion: reduce){
  .tasbih-dial.is-counting .tasbih-pulse,
  .tasbih-dial.is-complete .tasbih-pulse{ animation:none; }
}

.tasbih-controls{ display:flex; flex-wrap:wrap; gap: var(--sp-2); justify-content:center; }
.tasbih-toggles{ display:flex; gap: var(--sp-5); justify-content:center; }
.tasbih-toggle{
  display:inline-flex; align-items:center; gap:7px;
  font-family: var(--font-ui); font-size: var(--fs-xs);
  color: rgb(var(--text-muted)); cursor:pointer;
}
.tasbih-toggle input{ accent-color: rgb(var(--accent)); width:16px; height:16px; }
.tasbih-haptic-note{
  margin:0; max-width:38ch; text-align:center;
  font-family: var(--font-ui); font-size: var(--fs-2xs); line-height:1.5;
  color: rgb(var(--text-muted));
}

.tasbih-sidebar{ display:flex; flex-direction:column; gap: var(--sp-4); }
.tasbih-today{
  display:flex; flex-direction:column; gap:2px;
  padding: var(--sp-5); border-radius: var(--radius);
  background: linear-gradient(140deg, rgb(var(--wash) / 0.12), rgb(var(--accent-light) / 0.16));
  border:1px solid rgb(var(--wash) / 0.18);
}
.tasbih-today strong{
  font-family: var(--font-display); font-size:2.2rem; font-weight:600;
  color: rgb(var(--heading)); line-height:1;
  font-variant-numeric: tabular-nums;
}
.tasbih-today-sub{ font-family: var(--font-ui); font-size: var(--fs-2xs); color: rgb(var(--text-muted)); }
.tasbih-list{ display:flex; flex-direction:column; gap:6px; }
.tasbih-row{
  display:grid; grid-template-columns: auto 1fr auto; align-items:center;
  gap: var(--sp-3); width:100%; text-align:left;
  padding: var(--sp-3) var(--sp-4);
  border:1px solid var(--hairline); border-radius: var(--radius);
  background: rgb(var(--surface)); cursor:pointer;
  transition: border-color var(--dur-fast) var(--ease-soft),
              background var(--dur-fast) var(--ease-soft),
              transform var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .tasbih-row:hover{ border-color: rgb(var(--wash) / 0.4); transform: translateX(2px); } }
.tasbih-row.is-on{ border-color: rgb(var(--wash) / 0.7); background: rgb(var(--wash) / 0.07); }
.tasbih-row.is-seq{ box-shadow: inset 3px 0 0 rgb(var(--accent-3)); }
.tasbih-row-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size:1.05rem; line-height:1.7;
  color: rgb(var(--heading)); white-space:nowrap; overflow:hidden;
  text-overflow:ellipsis;
}
.tasbih-row-meta{ display:flex; flex-direction:column; min-width:0; }
.tasbih-row-name{
  font-family: var(--font-ui); font-size: var(--fs-xs); font-weight:500;
  color: rgb(var(--heading)); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.tasbih-row-nums{ font-family: var(--font-mono); font-size:0.62rem; color: rgb(var(--text-muted)); }
.tasbih-row-count{
  font-family: var(--font-mono); font-size: var(--fs-sm); font-weight:500;
  color: rgb(var(--accent-ui)); font-variant-numeric: tabular-nums;
}
.tasbih-row-count i{ font-style:normal; opacity:0.5; font-size:0.72em; }

.tasbih-notes{ display:grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: var(--sp-5); }
.tasbih-note{
  padding: var(--sp-6); border-radius: var(--radius);
  background: rgb(var(--surface)); border:1px solid var(--hairline);
}
.tasbih-note h3{ margin: var(--sp-3) 0 6px; font-size: var(--fs-md); }
.tasbih-note p{ margin:0; font-size: var(--fs-sm); color: rgb(var(--text-muted)); line-height:1.65; }
.tasbih-noscript{ padding: var(--sp-6); text-align:center; color: rgb(var(--text-muted)); }

@media (max-width:900px){
  .tasbih-app{ grid-template-columns: minmax(0,1fr); gap: var(--sp-6); }
  .tasbih-notes{ grid-template-columns: minmax(0,1fr); gap: var(--sp-4); }
}

/* -------------------------------------------------------------------------
   5. THE QUR'AN READER — per-ayah controls
   ------------------------------------------------------------------------- */
.quran-ayah-play .quran-ic-sound{ display:none; }
.quran-ayah-play.is-sounding .quran-ic-play{ display:none; }
.quran-ayah-play.is-sounding .quran-ic-sound{ display:block; }
.quran-ayah-play.is-sounding{
  color: rgb(var(--on-ink));
  background: rgb(var(--accent));
  border-color: rgb(var(--accent));
}

/* The ayah currently being recited.
   A soft wash and a margin bar rather than a border or a filled block:
   the reading column is the product, and a highlight that changed the
   text's metrics would shuffle every verse sideways as the recitation
   moved down the page. */
.quran-ayah{ transition: background 320ms var(--ease-soft), box-shadow 320ms var(--ease-soft); }
.quran-ayah.is-sounding{
  background: rgb(var(--wash) / 0.055);
  box-shadow: inset 3px 0 0 rgb(var(--accent) / 0.75);
  border-radius: var(--radius-sm);
}

.quran-rail-play{
  cursor:pointer;
}
@media (hover: hover){ .quran-rail-play:hover{ transform: scale(1.06); } }

.quran-unit-card-wrap{ position:relative; }
.quran-unit-play{
  position:absolute; top:8px; right:8px;
  width:28px; height:28px; display:grid; place-items:center;
  border-radius:50%; cursor:pointer; z-index:2;
  border:1px solid var(--hairline-strong);
  background: rgb(var(--surface));
  color: rgb(var(--accent-ui));
  opacity:0; transform: scale(0.85);
  transition: opacity var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--spring),
              background var(--dur-fast) var(--ease-soft);
}
.quran-unit-play:focus-visible{ opacity:1; transform: scale(1); }
@media (hover: hover){
  .quran-unit-card-wrap:hover .quran-unit-play{ opacity:1; transform: scale(1); }
  .quran-unit-play:hover{ background: rgb(var(--accent)); color: rgb(var(--on-ink)); border-color: rgb(var(--accent)); }
}
@media (hover: none){
  /* There is no hover on a touch screen, so it is simply always there. */
  .quran-unit-play{ opacity:1; transform: scale(1); }
}

/* -------------------------------------------------------------------------
   6. THE RECITATION PLAYER BAR
   ------------------------------------------------------------------------- */
.qa-bar{
  /*
   * v11.4 — z-index raised above .qa-tafsir (130), which was covering
   * this. A REAL, CONFIRMED BUG: this is the floating recitation
   * player — play/pause/next, the only transport controls for audio
   * that keeps playing while you read — and the tafsīr sheet (opened
   * from the same reading page, .qa-tafsir, z-index:130) sat on top of
   * it. Anyone who opened the commentary while reciting, or hit play
   * from inside the sheet itself, lost every control for the audio
   * still running underneath: no pause, no skip, nothing — the bar was
   * still there, just physically covered by the sheet's own footprint,
   * which reaches the same bottom edge of the screen. Reported as "the
   * play controls should show over, not hiding behind."
   */
  position:fixed; left:50%; bottom:0; z-index:140;
  transform: translateX(-50%) translateY(120%);
  transition: transform var(--dur-slow) var(--ease-out-expo);
  pointer-events:none;
}
.qa-bar.is-open{ transform: translateX(-50%) translateY(0); pointer-events:auto; }
.qa-bar-inner{
  margin-bottom: calc(12px + env(safe-area-inset-bottom));
  border:1px solid var(--glass-border);
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  overflow:hidden;
}
.qa-bar-main{ display:flex; align-items:center;  }
.qa-btn{
  width:38px; height:38px; flex-shrink:0;
  display:grid; place-items:center; position:relative;
  border:none; background:transparent; border-radius:50%;
  color: rgb(var(--heading-soft)); cursor:pointer;
  transition: background var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .qa-btn:hover{ background: rgb(var(--ink) / 0.07); color: rgb(var(--heading)); } }
.qa-btn svg{ width:17px; height:17px; }
.qa-btn-play{
  background: rgb(var(--accent)); color: rgb(var(--on-ink));
}
@media (hover: hover){ .qa-btn-play:hover{ background: rgb(var(--accent-ui)); color: rgb(var(--on-ink)); } }
.qa-btn-play svg{ width:19px; height:19px; }
.qa-ic-pause{ display:none; }
.qa-bar.is-playing .qa-ic-play{ display:none; }
.qa-bar.is-playing .qa-ic-pause{ display:block; }
.qa-bar.is-waiting .qa-btn-play{ animation: qaPulse 1.1s var(--ease-soft) infinite; }
@keyframes qaPulse{ 0%,100%{ opacity:1; } 50%{ opacity:0.55; } }

.qa-bar-mid{ flex:1; min-width:0; padding:0 var(--sp-2); display:flex; flex-direction:column; gap:3px; }
.qa-bar-ref{
  font-family: var(--font-display); font-weight:600;
  color: rgb(var(--heading)); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.qa-bar-status{
  font-family: var(--font-mono); color: rgb(var(--text-muted));
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.qa-bar-track{
  cursor:pointer; position:relative; touch-action:none;
}
/* A larger invisible hit area than the visible 3px track, so it's
   actually tappable/draggable on a phone rather than a hairline — as an
   absolutely-positioned pseudo-element this adds no height to the row
   itself, unlike padding would. */
.qa-bar-track::after{ content:''; position:absolute; inset:-11px 0; }
.qa-bar-track:focus-visible{ outline:2px solid rgb(var(--accent-ui)); outline-offset:3px; border-radius:3px; }
.qa-bar-fill{
  display:block; height:100%; width:0%;
  background: linear-gradient(90deg, rgb(var(--accent)), rgb(var(--accent-light)));
  transition: width 0.12s linear;
}
.qa-repeat-badge{
  position:absolute; bottom:1px; right:1px;
  font-family: var(--font-mono); font-size:0.52rem; font-weight:500;
  color: rgb(var(--on-ink)); background: rgb(var(--accent));
  border-radius: var(--radius-pill); padding:1px 4px; line-height:1.3;
}
.qa-bar.has-repeat .qa-repeat{ color: rgb(var(--accent-ui)); }

.qa-bar-panel{
  border-top:1px solid var(--hairline);
  padding: var(--sp-4); display:flex; flex-direction:column; gap: var(--sp-3);
  max-height: 52vh; overflow-y:auto;
}
.qa-field{ display:flex; flex-direction:column; gap:5px; }
.qa-field-row{ flex-direction:row; align-items:center; justify-content:space-between; gap: var(--sp-3); }
.qa-field label,
.qa-field-label{
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight:500;
  letter-spacing: var(--track-caps); text-transform:uppercase;
  color: rgb(var(--text-muted));
}
.qa-field select,
.qa-field input[type="number"]{
  font-family: var(--font-ui); font-size: var(--fs-xs);
  padding:8px 10px; border-radius: var(--radius-sm);
  border:1px solid var(--hairline-strong);
  background: rgb(var(--surface)); color: rgb(var(--heading));
  max-width:100%;
}
.qa-field-row input[type="number"]{ max-width:84px; }
.qa-seg{
  display:flex; gap:2px; padding:3px;
  background: rgb(var(--ink) / 0.05); border-radius: var(--radius-pill);
}
.qa-seg button{
  flex:1; padding:7px 10px; border:none; background:transparent; cursor:pointer;
  border-radius: var(--radius-pill);
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight:500;
  color: rgb(var(--text-muted)); white-space:nowrap;
  transition: background var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
.qa-seg button.is-on{ background: rgb(var(--surface)); color: rgb(var(--accent-ui)); box-shadow: var(--e1); }
.qa-check{
  display:flex; align-items:center; gap:8px;
  font-family: var(--font-ui); font-size: var(--fs-xs);
  color: rgb(var(--text-muted)); cursor:pointer;
}
.qa-check input{ accent-color: rgb(var(--accent)); width:16px; height:16px; }

/* The reading column gets out of the player's way rather than sitting
   under it — a bar that covers the last two verses of a surah is a bar
   that has to be dismissed before the surah can be finished. The settings
   panel can grow up to 52vh tall (.qa-bar-panel above), so the same is
   true, more so, whenever it's open. */
body.qa-playing .quran-ayat{ padding-bottom: 96px; }
body.qa-playing.qa-panel-open .quran-ayat{ padding-bottom: min(64vh, 460px); }

@media (max-width:560px){
  .qa-bar{ width:100%; }
  .qa-bar-inner{
    margin-bottom:0;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    border-bottom:none;
    padding-bottom: env(safe-area-inset-bottom);
  }
  /* A single row could not fit six controls at a comfortable tap size,
     which is why prev/next used to be dropped with nothing on screen to
     replace them. Wrapping the reference/status/track onto its own row
     leaves the full width for the button row underneath, so every
     control — prev and next included — stays reachable at a real touch
     size instead of disappearing. */
  .qa-bar-main{ flex-wrap:wrap; gap:6px 4px; }
  .qa-bar-mid{ order:-1; flex-basis:100%; padding:2px 2px 4px; }
  .qa-btn{ width:42px; height:42px; }
  .qa-btn svg{ width:18px; height:18px; }
}

/* -------------------------------------------------------------------------
   7. THE TAFSIR PANEL
   ------------------------------------------------------------------------- */
.qa-tafsir{ position:fixed; inset:0; z-index:130; visibility:hidden; }
.qa-tafsir.is-open{ visibility:visible; }
.qa-tafsir-backdrop{
  position:absolute; inset:0; background: rgb(var(--ink) / 0.45);
  opacity:0; transition: opacity var(--dur) var(--ease-soft);
}
.qa-tafsir.is-open .qa-tafsir-backdrop{ opacity:1; }
.qa-tafsir-sheet{
  position:absolute; top:0; right:0; bottom:0;
  box-shadow: var(--e-overlay);
  transform: translateX(100%);
  transition: transform var(--dur-slow) var(--ease-out-expo);
}
.qa-tafsir.is-open .qa-tafsir-sheet{ transform: translateX(0); }
.qa-tafsir-head{
  align-items:flex-start; justify-content:space-between;
  gap: var(--sp-3);
}
.qa-tafsir-eyebrow{
  display:block; font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform:uppercase;
  color: rgb(var(--accent-ui)); margin-bottom:3px;
}
.qa-tafsir-head-text strong{
  font-family: var(--font-display); font-size: var(--fs-lg); font-weight:600;
  color: rgb(var(--heading));
}
.qa-tafsir-close{
  width:36px; height:36px; flex-shrink:0; display:grid; place-items:center;
  border:none; background:transparent; border-radius:50%; cursor:pointer;
  color: rgb(var(--text-muted));
}
@media (hover: hover){ .qa-tafsir-close:hover{ background: rgb(var(--ink) / 0.07); color: rgb(var(--heading)); } }
.qa-tafsir-close svg{ width:18px; height:18px; }

/* v11.5 — `.qa-tafsir-editions` and its twenty chips no longer exist in
   the markup; the sheet has a book pill and a real chooser. See section
   5 of the v11.5 layer at the end of this file. */

.qa-tafsir-author{
  margin:0; padding: var(--sp-3) var(--sp-6) 0;
}
.qa-tafsir-body{
  overflow-y:auto;
  padding: var(--sp-4) var(--sp-6) calc(var(--sp-10) + env(safe-area-inset-bottom));
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  color: rgb(var(--text));
}
/* The words of the Qur'an being commented on. Given the Qur'anic face and
   the accent so the eye can find the lemma in a wall of commentary —
   which is exactly how a printed tafsir sets it. */
.qa-tafsir-ayah{
  font-family: var(--font-quran); font-weight:700;
  color: rgb(var(--accent-ui));
}
/* The editor's bracketed notes — sources, variant readings. Genuine
   apparatus rather than the commentator's own voice, so it is set smaller
   and quieter instead of inline at full weight. */
.qa-tafsir-note{
  padding-right:0.9em;
}
.qa-tafsir-loading,
.qa-tafsir-empty{
  font-family: var(--font-ui); font-size: var(--fs-sm);
  color: rgb(var(--text-muted)); text-align:center; direction:ltr;
  padding: var(--sp-10) 0;
}
body.qa-tafsir-open{ overflow:hidden; }

@media (max-width:620px){
  .qa-tafsir-sheet{
    top:auto; left:0; right:0; height:88dvh;
    border-top:1px solid var(--hairline);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    transform: translateY(100%);
  }
  .qa-tafsir.is-open .qa-tafsir-sheet{ transform: translateY(0); }
  .qa-tafsir-head,
  .qa-tafsir-bar{ padding-left: var(--sp-5); padding-right: var(--sp-5); }
}

/* -------------------------------------------------------------------------
   8. WARD AND MEMORISATION CARDS
   ------------------------------------------------------------------------- */
.quran-practice-grid{
  display:grid; grid-template-columns: repeat(2, minmax(0,1fr));
}
.quran-practice-card{
  border-radius: var(--radius-lg);
}.qa-ring-wrap{ position:relative; width:78px; height:78px; flex-shrink:0; }
.qa-ring{ width:100%; height:100%; transform: rotate(-90deg); }
.qa-ring-track{ fill:none; stroke: rgb(var(--ink) / 0.09); stroke-width:9; }
.qa-ring-fill{
  fill:none; stroke: rgb(var(--accent)); stroke-width:9; stroke-linecap:round;
  stroke-dasharray:339.3;
  transition: stroke-dashoffset 500ms var(--ease-out-expo);
}
.qa-ring-num{
  position:absolute; inset:0; display:grid; place-items:center;
  font-family: var(--font-display); font-size:1.05rem; font-weight:600;
  color: rgb(var(--heading)); font-variant-numeric: tabular-nums;
}
.qa-ring-num i{ font-style:normal; font-size:0.6em; opacity:0.6; }.qa-form h3{ margin:0 0 var(--sp-4); font-size: var(--fs-md); }
.qa-form-row{
  display:flex; align-items:center; justify-content:space-between;
  gap: var(--sp-3); padding: var(--sp-2) 0;
  border-bottom:1px solid var(--hairline-faint);
}
.qa-form-row label{
  font-family: var(--font-ui); font-size: var(--fs-xs); font-weight:500;
  color: rgb(var(--heading-soft));
}
.qa-form-pair{ display:flex; gap:6px; }
.qa-form input[type="number"],
.qa-form select{
  font-family: var(--font-ui); font-size: var(--fs-xs);
  padding:8px 10px; border-radius: var(--radius-sm);
  border:1px solid var(--hairline-strong);
  background: rgb(var(--bg)); color: rgb(var(--heading));
  max-width:150px;
}
.qa-form input[type="number"]{ max-width:82px; }
.qa-form-note{
  margin: var(--sp-3) 0; font-family: var(--font-ui); font-size: var(--fs-2xs);
  color: rgb(var(--text-muted)); line-height:1.5;
}
.qa-form-actions{ display:flex; align-items:center; gap: var(--sp-3); flex-wrap:wrap; }

@media (max-width:820px){
  .quran-practice-grid{ grid-template-columns: minmax(0,1fr); gap: var(--sp-4); }
}
@media (max-width:480px){
  .qa-card-active{ grid-template-columns: 62px 1fr; gap: var(--sp-4); }
  .qa-ring-wrap{ width:62px; height:62px; }
  .qa-card-empty{ flex-direction:column; align-items:flex-start; }
  .qa-form-row{ flex-direction:column; align-items:stretch; gap:6px; }
  .qa-form-pair{ width:100%; }
  .qa-form-pair select{ flex:1; max-width:none; }
}

/* -------------------------------------------------------------------------
   9. POST COVERS

   The generated panel fills its frame the way a photograph would, so a
   post with an image and a post without one are the same object in the
   grid rather than two different treatments sitting next to each other.
   ------------------------------------------------------------------------- */
/* =========================================================================
   THE COVER BOX MATCHES THE COVER CANVAS — v11.1

   A fixed pixel height on a fluid-width card gives the cover a different
   aspect ratio at every breakpoint, and `preserveAspectRatio="slice"`
   answers that by cropping. Measured on a real page before this change:
   the card box was 734x140 against a 400x300 canvas, so **75% of every
   cover was cropped away vertically** — the gold frame top and bottom
   never rendered at all.

   The canvas is now a wide band (400x150 for cards, 400x190 for the
   spotlight — see pp_post_cover_art) and the box is given the SAME ratio
   with `aspect-ratio` instead of a height. They cannot drift apart, and
   nothing is cropped: the whole illuminated panel is what you see, which
   is what makes the shamsa read as centred.
   ========================================================================= */
.featured-cover.has-cover-art{
  height: auto;
  aspect-ratio: 400 / 190;
}
@media (min-width:900px){
  /* At desktop the spotlight cover becomes a column beside the text, so
     it takes its height from the text and a ratio would fight it. */
  .featured-card.is-wide .featured-cover.has-cover-art{
    aspect-ratio: auto;
    height: auto;
  }
}

.featured-cover.has-cover-art {
  background: rgb(var(--bg-alt));
  overflow:hidden;
}
.featured-cover.has-cover-art .cover-art {
  position:absolute; inset:0;
  transition: transform 0.9s var(--ease);
}

/* The newest piece, marked so that its appearance in the grid reads as
   emphasis rather than as the same post twice. */

/* -------------------------------------------------------------------------
   10. HOMEPAGE SPACING, ESPECIALLY ON A PHONE

   The homepage is eleven stacked sections, and their vertical rhythm came
   from a mixture of .section-pad, .section-pad-sm and a couple of inline
   `padding-top:8px` attributes. On a wide screen that mixture reads as
   variety; at 375px, where every section is a single column and the eye
   has nothing but the gaps to tell one from the next, it reads as
   randomness — two bands jammed together here, a chasm there.

   So the phone gets ONE rhythm: a single value between sections, a
   smaller one inside them, and the same gap in every card grid. The
   inline paddings are overridden here rather than removed from the
   template, so the wide composition they were written for is untouched.
   ------------------------------------------------------------------------- */
@media (max-width:760px){
  .section-pad{ padding-top: var(--sp-10); padding-bottom: var(--sp-10); }
  .section-pad-sm{ padding-top: var(--sp-6); padding-bottom: var(--sp-6); }

  /* The two "of the day" bands, which carry inline padding-top:8px.
     Matched on the attribute so this cannot catch anything else. */
  .home section.wrap[style*="padding-top"]{
    padding-top: var(--sp-4) !important;
    padding-bottom: 0 !important;
  }

  .hero.wrap{ padding-top: var(--sp-5); }
  .hero-frame{ padding: var(--sp-8) var(--sp-5) !important; }
  .hero-ctas{ gap: var(--sp-2); }
  .hero-ctas .btn{ flex:1 1 auto; justify-content:center; }
  .hero-stats{ gap: var(--sp-4); margin-top: var(--sp-6); }

  .section-header{ margin-bottom: var(--sp-5); gap: var(--sp-2); }

  /* One gap value everywhere a set of cards stacks, so the page has a
     single vertical rhythm instead of five. */
  .topics-grid.topics-grid,
.essay-rec-grid.essay-rec-grid,
.hadith-home-grid.hadith-home-grid,
.welcome-grid.welcome-grid {
    gap: var(--sp-4);
  }

  .spotlight-solo{ margin-bottom: var(--sp-5); }
  .reflection-band{ margin-top: var(--sp-5); }
  .hadith-day.is-compact{ padding: var(--sp-5); }
  .newsletter-band{ padding: var(--sp-8) var(--sp-5); }
}

@media (max-width:520px){
  /* Below this a two-column card grid is a column and a half, which is
     worse than one column: the cards are too narrow for the excerpt and
     the covers crop to a sliver. */
  .topics-grid.topics-grid { grid-template-columns: minmax(0,1fr); }
  .hero-stats{ flex-wrap:wrap; row-gap: var(--sp-3); }
}

/* Nothing about any of this belongs on paper. */
@media print{
  .qa-bar, .qa-tafsir, .pp-tasbih-pop, .pp-tasbih-bead,
  .quran-ayah-play, .quran-ayah-tafsir, .quran-unit-play,
  .quran-practice-card, .tasbih-app{ display:none !important; }
  .quran-ayah.is-sounding{ background:none !important; box-shadow:none !important; }
}


/* =========================================================================
   v9.2 — JUZ' PAGES, THE COMPACT PRACTICE STRIPS, THE REBUILT TAFSIR
   PANEL, AND THE COMPASS CALIBRATION INDICATOR
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. THE JUZ' AND HIZB READING PAGES

   Same reader as a surah page, with one thing a surah page never needs: a
   heading wherever the reading crosses into a new surah. Without it a
   juz' is an undifferentiated wall of ayat with no way to see where
   Al-Baqarah ends and Al-'Imran begins.
   ------------------------------------------------------------------------- */
.quran-unit-cta{ margin-top: var(--sp-5); display:flex; justify-content:center; }

.quran-unit-surah-head{
  margin: var(--sp-10) 0 var(--sp-5);
  scroll-margin-top: calc(var(--header-h) + 20px);
}
.quran-ayat > .quran-unit-surah-head:first-child{ margin-top: var(--sp-2); }

.quran-unit-surah-link{
  display:flex; align-items:center; gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  border-radius: var(--radius);
  border:1px solid rgb(var(--wash) / 0.22);
  background: linear-gradient(120deg, rgb(var(--wash) / 0.09), rgb(var(--accent-light) / 0.10));
  text-decoration:none; color:inherit;
  transition: border-color var(--dur) var(--ease-soft), transform var(--dur) var(--ease-soft);
}
@media (hover: hover){ .quran-unit-surah-link:hover{ border-color: rgb(var(--wash) / 0.5); transform: translateY(-1px); } }
.quran-unit-surah-num{
  flex-shrink:0; width:34px; height:34px;
  display:grid; place-items:center; border-radius:50%;
  background: rgb(var(--wash) / 0.16); color: rgb(var(--accent-ui));
  font-family: var(--font-mono); font-size: var(--fs-xs); font-weight:500;
}
.quran-unit-surah-names{ display:flex; flex-direction:column; gap:1px; min-width:0; flex:1; }
.quran-unit-surah-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight); line-height:1.6;
  color: rgb(var(--heading));
}
.quran-unit-surah-en{
  font-family: var(--font-ui);
  color: rgb(var(--text-muted));
}
.quran-unit-surah-link svg{ flex-shrink:0; color: rgb(var(--accent-ui)); opacity:0.7; }

/* -------------------------------------------------------------------------
   2. THE PRACTICE STRIPS

   The v9.1 cards were 160px tall each and sat directly under the hero, so
   two of them pushed the search box and all 114 surahs below the fold on
   a phone — a habit tracker taking precedence over the Qur'an, on the
   Qur'an's own page. They are now one row apiece: a 44px ring, a line of
   text, and the buttons. About a third of the height, and everything the
   reader could actually act on is still in it.
   ------------------------------------------------------------------------- */
.quran-practice-grid{ gap: var(--sp-3); }
.quran-practice-card{ padding:0; border:none; background:none; box-shadow:none; }

.qa-strip{
  display:flex; align-items:center; gap: var(--sp-3); width:100%;
  padding: var(--sp-3) var(--sp-4);
  border:1px solid var(--hairline);
  border-radius: var(--radius);
  background: rgb(var(--surface));
  text-align:left; box-shadow: var(--e1);
}
button.qa-strip{ cursor:pointer; transition: border-color var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--ease-soft); }
@media (hover: hover){ button.qa-strip:hover{ border-color: rgb(var(--wash) / 0.45); transform: translateY(-1px); } }

.qa-strip-ic{
  flex-shrink:0; width:36px; height:36px;
  display:grid; place-items:center; border-radius:50%;
  background: rgb(var(--wash) / 0.12); color: rgb(var(--accent-ui));
}
.qa-strip-ic svg{ width:17px; height:17px; }

.qa-strip-ring{ position:relative; flex-shrink:0; width:44px; height:44px; }
.qa-strip-ring svg{ width:100%; height:100%; transform: rotate(-90deg); }
.qa-strip-ring .qa-ring-track{ fill:none; stroke: rgb(var(--ink) / 0.1); stroke-width:4; }
.qa-strip-ring .qa-ring-fill{
  fill:none; stroke: rgb(var(--accent)); stroke-width:4; stroke-linecap:round;
  transition: stroke-dashoffset 500ms var(--ease-out-expo);
}
.qa-strip-ring b{
  position:absolute; inset:0; display:grid; place-items:center;
  font-family: var(--font-mono); font-size:0.66rem; font-weight:500;
  color: rgb(var(--heading)); font-variant-numeric: tabular-nums;
}

.qa-strip-text{ flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; }
.qa-strip-text strong{
  font-family: var(--font-ui); font-size: var(--fs-xs); font-weight:600;
  color: rgb(var(--heading));
}
.qa-strip-text span{
  font-family: var(--font-mono); font-size:0.63rem; color: rgb(var(--text-muted));
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.qa-strip-empty .qa-strip-text span{ font-family: var(--font-ui); font-size: var(--fs-2xs); }

.qa-strip-actions{ display:flex; align-items:center; gap:4px; flex-shrink:0; }
.qa-strip-play,
.qa-strip-edit{
  width:34px; height:34px; display:grid; place-items:center;
  border-radius:50%; cursor:pointer; border:1px solid transparent;
  transition: background var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
.qa-strip-play{ background: rgb(var(--accent)); color: rgb(var(--on-ink)); }
@media (hover: hover){ .qa-strip-play:hover{ background: rgb(var(--accent-ui)); } }
.qa-strip-edit{ background:transparent; color: rgb(var(--text-muted)); border-color: var(--hairline-strong); }
@media (hover: hover){ .qa-strip-edit:hover{ color: rgb(var(--accent-ui)); border-color: rgb(var(--wash) / 0.45); } }
.qa-strip-play svg, .qa-strip-edit svg{ width:15px; height:15px; }
.qa-strip-go{ flex-shrink:0; color: rgb(var(--accent-ui)); opacity:0.65; display:grid; place-items:center; }
.qa-strip-go svg{ width:16px; height:16px; }

/* The setup form still needs room; it only appears when asked for. */
.quran-practice-card .qa-form{
  padding: var(--sp-5);
  border:1px solid var(--hairline);
  border-radius: var(--radius);
  background: rgb(var(--surface));
  box-shadow: var(--e1);
}

@media (max-width:520px){
  .qa-strip{ padding: var(--sp-3); gap: var(--sp-2); }
  .qa-strip-text span{ font-size:0.6rem; }
}

/* -------------------------------------------------------------------------
   3. THE TAFSIR PANEL, REBUILT

   The verse is pinned at the top, the editions name themselves, and the
   muhaqqiq's apparatus is set apart from the commentary rather than
   inside it.
   ------------------------------------------------------------------------- */
.qa-tafsir-sheet{
  background:
    linear-gradient(rgb(var(--surface)), rgb(var(--surface))) padding-box,
    linear-gradient(160deg, rgb(var(--wash) / 0.35), rgb(var(--wash) / 0)) border-box;
  border-left:1px solid transparent;
}
.qa-tafsir-grab{ display:none; }

.qa-tafsir-head{
  display:block;
  border-bottom:1px solid var(--hairline-faint);
  background: linear-gradient(180deg, rgb(var(--wash) / 0.06), rgb(var(--wash) / 0));
}
.qa-tafsir-head-row{
  justify-content:space-between;
}
.qa-tafsir-head-tools{ display:flex; align-items:center; gap:4px; }
.qa-tafsir-tool{
  min-width:32px; height:32px; padding:0 8px;
  display:grid; place-items:center;
  border:1px solid var(--hairline-strong); border-radius: var(--radius-sm);
  background:transparent; cursor:pointer;
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight:600;
  color: rgb(var(--text-muted));
  transition: color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .qa-tafsir-tool:hover{ color: rgb(var(--accent-ui)); border-color: rgb(var(--wash) / 0.45); } }
.qa-tafsir-tool svg{ width:16px; height:16px; }
.qa-tafsir-close{ border-color:transparent; }

/* The ayah, pinned. This is the single biggest change in the panel:
   reading a commentary with the verse scrolled off behind the sheet is
   the wrong way round. */
.qa-tafsir-verse{
  margin:0;
  border-radius: var(--radius);
  border:1px solid rgb(var(--wash) / 0.2);
  background: rgb(var(--wash) / 0.055);
  font-family: var(--font-quran-glyphs), var(--font-quran);
  text-align:center;
  color: rgb(var(--heading));
}
.qa-tafsir-ref{
  display:block; margin-top:6px; text-align:center; font-style:normal;
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform:uppercase;
  color: rgb(var(--accent-ui));
}


/* v11.5 — `.qa-tafsir-byline` is gone from the markup: the author's name
   sits inside the one bar beside the book pill, and the line describing
   the book sits in the foot. */
.qa-tafsir-author{
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size:0.95rem;
  color: rgb(var(--heading-soft)); text-align:right; direction:rtl;
}
.qa-tafsir-note-line{
  font-family: var(--font-ui); line-height:1.5;
  color: rgb(var(--text-muted));
}

.qa-tafsir-body{
  padding: var(--sp-4) var(--sp-6) var(--sp-8);
  /* overridden live by the A+/A− control */
}
.qa-tafsir-body p{ margin:0 0 1.15em; }
.qa-tafsir-body p:first-child{ margin-top:0; }

/* THE MUHAQQIQ'S NOTES.
   A commentary page carries two voices six centuries apart: the
   commentator's, and the modern editor's bracketed apparatus. v9.1 set
   them at nearly the same size, so Tabari read as one undifferentiated
   block. They are now markedly smaller, quieter, indented behind a rule
   — and can be switched off entirely, which is what somebody reading for
   meaning rather than for apparatus wants. */
.qa-tafsir-note{
  display:block; margin:0.7em 0; padding:0.35em 0.95em 0.35em 0;
  border-right:2px solid rgb(var(--wash) / 0.3);
  font-size:0.72em; line-height:1.95;
  color: rgb(var(--text-muted)); opacity:0.9;
}
.qa-tafsir.hide-notes .qa-tafsir-note{ display:none; }

.qa-tafsir-foot{
  margin-top:auto;
  padding: var(--sp-3) var(--sp-6) calc(var(--sp-4) + env(safe-area-inset-bottom));
  border-top:1px solid var(--hairline-faint);
  background: rgb(var(--surface));
}

/* A skeleton rather than a spinner: it holds the sheet's height steady,
   so the commentary does not arrive by shoving everything down. */
.qa-tafsir-skeleton{ display:flex; flex-direction:column; gap:12px; padding-top:6px; }
.qa-tafsir-skeleton span{
  display:block; height:13px; border-radius:4px;
  background: linear-gradient(90deg, rgb(var(--ink) / 0.06), rgb(var(--ink) / 0.12), rgb(var(--ink) / 0.06));
  background-size:200% 100%;
  animation: qaSkeleton 1.3s var(--ease-soft) infinite;
}
.qa-tafsir-skeleton span:nth-child(3n){ width:82%; }
.qa-tafsir-skeleton span:nth-child(4n){ width:64%; }
@keyframes qaSkeleton{ 0%{ background-position:200% 0; } 100%{ background-position:-200% 0; } }
@media (prefers-reduced-motion: reduce){ .qa-tafsir-skeleton span{ animation:none; } }

@media (max-width:620px){
  .qa-tafsir-sheet{ height:92dvh; border-left:none; }
  .qa-tafsir-grab{
    display:block; width:38px; height:4px; margin:8px auto 0;
    border-radius:2px; background: rgb(var(--ink) / 0.18);
  }
  .qa-tafsir-bar,
  .qa-tafsir-foot{ padding-left: var(--sp-5); padding-right: var(--sp-5); }
  .qa-tafsir-note-line{ display:none; }
}

/* -------------------------------------------------------------------------
   4. THE COMPASS CALIBRATION INDICATOR

   The most dangerous thing this page could do is look confident while it
   is not. Three states, and only one of them is calm enough in colour to
   read as permission to act.
   ------------------------------------------------------------------------- */
.qibla-cal{
  width:min(340px, 88%); margin: var(--sp-4) auto 0;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius);
  border:1px solid var(--hairline-strong);
  background: rgb(var(--surface));
  transition: border-color var(--dur) var(--ease-soft), background var(--dur) var(--ease-soft);
}
.qibla-cal-main{ display:flex; align-items:center; gap: var(--sp-3); }
.qibla-cal-figure{ flex-shrink:0; width:52px; height:28px; }
.qibla-cal-figure svg{ width:100%; height:100%; overflow:visible; }
.qibla-cal-path{ fill:none; stroke: currentColor; stroke-width:2; opacity:0.28; }
.qibla-cal-dot{ fill: currentColor; }

.qibla-cal-text{ display:flex; flex-direction:column; gap:1px; min-width:0; }
.qibla-cal-text strong{
  font-family: var(--font-ui); font-size: var(--fs-xs); font-weight:600;
  line-height:1.3;
}
.qibla-cal-text span{
  font-family: var(--font-ui); font-size: var(--fs-2xs); line-height:1.4;
  color: rgb(var(--text-muted));
}

.qibla-cal-meter{
  margin-top: var(--sp-2); height:3px; border-radius:2px;
  background: rgb(var(--ink) / 0.1); overflow:hidden;
}
.qibla-cal-meter-fill{
  display:block; height:100%; width:0%;
  background: currentColor;
  transition: width 420ms var(--ease-soft);
}

/* Settling — saying nothing either way. */
.qibla-cal[data-state="settling"]{ color: rgb(var(--text-muted)); }
.qibla-cal[data-state="settling"] .qibla-cal-text strong{ color: rgb(var(--heading-soft)); }

/* Calibrate — the one state that asks for something, and the only one
   that animates: the dot runs the figure of eight the reader is being
   asked to trace. */
.qibla-cal[data-state="calibrate"]{
  color: rgb(var(--accent-2, var(--accent)));
  border-color: rgb(var(--accent-2, var(--accent)) / 0.45);
  background: rgb(var(--accent-2, var(--accent)) / 0.07);
}
.qibla-cal[data-state="calibrate"] .qibla-cal-text strong{ color: rgb(var(--accent-2, var(--accent))); }
.qibla-cal[data-state="calibrate"] .qibla-cal-dot{
  animation: qiblaFigure8 2.6s var(--ease-soft) infinite;
  offset-path: path('M32 17 C32 4, 60 4, 60 17 C60 30, 32 30, 32 17 C32 4, 4 4, 4 17 C4 30, 32 30, 32 17 Z');
  offset-rotate: 0deg;
}
@keyframes qiblaFigure8{
  from{ offset-distance: 0%; }
  to{ offset-distance: 100%; }
}
/* Browsers without offset-path still get a pulse rather than a dot that
   sits inert in the middle of a figure it is supposed to be tracing. */
@supports not (offset-path: path('M0 0 L1 1')){
  .qibla-cal[data-state="calibrate"] .qibla-cal-dot{ animation: qiblaDotPulse 1.4s var(--ease-soft) infinite; }
}
@keyframes qiblaDotPulse{ 0%,100%{ opacity:1; r:3.6px; } 50%{ opacity:0.4; r:5px; } }

/* Ready — and only here does the wording say the direction can be
   relied on. */
.qibla-cal[data-state="ready"]{
  color: rgb(var(--accent-3, var(--accent)));
  border-color: rgb(var(--accent-3, var(--accent)) / 0.4);
  background: rgb(var(--accent-3, var(--accent)) / 0.06);
}
.qibla-cal[data-state="ready"] .qibla-cal-text strong{ color: rgb(var(--accent-3, var(--accent))); }
.qibla-cal[data-state="ready"] .qibla-cal-path{ opacity:0.12; }

@media (prefers-reduced-motion: reduce){
  .qibla-cal-dot{ animation:none !important; }
}

/* -------------------------------------------------------------------------
   5. THE GROUPED ADHKAR LIST
   ------------------------------------------------------------------------- */
.tasbih-group{ display:flex; flex-direction:column; gap:5px; }
.tasbih-group + .tasbih-group{ margin-top: var(--sp-4); }
.tasbih-group-label{
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform:uppercase;
  color: rgb(var(--accent-ui)); opacity:0.85;
  padding: 0 2px 2px;
}
/* The long siyagh of salawat run to two lines in the picker; give the
   Arabic column room rather than ellipsising a whole formula to four
   characters. */
.tasbih-row-ar{ max-width:12ch; }

@media print{
  .qibla-cal, .qa-strip{ display:none !important; }
}


/* =========================================================================
   v10.0 — FIXES
   ========================================================================= */

/* -------------------------------------------------------------------------
   2. THE READING RAIL

   v10.0 patched this here; v10.1 rebuilt it at its own definition
   further up this file, so the patch is gone rather than layered on top
   of a component it no longer describes. See the long note above
   `.quran-siderail`.
   ------------------------------------------------------------------------- */


/* =========================================================================
   v10.0 — THE ADHKAR LIBRARY, THE FULL-SCREEN TAFSIR, AND THE POLISH
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. THE ADHKAR PAGE
   ------------------------------------------------------------------------- */
/* ---- v11.0: the ʿunwān, the illuminated headpiece ---- */
.adhkar-unwan{
  position: relative;
  max-width: 760px; margin: 0 auto var(--sp-8);
  padding: calc(var(--sp-10) + 6px) var(--sp-6) var(--sp-8);
  text-align: center;
  border: 1px solid rgb(var(--ornament) / 0.3);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(120% 90% at 50% 0%, rgb(var(--ornament) / 0.09), transparent 62%),
    rgb(var(--surface));
  box-shadow: var(--e2);
}
/* The gold rule across the head of the panel. */
.adhkar-unwan-rule{
  position: absolute; top: 0; left: 0; right: 0; height: 3px;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  background: linear-gradient(90deg,
    rgb(var(--ornament) / 0) 0%,
    rgb(var(--ornament) / 0.85) 22%,
    rgb(var(--ornament) / 0.85) 78%,
    rgb(var(--ornament) / 0) 100%);
}
.adhkar-unwan-mark{
  position: absolute; top: 0; left: 50%;
  transform: translate(-50%, -50%);
  place-items: center;
  border-radius: 50%;
  background: rgb(var(--surface));
  border: 1px solid rgb(var(--ornament) / 0.4);
  color: rgb(var(--accent-ui));
  box-shadow: var(--e1);
}
.adhkar-unwan .eyebrow{ display: inline-block; }

.adhkar-title{
  color: rgb(var(--heading));
}
.adhkar-unwan-sub{
  font-family: var(--font-display); font-style: italic;
  font-size: var(--fs-base); color: rgb(var(--accent-ui));
}
/* A short centred rule between the title and the ayah. */
.adhkar-unwan-divider{
  display: block; width: 92px; height: 1px; margin: var(--sp-5) auto var(--sp-4);
  background: linear-gradient(90deg, transparent, rgb(var(--ornament) / 0.6), transparent);
  position: relative;
}
.adhkar-unwan-divider::after{
  content: ''; position: absolute; top: 50%; left: 50%;
  width: 5px; height: 5px; transform: translate(-50%, -50%) rotate(45deg);
  background: rgb(var(--ornament) / 0.7);
}
.adhkar-hero-ayah{
  margin: 0 0 var(--sp-3);
  /* The Qur'anic face, like every other ayah on the site. */
  line-height: 2.2; color: rgb(var(--heading));
}
.adhkar-hero-en{
  margin: 0 auto var(--sp-2); max-width: 46ch;
  font-family: var(--font-body); font-size: var(--fs-sm);
  line-height: 1.75; color: rgb(var(--text));
}
.adhkar-hero-ref{
  margin: 0;
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--accent-ui));
}
.adhkar-unwan-desc{
  line-height: 1.75;
}
@media (max-width:600px){
  .adhkar-unwan{ padding: calc(var(--sp-8) + 6px) var(--sp-4) var(--sp-6); }
  .adhkar-unwan-mark{ width: 46px; height: 46px; }
  .adhkar-unwan-mark svg{ width: 23px; height: 23px; }
}

/* ---- the tab strip ---- */
.adhkar-tab svg{ width: 19px; height: 19px; color: rgb(var(--accent-ui)); }

/* ---- a set ---- */
.adhkar-panel-head{
  justify-content: space-between;
  flex-wrap: wrap;
  padding-bottom: var(--sp-4);
}
.adhkar-panel-head h2{
  margin: 0 0 4px; font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2rem); line-height: 1.7;
}
.adhkar-panel-head p{
  margin: 0; max-width: 52ch;
  font-size: var(--fs-sm); color: rgb(var(--text-muted)); line-height: 1.6;
}
.adhkar-reset{
  align-self: flex-start; cursor: pointer;
  text-underline-offset: 3px;
}

/* ---- a dhikr ---- */
.adhkar-list{ list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-4); }
.adhkar-card{
  position: relative; padding: var(--sp-6);
  border: 1px solid var(--hairline); border-radius: var(--radius-lg);
  background: rgb(var(--surface)); box-shadow: var(--e1);
  transition: border-color var(--dur) var(--ease-soft), opacity var(--dur) var(--ease-soft);
}
.adhkar-card.is-done{ border-color: rgb(var(--accent-3, var(--accent)) / 0.5); }
.adhkar-card.is-done .adhkar-card-ar{ opacity: 0.6; }
.adhkar-card.is-pulsing{ animation: adhkarPulse 420ms var(--ease-out-expo); }
@keyframes adhkarPulse{
  0%{ box-shadow: 0 0 0 0 rgb(var(--accent) / 0.28); }
  100%{ box-shadow: 0 0 0 14px rgb(var(--accent) / 0); }
}
@media (prefers-reduced-motion: reduce){ .adhkar-card.is-pulsing{ animation: none; } }

.adhkar-card-head{ display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.adhkar-card-n{
  flex-shrink: 0; width: 26px; height: 26px; display: grid; place-items: center;
  border-radius: 50%; background: rgb(var(--wash) / 0.12);
  font-family: var(--font-mono); font-size: 0.66rem; color: rgb(var(--accent-ui));
}
.adhkar-card-head h3{
  margin: 0; flex: 1; font-size: var(--fs-sm); font-weight: 600;
  color: rgb(var(--heading-soft));
}
.adhkar-card-times{
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  color: rgb(var(--accent-ui));
}

.adhkar-card-ar{
  margin: 0 0 var(--sp-4);
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  text-align: right; direction: rtl;
  color: rgb(var(--heading));
  transition: opacity var(--dur) var(--ease-soft);
}
/* An entry that IS Qur'an is set in the Qur'anic face, the way every
   other ayah on this site is. */
.adhkar-card-ar.is-quran{
  font-family: var(--font-quran), var(--font-arabic);
  line-height: 2.5;
}
.adhkar-card-tr{
  /* Legible on its own terms rather than an afterthought under the
     Arabic — was smaller than the card's own title, which made a line
     most readers actually lean on the hardest to read.

     v12.1 — set in the BODY face rather than the display face. These are
     long lines of dense transliteration read while saying the words, and
     Fraunces Italic — a display cut with high contrast and tight
     spacing — is the wrong tool for that at 0.9rem. Newsreader Italic is
     a reading face and holds the diacritics more evenly. */
  margin: 0 0 8px; font-family: var(--font-body); font-style: italic;
  color: rgb(var(--accent-ui));
}
.adhkar-card-en{
  margin: 0 0 var(--sp-4);
  color: rgb(var(--text));
}
.adhkar-card-virtue{
  display: flex; align-items: flex-start; gap: 8px;
  margin: 0 0 var(--sp-4); padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-sm);
  background: rgb(var(--wash) / 0.06);
  font-size: var(--fs-xs); line-height: 1.6; color: rgb(var(--text-muted));
}
.adhkar-card-virtue svg{ width: 14px; height: 14px; flex-shrink: 0; margin-top: 2px; color: rgb(var(--accent)); }

/* v12.0 — the qualifying note. Deliberately quieter than the virtue above
   it and the citation below it: it is the small print of the card and
   should read as small print. Given a real measure so it does not run the
   full width of a wide card at 0.72rem, which is unreadable. */
.adhkar-card-note{
  margin: 0 0 var(--sp-4);
  max-width: 68ch;
  font-size: 0.72rem;
  line-height: 1.65;
  color: rgb(var(--text-muted));
  opacity: 0.9;
}
/* When it follows the virtue it belongs to, it sits directly under it
   rather than a full gap away — they are one block of small print. */
.adhkar-card-virtue + .adhkar-card-note{
  margin-top: calc(var(--sp-3) * -1);
  padding-inline-start: var(--sp-4);
}

.adhkar-card-foot{
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); padding-top: var(--sp-3);
  /* v12.1 — the hairline above this row is gone. The card already ends
     here; a rule across it only boxed the citation and the counter off
     from the words they belong to, and read as a seam in the middle of
     the card. */
}
.adhkar-card-source{
  font-family: var(--font-mono); font-size: 0.66rem;
  letter-spacing: 0.03em; color: rgb(var(--text-muted));
  display: flex; align-items: center; flex-wrap: wrap; gap: 2px 0;
}
/* A citation that can be checked. Where the reference has been verified
   against the bundled text (pp_adhkar_hadith_refs), the collection and
   its number are a link straight to that hadith on this site — so
   "al-Bukhārī 6069" is something a reader can tap and read, not a claim
   they have to take on trust. */
.adhkar-card-ref{
  display: inline-flex; align-items: baseline; gap: 5px;
  color: rgb(var(--text-muted)); text-decoration: none;
  padding: 3px 7px; margin: -3px 0; border-radius: var(--radius-sm);
  transition: color var(--dur-fast) var(--ease-soft), background var(--dur-fast) var(--ease-soft);
}
.adhkar-card-ref:focus-visible{
  color: rgb(var(--accent-ui)); background: rgb(var(--wash) / 0.09);
}
@media (hover: hover){
  .adhkar-card-ref:hover{
    color: rgb(var(--accent-ui)); background: rgb(var(--wash) / 0.09);
  }
}
.adhkar-card-refnum{
  font-variant-numeric: tabular-nums; font-weight: 600;
  color: rgb(var(--accent-ui));
}
/* A Sunnah.com reference. It carries its number like the linked ones,
   but it is not a link — the book is not on this site — so it must not
   look like one: no hover, no pointer, no tap affordance. */
.adhkar-card-ref.is-plain{
  cursor: default; padding-left: 0; padding-right: 7px;
}
@media (hover: hover){ .adhkar-card-ref.is-plain:hover{ color: rgb(var(--text-muted)); background: transparent; } }
.adhkar-card-ref.is-plain .adhkar-card-refnum{ color: rgb(var(--text-muted)); font-weight: 500; }
.adhkar-card-refsep{ opacity: 0.5; }
.adhkar-card-actions{ display: flex; align-items: center; gap: 8px; }
.adhkar-card-copy{
  width: 34px; height: 34px; display: grid; place-items: center;
  border: 1px solid var(--hairline-strong); border-radius: 50%;
  background: transparent; color: rgb(var(--text-muted)); cursor: pointer;
  transition: color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .adhkar-card-copy:hover{ color: rgb(var(--accent-ui)); border-color: rgb(var(--wash) / 0.45); } }
.adhkar-card-copy.is-copied{ color: rgb(var(--accent-3, var(--accent))); border-color: currentColor; }
.adhkar-card-copy svg{ width: 15px; height: 15px; }

/*
 * The count was the only thing on the card styled like a button — a
 * solid accent pill, the loudest element here after the Arabic itself.
 * That put tallying ahead of the words being said, which is backwards
 * for a page of dhikr. It's now a quiet corner control: same tap size
 * (a real 44px target, just not a filled pill), coloured like the rest
 * of the card's muted chrome until it's actually touched or completed,
 * so the dhikr — not the counter — is what the eye lands on first.
 */
/* =========================================================================
   v12.1 — THE COUNTER

   The one control on this page that is pressed over and over, usually with
   a thumb, often several hundred times in a sitting. It was a 44px
   outlined pill with a number in it and no sense of progress: at 3 of 7 it
   looked exactly like 1 of 7.

   Now it is a wide, tall target with a fill that grows across it as the
   count rises, a number big enough to read without looking properly, and a
   press that gives way under the finger and springs back.
   ========================================================================= */
.adhkar-card-count{
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 104px; min-height: 48px;
  padding: 0 20px;
  border-radius: var(--radius-pill);
  border: 1px solid rgb(var(--wash) / 0.34);
  background: rgb(var(--wash) / 0.06);
  color: rgb(var(--heading));
  cursor: pointer; overflow: hidden; isolation: isolate;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
  -webkit-user-select: none; user-select: none;
  transition:
    transform 0.12s var(--ease-out-expo),
    border-color var(--dur-fast) var(--ease-soft),
    background-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){
  .adhkar-card-count:hover{
    border-color: rgb(var(--wash) / 0.55);
    background: rgb(var(--wash) / 0.1);
  }
}
/* The press. Scaled down a little and released with the spring the rest of
   the site uses, so a tap feels like pressing something rather than like
   nothing happening. */
.adhkar-card-count:active{ transform: scale(0.955); }

/* The fill. Sits behind the number, painted from the saved count. */
.adhkar-count-fill{
  position: absolute; z-index: 0;
  inset-block: 0; inset-inline-start: 0;
  width: 0;
  background: rgb(var(--wash) / 0.26);
  transition: width 0.28s var(--ease-out-expo);
  pointer-events: none;
}
.adhkar-count-face{
  position: relative; z-index: 1;
  display: inline-flex; align-items: baseline; gap: 3px;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.adhkar-card-count-n{
  font-size: 1.12rem; font-weight: 700;
  color: rgb(var(--heading));
  line-height: 1;
}
.adhkar-card-count-of{
  font-size: 0.78rem;
  color: rgb(var(--text-muted));
  line-height: 1;
}

/* Done: the pill fills, the numbers step aside for a tick. */
.adhkar-card.is-done .adhkar-card-count{
  border-color: rgb(var(--wash) / 0.75);
  background: rgb(var(--wash) / 0.14);
}
.adhkar-card.is-done .adhkar-count-fill{ background: rgb(var(--wash) / 0.34); }
.adhkar-card.is-done .adhkar-count-face{ opacity: 0; transform: scale(0.9); }
.adhkar-count-face{ transition: opacity 0.18s var(--ease-soft), transform 0.18s var(--ease-soft); }
.adhkar-card-tick{
  position: absolute; z-index: 2;
  width: 22px; height: 22px;
  fill: none; stroke: rgb(var(--accent-ui)); stroke-width: 2.6;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: 0; transform: scale(0.5);
  transition: opacity 0.2s var(--ease-soft), transform 0.28s var(--spring);
}
.adhkar-card.is-done .adhkar-card-tick{ opacity: 1; transform: scale(1); }

@media (prefers-reduced-motion: reduce){
  .adhkar-card-count,
  .adhkar-count-fill,
  .adhkar-count-face,
  .adhkar-card-tick{ transition: none; }
  .adhkar-card-count:active{ transform: none; }
}

/* On a phone the counter is the whole point of the row, so it takes the
   width it needs and the copy button tucks in beside it. */
@media (max-width: 560px){
  .adhkar-card-foot{ flex-wrap: wrap; row-gap: 10px; }
  .adhkar-card-source{ flex: 1 1 100%; order: 2; }
  .adhkar-card-actions{ flex: 1 1 100%; order: 1; display: flex; gap: 10px; }
  .adhkar-card-count{ flex: 1 1 auto; min-height: 54px; font-size: 1.05rem; }
  .adhkar-card-count-n{ font-size: 1.2rem; }
  .adhkar-card-copy{ flex: 0 0 auto; width: 54px; height: 54px; }
}
/* v12.1 — the old counter's rules used to sit here and they contradicted
   the new ones above: display:none on the tick, display:none on the
   numbers, and a second :active transform. Removed rather than layered
   over, so there is one description of this control and not two. */

/* =========================================================================
   v12.1 — FINISHING A SET

   The only moment on this page worth marking, and the thing that brings
   somebody back the next morning. It was one green line of text.

   It is now an illuminated panel: a rosette that draws its ring and its
   tick, eight petals that open around it, and a slow bloom of light
   behind. All of it is CSS on markup that is already in the DOM — nothing
   is injected and nothing is fetched — and the animation runs only on the
   tap that actually completes the set (see paintSet in assets/adhkar.js),
   never on a repaint.
   ========================================================================= */
.adhkar-complete{
  position: relative;
  margin: var(--sp-6) 0 0;
  padding: var(--sp-6) var(--sp-5) var(--sp-6);
  text-align: center;
  border-radius: var(--radius-lg);
  border: 1px solid rgb(var(--wash) / 0.3);
  background:
    radial-gradient(120% 100% at 50% 0%, rgb(var(--wash) / 0.13), transparent 68%),
    rgb(var(--surface));
  overflow: hidden;
}
/* The bloom. Sits behind everything, scales up once and settles. */
.adhkar-complete-glow{
  position: absolute; z-index: 0;
  top: -40%; left: 50%; width: 340px; height: 340px;
  transform: translateX(-50%) scale(0.4);
  border-radius: 50%;
  background: radial-gradient(circle, rgb(var(--wash) / 0.3), transparent 62%);
  opacity: 0; pointer-events: none;
}
.adhkar-complete.is-playing .adhkar-complete-glow{
  animation: pp-bloom 1500ms var(--ease-out-expo) forwards;
}
@keyframes pp-bloom{
  0%   { opacity: 0;    transform: translateX(-50%) scale(0.4); }
  40%  { opacity: 0.95; }
  100% { opacity: 0.55; transform: translateX(-50%) scale(1); }
}

.adhkar-complete-rosette{ position: relative; z-index: 1; display: block; margin: 0 auto var(--sp-4); width: 72px; height: 72px; }
.adhkar-complete-rosette svg{ width: 100%; height: 100%; overflow: visible; }
.adhkar-rosette-ring{
  fill: none; stroke: rgb(var(--accent) / 0.85); stroke-width: 2.5;
  stroke-dasharray: 170; stroke-dashoffset: 0;
  transform-origin: 50% 50%; transform: rotate(-90deg);
}
.adhkar-complete.is-playing .adhkar-rosette-ring{
  animation: pp-ring 900ms var(--ease-out-expo) forwards;
}
@keyframes pp-ring{ from{ stroke-dashoffset: 170; } to{ stroke-dashoffset: 0; } }

.adhkar-rosette-tick{
  fill: none; stroke: rgb(var(--accent-ui)); stroke-width: 4;
  stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 40; stroke-dashoffset: 0;
}
.adhkar-complete.is-playing .adhkar-rosette-tick{
  animation: pp-tick 460ms var(--ease-out-expo) 620ms backwards;
}
@keyframes pp-tick{ from{ stroke-dashoffset: 40; } to{ stroke-dashoffset: 0; } }

/*
 * v12.2 — `transform-origin: 32px 32px` IS GONE, AND IT WAS THE BUG.
 *
 * Reported as "the end تقبل الله in adhkar text has things overlapping
 * with it". Measured: the petal group's box came out 151px wide inside
 * a 72px rosette, and two of the eight petals were sitting on top of the
 * Arabic line 90px below.
 *
 * The cause is that these paths already carry their own origin in the
 * markup — `transform="rotate(45 32 32)"`, which expands to
 * translate(32,32)·R·translate(-32,-32). Under SVG2 the CSS
 * `transform-origin` property applies to that presentation attribute as
 * well, wrapping it in a second translate(32,32)…translate(-32,-32). The
 * two compose: the net transform is a rotation about (64,64) — the
 * bottom-right CORNER of the 64-unit viewBox — so every petal was thrown
 * out on a 45-unit radius from the wrong point.
 *
 * The rotate() already says where to turn. Nothing else may.
 */
.adhkar-rosette-petals path{ fill: rgb(var(--accent) / 0.55); }
.adhkar-complete.is-playing .adhkar-rosette-petals{
  animation: pp-petals 1100ms var(--spring) 500ms backwards;
  transform-origin: 50% 50%;
}
@keyframes pp-petals{
  from{ opacity: 0; transform: scale(0.55) rotate(-25deg); }
  to  { opacity: 1; transform: scale(1) rotate(0deg); }
}

.adhkar-complete-ar{
  position: relative; z-index: 1; margin: 0 0 8px;
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2rem);
  /* 2.0, not 1.7. Vowelled Naskh carries marks well above and below the
     baseline and this line has a shadda on it; at 1.7 a second line
     would print into the first. */
  line-height: 2; color: rgb(var(--heading));
}
.adhkar-complete-en{
  position: relative; z-index: 1; margin: 0 auto; max-width: 46ch;
  font-size: var(--fs-sm); line-height: 1.65; color: rgb(var(--text));
}
.adhkar-complete-back{
  position: relative; z-index: 1; margin: 10px 0 0;
  font-size: var(--fs-2xs); color: rgb(var(--text-muted));
}
.adhkar-complete.is-playing .adhkar-complete-ar,
.adhkar-complete.is-playing .adhkar-complete-en{
  animation: pp-rise 700ms var(--ease-out-expo) 780ms backwards;
}
@keyframes pp-rise{ from{ opacity: 0; transform: translateY(9px); } to{ opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce){
  .adhkar-complete *,
  .adhkar-complete.is-playing *{ animation: none !important; }
  .adhkar-complete-glow{ opacity: 0.5; transform: translateX(-50%) scale(1); }
}


@media (max-width:620px){
  .adhkar-card{ padding: var(--sp-5) var(--sp-4); }
  .adhkar-panel-head{ flex-direction: column; align-items: stretch; gap: var(--sp-3); }
  .adhkar-progress{ min-width: 0; }
  .adhkar-tab{ min-width: 92px; padding: var(--sp-3); }
}

/* ---- the counter's own target box ---- */
.tasbih-target{
  display: flex; align-items: center; gap: 8px;
  font-family: var(--font-ui); font-size: var(--fs-2xs);
  color: rgb(var(--text-muted));
}
.tasbih-target input{
  width: 84px; padding: 6px 9px; text-align: center;
  border: 1px solid var(--hairline-strong); border-radius: var(--radius-sm);
  background: rgb(var(--surface)); color: rgb(var(--heading));
  font-family: var(--font-mono); font-size: var(--fs-xs);
}
.tasbih-target-hint{ font-family: var(--font-mono); font-size: 0.6rem; opacity: 0.7; }
.tasbih-target-reset{
  width: 22px; height: 22px; display: grid; place-items: center;
  border: none; border-radius: 50%; cursor: pointer;
  background: rgb(var(--ink) / 0.07); color: rgb(var(--text-muted));
  font-size: 0.8rem; line-height: 1;
}
@media (hover: hover){ .tasbih-target-reset:hover{ color: rgb(var(--accent-ui)); } }

/* -------------------------------------------------------------------------
   2. THE TAFSIR, FULL SCREEN

   It was a 560px sheet on the right, which is a sidebar's width for a
   text that is the whole point of opening it. On a laptop that is a
   third of the screen carrying a classical commentary at 1.1rem, with
   the other two thirds showing a page nobody is reading.
   ------------------------------------------------------------------------- */
.qa-tafsir-nav{
  display: flex; align-items: center; justify-content: center;
  gap: var(--sp-4);
}
.qa-tafsir-step{
  flex-shrink: 0;
  display: grid; place-items: center; border-radius: 50%;
  border: 1px solid var(--hairline-strong); background: transparent;
  color: rgb(var(--text-muted)); cursor: pointer;
  transition: color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .qa-tafsir-step:hover{ color: rgb(var(--accent-ui)); border-color: rgb(var(--wash) / 0.5); } }
.qa-tafsir-step svg{ width: 15px; height: 15px; }
.qa-tafsir-nav .qa-tafsir-ref{ margin: 0; min-width: 12ch; }

.qa-tafsir-tool.is-copied{ color: rgb(var(--accent-3, var(--accent))); border-color: currentColor; }

/* v11.5 — the horizontal edition rail (`.qa-tafsir-edition*`) is gone
   from the markup. It was twenty near-identical pills scrolled sideways
   directly above the commentary; it is now one book pill and a real
   chooser on the library's shelves. See buildTafsirPanel() in
   assets/quran-audio.js and section 5 of the v11.5 layer at the end of
   this file. */


@media (max-width:620px){
  .qa-tafsir-sheet{ width: 100%; grid-template-rows: auto auto auto 1fr auto; }
  .qa-tafsir-nav{ gap: var(--sp-3); }
  .qa-tafsir-nav .qa-tafsir-ref{ min-width: 0; }

  /*
   * v10.2 — "huge headers and unscrollable properly" was this: the
   * verse card kept its full desktop padding and 1.5rem Uthmani type
   * regardless of how short the ayah was or how tall the phone screen
   * wasn't, and the sheet's grid gives the header rows (tools, verse,
   * nav) whatever height they ask for before the body's 1fr track gets
   * whatever is left over. On a short ayah in the glyph-encoded Qur'an
   * face — whose metrics run taller than its declared size, see the
   * @font-face note at the top of this file — that "whatever they ask
   * for" was easily a third of the screen for three letters (2:1,
   * "الم"), leaving barely a strip for the commentary underneath.
   * Tightened on every axis, and capped with its own scroll so a long
   * ayah (Āyat al-Kursī) can never do the same thing the short one did.
   */
  .qa-tafsir-head{ padding: var(--sp-4) var(--sp-4) var(--sp-3); }
  .qa-tafsir-head-row{ margin-bottom: var(--sp-2); }
  .qa-tafsir-verse{
    padding: var(--sp-3) var(--sp-4);
    overflow-y: auto;
  }
  .qa-tafsir-body{ padding-left: var(--sp-4); padding-right: var(--sp-4);  }
}

/* =========================================================================
   THE TAFSĪR SHEET, REBALANCED — v11.0

   Measured on a real 1280x720 window before touching anything, because
   "the actual tafsīr is the tiniest part of the page" deserved a number
   rather than a guess. On a 980x720 sheet:

       header (tools + ayah + prev/next) ... 217px   30%
       the edition chooser ................ 151px   21%
       the byline ......................... 	68px    9%
       THE COMMENTARY .....................	219px   30%
       the footer .........................  64px    9%

   Seventy per cent of a panel opened to read a commentary was spent on
   everything except the commentary — and the 219px that remained was
   holding 35,000 characters of aṭ-Ṭabarī.

   The chrome is now compressed on every axis: the edition chooser is a
   single row of compact pills instead of a 151px block of stacked cards
   with descriptions (the descriptions move to the tooltip and to the
   tafsīr room, where there is room for them), the byline is one line,
   the footer is one row, and the ayah is capped. The commentary takes
   what that frees — about 60% of the sheet instead of 30% — and is set
   larger, because it is the thing being read.
   ========================================================================= */
.qa-tafsir-sheet{
  /*
   * v11.4 — WIDENED AGAIN, ON PURPOSE THIS TIME.
   *
   * "when reading Qur'an and opening tafsir view, the tafsir itself is
   * taking such little space! this should never ever be the case, make
   * sure its the main focus!! and big and beautiful." Fair — 1000px on
   * a 1920px display left more than 900px of the reading page still
   * showing beside it, which reads as a sidebar glancing at the
   * commentary rather than a room to actually read it in.
   *
   * The old comment here reasoned from the READING MEASURE alone — "a
   * 1100px sheet holding a 550px column of text is a waste" — and that
   * logic was sound for the text column, but the sheet is not just the
   * text column: it carries the ayah card, the edition rail and the
   * byline too, and at v11.4's larger type scale (see .qa-tafsir-body
   * below) that whole stack earns real width. 94vw, capped at 1400px so
   * it never becomes the entire screen with nothing to signal "this is
   * a panel, not the page" — is the sheet actually commanding the
   * screen the way "main focus" asks for.
   */
  width: min(1400px, 94vw);
}

/* The ayah: present, quotable, but never more than a glance. */
.qa-tafsir-verse{
  padding: var(--sp-3) var(--sp-5);
  line-height: 2.05;
  max-height: 20vh; overflow-y: auto;
}
.qa-tafsir-nav{ margin-top: var(--sp-2); }
.qa-tafsir-step{ width: 32px; height: 32px; }


.qa-tafsir-note-line{ font-size: var(--fs-2xs); opacity: 0.85; text-align: left; direction: ltr; }

/* THE COMMENTARY — everything above exists to serve this. */
.qa-tafsir-body{
  padding: var(--sp-4) var(--sp-6) var(--sp-6);
  /* overridden live by the A+/A− control */
}

.qa-tafsir-foot{
  padding: 10px var(--sp-6) calc(10px + env(safe-area-inset-bottom));
}

@media (max-width:620px){
  .qa-tafsir-verse{ font-size: 1.16rem; line-height: 1.95; max-height: 17vh; }
  .qa-tafsir-body{ font-size: 1.1rem; line-height: 2.05; padding: var(--sp-3) var(--sp-4) var(--sp-5); }
  .qa-tafsir-foot{ padding-left: var(--sp-4); padding-right: var(--sp-4); }
}

/* -------------------------------------------------------------------------
   3. THE RECITATION BAR

   Wider, calmer, and with the reference where the eye looks first. The
   v9.1 bar put a mono status line above a 3px track and the surah name
   in the same size as everything else; at a glance it was six grey
   controls and no answer to "what am I listening to".
   ------------------------------------------------------------------------- */
.qa-bar{ width: min(880px, calc(100vw - 24px)); }
.qa-bar-inner{
  border-radius: 20px;
  box-shadow: 0 24px 60px -22px rgb(var(--shadow) / 0.55), var(--e-overlay);
}
.qa-bar-main{ padding: 10px 14px; gap: 6px; }
.qa-btn-play{
  width: 48px; height: 48px;
  box-shadow: 0 8px 20px -8px rgb(var(--accent) / 0.7);
}
.qa-bar-ref{
  font-size: var(--fs-base); letter-spacing: -0.01em;
}
.qa-bar-status{ font-size: 0.66rem; opacity: 0.85; }
.qa-bar-track{
  height: 4px; border-radius: 3px;
  background: rgb(var(--ink) / 0.12);
}
.qa-bar-fill{ border-radius: 3px; }

/*
 * THE PLAYER GETS OUT OF THE WAY, rather than everything else climbing
 * over it. v10.2 solved the "recitation bar shows through the mobile
 * menu" problem by raising the overlay and the drawer above the bar's
 * z-index of 110 — which could not work, because both live inside the
 * header's own stacking context (see the note on .overlay), and it
 * blurred the menu instead.
 *
 * `no-scroll` is on <body> whenever the nav drawer or the search panel
 * has the screen, and `theme-sheet-open` whenever the appearance sheet
 * does — both set by assets/main.js. In those states the docked bar
 * simply drops below the header. It keeps playing; it is just not in
 * the way of the thing the reader just opened.
 */
body.no-scroll .qa-bar,
body.theme-sheet-open .qa-bar{
  z-index: 90;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease-soft);
}

@media (max-width:560px){
  .qa-bar-main{ padding: 9px 8px; }
  .qa-btn-play{ width: 44px; height: 44px; }
}

/* -------------------------------------------------------------------------
   4. THE TOPICS INDEX GETS ITS MARKS
   ------------------------------------------------------------------------- */
.lib-row{ align-items: center; gap: var(--sp-3); }
.lib-row-mark{
  flex-shrink: 0; width: 34px; height: 34px;
  border-radius: 50%; overflow: hidden;
  display: grid; place-items: center;
  background: rgb(var(--ink) / 0.04);
}
.lib-row-mark img,
.lib-row-mark .cover-mark{
  width: 100%; height: 100%; object-fit: cover; display: block;
}
@media (max-width:520px){
  .lib-row-mark{ width: 28px; height: 28px; }
}

/* -------------------------------------------------------------------------
   5. THE HOMEPAGE

   Small, deliberate lifts rather than a redesign: everything that was
   there is still there, in the same order. What changes is the weight
   the eye gives each band — the spotlight sits on a warmer ground, the
   two "of the day" cards read as a matched pair rather than two
   unrelated boxes, and the section headings have a rule that ties the
   page together vertically.
   ------------------------------------------------------------------------- */
.section-header{ position: relative; }
.section-header .eyebrow{ display: inline-flex; align-items: center; gap: 8px; }
.section-header .eyebrow::before{
  content: ''; width: 22px; height: 1px;
  background: rgb(var(--wash) / 0.55);
}

.spotlight-solo .featured-card{
  border-radius: var(--radius-lg);
  box-shadow: 0 26px 60px -34px rgb(var(--shadow) / 0.5);
}

/* The two daily cards, matched. */
.hadith-day.is-compact{
  border-radius: var(--radius-lg);
  border: 1px solid rgb(var(--wash) / 0.16);
  background:
    linear-gradient(150deg, rgb(var(--wash) / 0.05), rgb(var(--wash) / 0)) ,
    rgb(var(--surface));
  transition: border-color var(--dur) var(--ease-soft), transform var(--dur) var(--ease-soft);
}
@media (hover: hover){ .hadith-day.is-compact:hover{ border-color: rgb(var(--wash) / 0.32); } }
.hadith-day-head svg{ color: rgb(var(--accent)); }

/* The cover sits behind a soft inner edge rather than flush, which is
   what stops a generated panel reading as a coloured rectangle. */
.featured-cover.has-cover-art::after {
  content: ''; position: absolute; inset: 0;
  box-shadow: inset 0 0 0 1px rgb(var(--ornament) / 0.16);
  border-radius: inherit; pointer-events: none;
}

.topic-tile-inner{ transition: transform var(--dur) var(--ease-soft); }
@media (hover: hover){ .topic-tile:hover .topic-tile-inner{ transform: translateY(-2px); } }

/* -------------------------------------------------------------------------
   6. THE DROPDOWNS

   The footer link is gone from the markup; this reclaims the padding it
   used to sit in so the panel does not end with a gap where it was.
   ------------------------------------------------------------------------- */

@media print{
    /* v12.5 — .adhkar-tabs is gone; the picker and the search that
     replaced it are the two things a printed page least needs. */
  .adhkar-card-count,
.adhkar-card-copy,
.adhkar-tabs,
.adhkar-reset { display: none !important; }
}


/* =========================================================================
   v11.5 — THE v10.1 TAFSĪR ROOM'S STYLESHEET IS GONE FROM HERE.

   Four hundred lines describing a page that stopped existing in v11.3,
   left in place and still winning cascade fights against the page that
   replaced it. Every one of these was a live, visible fault on
   /tafsir/{book}/{surah}/{ayah}/ :

     · `.tafsir-body{max-width:74ch}` with no `margin-inline:auto`.
       The live rule further down sets no max-width, so this one
       survived — and because its parent `.tafsir-text` is a wide,
       centred column, the commentary sat hard against its LEFT edge.
       Reported as "the text in tafsir is not centered! its on left
       now", and it was exactly that: one missing `auto`.
     · `.tafsir-tool{width:30px;height:30px}` — the live rule sets
       padding and min-height but no width, so the four buttons under
       the ayah were clamped to 30px squares with "Read in the muṣḥaf"
       spilling out over its neighbours. Reported as "so much text from
       the options is not properly in place!! like copy etc".
     · `.tafsir-panel{padding;border;background}` — written for a
       sidebar card, and `.tafsir-panel` is also the modifier on the
       Tafsīr NAV DROPDOWN, so that dropdown alone among the five had
       different padding from every other menu in the header.
     · `.tafsir-jump{position:fixed;inset:0;display:grid}` and
       `.tafsir-jump-close{position:absolute;top:12px;right:12px}` —
       both fighting the live sheet's own geometry.
     · `.tafsir-room{padding-block:…}` against the live `display:block`.

   Checked before deleting: every class defined in the removed block is
   either absent from the shipped markup, or has its real definition in
   "THE READING ROOM" further down this file. tools/verify.py now
   asserts that none of these selectors comes back.
   ========================================================================= */


/* =========================================================================
   v10.1 — THE TAFSĪR BUTTON IN THE READER

   The reason the page above had to exist is here: the ayah actions were
   `opacity:0` until `:hover` or `:focus-within`, and a touch screen has
   neither. On a phone — which is most readers — the commentary button was
   invisible, and so was copy, and so was save. They were not hidden by
   choice; they were hidden by a rule written for a mouse.

   On anything without hover the actions are simply always visible, and
   the tafsīr button carries a word as well as a glyph so it says what it
   opens.
   ========================================================================= */
@media (hover: none){
  /* 32px is fine for a mouse pointer; a thumb needs more, and this row
     is always-on on a touch screen rather than a hover reveal, so it's
     the one place the smaller size was actually being tapped daily. */
  .quran-ayah-action{ width:40px; height:40px; }
  .qa-tafsir-tool{ min-height:40px; padding:0 12px; }
}
.quran-ayah-tafsir{
  /* The only action on the row that carries a word, so it is the only one
     that is not a circle — width:auto on a 50% radius would make an
     ellipse, which reads as a mistake. */
  width:auto; padding:0 12px; gap:6px; border-radius: var(--radius-pill);
  border-color: rgb(var(--wash) / 0.4); color: rgb(var(--accent-ui));
}
.quran-ayah-tafsir .quran-ayah-action-text{
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight:600;
  letter-spacing:0.01em;
}

/* The sheet's footer now carries two things — the editor's-notes switch
   and the way through to the full page — so it becomes a row. */
.qa-tafsir-foot{
  flex-wrap:wrap;
}
.qa-tafsir-room{
  display:inline-flex; align-items:center; gap:6px;
  font-size: var(--fs-2xs); font-weight:600;
  color: rgb(var(--accent-ui));
  padding: 7px 13px; border-radius: var(--radius-pill);
  border:1px solid rgb(var(--wash) / 0.35);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
@media (hover: hover){
  .qa-tafsir-room:hover{ background: rgb(var(--accent)); color: rgb(var(--on-accent)); border-color: rgb(var(--accent)); }
}
.qa-tafsir-room svg{ width:13px; height:13px; }

/* The card on the fihrist that says the tafsīr room exists. Without an
   entry somewhere on the Qur'an's own front page, a reader would have to
   already know the URL — which is not discovery, it is a secret. */
.quran-tafsir-card{
  display:flex; align-items:center; gap: var(--sp-5); flex-wrap:wrap;
  padding: var(--sp-6);
  border-radius: var(--radius-lg);
  border:1px solid rgb(var(--wash) / 0.24);
  background:
    radial-gradient(110% 160% at 12% 0%, rgb(var(--wash) / 0.12), transparent 62%),
    rgb(var(--surface));
  box-shadow: var(--e1);
}
.quran-tafsir-card-ic{
  flex:0 0 auto; width:54px; height:54px; border-radius: var(--radius);
  display:grid; place-items:center;
  background: rgb(var(--wash) / 0.16); color: rgb(var(--accent-ui));
}
.quran-tafsir-card-ic svg{ width:24px; height:24px; }
.quran-tafsir-card-text{ flex:1 1 260px; min-width:0; }
.quran-tafsir-card-text h3{
  font-size: var(--fs-lg); margin:0 0 4px; color: rgb(var(--heading));
}
.quran-tafsir-card-text h3 span[lang="ar"]{
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size:1.1em; margin-inline-start:8px;
  color: rgb(var(--accent-ui));
}
.quran-tafsir-card-text p{
  margin:0; font-size: var(--fs-sm); line-height:1.6; color: rgb(var(--text-muted));
  max-width: 62ch;
}
.quran-tafsir-card .btn{ flex:0 0 auto; }
@media (max-width: 560px){
  .quran-tafsir-card{ padding: var(--sp-5); gap: var(--sp-4); }
  .quran-tafsir-card .btn{ width:100%; justify-content:center; }
}


/* =========================================================================
   v10.1 — THE QIBLA PAGE SAYS HOW MUCH IT CAN BE TRUSTED

   Everything here exists because of one reported fault: the page did not
   ask for calibration and did not show accuracy, so a reader could face
   the wrong way with a confident-looking number in front of them.

   The cause was structural rather than cosmetic — the whole status
   apparatus was hidden until the live compass was running, and the live
   compass only ran if somebody found and pressed a line of grey text.
   See page-qibla.php and assets/qibla.js for the behaviour; this is what
   the new pieces look like.
   ========================================================================= */

/* The figure — "±14°" — beside the label. It used to live only in a
   `title` attribute, which is a tooltip, which a phone does not have. */
.qibla-accuracy-fig{
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  padding: 2px 7px; border-radius: var(--radius-pill);
  background: rgb(var(--heading) / 0.07); color: rgb(var(--text-muted));
  letter-spacing: 0.02em; white-space: nowrap;
}
.qibla-accuracy[data-level="good"] .qibla-accuracy-fig{ background: rgb(47 158 107 / 0.14); color:#2f9e6b; }
.qibla-accuracy[data-level="fair"] .qibla-accuracy-fig{ background: rgb(215 154 43 / 0.16); color:#b57d18; }
.qibla-accuracy[data-level="poor"] .qibla-accuracy-fig{ background: rgb(207 90 74 / 0.15); color:#cf5a4a; }

/* "Live compass off" is a real state, not an error: the bearing beside it
   is exact, and only the dial's ability to follow you is missing. It is
   drawn quietly so it does not read as a warning. */
.qibla-accuracy[data-level="off"] .qibla-accuracy-text{ color: rgb(var(--text-muted)); }
.qibla-accuracy[data-level="off"] .qibla-accuracy-bars span{ background: rgb(var(--heading) / 0.14); }

/* The sentence under the meter. Only rendered when there is something to
   warn about, so it can never become wallpaper. */
.qibla-trust-warning{
  width: min(420px, 92%); margin: var(--sp-3) auto 0;
  padding: 10px 13px; border-radius: var(--radius);
  background: rgb(207 90 74 / 0.09);
  border: 1px solid rgb(207 90 74 / 0.3);
  color: rgb(var(--heading-soft));
  font-size: var(--fs-2xs); line-height: 1.55; text-align: left;
}
.qibla-accuracy[data-level="fair"] ~ .qibla-trust-warning,
.qibla-cal[data-state="calibrate"] + .qibla-trust-warning{
  background: rgb(215 154 43 / 0.1); border-color: rgb(215 154 43 / 0.32);
}

/* The state that says the sensor is not on yet. Quiet, and without the
   figure-of-eight, because there is nothing to calibrate until it is. */
.qibla-cal[data-state="off"]{
  color: rgb(var(--text-muted));
  border-style: dashed;
}
.qibla-cal[data-state="off"] .qibla-cal-text strong{ color: rgb(var(--heading-soft)); }
.qibla-cal[data-state="off"] .qibla-cal-path{ opacity: 0.12; }
.qibla-cal[data-state="off"] .qibla-cal-meter{ opacity: 0.4; }

/* ---- Turning the compass on: a button, not a footnote ------------------
   The old control was `.qibla-compass-link`, set as small grey text under
   the camera card. On Android and desktop the compass now starts by
   itself and this is hidden within a frame; it matters on iOS, where the
   permission prompt can only be raised from inside a tap. So it is
   written for that reader, and it looks like something you press. */
.qibla-compass-cta{
  display: flex; align-items: center; gap: var(--sp-3);
  /* The mode row is a centred column with a full-width camera card in
     it; matching that width is what stops this reading as a stray
     control floating under it. */
  width: 100%; max-width: 100%; text-align: left; cursor: pointer;
  padding: 12px 16px; border-radius: var(--radius);
  border: 1px solid rgb(var(--wash) / 0.3);
  background: rgb(var(--wash) / 0.06);
  color: rgb(var(--heading));
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
@media (hover: hover){ .qibla-compass-cta:hover{ background: rgb(var(--wash) / 0.12); border-color: rgb(var(--wash) / 0.5); } }
.qibla-compass-cta-ic{
  flex: 0 0 auto; width: 38px; height: 38px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgb(var(--wash) / 0.16); color: rgb(var(--accent-ui));
}
.qibla-compass-cta-ic svg{ width: 18px; height: 18px; }
.qibla-compass-cta-text{ display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.qibla-compass-cta-title{ font-size: var(--fs-sm); font-weight: 600; line-height: 1.25; }
.qibla-compass-cta-sub{
  font-size: var(--fs-2xs); color: rgb(var(--text-muted)); line-height: 1.4;
}

/* Live-compass accuracy over the camera view, where the background is a
   photograph and a translucent chip is the only thing that stays legible. */
.qibla-accuracy-oncam .qibla-accuracy-fig{
  background: rgb(0 0 0 / 0.4); color: #fff;
}

@media print{
  .qibla-trust-warning, .qibla-compass-cta{ display: none !important; }
}


/* =========================================================================
   v10.1 — THE ADHKĀR PAGE, REBUILT

   The v10.0 page was five flat lists of identical cards. This adds the
   three things it needed to become usable at a hundred and twenty
   entries: groups with headings, a rail that jumps between them, and a
   search box. It also fixes how the Qur'an was set, which is the fault
   that mattered most.
   ========================================================================= */

/* ---- The hero ayah, set from the muṣḥaf --------------------------------
   It used to carry `.quran-text`, which brought the block ornament, the
   bordered box and the centred layout with it — none of which belongs in
   a hero — and set the text in Amiri Quran, which cannot render the
   glyph-encoded Uthmani the bundled data holds. It is now the Hafs face
   and nothing else. */
.adhkar-hero-ayah{
  font-family: var(--font-quran-glyphs);
  direction: rtl; unicode-bidi: isolate;
}

/* ---- The tab strip gains a count --------------------------------------- */
.adhkar-tab-n{
  top: 6px; left: 8px;
}

/* ---- Search ------------------------------------------------------------ */


#adhkarSearch{
  flex: 1 1 auto; min-width: 0; height: 46px;
  border: none; background: none; outline: none;
  font-family: var(--font-ui); font-size: var(--fs-sm); color: rgb(var(--heading));
}
#adhkarSearch::-webkit-search-cancel-button{ display: none; }


/* While filtering, the tab strip is describing sets the reader is not
   looking at, so it steps back rather than competing. */
.adhkar-app.is-searching .adhkar-tabs{ opacity: 0.55; }

/* ---- The panel head ---------------------------------------------------- */
.adhkar-panel-when{
  margin-bottom: 8px;
}

/* A set nobody "finishes" gets no progress bar — see the note on
   pp_adhkar_set_is_tracked(). */
.adhkar-panel.is-untracked .adhkar-panel-head{ align-items: flex-start; }

.adhkar-panel-empty{
  margin: var(--sp-6) 0 0; padding: var(--sp-5);
  border-radius: var(--radius); border: 1px dashed var(--hairline-strong);
  text-align: center; font-size: var(--fs-sm); color: rgb(var(--text-muted));
}


/* ---- The card ---------------------------------------------------------- */
/* v10.1 moved the card title from h3 to h4, because the group heading
   above it is now the h3. Both are matched so the rule survives either. */
.adhkar-card-head h3,
.adhkar-card-head h4{
  margin: 0; flex: 1; font-size: var(--fs-sm); font-weight: 600;
  color: rgb(var(--heading-soft));
}
.adhkar-card-tag{
  font-family: var(--font-mono); font-size: 0.55rem;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--accent-ui)); background: rgb(var(--wash) / 0.12);
  padding: 3px 8px; border-radius: var(--radius-pill);
}
.adhkar-card.is-quran{
  border-color: rgb(var(--wash) / 0.28);
  background:
    radial-gradient(120% 150% at 90% -10%, rgb(var(--wash) / 0.07), transparent 58%),
    rgb(var(--surface));
}

/* ---- An ayah inside a card ---------------------------------------------
   THE FAULT THIS FIXES.

   Through v10.0 an ayah here was a hand-typed Unicode string in a naskh
   face with a paraphrase under it. It is now the pre-composed Uthmani
   text from data/quran/, set in the bundled KFGQPC Hafs face — which is
   the only text that face can render — with the Ṣaḥīḥ International
   translation the rest of the site uses.

   Each ayah is its own block with its own reference, so a card carrying
   three surahs reads as three surahs rather than as one long line. */
.adhkar-card-ayat{
  display: flex; flex-direction: column; gap: var(--sp-4);
  margin: 0 0 var(--sp-4);
}
.adhkar-ayah{
  padding: var(--sp-4) var(--sp-5);
  border-radius: var(--radius);
  background: rgb(var(--wash) / 0.05);
  border: 1px solid rgb(var(--wash) / 0.16);
}
.adhkar-ayah + .adhkar-ayah{ margin-top: 0; }
.adhkar-ayah-ar{
  margin: 0 0 var(--sp-3);
  font-family: var(--font-quran-glyphs);
  direction: rtl; text-align: right; unicode-bidi: isolate;
  color: rgb(var(--heading));
  transition: opacity var(--dur) var(--ease-soft);
}
.adhkar-ayah-en{
  margin: 0; color: rgb(var(--text));
}
.adhkar-ayah-ref{
  font-family: var(--font-mono); font-size: 0.62rem;
  color: rgb(var(--accent-ui)); white-space: nowrap;
  padding: 1px 6px; border-radius: var(--radius-pill);
  background: rgb(var(--wash) / 0.1);
  margin-inline-start: 4px;
}
@media (hover: hover){ .adhkar-ayah-ref:hover{ background: rgb(var(--accent)); color: rgb(var(--on-accent)); } }
.adhkar-card.is-done .adhkar-ayah-ar{ opacity: 0.6; }

/* =========================================================================
   v12.0 — TOUCH TARGETS ON THE ADHKĀR PAGE

   Measured on a real 375px render, not by eye. Every control below was
   under the 44x44 minimum that both Apple's and Google's guidelines set,
   on a page whose whole purpose is repeated tapping:

     .adhkar-reset        105 x 34
     .adhkar-card-copy     29 x 34
     .adhkar-ayah-ref     107 x 15      (the worst — a 15px-tall link)

   The visual size of each is left alone; what changes is the TAP AREA,
   grown with padding where that costs nothing and with a transparent
   ::after overlay where growing the box would break the layout. That way
   nothing on the page looks different and everything is reachable.

   Pointer-coarse only, so the desktop density is untouched.
   ========================================================================= */
@media (pointer: coarse){
  /* Scoped through the page shell so it beats the SECOND .adhkar-reset
     block further down this file, which sets min-height:34px and would
     otherwise win on source order alone. */
  #adhkarApp .adhkar-reset,
  .adhkar-shell .adhkar-reset,
  button.adhkar-reset{ min-height: 44px; }
  .adhkar-card-copy{ width: 44px; height: 44px; }

  /* This one is inline inside a line of Arabic, so it cannot simply grow
     — a 44px-tall inline box would space the ayat apart. The hit area is
     extended instead, which is invisible and does not affect line box
     height. */
  .adhkar-ayah-ref{ position: relative; }
  .adhkar-ayah-ref::after{
    content: '';
    position: absolute; left: 0; right: 0;
    top: 50%; transform: translateY(-50%);
    height: 44px; min-width: 44px;
  }

  /* The appearance sheet's close button, same problem. */
  .theme-panel-close{ width: 44px; height: 44px; }
}

.adhkar-ic-check{ display: none; }
.adhkar-card-copy.is-copied .adhkar-ic-copy{ display: none; }
.adhkar-card-copy.is-copied .adhkar-ic-check{ display: block; }

@media (max-width: 620px){
  .adhkar-ayah{ padding: var(--sp-3) var(--sp-4); }
}

@media print{
  .adhkar-panel-empty { display: none !important; }
  /* On paper every set is worth having, not only the one that happened
     to be open. */
  .adhkar-panel[hidden]{ display: block !important; }
  .adhkar-card{ break-inside: avoid; box-shadow: none; }
}


/* =========================================================================
   v10.1 — THE ORNATE BRACKETS SIT ON THE LINE

   Reported as "the brackets in Ayat are in different lines", and it was
   literal: `.quran-text::before` and `::after` were `display:block`, so
   the opening ﴿ was a line of its own above the ayah and the closing ﴾ a
   line of its own below it. An ayah in a post was three lines, two of
   them a single punctuation mark.

   They are inline now, on the same line as the text they enclose, with a
   little space so they do not touch the first and last letters. This is
   the site-wide Qur'an-verse block style, so it applies to every ayah in
   every post as well as to the ones on this page.
   ========================================================================= */
.quran-text::before,
.is-style-quran-verse::before,
.quran-text::after,
.is-style-quran-verse::after{
  display: inline;
  font-size: 0.78em;
  vertical-align: baseline;
  margin: 0;
  opacity: 0.75;
}
.quran-text::before,
.is-style-quran-verse::before{ margin-inline-end: 0.28em; }
.quran-text::after,
.is-style-quran-verse::after{ margin-inline-start: 0.28em; }

/* =========================================================================
   =========================================================================
   v11.2
   =========================================================================
   ========================================================================= */


/* =========================================================================
   1. MENUS ARE OPAQUE. ALL OF THEM.

   THE BUG: "look at the extra text coming out of some of these drop down
   menus". It was reported as a glitch in the menus and it is a glitch in
   one number.

   Every floating surface on this site was painted with

       --glass-bg-strong: rgb(var(--surface) / 0.88)

   — twelve per cent transparent, with a 20px backdrop blur behind it.
   That is a beautiful treatment for a BAR that sits over a scrolling
   page, which is what it was designed for. It is the wrong treatment for
   a MENU, because a menu is a list of words and the page behind it is
   also a list of words, and twelve per cent of a 48px headline in a
   high-contrast palette is legible. The blur smears it rather than
   hiding it, so what the reader sees is ghost text drifting inside the
   panel: page content that appears to be part of the menu.

   It got worse in exactly the situations where a menu matters most —
   over the 404 page's large display type, over a post title, over the
   Qur'an's Uthmani text — and it was invisible over plain body copy,
   which is why it read as intermittent.

   THE RULE, from here on: a surface you can SCROLL CONTENT UNDER may be
   translucent. A surface that CONTAINS ITS OWN CONTENT must be opaque.
   The site header keeps its frost. Every menu, panel, popover, sheet and
   floating bar below is now solid, and the blur is kept only as the
   decorative edge treatment it should always have been.
   ========================================================================= */

:root{
  /* Fully opaque. Nothing behind a menu is ever visible through it. */
  --menu-bg: rgb(var(--surface));
  /* The depth the translucency used to provide, done with light instead:
     a barely-there vertical sheen that reads as a lifted surface without
     letting a single pixel of the page through. */
  --menu-sheen: linear-gradient(
    180deg,
    rgb(var(--wash) / 0.055) 0%,
    rgb(var(--wash) / 0.012) 42%,
    rgb(var(--wash) / 0) 100%
  );
  --menu-border: var(--glass-border);
}

/* The dropdown panels. */
/* The pointer joining a panel to its trigger. It sits ON the page rather
   than on the panel, so it needs the flat colour with no sheen or the
   gradient's top stop shows as a seam. */

/* Search and theme popovers, the mobile drawer, the picker sheet and its
   sticky headings, the tasbih popover, the Qur'an audio bar. Everything
   that opens over the page. */
.theme-panel,
.pp-picker-sheet,
.pp-tasbih-pop,
.qa-bar-inner{
  background-color: var(--menu-bg);
  background-image: var(--menu-sheen);
}
/*
 * v11.5 — the drawer only.
 *
 * `.site-header .main-nav.main-nav` used to sit in the list above,
 * unqualified. The nav is a floating surface ONLY below 1180px; above
 * it, it is seven inline items in the middle of the bar — and this rule
 * was painting an opaque, slightly lighter rectangle behind them at
 * every width. Visible in a screenshot as a pale band running from
 * "Home" to "About", and part of what "the header... is messy" was
 * pointing at.
 */
.pp-picker-group-label{
  background-color: var(--menu-bg);
  background-image: none;
}

/* The tafsīr sheet on a Qur'an page is a reading surface with an
   ~800-word commentary in it. Anything showing through it is text over
   text. */
.qa-tafsir-sheet{
  background-color: var(--menu-bg);
}

/* =========================================================================
   2. A DROPDOWN THAT OPENS ON HOVER MUST NOT OPEN ON TOUCH

   `.has-dropdown:hover .mega-panel` was unguarded. On a touch screen the
   first tap on a nav link fires a synthetic hover that STICKS until you
   tap elsewhere, so tapping "Qur'an" opened the panel over the page
   instead of following the link, and the panel then stayed open on the
   page you eventually got to. Anything below 1180px is the drawer, but
   tablets and touch laptops in the desktop layout were squarely in it.

   Hover-to-open now requires a device that genuinely hovers. Everything
   else uses the caret button, which always worked.
   ========================================================================= */

/* =========================================================================
   3. THE TAFSĪR AND ADHKĀR PANELS — v11.2

   Both were plain links in a nav where everything either side of them
   opened a panel. That is not only an inconsistency to look at: a bare
   link asks the reader to already know what is behind it, and "Tafsīr"
   is precisely the word a reader is least likely to already know.
   ========================================================================= */

/* v11.5 — `.hadith-menu-ar` (the adhkār set name at the trailing edge of
   a row) is gone from the markup: it clipped mid-word on half the sets.
   See the note in header.php; the name is on the second line now. */

/* "now" — the set whose window is open at this hour. */

/* ---- The edition chips --------------------------------------------------
   Twenty commentaries is the right number to OFFER and the wrong number
   to list in a dropdown. Six chips say "here is the range of what is
   here" in one row, and every one is a real link that opens that book. */
/* Both new panels carry six two-line rows plus a head, which is the same
   shape the Qur'an panel already proved at this width. */

/* In the drawer everything is one column and the chips wrap freely. */

/* =========================================================================
   4. THE CLOCK — v12.2

   Replaces the day's arc, which replaced the countdown ring. See the long
   note in page-prayer-times.php for why: the arc drew, in the abstract,
   the same five numbers the grid immediately below it gives by name.

   What a person opens this page for is the time now and how long until
   the next prayer, so those are the two things in the panel and the only
   two. Everything here is set in tabular figures — a countdown whose
   digits change width shudders once a second.
   ========================================================================= */
.prayer-now{
  text-align: center;
  margin: 0 auto var(--sp-6);
  max-width: 560px;
}

/* ---- The clock ---- */
.prayer-clock{
  display: flex;
}
.prayer-clock-label{
  font-family: var(--font-mono);
  font-size: 0.62rem; text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.prayer-clock-time{
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}
.prayer-clock-place{
  font-family: var(--font-ui);
  font-size: var(--fs-2xs);
  color: rgb(var(--text-muted));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* The gold rule the rest of the site uses to separate two thoughts
   inside one panel. */
.prayer-now-rule{
  width: 96px; height: 1px;
  margin: 0 auto var(--sp-5);
  background: linear-gradient(90deg, transparent, rgb(var(--ornament) / 0.6), transparent);
}

/* ---- The next prayer ---- */
.prayer-now-head{
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.prayer-now-label{
  font-family: var(--font-mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  color: rgb(var(--accent-ui));
}
.prayer-now-names{
  display: flex; flex-direction: column; align-items: center; gap: 0;
}
/* The Arabic leads: it is the name of the prayer, and it is the line a
   reader recognises fastest. */
.prayer-now-ar{
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  color: rgb(var(--heading));
}
.prayer-now-name{
  font-family: var(--font-ui);
  font-size: var(--fs-sm); font-weight: 600;
  letter-spacing: 0.02em;
  color: rgb(var(--heading-soft));
}

.prayer-now-countdown{
  margin: var(--sp-3) 0 0;
  display: flex; align-items: baseline; justify-content: center; gap: 2px;
}
.prayer-now-countdown .pc-num{ font-variant-numeric: tabular-nums; }
.prayer-now-countdown .pc-unit{
  font-family: var(--font-ui);
  margin-inline-end: 0.32em;
  transform: translateY(-0.1em);
}
.prayer-now-countdown .pc-sec{
  margin-inline-start: 0.2em;
  transform: translateY(-0.15em);
}
.prayer-now-at{
  margin: var(--sp-3) 0 0;
  letter-spacing: var(--track-caps);
}

@media (max-width: 600px){
  .prayer-now{ margin-bottom: var(--sp-5); }
  .prayer-clock{ margin-bottom: var(--sp-4); }
  .prayer-now-rule{ margin-bottom: var(--sp-4); }
  .prayer-now-countdown{ font-size: clamp(2.2rem, 1.2rem + 7vw, 3rem); }
}

/* =========================================================================
   5. THE FRONTISPIECE, QUIETER — v11.2

   Reported as "this is way too big on home page" with the mark called
   out by name. Both were true and they were the same fault: the panel
   had been given a badge, a rule, an ayah, a translation, a citation,
   a second rule, a paragraph, two buttons, a note and three counters,
   each at a size chosen without the others in view. It filled a 1024px
   screen entirely before a single post was visible.

   The mark is gone from the markup. The rest is not deleted — every
   element in it earns its place — it is set at a size that lets the
   page below it exist.
   ========================================================================= */

.hero.hero h1{ font-size: clamp(2rem, 1.4rem + 2.6vw, 3rem); }

/* The ayah is the heart of the panel, so it keeps its size — but the
   rules above and below it close in, which is what makes it read as a
   quotation set into the page rather than another block of hero. */
.hero-rule{ width: 84px; }
.hero-ayah-en{ line-height: 1.6; }


/* The counters are archive facts, not an invitation. They sit on the
   panel's own hairline now, which turns three floating numbers into a
   footer — and stops them competing with the buttons above. */
.hero-stats{
  border-top: 1px solid var(--hairline);
  gap: 26px;
  opacity: 0.85;
}
.hero-stat-num{ font-size: clamp(1.05rem, 0.9rem + 0.5vw, 1.3rem); }
.hero-stat-label{ font-size: 0.6rem; }
.hero-stat-divider{ height: 24px; }

/* The watermarks were sized for the old, much taller panel and bled
   across the text at the new height. */
.hero .corner{ width: 38px; height: 38px; }

@media (max-width: 760px){
  .hero{ padding: 26px 0 18px; }
  .hero-frame.hero-frame{ padding: 30px 20px 26px !important; }
  .hero-stats{ margin-top: 20px; padding-top: 14px; gap: 0; }
}

/* =========================================================================
   6. PHONES — v11.2

   Audited at 375×812 across the front page, the tafsīr room, a surah, the
   adhkār, the prayer times, the hadith index and the topics page. Nothing
   below is a precaution; each rule is one measured failure.

   The good news first, because it shapes what follows: not one page
   scrolls horizontally. document.scrollWidth equals the viewport on all
   seven. The edition strip in the tafsīr room and the tab strip on the
   adhkār page do overflow their own boxes, and both are supposed to —
   they are `overflow-x:auto` rails, and they scroll correctly.

   What was actually wrong was touch.
   ========================================================================= */

/* ---- 6a. THE WORDMARK CAME BACK ----------------------------------------
   Two rules were fighting, and the wrong one was winning.

   A block at `max-width:353px` hides the wordmark and leaves the mark
   alone, with a comment showing its work: the row needs 354px, so at
   360px and at 375px the name fits and below that it would ellipsise.
   That reasoning is right.

   Five thousand lines later a second block did the same thing at
   `max-width:400px`. Same specificity, later in the file, so it won —
   and the measured breakpoint had been dead ever since. The result: on
   every phone narrower than 400px, which is most phones, the site's name
   was simply absent from the header and a 30px roundel stood in for it.

   The duplicate is deleted below rather than left to be re-discovered. */

/* ---- 6b. THE LOGO IS A BUTTON, AND BUTTONS ARE 44px --------------------
   The header's "go home" affordance measured 30×30 on a phone. It is the
   single most-tapped control on the site and it was the smallest.

   Height comes from the header row, which is tall enough; the mark is
   left at its drawn size and the anchor is given the target. */

/* ---- 6c. 44px HIT AREAS, WITHOUT REDRAWING ANYTHING --------------------
   These controls are all correctly sized as GRAPHICS — a 30px A− button
   in a toolbar is right, and inflating it to 44px would turn a neat row
   of tools into a row of slabs. What was wrong is that the graphic and
   the target were the same rectangle.

   So the target is separated from the graphic: a transparent ::after,
   centred on the control, expanded to 44×44. Nothing moves, nothing
   changes size, and every one of them can be hit with a thumb.

   `position:relative` is asserted on each host so the pseudo-element has
   something to be absolute against, and z-index is left alone so these
   never cover a neighbouring control's own label. */
@media (max-width: 1180px){
  .tafsir-tool,
.qa-tafsir-tool,
.adhkar-card-copy,
.adhkar-card-count,
.adhkar-reset,
.quran-surah-nav-btn,
.adhkar-card-ref,
.hadith-day-link {
    position: relative;
  }
  .tafsir-tool::after,
.qa-tafsir-tool::after,
.adhkar-card-copy::after,
.adhkar-card-count::after,
.adhkar-reset::after,
.quran-surah-nav-btn::after,
.adhkar-card-ref::after,
.hadith-day-link::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: max(100%, 44px);
    height: max(100%, 44px);
    transform: translate(-50%, -50%);
    /* Invisible, and never in front of the control's own contents. */
    background: transparent;
    pointer-events: auto;
  }
  /* A few of these already draw something on ::after. Where that is the
     case the rule above would have replaced it, so they opt out and get
     their target from real padding instead. */
  .adhkar-card-count::after{ content: none; }
  .adhkar-card-count{ min-width: 44px; min-height: 44px; }
}

/* ---- 6d. THE TAFSĪR ROOM ON A PHONE -----------------------------------
   v11.5 — every selector this block styled (`.tafsir-ayah-actions`,
   `.tafsir-act`, `.tafsir-editions-bar`, `.tafsir-compare-btn`,
   `.tafsir-editions`, `.tafsir-edition`) belonged to the v10.1 room and
   has not been in the markup since v11.3. The room's own action row is
   `.tafsir-ayah-tools` / `.tafsir-tool`, which is laid out for a phone
   where it is defined. tools/verify.py now fails if any of these come
   back, because the last four hundred lines of them spent two releases
   quietly overriding the page that replaced them. */
@media (max-width: 620px){
  .tafsir-ayah-tools{ gap: 8px; }
  .tafsir-ayah-tools .tafsir-tool{ flex: 1 1 auto; justify-content: center; min-height: 42px; }
}

/* ---- 6e. THE ADHKĀR TAB RAIL ------------------------------------------
   v12.2 — REMOVED. The rail does not exist below 760px any more; the
   sheet replaced it (see "THE ADHKĀR SET PICKER" later in this file).
   These rules were still adding scroll-snap and 18px of trailing padding
   to a `display:none` element, which is harmless and misleading, and the
   next person to read them would have concluded the rail was still the
   phone control. */

/* ---- 6f. THE DRAWER'S OWN PANELS --------------------------------------
   The two new panels are accordions in the drawer, like the other three.
   The chips row needs room to breathe there and the Arabic set names are
   dropped, both because the drawer is 297px wide. */


/* The tafsīr sheet's failure state — v11.2. It used to be a dead end:
   one line of text and no way to ask again short of closing the sheet,
   finding the row and reopening it. */
.qa-tafsir-fail{
  display: flex; flex-direction: column; align-items: center;
  gap: var(--sp-3); padding: var(--sp-6) var(--sp-4); text-align: center;
}
.qa-tafsir-retry{
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 600;
  color: rgb(var(--on-accent)); background: rgb(var(--accent));
  border: none; border-radius: 999px; padding: 10px 20px; min-height: 40px;
  transition: filter var(--dur-fast) var(--ease-soft), transform var(--dur) var(--spring);
}
@media (hover: hover){ .qa-tafsir-retry:hover{ filter: brightness(1.06); transform: translateY(-1px); } }

/* ---- The frontispiece, second pass — v11.2 ------------------------------
   The first pass took the panel from filling a 1024px screen to 744px,
   which was better and still not right: nothing of the writing below
   showed at all on a laptop. Measured element by element, the height was
   not in any one thing being large — it was in a 48px heading set at
   line-height 1.6, an ayah and a paragraph each running one line longer
   than they needed to, and eleven gaps chosen independently.

   So: the display heading gets display leading, the two measures widen
   enough to lose a line each, and the rhythm is tightened once,
   consistently, rather than eleven times. Nothing is removed and nothing
   is shrunk to the point of looking timid. */
.hero-frame.hero-frame{ padding: 34px 36px 30px; }
.hero.hero h1{ line-height: 1.06; }
.hero-ayah{
  margin-bottom: 7px;
}
.hero-stats{ margin-top: 20px; padding-top: 15px; }

@media (max-width: 760px){
  .hero-ayah{ max-width: 30ch; }
  .hero p.desc{ max-width: 42ch; }
}

/* On a phone the panel is narrower, so every measure runs longer and the
   same content stacks taller than it does on a laptop. Trimmed to match. */
@media (max-width: 480px){
  .hero-frame.hero-frame{ padding: 26px 18px 24px !important; }
  .hero.hero h1{ font-size: clamp(1.75rem, 1.2rem + 3.4vw, 2.2rem); }
  .hero .sub{ margin-top: 7px; }
  .hero-rule{ margin: 11px auto; width: 72px; }
  .hero-ayah{ font-size: 1.16rem; line-height: 1.85; }
  .hero-ayah-en{ font-size: 0.82rem; }
  .hero p.desc{ margin-top: 12px; font-size: 0.92rem; }
  .hero-ctas{ margin-top: 16px; }
  .hero-stats{ margin-top: 16px; padding-top: 13px; }
}

/* =========================================================================
   =========================================================================
   v11.3
   =========================================================================
   ========================================================================= */


/* =========================================================================
   1. NO TEXT LEAVES A MENU. EVER.

   Reported again after v11.2: "there is still flowing text outside the
   box in the dropdown menu". v11.2 made every panel opaque, which fixed
   text showing THROUGH a menu. This is the other one — text running out
   PAST the right edge of a menu row.

   Measured rather than guessed: `.hadith-menu-count` in the Qur'an
   panel's tafsīr row wanted 252px inside a 200px grid cell, and the rule
   was

       .hadith-menu-count{ … white-space: nowrap; }

   nowrap with no overflow handling and no min-width:0 on the flex chain
   above it, so the text simply kept going. The row it happened to be in
   is now full-width and its label shorter, but that only fixes today's
   string. This fixes the class of bug: every menu row is a flex chain
   that can shrink, and any label too long for its box is cut with an
   ellipsis instead of escaping.
   ========================================================================= */


/* The count/description line stays one line — two lines of 10px mono in
   a nav row reads as a paragraph — but it is now a line that ENDS. */
/* Titles may wrap to two, which is what stops a long book name being
   truncated when there is room for it below. */

/* =========================================================================
   v11.5 — THE TWO MENUS THAT WERE NOT WORKING

   ── The Qur'an panel's Arabic gutter ────────────────────────────────
   `min-width:56px` with no maximum, so the column was as wide as the
   longest name in it and every English title started at a different
   place depending on which six surahs the panel happens to list. A
   fixed 64px box, right-aligned to the text it belongs to, makes the
   six rows one grid instead of six independent ones.

   ── The panel's quiet foot ──────────────────────────────────────────
   Where the tafsīr link went. Deliberately in the register of a
   footnote: same size as the head's "See all", one line, no icon well,
   an arrow that only appears on hover.

   ── The tafsīr panel's rows ─────────────────────────────────────────
   The Arabic gutter is gone from these entirely (see header.php); what
   is left is a name and one muted line under it holding the Arabic
   title and the shelf it comes from.
   ========================================================================= */
/*
 * v11.5 — PHYSICAL `right`, NOT LOGICAL `end`.
 *
 * These boxes hold Arabic and therefore carry `direction:rtl`, and a
 * logical property resolves against the ELEMENT's own direction — so
 * `text-align:end` on an RTL element means the LEFT edge. Measured: the
 * Qur'an panel's gutter is 64px wide and its text sat at the left of it,
 * nineteen pixels away from the English title it belongs to; the
 * chooser's was a hundred pixels away. Both wanted the right edge, which
 * in a right-to-left run is `start` — and saying `right` is clearer than
 * saying `start` and hoping the next reader works out why.
 */


/*
 * The prose second line in the Qur'an panel ("Friday reading", "The
 * heart of the Qur'an") is a sentence, not a measurement, and the mono
 * face this class carries is for measurements. Counts elsewhere —
 * "1,896 hadiths", "23 adhkār" — keep it.
 */

/* =========================================================================
   2. THE HEADER FITS INSIDE ITSELF

   "things arent centered properly and subscribe is almost hidden".
   Both were one fault, and it was measurable: at 1440px the bar's own
   container is 1220px wide and its three children — logo 276, nav 548,
   actions 494, plus 36px of gaps — need 1354. The row overflowed its
   box by 134px, `overflow-x: clip` on the root swallowed the difference,
   and what got cut off was the right-hand end: Subscribe.

   Nothing was centred because nothing could be: with the row overflowing
   and `justify-content: space-between` on unequal children, the nav sat
   wherever the overflow left it.

   Fixed in two parts. The layout becomes a real three-column grid, so
   the nav is centred against the bar itself rather than against whatever
   the logo and the actions happen to weigh. And the bar stops carrying
   more than it has room for: the eight secondary icons only appear at
   the width where they genuinely fit, and below that they are exactly
   where they always were on a phone — in the drawer, with labels.
   ========================================================================= */

/*
 * v12.1 — THE NAV TIGHTENS BEFORE IT COLLIDES.
 *
 * Adding Sīrah made the bar eight items. Measured, that is 11px too wide
 * at 1181px — the narrowest width at which the desktop bar is used at all
 * — and 1px too wide at 1200px. Everywhere above 1240px it fits with room
 * to spare.
 *
 * So the nav gives up a little padding over exactly that band rather than
 * the bar overflowing, or the drawer breakpoint being moved and taking
 * the nav away from a whole class of laptops that can carry it perfectly
 * well. Eight items at 9px of side padding measure 64px narrower than at
 * 13px, which is five times the margin needed.
 */
/*
 * The lower bound is 1140px, not the 1181px where the desktop bar begins.
 * A classic scrollbar takes 11-17px out of the layout without changing
 * what the media query is evaluated against, so at an outer width of
 * 1181px the bar can be laid out in 1170px — and measurement showed
 * exactly that 11px of overlap. Starting the tightening below the
 * breakpoint costs nothing (under 1181px the nav is a drawer and these
 * rules do not apply to anything visible) and removes the whole class of
 * scrollbar-width edge cases rather than one instance of it.
 */
/* One step tighter again over the band nearest the drawer. */


/* v11.4 — REMOVED. This hid the four now-deleted icon-bar duplicates
   (Surprise/Saved/Prayer Times/Qibla) below 1400px, which contradicted
   the v8.0 measurement two screens up that the same row fit down to
   861px — an artefact of patching a symptom instead of the cause. See
   the note above .header-actions in header.php for what actually
   changed and why. */

/* The tagline is a second line inside the logo lockup and the single
   widest thing in it. It belongs on a wide screen and nowhere else. */

/* Subscribe is the one call to action in the bar; it must never be the
   thing that gets cut. */

/* =========================================================================
   3. THE TAFSĪR LIBRARY — /tafsir/
   ========================================================================= */

.tafsir-library{ padding-block: var(--sp-6) var(--sp-10); }

.tafsir-lib-head{
  max-width: 62ch;
  margin: 0 auto var(--sp-10);
  text-align: center;
}
.tafsir-lib-ar{
  display: block;
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: clamp(2rem, 1.4rem + 2.6vw, 3.1rem);
  line-height: 1.5;
  color: rgb(var(--accent-ui));
  margin-bottom: 2px;
}
.tafsir-lib-head h1{
  font-size: clamp(1.7rem, 1.2rem + 2vw, 2.5rem);
  line-height: 1.15;
  margin: 0 0 var(--sp-3);
}
.tafsir-lib-sub{
  margin: 0 auto;
  max-width: 54ch;
  color: rgb(var(--text-muted));
  font-size: var(--fs-sm);
  line-height: 1.65;
}

/* ---- the "which ayah" box ---- */
.tafsir-lib-search{
  display: flex;
  align-items: center;
  gap: 10px;
  margin: var(--sp-6) auto 0;
  max-width: 34rem;
  padding: 4px 6px 4px 14px;
  border-radius: 999px;
  border: 1px solid var(--hairline-strong);
  background: rgb(var(--surface));
  box-shadow: var(--e1);
  transition: border-color var(--dur) var(--ease-soft), box-shadow var(--dur) var(--ease-soft);
}
.tafsir-lib-search:focus-within{
  border-color: rgb(var(--wash) / 0.55);
  box-shadow: var(--e2);
}
.tafsir-lib-search-ic{ display: grid; place-items: center; color: rgb(var(--text-muted)); }
.tafsir-lib-search-ic svg{ width: 18px; height: 18px; fill: none; stroke: currentColor; }
.tafsir-lib-search input{
  flex: 1; min-width: 0;
  border: none; background: transparent; outline: none;
  font-family: var(--font-ui); font-size: var(--fs-sm);
  color: rgb(var(--text));
  padding: 11px 0;
}
.tafsir-lib-search input::-webkit-search-cancel-button{ display: none; }
.tafsir-lib-search-clear{
  display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 50%;
  border: none; background: rgb(var(--ink) / 0.06); color: rgb(var(--text-muted));
}
.tafsir-lib-search-clear svg{ width: 15px; height: 15px; fill: none; stroke: currentColor; }
.tafsir-lib-hint{
  margin: 8px 0 0;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: rgb(var(--text-muted));
}

/* ---- results, shared with the room's jump sheet ---- */
.tafsir-lib-results,
.tafsir-jump-results{
  margin: var(--sp-4) auto 0;
  max-width: 34rem;
  text-align: start;
  display: flex; flex-direction: column; gap: 4px;
}
.tafsir-hit{
  display: flex; align-items: center; gap: 12px;
  padding: 11px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--hairline);
  background: rgb(var(--surface));
  min-width: 0;
  transition: background-color var(--dur-fast) var(--ease-soft), transform var(--dur) var(--ease-out-expo);
}
@media (hover: hover){ .tafsir-hit:hover{ background: rgb(var(--wash) / 0.08); transform: translateX(2px); } }
.tafsir-hit-ref{ border-color: rgb(var(--wash) / 0.4); background: rgb(var(--wash) / 0.07); }
.tafsir-hit-kind{
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--accent-ui)); white-space: nowrap;
}
.tafsir-hit-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 1.05rem;
  color: rgb(var(--accent-ui)); white-space: nowrap;
}
.tafsir-hit-main{ flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.tafsir-hit-main b{
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 600;
  color: rgb(var(--heading));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tafsir-hit-main small{
  font-size: var(--fs-2xs); color: rgb(var(--text-muted));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tafsir-hit-go{ width: 15px; height: 15px; flex-shrink: 0; fill: none; stroke: currentColor; color: rgb(var(--text-muted)); }
.tafsir-hit-none{
  margin: 0; padding: 14px; text-align: center;
  font-size: var(--fs-sm); color: rgb(var(--text-muted));
}

/* ---- carry on reading ---- */
.tafsir-lib-resume{
  display: flex; align-items: center; gap: 12px;
  margin: var(--sp-5) auto 0;
  max-width: 34rem;
  padding: 12px 16px;
  border-radius: var(--radius);
  border: 1px solid rgb(var(--wash) / 0.3);
  background: rgb(var(--wash) / 0.08);
  text-align: start;
  transition: background-color var(--dur) var(--ease-soft);
}
@media (hover: hover){ .tafsir-lib-resume:hover{ background: rgb(var(--wash) / 0.14); } }
.tafsir-lib-resume-ic{ display: grid; place-items: center; color: rgb(var(--accent-ui)); }
.tafsir-lib-resume-ic svg{ width: 18px; height: 18px; fill: none; stroke: currentColor; }
.tafsir-lib-resume-text{ flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.tafsir-lib-resume-text strong{ font-size: var(--fs-sm); color: rgb(var(--heading)); }
.tafsir-lib-resume-text span{ font-family: var(--font-mono); font-size: var(--fs-2xs); color: rgb(var(--accent-ui)); }
.tafsir-lib-resume-go{ width: 16px; height: 16px; fill: none; stroke: currentColor; color: rgb(var(--accent-ui)); }

/* =========================================================================
   THE TAFSĪR BROWSER — sūrahs and ajzāʾ
   v12.0. Markup: pp_tafsir_render_browser(). Behaviour: assets/tafsir.js.

   Two densities of the same component. On the library page it is a
   section of the page; inside the reader's jump sheet it is a scrolling
   panel with a height cap, because the sheet must not grow taller than
   the window.
   ========================================================================= */

.tafsir-browse-section{ margin: 0 0 var(--sp-10); }
.tafsir-browse-head{ margin-bottom: var(--sp-4); }
.tafsir-browse-head h2{
  margin: 0 0 4px;
  font-size: clamp(1.1rem, 1rem + 0.5vw, 1.35rem);
  line-height: 1.2;
}
.tafsir-browse-head p{
  margin: 0; max-width: 62ch;
  font-size: var(--fs-sm); line-height: 1.6;
  color: rgb(var(--text-muted));
}
.tafsir-shelves-head{
  margin: 0 0 var(--sp-5); padding-top: var(--sp-6);
  border-top: 1px solid var(--hairline);
}
.tafsir-shelves-head h2{
  margin: 0 0 4px;
  font-size: clamp(1.1rem, 1rem + 0.5vw, 1.35rem);
  line-height: 1.2;
}
.tafsir-shelves-head p{
  margin: 0; font-size: var(--fs-sm); color: rgb(var(--text-muted));
}

.tafsir-browse{
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: rgb(var(--surface));
  overflow: hidden;
}

/* ---- the bar: tabs on one side, filter on the other ---- */
.tafsir-browse-bar{
  display: flex; align-items: center; gap: var(--sp-3);
  flex-wrap: wrap;
  padding: var(--sp-3);
  border-bottom: 1px solid var(--hairline);
  background: rgb(var(--wash) / 0.04);
}
.tafsir-browse-tabs{
  position: relative;
  flex-shrink: 0;
  padding: 3px;
  border-radius: var(--radius-pill);
  background: rgb(var(--ink) / 0.06);
}
.tafsir-browse-thumb{
  position: absolute; z-index: 0;
  top: 3px; bottom: 3px; left: 3px;
  width: calc(50% - 3px);
  border-radius: var(--radius-pill);
  background: rgb(var(--surface));
  box-shadow: var(--e1);
  transition: transform var(--dur) var(--spring);
}
.tafsir-browse[data-tab="juz"] .tafsir-browse-thumb{ transform: translateX(100%); }
.tafsir-browse-tab{
  position: relative; z-index: 1;
  display: inline-flex;
  min-height: 38px; padding: 0 16px;
  border: none; background: transparent; cursor: pointer;
  border-radius: var(--radius-pill);
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 600;
  color: rgb(var(--text-muted));
  transition: color var(--dur) var(--ease-soft);
}
.tafsir-browse-tab.is-on{ color: rgb(var(--accent-ui)); }
.tafsir-browse-tab-ar{
  font-weight: var(--ar-weight);
}

.tafsir-browse-filter{
  position: relative;
  flex: 1 1 240px; min-width: 0;
  display: flex; align-items: center;
}
.tafsir-browse-filter-ic{
  position: absolute; inset-inline-start: 12px;
  width: 16px; height: 16px; pointer-events: none;
  fill: none; stroke: currentColor; color: rgb(var(--text-muted));
}
.tafsir-browse-filter input{
  width: 100%; min-height: 40px;
  padding: 0 40px 0 36px;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-pill);
  background: rgb(var(--surface));
  font-family: var(--font-ui); font-size: var(--fs-sm);
  color: rgb(var(--text));
  transition: border-color var(--dur) var(--ease-soft), box-shadow var(--dur) var(--ease-soft);
}
.tafsir-browse-filter input:focus{
  outline: none;
  border-color: rgb(var(--wash) / 0.55);
  box-shadow: 0 0 0 3px rgb(var(--accent) / 0.14);
}
.tafsir-browse-filter input::-webkit-search-cancel-button{ display: none; }
.tafsir-browse-clear{
  position: absolute; inset-inline-end: 6px;
  display: grid; place-items: center;
  width: 30px; height: 30px; padding: 0;
  border: none; border-radius: 50%; cursor: pointer;
  background: transparent; color: rgb(var(--text-muted));
}
@media (hover: hover){ .tafsir-browse-clear:hover{ background: rgb(var(--ink) / 0.06); color: rgb(var(--heading)); } }
.tafsir-browse-clear svg{ width: 14px; height: 14px; fill: none; stroke: currentColor; }

/* ---- panels ---- */
.tafsir-browse-panel{ padding: var(--sp-3); }
.tafsir-browse-empty{
  margin: var(--sp-5) 0; text-align: center;
  font-size: var(--fs-sm); color: rgb(var(--text-muted));
}

/* ---- the 114 ---- */
.tafsir-surah-grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(206px, 1fr));
  gap: 6px;
}
/* An opened surah takes the full row, so its ayah grid has somewhere to
   go and the cells beside it are not shoved out of alignment. */
.tafsir-surah-cell.is-open{ grid-column: 1 / -1; }
.tafsir-surah-chip{
  display: flex; align-items: center; gap: 10px;
  width: 100%; min-height: 52px;
  padding: 8px 12px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  text-align: start;
  transition:
    background-color var(--dur-fast) var(--ease-soft),
    border-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){
  .tafsir-surah-chip:hover{
    background: rgb(var(--wash) / 0.07);
    border-color: rgb(var(--wash) / 0.22);
  }
}
.tafsir-surah-cell.is-open .tafsir-surah-chip{
  background: rgb(var(--wash) / 0.1);
  border-color: rgb(var(--wash) / 0.3);
}
.tafsir-surah-cell.is-current .tafsir-surah-chip{ border-color: rgb(var(--wash) / 0.4); }
/* The number as a struck roundel, which is how a muṣḥaf indexes itself. */
.tafsir-surah-n{
  display: grid; place-items: center;
  width: 28px; height: 28px; flex-shrink: 0;
  border-radius: 50%;
  background: rgb(var(--wash) / 0.12);
  color: rgb(var(--accent-ui));
  font-family: var(--font-mono); font-size: 0.72rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.tafsir-surah-names{ flex: 1; min-width: 0; display: flex; flex-direction: column; }
.tafsir-surah-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 1.02rem; line-height: 1.4;
  color: rgb(var(--heading));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tafsir-surah-tr{
  font-size: 0.74rem; line-height: 1.3;
  color: rgb(var(--text-muted));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tafsir-surah-count{
  flex-shrink: 0;
  font-family: var(--font-mono); font-size: 0.66rem;
  color: rgb(var(--text-muted));
  opacity: 0.85;
}

/* ---- the ayah grid ---- */
.tafsir-ayah-grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(46px, 1fr));
  gap: 5px;
  margin: 8px 0 4px;
  padding: var(--sp-3);
  border-radius: var(--radius);
  background: rgb(var(--ink) / 0.04);
  border: 1px solid var(--hairline-faint);
}
.tafsir-ayah-btn{
  display: grid; place-items: center;
  min-height: 44px;
  border-radius: var(--radius-sm);
  background: rgb(var(--surface));
  border: 1px solid var(--hairline);
  font-family: var(--font-mono); font-size: 0.8rem; font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: rgb(var(--heading-soft));
  transition:
    background-color var(--dur-fast) var(--ease-soft),
    color var(--dur-fast) var(--ease-soft),
    border-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){
  .tafsir-ayah-btn:hover{
    background: rgb(var(--wash) / 0.14);
    border-color: rgb(var(--wash) / 0.4);
    color: rgb(var(--accent-ui));
  }
}

/* ---- the thirty ---- */
.tafsir-juz-grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(238px, 1fr));
  gap: 6px;
}
.tafsir-juz-cell{
  display: flex; align-items: center; gap: 11px;
  min-height: 58px; padding: 9px 12px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  transition:
    background-color var(--dur-fast) var(--ease-soft),
    border-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){
  .tafsir-juz-cell:hover{
    background: rgb(var(--wash) / 0.07);
    border-color: rgb(var(--wash) / 0.22);
  }
}
.tafsir-juz-n{
  display: grid; place-items: center;
  width: 34px; height: 34px; flex-shrink: 0;
  border-radius: 50%;
  background: rgb(var(--wash) / 0.12);
  color: rgb(var(--accent-ui));
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 0.95rem; line-height: 1;
}
.tafsir-juz-body{ flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.tafsir-juz-label{
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 600;
  color: rgb(var(--heading));
}
.tafsir-juz-range{
  display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
  font-size: 0.72rem; line-height: 1.4;
  color: rgb(var(--text-muted));
}
.tafsir-juz-ref{
  font-family: var(--font-mono); font-size: 0.68rem;
  color: rgb(var(--accent-ui)); opacity: 0.9;
}
.tafsir-juz-dash{ opacity: 0.5; }

/* ---- inside the reader's sheet ---- */
.tafsir-browse-sheet{
  margin-top: var(--sp-3);
  border-radius: var(--radius);
}
/* The sheet is already a fixed overlay; the grids inside it scroll rather
   than pushing it past the bottom of the window. */
.tafsir-browse-sheet .tafsir-browse-panel{
  /* clamp(), not min(): a floor guarantees a usable panel even where the
     viewport height resolves to something unexpected (an embedded frame,
     a browser reporting 0 before layout settles). Without the floor the
     grid can collapse to nothing and the sheet looks broken. */
  max-height: clamp(220px, 46vh, 420px);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
.tafsir-jump-hint{
  margin: 8px 0 0;
  font-size: var(--fs-2xs);
  color: rgb(var(--text-muted));
}

@media (max-width: 600px){
  .tafsir-browse-bar{ padding: 10px; gap: 10px; }
  .tafsir-browse-tabs{ width: 100%; }
  /* 38px was under the 44px touch minimum, measured at 375px. */
  .tafsir-browse-tab{ flex: 1; justify-content: center; padding: 0 10px; min-height: 44px; }
  .tafsir-browse-thumb{ top: 3px; bottom: 3px; }
  .tafsir-browse-filter{ flex: 1 1 100%; }
  .tafsir-surah-grid{ grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
  .tafsir-juz-grid{ grid-template-columns: 1fr; }
  .tafsir-surah-count{ display: none; }
  .tafsir-ayah-grid{ grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); }
  .tafsir-browse-sheet .tafsir-browse-panel{ max-height: clamp(200px, 42vh, 360px); }
}

@media (prefers-reduced-motion: reduce){
  .tafsir-browse-thumb{ transition: none; }
}

/* =========================================================================
   THE SURAH AND AYAH PICKERS — the v12.1 rules were DELETED in v12.5.

   They styled one control that lived in one place: a joined pair of
   buttons in the reader's bar, with the label hidden below 620px and the
   caret hidden below 900px so the pair could squeeze in beside the book
   name. v12.5 made the pickers a component used in two places and gave
   each one its own popover, so those rules were no longer describing the
   thing they were named after — and the two `display: none`s were
   actively wrong on the library page, where there is room for both.

   Deleted rather than overridden: an override would have left a rule in
   the cascade whose whole purpose was to hide something the design now
   wants. The control is styled in the v12.5 layer at the foot of this
   file.
   ========================================================================= */

/* The ayah the reader is on, marked inside the number grid. */
.tafsir-ayah-btn.is-current{
  background: rgb(var(--wash) / 0.9);
  border-color: rgb(var(--accent));
  color: rgb(var(--on-accent));
}


/* ---- the editor's-notes bar ---------------------------------------------
   v12.0. Inserted by assets/tafsir.js at the head of the commentary, and
   only when this edition actually carries an apparatus. Quiet enough to
   ignore, present enough to find — see the note in tafsir.js.
   ------------------------------------------------------------------------ */
.tafsir-notesbar{
  direction: ltr; text-align: left;
}
.tafsir-notesbar.is-on{
  border-style: solid;
}
.tafsir-notesbar-text{
  flex: 1; min-width: 0;
  line-height: 1.5;
}
.tafsir-notesbar-btn{
  flex-shrink: 0;
  cursor: pointer;
  font-weight: 700;
  transition: background-color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){
  .tafsir-notesbar-btn:hover{
    background: rgb(var(--wash) / 0.12);
    border-color: rgb(var(--wash) / 0.6);
  }
}

/* ---- a shelf ---- */
.tafsir-shelf{ margin-bottom: var(--sp-10); scroll-margin-top: calc(var(--header-h) + 20px); }
.tafsir-shelf-head{
  display: flex; gap: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--hairline);
}
.tafsir-shelf-ic{
  display: grid; place-items: center;
  width: 34px; height: 34px; flex-shrink: 0;
  border-radius: 50%;
  background: rgb(var(--ornament) / 0.12);
  color: rgb(var(--accent-ui));
}
.tafsir-shelf-ic svg{ width: 18px; height: 18px; fill: none; stroke: currentColor; }
.tafsir-shelf-titles{ flex: 1; min-width: 0;  }
.tafsir-shelf-titles h2{
  font-size: clamp(1.05rem, 0.95rem + 0.5vw, 1.3rem);
}
.tafsir-shelf-ar{
  opacity: 0.9;
}
.tafsir-shelf-n{
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  color: rgb(var(--text-muted));
  padding: 3px 9px; border-radius: 999px;
  background: rgb(var(--ink) / 0.055);
  flex-shrink: 0;
}
.tafsir-shelf-note{
  margin: 10px 0 var(--sp-5);
  max-width: 68ch;
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: rgb(var(--text-muted));
}

/* ---- a book -------------------------------------------------------------
   v12.0 — REBUILT. See the note above the markup in tafsir-library.php.

   The old card was a white rectangle with a 6px bar down the edge and
   five text sizes stacked flush left, the Arabic title and the century
   colliding along the top. This gives every book a TITLE PLATE: an
   arch-topped panel — the mihrab arch, the right form for this material —
   carrying the Arabic name, with the century struck into its corner as a
   roundel. All the colour lives on the plate, so twenty of them read as a
   shelf rather than twenty equal boxes.
   ------------------------------------------------------------------------ */
/* v12.5 — the v12.0 title plate, its mihrab arch, the struck century
   roundel and the OPEN footer row were deleted here rather than
   overridden. Reported as "these boxes ... are too repeated", and an
   override would have left the old rules in the cascade for the next
   person to wonder about. The card is rebuilt in the v12.5 layer at the
   foot of this file; the markup is in tafsir-library.php. */

.tafsir-lib-foot{
  margin: var(--sp-8) auto 0;
  max-width: 62ch;
  text-align: center;
  font-size: var(--fs-2xs);
  line-height: 1.7;
  color: rgb(var(--text-muted));
}

@media (max-width: 600px){
  .tafsir-shelf{ margin-bottom: var(--sp-8); }
  .tafsir-lib-head{ margin-bottom: var(--sp-8); }
}

/* =========================================================================
   4. THE READING ROOM — /tafsir/{book}/{surah}/{ayah}/

   The book is the page. Everything that is not the book or the verse it
   is commenting on is either below the commentary or inside a control
   that stays shut until it is asked for.
   ========================================================================= */

.tafsir-room{ display: block; }

/* ---- the bar ---------------------------------------------------------- */
.tafsir-bar{
  position: sticky;
  z-index: 40;
  border-bottom: 1px solid var(--hairline);
}
.tafsir-bar-inner{
  padding-block: 7px;
}
.tafsir-bar-back{
  display: inline-flex; align-items: center; gap: 6px;
  flex-shrink: 0;
  padding: 8px 12px 8px 8px;
  border-radius: 999px;
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight: 600;
  color: rgb(var(--text-muted));
  transition: background-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .tafsir-bar-back:hover{ background: rgb(var(--ink) / 0.05); color: rgb(var(--heading)); } }
.tafsir-bar-back svg{ width: 15px; height: 15px; fill: none; stroke: currentColor; }
.tafsir-bar-back-short{ display: none; }

/* Which book — the control reached for most while reading. */
.tafsir-bar-book{
  display: inline-flex; align-items: center; gap: 8px;
  flex: 0 1 auto;
  padding: 7px 12px;
  border-radius: 999px;
  border: 1px solid rgb(var(--wash) / 0.3);
  background: rgb(var(--wash) / 0.08);
  transition: background-color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .tafsir-bar-book:hover{ background: rgb(var(--wash) / 0.16); border-color: rgb(var(--wash) / 0.5); } }
.tafsir-bar-book-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 1rem;
  color: rgb(var(--heading));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.tafsir-bar-book-en{
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--accent-ui));
  white-space: nowrap;
}
.tafsir-bar-caret{ width: 14px; height: 14px; flex-shrink: 0; fill: none; stroke: currentColor; color: rgb(var(--accent-ui)); }

.tafsir-bar-where{
  display: inline-flex; align-items: center;
  flex-shrink: 0;
  padding: 7px 12px;
  border-radius: 999px;
  border: 1px solid var(--hairline-strong);
  background: transparent;
  transition: background-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .tafsir-bar-where:hover{ background: rgb(var(--ink) / 0.05); } }
.tafsir-bar-where-ref{
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps);
  color: rgb(var(--text));
  white-space: nowrap;
}
.tafsir-bar-where svg{ width: 14px; height: 14px; fill: none; stroke: currentColor; color: rgb(var(--text-muted)); }

.tafsir-bar-steps{ display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.tafsir-bar-step{
  display: grid; place-items: center;
  width: 36px; height: 36px;
  border-radius: 50%;
  color: rgb(var(--text-muted));
  transition: background-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .tafsir-bar-step:hover{ background: rgb(var(--wash) / 0.12); color: rgb(var(--accent-ui)); } }
.tafsir-bar-step svg{ width: 17px; height: 17px; fill: none; stroke: currentColor; }
.tafsir-bar-step.is-off{ opacity: 0.25; pointer-events: none; }


/* ---- the book, named once --------------------------------------------- */

/* ---- the ayah ---------------------------------------------------------- */
.tafsir-ayah{
  max-width: var(--tafsir-measure);
  margin: 0 auto var(--sp-8);
  padding: var(--sp-5) var(--sp-6) var(--sp-4);
  border-radius: var(--radius-lg);
  border: 1px solid rgb(var(--wash) / 0.22);
  background:
    radial-gradient(ellipse 70% 60% at 50% 0%, rgb(var(--wash) / 0.07), transparent 70%),
    rgb(var(--surface));
}
.tafsir-ayah-head{
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  padding-bottom: var(--sp-3);
  margin-bottom: var(--sp-4);
  border-bottom: 1px solid var(--hairline);
}
.tafsir-ayah-ref{ display: inline-flex; align-items: baseline; gap: 9px; min-width: 0; }
.tafsir-ayah-surah{
  font-family: var(--font-display); font-weight: 600; font-size: 1.02rem;
  color: rgb(var(--heading));
}
.tafsir-ayah-num{
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps);
  color: rgb(var(--accent-ui));
  padding: 2px 8px; border-radius: 999px;
  background: rgb(var(--wash) / 0.12);
}
.tafsir-ayah-meta{ display: flex; gap: 10px; flex-wrap: wrap; }
.tafsir-ayah-meta span{
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  color: rgb(var(--text-muted));
}

/* The Uthmani glyph text, in the bundled Hafs face. */
.tafsir-ayah-ar{
  margin: 0 auto var(--sp-4);
  font-family: var(--font-quran-glyphs), var(--font-quran), var(--font-arabic);
  direction: rtl; unicode-bidi: isolate;
  line-height: 2.15;
  text-align: center;
  color: rgb(var(--heading));
}

.tafsir-ayah-tools{
  display: flex; flex-wrap: wrap; justify-content: center; gap: 8px;
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--hairline);
}
.tafsir-tool{
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 38px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--hairline-strong);
  background: transparent;
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight: 600;
  color: rgb(var(--text));
  transition: background-color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .tafsir-tool:hover{ background: rgb(var(--wash) / 0.1); border-color: rgb(var(--wash) / 0.35); } }
.tafsir-tool svg{ width: 15px; height: 15px; fill: none; stroke: currentColor; }
.tafsir-tool.is-done{ background: rgb(var(--wash) / 0.16); border-color: rgb(var(--wash) / 0.5); color: rgb(var(--accent-ui)); }
.tafsir-tool-read{ background: rgb(var(--wash) / 0.09); border-color: rgb(var(--wash) / 0.32); color: rgb(var(--accent-ui)); }
@media (hover: hover){ .tafsir-tool-read:hover{ background: rgb(var(--wash) / 0.18); } }
.tafsir-ic-pause{ display: none; }
.tafsir-tool.is-playing .tafsir-ic-play{ display: none; }
.tafsir-tool.is-playing .tafsir-ic-pause{ display: block; }
.tafsir-tool.is-failed{ border-color: rgb(var(--danger) / 0.55); }

/* ---- the commentary ---------------------------------------------------- */
.tafsir-text{ max-width: var(--tafsir-measure); margin: 0 auto; }
.tafsir-text-rule{
  display: flex; align-items: center; gap: 14px;
  margin-bottom: var(--sp-5);
  color: rgb(var(--text-muted));
}
.tafsir-text-rule::before,
.tafsir-text-rule::after{
  content: ''; flex: 1; height: 1px;
  background: linear-gradient(90deg, transparent, rgb(var(--ornament) / 0.35), transparent);
}
.tafsir-text-rule span{
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  white-space: nowrap;
}

/*
 * The body. Ordinary Arabic Unicode in a full naskh — NOT the Hafs face,
 * which carries 2,737 Private Use Area glyphs and ten standard Arabic
 * codepoints and would render every letter of this as an empty box.
 */
.tafsir-body{
  font-family: var(--font-arabic);
  direction: rtl; unicode-bidi: isolate;
  color: rgb(var(--text));
}
.tafsir-body p{ margin: 0 0 1.1em; }
.tafsir-body p:last-child{ margin-bottom: 0; }
/* An ayah quoted inside the commentary. Ordinary Unicode, so it is
   marked rather than re-rendered — colour and the ﴿﴾ the source gives. */
.tafsir-body .qa-tafsir-ayah{
  color: rgb(var(--accent-ui));
}
.tafsir-body .qa-tafsir-note,
.tafsir-body [class*="note"]{
  display: block;
  margin: 0.5em 0;
  padding-inline-start: 0.9em;
  border-inline-start: 2px solid rgb(var(--wash) / 0.25);
  font-size: 0.8em;
  line-height: 1.9;
  color: rgb(var(--text-muted));
}

.tafsir-fail{
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-3);
  padding: var(--sp-8) var(--sp-4);
  text-align: center;
}
.tafsir-fail p{ margin: 0; color: rgb(var(--text-muted)); font-size: var(--fs-sm); }
.tafsir-retry{
  min-height: 40px; padding: 10px 22px;
  border: none; border-radius: 999px;
  background: rgb(var(--accent)); color: rgb(var(--on-accent));
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 600;
}

.tafsir-text-foot{
  display: flex; align-items: center; gap: 8px;
  margin-top: var(--sp-6);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--hairline);
}
.tafsir-size{
  display: inline-flex; align-items: center; gap: 6px;
  min-width: 40px; min-height: 36px;
  padding: 7px 12px;
  border-radius: 999px;
  border: 1px solid var(--hairline-strong);
  background: transparent;
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight: 600;
  color: rgb(var(--text-muted));
  justify-content: center;
  transition: background-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .tafsir-size:hover{ background: rgb(var(--ink) / 0.05); color: rgb(var(--heading)); } }
.tafsir-size svg{ width: 14px; height: 14px; fill: none; stroke: currentColor; }
.tafsir-size.is-done{ background: rgb(var(--wash) / 0.16); color: rgb(var(--accent-ui)); }

/* ---- onward ------------------------------------------------------------ */
.tafsir-onward{
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  max-width: var(--tafsir-measure); margin: var(--sp-8) auto 0;
}
.tafsir-onward-link{
  display: inline-flex; align-items: center; gap: 10px;
  padding: 12px 18px;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  background: rgb(var(--surface));
  transition: border-color var(--dur) var(--ease-soft), transform var(--dur) var(--ease-out-expo);
}
@media (hover: hover){ .tafsir-onward-link:hover{ border-color: rgb(var(--wash) / 0.4); transform: translateY(-1px); } }
.tafsir-onward-link svg{ width: 16px; height: 16px; fill: none; stroke: currentColor; color: rgb(var(--accent-ui)); }
.tafsir-onward-link span{ display: flex; flex-direction: column; gap: 1px; }
.tafsir-onward-link small{
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.tafsir-onward-link b{ font-family: var(--font-ui); font-size: var(--fs-sm); color: rgb(var(--heading)); }
.tafsir-onward-next{ margin-inline-start: auto; text-align: right; }

/* ---- the other nineteen ------------------------------------------------ */

/* ---- the two sheets ---------------------------------------------------- */
.tafsir-jump {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: start center;
  padding: calc(var(--header-h) + 20px) var(--sp-4) var(--sp-4);
  background: rgb(var(--shadow, 0 0 0) / 0.45);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out-expo);
  overflow-y: auto;
}
.tafsir-jump.is-open { opacity: 1; }
.tafsir-jump-inner {
  width: 100%;
  max-width: 40rem;
  padding: var(--sp-4);
  border-radius: var(--radius-lg);
  background: rgb(var(--surface));
  border: 1px solid var(--hairline-strong);
  box-shadow: var(--e-overlay);
  transform: translateY(-10px) scale(0.98);
  transition: transform var(--dur) var(--spring);
}
.tafsir-jump.is-open .tafsir-jump-inner { transform: none; }

.tafsir-jump-form{
  display: flex; align-items: center; gap: 10px;
  padding: 4px 6px 4px 14px;
  border-radius: 999px;
  border: 1px solid var(--hairline-strong);
  background: rgb(var(--bg-alt, var(--surface)));
}
.tafsir-jump-ic{ display: grid; place-items: center; color: rgb(var(--text-muted)); }
.tafsir-jump-ic svg{ width: 17px; height: 17px; fill: none; stroke: currentColor; }
.tafsir-jump-form input{
  flex: 1; min-width: 0; border: none; background: transparent; outline: none;
  font-family: var(--font-ui); font-size: var(--fs-sm); color: rgb(var(--text));
  padding: 11px 0;
}
.tafsir-jump-form input::-webkit-search-cancel-button{ display: none; }
.tafsir-jump-close {
  display: grid; place-items: center;
  width: 36px; height: 36px; border-radius: 50%;
  border: none; background: rgb(var(--ink) / 0.06); color: rgb(var(--text-muted));
  flex-shrink: 0;
}
.tafsir-jump-close svg { width: 16px; height: 16px; fill: none; stroke: currentColor; }


body.tafsir-sheet-open{ overflow: hidden; }

@media (max-width: 760px){
  .tafsir-bar-back-full{ display: none; }
  .tafsir-bar-back-short{ display: inline; }
  .tafsir-bar-book-ar{ display: none; }
  .tafsir-bar-inner{ gap: 6px; }
  .tafsir-bar-where-ref{ font-size: 0.66rem; }
  .tafsir-ayah{ padding: var(--sp-4) var(--sp-4) var(--sp-3); }
  .tafsir-body{ font-size: 1.16rem; line-height: 2.05; text-align: right; }
  .tafsir-onward{ gap: 8px; }
  .tafsir-onward-link{ padding: 10px 14px; }
  .tafsir-jump { padding-top: calc(var(--header-h) + 10px); }
}

/* =========================================================================
   5. THE ADHKĀR PANEL HEAD
   See the note in page-tasbih.php for what this replaced.
   ========================================================================= */

.adhkar-panel-head{
  grid-template-columns: auto 1fr;
  gap: var(--sp-3) var(--sp-4);
  align-items: start;
}
.adhkar-panel-mark{
  display: grid; place-items: center;
  width: 46px; height: 46px;
  border-radius: 50%;
  background: rgb(var(--wash) / 0.14);
  color: rgb(var(--accent-ui));
  flex-shrink: 0;
}
.adhkar-panel-mark svg{ width: 24px; height: 24px; fill: none; stroke: currentColor; }
.adhkar-panel-id{ min-width: 0; }
.adhkar-panel-id h2{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  line-height: 1.5;
  color: rgb(var(--heading));
  text-align: start;
}
.adhkar-panel-line{
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 2px 0 0;
}
.adhkar-panel-en{
  font-family: var(--font-display); font-weight: 600;
  font-size: 1.02rem;
  color: rgb(var(--accent-ui));
}
.adhkar-panel-when{
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  background: rgb(var(--wash) / 0.1);
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: 0.02em;
  color: rgb(var(--accent-ui));
}
.adhkar-panel-when svg{ width: 12px; height: 12px; fill: none; stroke: currentColor; }

/* The progress, as one line along the foot of the panel. */
.adhkar-progress{
  grid-column: 1 / -1;
  margin-top: var(--sp-2);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--hairline);
}
.adhkar-progress-fill{
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, rgb(var(--wash) / 0.6), rgb(var(--accent)));
  transition: width var(--dur-slow, 420ms) var(--ease-out-expo);
}
.adhkar-progress-row{
  display: flex; justify-content: space-between;
}
.adhkar-reset{
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 34px;
  padding: 7px 13px;
  border-radius: 999px;
  border: 1px solid var(--hairline-strong);
  background: transparent;
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight: 600;
  color: rgb(var(--text-muted));
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .adhkar-reset:hover{ background: rgb(var(--ink) / 0.06); color: rgb(var(--heading)); } }
.adhkar-reset svg{ width: 13px; height: 13px; fill: none; stroke: currentColor; }

@media (max-width: 600px){
  .adhkar-panel-head{ padding: var(--sp-4); gap: var(--sp-3); }
  .adhkar-panel-mark{ width: 38px; height: 38px; }
  .adhkar-panel-mark svg{ width: 20px; height: 20px; }
}

/* =========================================================================
   6. THE ARC'S ENDS — v12.2, REMOVED WITH THE ARC.

   Five rules for `.prayer-arc-end*`, an element that no longer exists in
   any template. Left in place they would be the next person's evidence
   that the arc is still on the page.
   ========================================================================= */

/* =========================================================================
   7. THE MENU CHIPS
   ========================================================================= */


/* =========================================================================
   8. TWO THINGS THAT WERE BEING CUT, NOT WRAPPED — v11.3

   Found by measuring scrollWidth against clientWidth on every leaf
   element at 390px: two labels wanted more room than their box had and
   were being sliced mid-glyph rather than shortened.
   ========================================================================= */

/* The wordmark. It is hidden below 353px by a measured rule; between
   there and a small tablet it must FIT, and if a longer site name is
   ever set it must shorten cleanly instead of losing its last letters
   behind an overflow:clip edge. */

/* The picker buttons on the prayer-times page carry a method name that
   can run to forty characters. */
.pp-choice-value,
.pp-choice-text{
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}


/* =========================================================================
   =========================================================================
   v11.5 — THE READING SURFACES

   One dated layer, in the pattern this file has used since v8.0. What is
   here is the tafsir — the room at /tafsir/{book}/{surah}/{ayah}/ and the
   sheet that opens over a Qur'an page — plus the site search both of them
   are reachable from.

   Everything below either introduces a component that did not exist or
   deliberately overrides an earlier rule, and where it overrides one it
   says which and why.
   =========================================================================
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. QUOTED AYAT, WHEREVER THEY APPEAR IN A COMMENTARY

   Overrides `.qa-tafsir-ayah` (the Qur'an-page sheet, v9.1) and
   `.tafsir-body .qa-tafsir-ayah` (the room, v11.3), both of which set
   these gold.

   "inside all tafasir when an Ayah is mentioned from the Qur'an it must
   be in black colour not golden, and it must be same hafs font used for
   Qur'an page."

   BLACK: `--heading`, the same ink the mushaf itself is set in on
   /quran/, in all ten palettes. Not `--text`: revelation quoted inside
   commentary should read as the darker of the two, which is exactly what
   a printed tafsir does.

   HAFS: only where the words were resolved back to the mushaf — see the
   note above pp_quran_quote_glyphs() in inc/quran.php for why that is a
   lookup and not a font-family declaration. `.is-mushaf` is the real
   thing; `.is-plain` is the edition's own Unicode, which gets a full
   naskh and the same ink, because a quotation that could not be resolved
   is still a quotation.

   The ornate brackets are kept OUT of the glyph run: U+FD3E/U+FD3F are
   not in the Hafs face, and giving them their own span means they can be
   sized and tinted as the punctuation they are.
   ------------------------------------------------------------------------- */
.qa-tafsir-ayah,
.tafsir-body .qa-tafsir-ayah,
.qa-tafsir-body .qa-tafsir-ayah{
  color: rgb(var(--heading));
  font-weight: 500;
  unicode-bidi: isolate;
}
.qa-tafsir-ayah.is-plain,
.tafsir-body .qa-tafsir-ayah.is-plain,
.qa-tafsir-body .qa-tafsir-ayah.is-plain{
  font-family: var(--font-quran), var(--font-arabic);
}
.qa-ayah-glyph{
  /* The bundled mushaf face. The fallbacks are there for the same reason
     they are on .quran-ayah-ar: if the woff2 fails to arrive, PUA
     codepoints render as tofu in any face, and the fallbacks at least
     keep the line metrics sane while font-display:block waits. */
  font-family: var(--font-quran-glyphs), var(--font-quran), var(--font-arabic);
  /* Measured against the prose beside it rather than assumed: the Hafs
     glyphs sit on a smaller optical body than Scheherazade at the same
     declared size, so a 1em run read as a step DOWN in the middle of a
     sentence. 1.12em puts the two on the same optical line. The
     line-height is pinned to 1 so a quotation cannot open the leading of
     the paragraph it sits in. */
}
.qa-ayah-brk{
  /* Punctuation of the edition, not part of the revelation — so the same
     ink, lightened, rather than the gold the whole quotation used to be
     set in. Gold here would keep reading as "the ayah is gold". */
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  color: rgb(var(--heading) / 0.45);
  padding-inline: 0.1em;
}

/* -------------------------------------------------------------------------
   2. THE EDITOR'S NOTES ARE OFF UNLESS ASKED FOR

   `hide-notes` is put on `.tafsir-body` by the SERVER (tafsir.php), so
   there is no moment where the apparatus is visible and then removed.
   The Qur'an-page sheet already had this class and its own checkbox;
   this is the room catching up, and both now default to hidden.
   ------------------------------------------------------------------------- */
.tafsir-body.hide-notes .qa-tafsir-note{ display: none; }
.tafsir-body .qa-tafsir-note{
  display: block;
  margin: 0.75em 0;
  padding: 0.3em 0.95em 0.3em 0;
  border-inline-start: none;
  border-inline-end: 2px solid rgb(var(--wash) / 0.28);
  font-size: 0.74em;
  line-height: 1.95;
  color: rgb(var(--text-muted));
}

/* -------------------------------------------------------------------------
   3. THE ROOM'S BAR

   See the long note in tafsir.php. It is a three-track grid rather than
   one item pinned left and a clump pinned right.

   WHERE IT SITS is not decided here any more. v13.1 pinned it to
   --header-live (the header's height, or 0px once the header has
   retreated) and animated `top` between the two. That animation is what
   v14.0 removed from every welded bar: `top` is also where the header's
   SHRINK arrives, and a measurement that lags behind what it measures is
   a visible gap on every scroll. The offset and the retreat both live in
   v140-layer-60-chrome.css now. (item 28)
   ------------------------------------------------------------------------- */

.tafsir-bar-inner{
  /*
   * v12.1 — the same fault the site header had, in the same words.
   *
   * `minmax(0, 1fr)` on both side tracks means "split the leftover width
   * evenly, whatever is in you". The reading controls on the right are a
   * good deal wider than the "All commentaries" link on the left, so once
   * the surah and ayah pickers were added the right-hand track was too
   * small for its contents and they spilled leftwards across the book
   * name in the middle.
   *
   * `max-content` as the minimum is the missing half of the rule: share
   * the spare space, but never below what you are holding.
   */
  display: grid;
  grid-template-columns: minmax(max-content, 1fr) auto minmax(max-content, 1fr);
  align-items: center;
  gap: 12px;
  min-height: 56px;
  max-width: 1360px;
}
.tafsir-bar-back{ grid-column: 1; justify-self: start; min-width: 0; }
.tafsir-bar-book{ grid-column: 2; justify-self: center; margin-inline-start: 0; max-width: 100%; min-width: 0; }
.tafsir-bar-side{
  grid-column: 3; justify-self: end;
  display: flex; align-items: center; gap: 6px;
}
/* Nothing in the reading controls may be squeezed — every one of them is
   a tap target with a fixed size. */
.tafsir-bar-side > *{ flex-shrink: 0; }
.tafsir-bar-where{ flex-direction: row-reverse; gap: 6px; }
.tafsir-bar-where svg{ opacity: 0.75; }

/* The reading control. `Aa` rather than a glyph, because every reading
   app on every platform marks this control that way and nothing else in
   this icon set would be read as "how the text is set". */
.tafsir-reading{ position: relative; }
.tafsir-bar-aa{
  display: grid; place-items: center;
  width: 38px; height: 36px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline-strong);
  background: transparent;
  font-family: var(--font-display);
  font-size: 0.86rem; font-weight: 600; line-height: 1;
  color: rgb(var(--heading-soft));
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
.tafsir-bar-aa[aria-expanded="true"]{
  background: rgb(var(--wash) / 0.12);
  border-color: rgb(var(--wash) / 0.4);
  color: rgb(var(--accent-ui));
}
@media (hover: hover){
  .tafsir-bar-aa:hover{
    background: rgb(var(--wash) / 0.12);
    border-color: rgb(var(--wash) / 0.4);
    color: rgb(var(--accent-ui));
  }
}
.tafsir-reading-pop{
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 60;
  width: min(300px, calc(100vw - 32px));
  padding: 14px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--hairline-strong);
  background: var(--menu-bg);
  background-image: var(--menu-sheen);
  box-shadow: var(--e-overlay);
  opacity: 0; transform: translateY(-6px) scale(0.98);
  transition: opacity var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--ease-soft);
}
.tafsir-reading-pop.is-open{ opacity: 1; transform: none; }
.tafsir-reading-label{
  display: block; margin-bottom: 8px;
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--text-muted));
}.tafsir-reading-size .tafsir-size{ flex: 0 0 auto; }
.tafsir-reading-size .tafsir-size:disabled{ opacity: 0.35; cursor: default; }.tafsir-reading-steps i.is-on{ background: rgb(var(--accent)); transform: scale(1.15); }/* -------------------------------------------------------------------------
   4. THE COMMENTARY IS THE WIDEST THING ON THE PAGE

   "also once again, tafsir text should be eating the most space and the
   biggest, and very easy to read".

   The measure is set from the viewport rather than hand-typed, so a
   1920px window gets a genuinely wide column and a laptop still gets a
   line it can track. `ch` is deliberately not used: it is measured
   against the LATIN `0` of the font in force, and this column is Arabic
   naskh, so the old `74ch` cap was never the 74 characters it claimed.
   ------------------------------------------------------------------------- */
.tafsir-page{ --tafsir-measure: min(68rem, calc(100vw - 5rem)); }
/* The ayah card's two texts. `ch` again measured against the wrong font —
   the Uthmani glyph face has ten standard codepoints and `0` is not one
   of them — so both are set in rem, sized so the verse and its
   translation read as a pair rather than as a wide line above a narrow
   column. */
.tafsir-ayah-ar{ max-width: min(44rem, 100%); }
.tafsir-body{
  max-width: 100%;
  margin-inline: auto;
  text-align: justify;
  text-align-last: right;
}
/* The book's own frontispiece. Kept — it is how you know which of the
   twenty you are in — but tightened, because between it and the ayah
   card it was putting 640px of preamble in front of the text on a
   1000px screen. */
.tafsir-page{ padding-block: var(--sp-5) var(--sp-10); }
.tafsir-ayah{ margin-bottom: var(--sp-6); }
.tafsir-text-foot{ justify-content: center; }
.tafsir-size-copy{ gap: 8px; }
.tafsir-size-copy svg{ width: 15px; height: 15px; fill: none; stroke: currentColor; }

@media (max-width: 900px){
  /*
   * ═══════════════════════════════════════════════════════════════════
   * v12.2 — TWO ROWS ON A PHONE, AND THE REASON.
   * ═══════════════════════════════════════════════════════════════════
   *
   * `grid-template-columns: auto minmax(0,1fr) auto` was here, and it is
   * the exact fault v12.1 fixed on the base rule directly above and on
   * the site header — a later, higher-specificity rule quietly putting
   * it back. Both `auto` and `minmax(0,…)` let a track come out narrower
   * than what is in it, and both `.tafsir-bar-back` and
   * `.tafsir-bar-book` carry `min-width: 0`, which is an explicit
   * instruction that they may be crushed.
   *
   * Measured at 375px: the reading controls took 293 of the 335px
   * available, the tracks resolved to 30.4px and 0px, and the two
   * buttons that had to live in them — 59px and 26px wide — were painted
   * straight over each other and over the controls. That is the
   * screenshot in the report.
   *
   * And there was no arrangement of one row that could have worked. Back
   * (59) + book + controls (293) + two gaps needs 368px of a 335px row
   * before the book name is given a single pixel. The row is over budget
   * by design, and a grid asked to fit an over-budget row does not fail
   * — it overlaps.
   *
   * So on a phone it is two rows: what you are reading on top, what you
   * can do with it underneath. Every part keeps its own width, the book
   * name is the one thing allowed to elide, and there is no width at
   * which anything can be drawn on top of anything else.
   */
  .tafsir-bar-inner{
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
      "back book"
      "side side";
    column-gap: 8px; row-gap: 7px;
    align-items: center;
    min-height: 0;
    padding-block: 8px;
  }
  .tafsir-bar-back{ grid-area: back; min-width: max-content; }
  .tafsir-bar-book{ grid-area: book; justify-self: start; min-width: 0; max-width: 100%; }
  .tafsir-bar-side{
    grid-area: side; justify-self: stretch;
    justify-content: space-between; gap: 8px;
  }
  /* The two pickers share whatever the fixed-size buttons leave. */
  .tafsir-bar-side .tafsir-pick{ flex: 1 1 auto; min-width: 0; }
  .tafsir-bar-side .tafsir-pick-btn{ flex: 1 1 0; min-width: 0; }
  .tafsir-pick-value{ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* The book name elides rather than pushing the row wide. */
  .tafsir-bar-book-en,
  .tafsir-bar-book-ar{ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  .tafsir-bar-back-full{ display: none; }
  .tafsir-bar-back-short{ display: inline; }
  .tafsir-bar-where-ref{ display: none; }
  .tafsir-bar-where{ padding-inline: 9px; }
  .tafsir-page{ --tafsir-measure: calc(100vw - 2rem); }
  .tafsir-body{ line-height: 2.05; }
  .tafsir-reading-pop{ right: -6px; }
}
@media (max-width: 560px){
  .tafsir-bar-book-ar{ display: none; }
  .tafsir-bar-inner{ gap: 6px; }
  .tafsir-bar-step{ width: 34px; height: 34px; }
  .tafsir-bar-aa{ width: 34px; height: 34px; }
  /*
   * The popover measures 300px and hangs off a button roughly 300px from
   * the left edge of a 390px phone, so anchored to that button its left
   * corner fell two pixels off the screen. Dropping `position:relative`
   * from the wrapper hands the job to `.tafsir-bar`, which is sticky and
   * therefore already a containing block and already spans the window —
   * so `left`/`right` can simply be a margin, with no arithmetic that
   * depends on where the button happened to end up.
   */
  .tafsir-reading{ position: static; }
  .tafsir-reading-pop{ left: 12px; right: 12px; width: auto; }
}

/* -------------------------------------------------------------------------
   5. THE TAFSIR SHEET OVER A QUR'AN PAGE

   See the measurement in buildTafsirPanel() (assets/quran-audio.js) for
   what was wrong. In short: five bands of chrome above a commentary that
   got half the sheet, and the largest of them was twenty near-identical
   pills scrolled sideways.

   The grid below is the whole change: head, one bar, THE TEXT, foot.
   `1fr` is on the text and on nothing else, so every future addition to
   the chrome takes its space from itself rather than from the reading.
   ------------------------------------------------------------------------- */
/*
 * A column, not a grid.
 *
 * v10.2 made this `display:grid` with five named rows and put the `1fr`
 * on the third of them, which meant the commentary only got the elastic
 * row for as long as the sheet had exactly five children in exactly that
 * order. This release removes one of them (the edition rail) and adds
 * one that is position:absolute and therefore not a grid item at all, so
 * the `1fr` would have landed on the FOOTER. A flex column with `flex:1`
 * on the body — which `.qa-tafsir-body` has carried since v9.1 — says
 * "the text takes what is left" without counting anything.
 *
 * `position` is deliberately NOT set here: the base rule pins the sheet
 * with `position:absolute; top:0; right:0; bottom:0`, and an earlier
 * draft of this block set `position:relative` for the chooser's benefit,
 * which un-pinned the sheet and slid the whole thing to the left edge of
 * the window. An absolutely positioned element is already a containing
 * block for its absolute children; it needed nothing.
 */
.qa-tafsir-sheet{
  display: flex;
  flex-direction: column;
  grid-template-rows: none;
}
.qa-tafsir-head{ padding: var(--sp-4) var(--sp-6) var(--sp-3); }
.qa-tafsir-head-row{
  display: flex; align-items: center; gap: var(--sp-4);
  margin-bottom: var(--sp-3);
}
/* The reference and its two arrows sit in the middle of the head row
   now, where the eye lands on opening, instead of on a row of their own
   under the ayah. */
.qa-tafsir-head-row .qa-tafsir-nav{
  margin: 0 auto; gap: var(--sp-2);
}
.qa-tafsir-eyebrow{ flex: 0 0 auto; }
.qa-tafsir-head-row .qa-tafsir-close{ flex: 0 0 auto; }

.qa-tafsir-verse{
  max-width: 46ch;
  margin-inline: auto;
}
.qa-tafsir-verse-en{
  max-width: 62ch; margin: var(--sp-3) auto 0;
  font-family: var(--font-body); font-style: italic;
  font-size: var(--fs-sm); line-height: 1.65;
  color: rgb(var(--text-muted)); text-align: center;
}

/* ---- the one bar ------------------------------------------------------- */
.qa-tafsir-bar{
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 8px var(--sp-6);
  border-top: 1px solid var(--hairline-faint);
  border-bottom: 1px solid var(--hairline-faint);
}
.qa-tafsir-book{
  display: inline-flex; align-items: center; gap: 8px;
  min-width: 0; flex: 0 1 auto;
  padding: 7px 13px;
  border-radius: var(--radius-pill);
  border: 1px solid rgb(var(--wash) / 0.3);
  background: rgb(var(--wash) / 0.08);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
.qa-tafsir-book[aria-expanded="true"]{ background: rgb(var(--wash) / 0.16); border-color: rgb(var(--wash) / 0.5); }
@media (hover: hover){ .qa-tafsir-book:hover{ background: rgb(var(--wash) / 0.16); border-color: rgb(var(--wash) / 0.5); } }
.qa-tafsir-book-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 1rem; line-height: 1.4;
  color: rgb(var(--heading));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.qa-tafsir-book-en{
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--accent-ui)); white-space: nowrap;
}
.qa-tafsir-book-caret{ width: 14px; height: 14px; flex-shrink: 0; fill: none; stroke: currentColor; color: rgb(var(--accent-ui)); }
/* Sits directly beside the book it belongs to, not floated off to the
   far end of the bar: `flex:1` plus the `direction:rtl` the base rule
   gives this element put the name hard against the tools. */
.qa-tafsir-bar .qa-tafsir-author{
  flex: 0 1 auto; min-width: 0;
  /* `margin-right`, not `margin-inline-end`: this element is RTL, so the
     logical property resolves to margin-LEFT and pushes the name to the
     far end of the bar instead of holding it beside the book it names. */
  margin-right: auto;
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 0.92rem;
  color: rgb(var(--text-muted));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.qa-tafsir-bar-tools{ display: flex; align-items: center; gap: 5px; flex: 0 0 auto; }
.qa-tafsir-aa{
  font-family: var(--font-display); font-size: 0.82rem; font-weight: 600; line-height: 1;
}
.qa-tafsir-reading{ position: relative; }
.qa-tafsir-reading-pop{
  position: absolute; bottom: calc(100% + 10px); right: 0; z-index: 8;
  width: min(300px, calc(100vw - 40px));
  padding: 14px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--hairline-strong);
  background: var(--menu-bg);
  background-image: var(--menu-sheen);
  box-shadow: var(--e-overlay);
  opacity: 0; transform: translateY(6px) scale(0.98);
  transition: opacity var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--ease-soft);
}
.qa-tafsir-reading-pop.is-open{ opacity: 1; transform: none; }

/* ---- the chooser ------------------------------------------------------- */
.qa-tafsir-books{
  position: absolute; inset: 0; z-index: 10;
  display: flex; flex-direction: column;
  background: var(--menu-bg);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-soft);
}
.qa-tafsir-books.is-open{ opacity: 1; }
.qa-tafsir-books-head{
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-6);
  border-bottom: 1px solid var(--hairline);
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.qa-tafsir-books-body{
  flex: 1; min-height: 0; overflow-y: auto;
  padding: var(--sp-3) var(--sp-4) calc(var(--sp-6) + env(safe-area-inset-bottom));
  overscroll-behavior: contain;
}
.qa-tafsir-shelf{ margin-bottom: var(--sp-4); }
.qa-tafsir-shelf-label{
  display: flex; align-items: center; gap: 7px;
  padding: 6px 10px;
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.qa-tafsir-shelf-label svg{ width: 14px; height: 14px; fill: none; stroke: currentColor; color: rgb(var(--accent)); }
.qa-tafsir-pick{
  display: flex; align-items: center; gap: var(--sp-3);
  width: 100%; min-width: 0;
  padding: 10px 12px;
  border: none; border-radius: var(--radius);
  background: transparent; text-align: start; cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .qa-tafsir-pick:hover{ background: rgb(var(--wash) / 0.09); } }
.qa-tafsir-pick.is-on{ background: rgb(var(--wash) / 0.14); }
.qa-tafsir-pick-ar{
  flex: 0 0 auto; width: 34%; max-width: 190px;
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 1.02rem; line-height: 1.4;
  /* `right`, not `end` — see the note on .quran-menu-ar. */
  color: rgb(var(--heading)); text-align: right;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.qa-tafsir-pick-main{ display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.qa-tafsir-pick-en{
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 600;
  color: rgb(var(--heading));
}
.qa-tafsir-pick-note{
  font-family: var(--font-ui); font-size: var(--fs-2xs); line-height: 1.5;
  color: rgb(var(--text-muted));
}
.qa-tafsir-pick-tick{
  width: 16px; height: 16px; flex-shrink: 0;
  fill: none; stroke: currentColor; color: rgb(var(--accent));
  opacity: 0;
}
.qa-tafsir-pick.is-on .qa-tafsir-pick-tick{ opacity: 1; }

/* ---- THE COMMENTARY, which is what all of the above is for ------------- */
.qa-tafsir-body{
  flex: 1; min-height: 0;
  padding: var(--sp-5) var(--sp-6) calc(var(--sp-8) + env(safe-area-inset-bottom));
  font-size: 1.3rem;             /* overridden live by the A+/A- control */
  line-height: 2.2;
  /* Two thirds of a 1400px sheet, and the largest thing in it — which is
     what "main focus is the text of the tafsir" asks for. Not `ch`: that
     unit measures the LATIN `0` of the font in force, and this column is
     Arabic naskh, so the old `74ch` was never 74 characters. */
  max-width: min(58rem, 100%);
  margin-inline: auto;
  width: 100%;
  text-align: justify;
  text-align-last: right;
}
.qa-tafsir-foot{
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4);
}
.qa-tafsir-foot .qa-tafsir-note-line{
  flex: 1 1 auto; min-width: 0;
  font-family: var(--font-ui); font-size: var(--fs-2xs); line-height: 1.5;
  color: rgb(var(--text-muted));
  direction: ltr; text-align: start;
}

@media (max-width: 620px){
  .qa-tafsir-head{ padding: var(--sp-3) var(--sp-4) var(--sp-2); }
  .qa-tafsir-head-row{ margin-bottom: var(--sp-2); gap: var(--sp-2); }
  .qa-tafsir-bar{ padding: 7px var(--sp-4); gap: var(--sp-2); }
  /* The Arabic title goes on a phone rather than being cut to
     "جامع الب…", which names nothing. The transliteration beside it is
     the half that stays legible at this width. */
  .qa-tafsir-book-ar{ display: none; }
  .qa-tafsir-verse-en{ margin-top: var(--sp-2); font-size: var(--fs-2xs); line-height: 1.6; }
  /* The author's name is the first thing to go on a phone: the book pill
     beside it already names the book, and the row has to hold three
     controls at a thumb-sized target. */
  .qa-tafsir-bar .qa-tafsir-author{ display: none; }
  .qa-tafsir-body{ padding: var(--sp-4) var(--sp-4) var(--sp-5); font-size: 1.16rem; line-height: 2.05; }
  .qa-tafsir-books-body{ padding-inline: var(--sp-3); }
  .qa-tafsir-pick-ar{ width: 38%; }
  .qa-tafsir-foot .qa-tafsir-note-line{ display: none; }
  .qa-tafsir-reading-pop{ right: -4px; }
}

/* v11.5 — was an inline `style="max-width:800px;margin:0 auto"` on the
   section in hadith-single.php. A hadith is a short text and deserves a
   narrower measure than the site's default; that is a design decision
   and belongs in the stylesheet with the rest of them. */
.hadith-single-shell{ max-width: 800px; margin-inline: auto; }

/* -------------------------------------------------------------------------
   6. THE BREADCRUMB TRAIL, IN ONE PLACE, ON EVERY PAGE

   The trail now carries its own `.wrap` (see pp_render_breadcrumbs() in
   functions.php) and every template emits it OUTSIDE the page's own
   container, so it cannot inherit a different indent on a Qur'an page
   from the one it has on a hadith page. This owns the vertical rhythm
   for all of them: the same gap under the header, the same gap above the
   content, everywhere.
   ------------------------------------------------------------------------- */
.breadcrumbs{
  display: block;
  font-family: var(--font-ui);
  font-size: 0.78rem;
  color: rgb(var(--text-muted));
}
.breadcrumbs-inner{
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  min-width: 0;
}
.breadcrumbs a{
  border-radius: 5px;
  transition: color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .breadcrumbs a:hover{ color: rgb(var(--accent-ui)); } }
.breadcrumbs span[aria-current]{
  color: rgb(var(--heading)); font-weight: 500;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.crumb-sep{ width: 11px; height: 11px; opacity: 0.45; transform: rotate(-90deg); flex-shrink: 0; }
/* On the pages where the trail is followed by a full-bleed hero — the
   Qur'an reader, the tafsir room — it should not add its own gap on top
   of the hero's. */
.breadcrumbs + .quran-reader{ padding-top: var(--sp-2); }

/* -------------------------------------------------------------------------
   7. AN INPUT INSIDE A DECORATED SHELL DOES NOT DRAW A SECOND ONE

   "in the Qur'an page remove this ugly outline around the text on the
   search the Qur'an bar."

   It was not the Qur'an page's own rule. `.quran-search-box input` sets
   `border:none` at (0,1,1), and the v7.1 forms pass added a blanket

       input[type="text"], input[type="search"], select, textarea {
         border: 1px solid var(--hairline-strong); box-shadow: var(--e1); }

   at the same (0,1,1) but seventeen hundred lines further down, so it
   won on source order alone. Every search field on this site that lives
   inside its own rounded, bordered, shadowed shell was therefore drawing
   a second rectangle inside the first — the Qur'an search, the header
   search, the tafsir jump, the hadith and adhkar filters, the library.
   The Qur'an one was simply the most visible, being 1100px wide.

   Fixed for the whole class rather than for the one that was reported.
   The shells all carry `:focus-within`, so the focus ring is not lost —
   it moves to the shape a reader can actually see.
   ------------------------------------------------------------------------- */
.quran-search-box input,
.tafsir-jump-form input,
.tafsir-lib-search input,
.hadith-search input,
.pp-cmd-field input{
  border: none;
  box-shadow: none;
  background: transparent;
  border-radius: 0;
}
.quran-search-box input:focus-visible,
.tafsir-jump-form input:focus-visible,
.tafsir-lib-search input:focus-visible,
.hadith-search input:focus-visible,
.pp-cmd-field input:focus-visible{
  border-color: transparent;
  box-shadow: none;
  outline: none;
}
@media (hover: hover){
  .quran-search-box input:hover,
  .tafsir-jump-form input:hover,
  .tafsir-lib-search input:hover,
  .hadith-search input:hover,
  .pp-cmd-field input:hover{
    border-color: transparent;
    box-shadow: none;
    outline: none;
  }
}
/* …and the shell takes the focus ring instead, so keyboard focus is
   still unmistakable. */
.quran-search-box:focus-within,
.tafsir-lib-search:focus-within,
.hadith-search:focus-within{
  border-color: rgb(var(--wash) / 0.55);
  box-shadow: var(--ring);
}

/* -------------------------------------------------------------------------
   8. A PAGE MEDALLION MUST NOT HIDE UNDER THE HEADER

   "also in adhkar on phone the top icon is partially hidden from the
   header."

   The adhkar page opens with a card whose emblem is deliberately pulled
   ABOVE the card's top edge with a negative margin — a nice detail, and
   one that spends part of the page's top padding. `.site-main` provides
   exactly `--header-h-static + 4px`, which is the height of the header
   and nothing more, so on a phone the medallion was overlapping the
   fixed bar rather than sitting under it.

   The page declares the extra room it needs instead of hoping there is
   some. Scoped to the pages that actually pull something upward, so no
   other page grows a gap it did not ask for.
   ------------------------------------------------------------------------- */
.adhkar-unwan{ margin-top: 18px; }
@media (max-width: 780px){
  /* Measured on a 390px phone: the medallion's top edge sat at 51px with
     the header's bottom at 69px — eighteen pixels of it behind the bar.
     The page also gains its breadcrumb trail in this release, which is
     part of the clearance; this is the rest of it, stated rather than
     relied on, so removing the trail could never bring the bug back. */
  .adhkar-unwan{ margin-top: 26px; }
}

/* -------------------------------------------------------------------------
   9. THE COMMAND PALETTE

   Replaces `.search-panel`, the 280px popover that hung off the header's
   search button. See the note in header.php for what it could and could
   not find; this is only how it looks.

   It sits high rather than centred — at 12vh — for the reason every
   palette does: the list grows downward as you type, and a vertically
   centred card would slide the field you are typing into up the screen
   while you use it.
   ------------------------------------------------------------------------- */
.pp-cmd{
  position: fixed; inset: 0; z-index: 240;
  display: grid; align-items: start; justify-items: center;
  padding: 12vh var(--sp-4) var(--sp-6);
}
.pp-cmd[hidden]{ display: none; }
.pp-cmd-scrim{
  position: absolute; inset: 0;
  /* `--scrim` is a finished colour, not an R G B triplet — see the
     palette block. Compositing it again with `rgb(… / 0.5)` would emit
     an invalid value and paint nothing at all. */
  background: var(--scrim);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-soft);
}
.pp-cmd.is-open .pp-cmd-scrim{ opacity: 1; }
.pp-cmd-card{
  position: relative;
  width: min(680px, 100%);
  max-height: min(70vh, 640px);
  display: flex; flex-direction: column;
  border-radius: var(--radius-lg);
  border: 1px solid var(--hairline-strong);
  background: var(--menu-bg);
  background-image: var(--menu-sheen);
  box-shadow: var(--e-overlay);
  overflow: hidden;
  opacity: 0; transform: translateY(-10px) scale(0.985);
  transition: opacity var(--dur) var(--ease-out-expo), transform var(--dur) var(--spring);
}
.pp-cmd.is-open .pp-cmd-card{ opacity: 1; transform: none; }
body.pp-cmd-open{ overflow: hidden; }

/* ---- the field --------------------------------------------------------- */
.pp-cmd-field{
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 14px 16px;
  border-bottom: 1px solid var(--hairline);
  flex: 0 0 auto;
}
.pp-cmd-ic{
  width: 19px; height: 19px; flex-shrink: 0;
  fill: none; stroke: currentColor;
  color: rgb(var(--text-muted));
  transition: color var(--dur-fast) var(--ease-soft);
}
.pp-cmd.is-busy .pp-cmd-ic{ color: rgb(var(--accent)); animation: ppCmdPulse 1s var(--ease-soft) infinite; }
@keyframes ppCmdPulse{ 50%{ opacity: 0.4; } }
.pp-cmd-field input{
  flex: 1; min-width: 0;
  padding: 4px 0;
  font-family: var(--font-ui); font-size: 1.02rem; line-height: 1.4;
  color: rgb(var(--heading));
}
.pp-cmd-field input::placeholder{ color: rgb(var(--text-muted)); opacity: 0.85; }
.pp-cmd-field input::-webkit-search-cancel-button{ display: none; }
.pp-cmd-clear{
  width: 26px; height: 26px; flex-shrink: 0;
  display: grid; place-items: center;
  border: none; border-radius: 50%;
  background: rgb(var(--ink) / 0.07);
  color: rgb(var(--text-muted)); cursor: pointer;
}
.pp-cmd-clear svg{ width: 13px; height: 13px; fill: none; stroke: currentColor; }
@media (hover: hover){ .pp-cmd-clear:hover{ background: rgb(var(--ink) / 0.13); color: rgb(var(--heading)); } }
.pp-cmd-esc{
  flex-shrink: 0;
  padding: 4px 8px;
  border: 1px solid var(--hairline-strong); border-radius: 6px;
  background: transparent; cursor: pointer;
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: var(--track-caps);
  text-transform: uppercase; color: rgb(var(--text-muted));
}
@media (hover: hover){ .pp-cmd-esc:hover{ color: rgb(var(--heading)); border-color: rgb(var(--wash) / 0.45); } }

/* ---- the results ------------------------------------------------------- */
.pp-cmd-results{
  flex: 1; min-height: 0;
  overflow-y: auto; overscroll-behavior: contain;
  padding: var(--sp-2) var(--sp-2) var(--sp-3);
}
.pp-cmd-group + .pp-cmd-group{ margin-top: var(--sp-2); }
.pp-cmd-group-label{
  display: flex; align-items: center; gap: 7px;
  padding: 8px 12px 5px;
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.pp-cmd-group-label svg{ width: 13px; height: 13px; fill: none; stroke: currentColor; color: rgb(var(--accent)); }
.pp-cmd-row{
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 9px 12px; border-radius: var(--radius);
  min-width: 0;
  transition: background-color var(--dur-fast) var(--ease-soft);
}
/* One highlight, driven by the keyboard, and the mouse moves it rather
   than adding a second one — two different "current" rows in a list you
   are arrowing through is the classic palette bug. */
.pp-cmd-row.is-on{ background: rgb(var(--wash) / 0.13); }
.pp-cmd-row-ic{
  width: 30px; height: 30px; flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: 9px;
  background: rgb(var(--wash) / 0.11);
  color: rgb(var(--accent));
}
.pp-cmd-row-ic svg{ width: 15px; height: 15px; fill: none; stroke: currentColor; }
.pp-cmd-row-main{ display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.pp-cmd-row-title{
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 600;
  color: rgb(var(--heading));
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pp-cmd-row-sub{
  font-family: var(--font-ui); font-size: var(--fs-2xs); line-height: 1.5;
  color: rgb(var(--text-muted));
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pp-cmd-row mark{
  background: rgb(var(--wash) / 0.28);
  color: inherit; border-radius: 3px; padding: 0 1px;
}
.pp-cmd-row-ar{
  flex: 0 0 auto; max-width: 34%;
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 1.02rem; line-height: 1.4;
  color: rgb(var(--heading-soft));
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  unicode-bidi: isolate;
}
.pp-cmd-row-meta{
  /* Capped: a hadith's narrator chain runs to sixty characters, and this
     column is a label, not a second description. */
  flex: 0 1 auto; max-width: 22ch;
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.03em;
  color: rgb(var(--text-muted));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pp-cmd-empty{
  display: flex; flex-direction: column; gap: 6px;
  padding: var(--sp-8) var(--sp-6);
  text-align: center;
}
.pp-cmd-empty-title{
  font-family: var(--font-display); font-size: var(--fs-md); font-weight: 600;
  color: rgb(var(--heading));
}
.pp-cmd-empty-hint{
  font-family: var(--font-ui); font-size: var(--fs-2xs); line-height: 1.6;
  color: rgb(var(--text-muted)); max-width: 42ch; margin-inline: auto;
}

/* ---- the foot ---------------------------------------------------------- */
.pp-cmd-foot{
  display: flex; align-items: center; gap: var(--sp-4);
  flex: 0 0 auto;
  padding: 9px 16px calc(9px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--hairline);
  background: rgb(var(--ink) / 0.02);
}
.pp-cmd-hint{
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--font-ui); font-size: var(--fs-2xs);
  color: rgb(var(--text-muted));
}
.pp-cmd-hint kbd{
  min-width: 18px; padding: 1px 5px;
  border: 1px solid var(--hairline-strong); border-radius: 5px;
  background: rgb(var(--surface));
  font-family: var(--font-code); font-size: 0.62rem; line-height: 1.5;
  text-align: center; color: rgb(var(--heading-soft));
}
.pp-cmd-all{
  display: inline-flex; align-items: center; gap: 5px;
  margin-inline-start: auto;
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight: 600;
  color: rgb(var(--accent-ui)); white-space: nowrap;
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
.pp-cmd-all svg{ width: 13px; height: 13px; flex-shrink: 0; fill: none; stroke: currentColor; }

@media (max-width: 620px){
  /* On a phone it is the screen. Nothing is gained by floating a card
     with 16px of dimmed page around it, and a full sheet keeps the list
     as long as the device allows. */
  .pp-cmd{ padding: 0; }
  .pp-cmd-card{
    width: 100%; max-height: 100%; height: 100%;
    border-radius: 0; border: none;
  }
  .pp-cmd-field{ padding: calc(10px + env(safe-area-inset-top)) 14px 10px; }
  .pp-cmd-row-ar{ display: none; }
  .pp-cmd-row-meta{ display: none; }
  /* Two hints, not three: "esc" is the button in the field on a phone,
     and there is no keyboard to press it on anyway. */
  .pp-cmd-hint:nth-child(1),
  .pp-cmd-hint:nth-child(2),
  .pp-cmd-hint:nth-child(3){ display: none; }
  .pp-cmd-all{ margin-inline-start: 0; }
  .pp-cmd-foot{ justify-content: center; }
}


/* -------------------------------------------------------------------------
   10. THE RESULTS PAGE

   See the note at the top of search.php. The shape is deliberately the
   same as the palette's — the same icon well, title, description, Arabic
   and meta — because they answer the same question from the same
   function, and two different-looking answers to one query is how a
   reader stops trusting a search.
   ------------------------------------------------------------------------- */
.pp-results-head{ margin-bottom: var(--sp-5); }
.pp-results-head h1{
  margin: var(--sp-2) 0 0;
  font-size: clamp(1.6rem, 1.1rem + 2vw, 2.4rem);
  line-height: 1.25;
}
.pp-results-q{ color: rgb(var(--accent-ui)); }
.pp-results-count{
  margin: var(--sp-2) 0 0;
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps);
  color: rgb(var(--text-muted));
}

.pp-results-form{
  display: flex; align-items: center; gap: var(--sp-3);
  margin-bottom: var(--sp-5);
  padding: 8px 10px 8px 18px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline-strong);
  background: rgb(var(--surface));
  box-shadow: var(--e1);
  transition: border-color var(--dur-fast) var(--ease-soft), box-shadow var(--dur-fast) var(--ease-soft);
}
.pp-results-form:focus-within{ border-color: rgb(var(--wash) / 0.55); box-shadow: var(--ring); }
.pp-results-form-ic{ display: grid; place-items: center; color: rgb(var(--text-muted)); flex-shrink: 0; }
.pp-results-form-ic svg{ width: 18px; height: 18px; fill: none; stroke: currentColor; }
.pp-results-form input{
  flex: 1; min-width: 0;
  border: none; background: transparent; box-shadow: none; border-radius: 0;
  font-family: var(--font-ui); font-size: 1rem;
  color: rgb(var(--heading));
}
.pp-results-form input:focus, .pp-results-form input:focus-visible{ outline: none; border-color: transparent; box-shadow: none; }
@media (hover: hover){ .pp-results-form input:hover{ outline: none; border-color: transparent; box-shadow: none; } }
.pp-results-form input::-webkit-search-cancel-button{ display: none; }
.pp-results-form .btn{ flex-shrink: 0; }

/* ---- the filter strip -------------------------------------------------- */
.pp-results-filters{
  display: flex; align-items: center; gap: 7px;
  flex-wrap: wrap;
  margin-bottom: var(--sp-6);
}
.pp-filter{
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline-strong);
  background: transparent;
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight: 600;
  color: rgb(var(--heading-soft));
  transition: background-color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
.pp-filter svg{ width: 14px; height: 14px; fill: none; stroke: currentColor; opacity: 0.8; }
@media (hover: hover){ .pp-filter:hover{ border-color: rgb(var(--wash) / 0.45); color: rgb(var(--accent-ui)); } }
.pp-filter.is-on{
  background: rgb(var(--wash) / 0.13);
  border-color: rgb(var(--wash) / 0.45);
  color: rgb(var(--accent-ui));
}
.pp-filter-n{
  font-family: var(--font-mono); font-size: 0.62rem;
  padding: 1px 6px; border-radius: 999px;
  background: rgb(var(--ink) / 0.07);
  color: rgb(var(--text-muted));
}
.pp-filter.is-on .pp-filter-n{ background: rgb(var(--wash) / 0.2); color: rgb(var(--accent-ui)); }

/* ---- the groups -------------------------------------------------------- */
.pp-res-group{ margin-bottom: var(--sp-8); scroll-margin-top: calc(var(--header-h) + 20px); }
.pp-res-group-title{
  display: flex; align-items: center; gap: 9px;
  margin: 0 0 var(--sp-3);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--hairline);
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  font-weight: 600;
  color: rgb(var(--text-muted));
}
.pp-res-group-title svg{ width: 15px; height: 15px; fill: none; stroke: currentColor; color: rgb(var(--accent)); }
.pp-res-group-n{
  margin-inline-start: auto;
  font-size: 0.62rem; color: rgb(var(--text-muted));
}
.pp-res-list{ display: flex; flex-direction: column; gap: 2px; }
.pp-res-row{
  display: flex; align-items: center; gap: var(--sp-4);
  min-width: 0;
  padding: 13px 14px;
  border-radius: var(--radius);
  transition: background-color var(--dur-fast) var(--ease-soft), transform var(--dur) var(--ease-out-expo);
}
@media (hover: hover){ .pp-res-row:hover{ background: rgb(var(--wash) / 0.08); transform: translateX(3px); } }
.pp-res-ic{
  width: 36px; height: 36px; flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: 11px;
  background: rgb(var(--wash) / 0.11);
  color: rgb(var(--accent));
}
.pp-res-ic svg{ width: 17px; height: 17px; fill: none; stroke: currentColor; }
.pp-res-main{ display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.pp-res-title{
  font-family: var(--font-display); font-size: 1rem; font-weight: 600;
  color: rgb(var(--heading));
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pp-res-sub{
  font-family: var(--font-ui); font-size: var(--fs-2xs); line-height: 1.55;
  color: rgb(var(--text-muted));
  min-width: 0;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.pp-res-ar{
  flex: 0 1 auto; max-width: 30%;
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 1.08rem; line-height: 1.5;
  color: rgb(var(--heading-soft));
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  unicode-bidi: isolate;
}
.pp-res-meta{
  flex: 0 1 auto; max-width: 24ch;
  font-family: var(--font-mono); font-size: 0.64rem; letter-spacing: 0.03em;
  color: rgb(var(--text-muted));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pp-res-go{
  width: 15px; height: 15px; flex-shrink: 0;
  fill: none; stroke: currentColor; color: rgb(var(--accent));
  opacity: 0; transform: translateX(-5px);
  transition: opacity var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .pp-res-row:hover .pp-res-go{ opacity: 1; transform: none; } }

.pp-results-note{
  margin: 0 0 var(--sp-6);
  padding: 12px 16px;
  border-radius: var(--radius);
  background: rgb(var(--ink) / 0.03);
  border: 1px dashed var(--hairline-strong);
  font-family: var(--font-ui); font-size: var(--fs-2xs); line-height: 1.7;
  color: rgb(var(--text-muted));
}
.pp-results-note a{ color: rgb(var(--accent-ui)); font-weight: 600; white-space: nowrap; }

.pp-results-none{
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-3);
  padding: var(--sp-10) var(--sp-4) var(--sp-8);
  text-align: center;
}
.pp-results-none-ic{
  width: 34px; height: 34px;
  fill: none; stroke: currentColor; color: rgb(var(--accent)); opacity: 0.5;
}
.pp-results-none h2{ margin: 0; font-size: var(--fs-xl); }
.pp-results-none p{
  margin: 0; max-width: 56ch;
  font-size: var(--fs-sm); line-height: 1.75; color: rgb(var(--text-muted));
}

@media (max-width: 700px){
  .pp-res-ar{ display: none; }
  .pp-res-meta{ display: none; }
  .pp-res-row{ gap: var(--sp-3); padding: 12px 10px; }
  .pp-res-go{ display: none; }
  .pp-results-form{ flex-wrap: wrap; border-radius: var(--radius-lg); padding: 10px 12px; }
  .pp-results-form input{ flex: 1 1 100%; order: -1; padding: 4px 0 8px; }
  .pp-results-form .btn{ flex: 1; justify-content: center; }
  .pp-results-form-ic{ display: none; }
}

/* -------------------------------------------------------------------------
   11. THE FRONTISPIECE, REBALANCED

   See the long note in front-page.php. In one line: the ayah is the
   hero and the wordmark is a lockup above it, so the panel is about
   half the height it was and the first thing a reader meets is a verse
   rather than a statistic about the archive.

   Overrides `.hero`, `.hero-frame`, `.hero h1` and the stats block from
   sections 4 and "THE FRONTISPIECE — v11.1" earlier in this file.
   ------------------------------------------------------------------------- */
.hero{ padding: 34px 0 8px; }
.hero-frame{
  padding: clamp(26px, 3vw, 38px) clamp(20px, 4vw, 44px);
  border-radius: var(--radius-xl, var(--radius-lg));
}
/* Wider than the 660px it was, for one reason: at the size the ayah is
   now set, 29:69 needs about 800px to sit on ONE line, and a two-line
   Qur'anic verse costs 70px of panel height that the whole rebalance
   was meant to give back. */
.hero-content{ max-width: 840px; }

/* ---- the lockup -------------------------------------------------------- */
.hero-lockup{ display: flex; flex-direction: column; align-items: center; gap: 4px; }
.hero .eyebrow{ margin-bottom: 4px; }
.hero h1.hero-name{
  /* Was clamp(2.4rem, 6vw, 3.7rem). A name, not a billboard: the header
     sixty pixels above says the same words, and so does the tab. */
  margin: 0;
  font-size: clamp(1.5rem, 1.15rem + 1.5vw, 2rem);
  line-height: 1.15;
  letter-spacing: -0.012em;
}
.hero .sub{
  margin-top: 2px;
  font-size: clamp(0.95rem, 0.88rem + 0.35vw, 1.1rem);
}

/* ---- the verse, which is now the middle of the panel -------------------- */
.hero-rule{ margin: clamp(18px, 2.4vw, 26px) auto; }
.hero-verse{ margin: 0; }
.hero-ayah{
  /* Up from the old clamp(1.3rem … 1.85rem): it is the centrepiece now,
     so it may be the largest thing on the panel — which it can be
     without the panel growing, because the wordmark above it shrank by
     more than this gains. */
  margin: 0 auto var(--sp-3);
  max-width: none;
  font-size: clamp(1.3rem, 0.95rem + 1.35vw, 1.78rem);
  line-height: 1.95;
}
.hero-ayah-en{
  margin: 0 auto 7px;
  max-width: 50ch;
  font-size: clamp(0.92rem, 0.87rem + 0.25vw, 1.02rem);
}
.hero-ayah-ref{ font-style: normal; }
.hero-ayah-ref a{
  color: rgb(var(--accent-ui));
  border-bottom: 1px solid rgb(var(--ornament) / 0);
  transition: border-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .hero-ayah-ref a:hover{ border-bottom-color: rgb(var(--ornament) / 0.55); } }

/* ---- the invitation ---------------------------------------------------- */
.hero p.desc{
  margin-top: 0;
  max-width: 46ch;
  font-size: clamp(0.95rem, 0.9rem + 0.25vw, 1.05rem);
  line-height: 1.65;
}
.hero-ctas{ margin-top: clamp(18px, 2.4vw, 26px); gap: 12px; }
.hero-note{
  margin-top: 14px;
  font-family: var(--font-mono);
  font-style: normal;
  font-size: 0.66rem;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: rgb(var(--text-muted));
  opacity: 0.9;
}

/* The corner rules and the watermarks were drawn for a 604px panel and
   crowd a 372px one. Kept — they are the manuscript detail that makes
   this a frontispiece rather than a box — but pulled in and quietened. */
.corner{ width: 34px; height: 34px; opacity: 0.55; }
.corner.tl{ top: 11px; left: 11px; }
.corner.tr{ top: 11px; right: 11px; }
.corner.bl{ bottom: 11px; left: 11px; }
.corner.br{ bottom: 11px; right: 11px; }
.hero-watermark-1{ width: 240px; height: 240px; top: -70px; right: -50px; }
.hero-watermark-2{ width: 150px; height: 150px; bottom: -46px; left: -36px; }

@media (max-width: 620px){
  .hero{ padding-top: 22px; }
  .corner{ width: 26px; height: 26px; }
  .corner.tl, .corner.tr{ top: 8px; }
  .corner.bl, .corner.br{ bottom: 8px; }
  .corner.tl, .corner.bl{ left: 8px; }
  .corner.tr, .corner.br{ right: 8px; }
  .hero-ayah{ max-width: none; }
  .hero-note{ font-size: 0.6rem; }
}

/* The Arabic name beside the English title on the Qur'an page's
   commentaries card. Isolated so the two directions cannot reorder into
   one run, and given a real gap rather than a single shared space. */
.quran-tafsir-card-ar{
  display: inline-block;
  /* `margin-left`, not `margin-inline-start`: this element carries
     dir="rtl", so the logical property resolves to margin-RIGHT and the
     gap opens on the wrong side of it. The heading it sits in is
     left-to-right, and that is the direction the gap belongs to. */
  margin-left: 0.6em;
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 0.92em;
  color: rgb(var(--accent-ui));
  unicode-bidi: isolate;
  vertical-align: baseline;
}


/* =========================================================================
   v12.2 — THE COUNTER: WHAT IS BEING COUNTED, AND HOW TO STOP

   See the long note at the head of assets/tasbih.js. The counter used to
   open on whichever dhikr happened to be first in the list and offered no
   way back out of a chosen one. It now opens on a free count and says so,
   and the chip below carries the one control that lets a chosen dhikr go.
   ========================================================================= */
.tasbih-chip{
  display: inline-flex; align-items: center; gap: 8px;
  max-width: 100%;
  padding: 6px 8px 6px 14px;
  border: 1px solid rgb(var(--wash) / 0.34);
  border-radius: var(--radius-pill);
  background: rgb(var(--wash) / 0.09);
}
/* A free count is the resting state, so it is drawn as one: no accent, no
   affordance, nothing suggesting something is switched on. */
.tasbih-chip.is-free{
  padding-inline: 14px;
  border-color: var(--hairline-strong);
  background: rgb(var(--ink) / 0.04);
}
.tasbih-chip-label{
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: 0.02em;
  color: rgb(var(--accent-ui));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tasbih-chip.is-free .tasbih-chip-label{ color: rgb(var(--text-muted)); font-weight: 500; }
.tasbih-chip-clear{
  flex: 0 0 auto;
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  border: none; background: rgb(var(--wash) / 0.16);
  color: rgb(var(--accent-ui));
  transition: background var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .tasbih-chip-clear:hover{ background: rgb(var(--wash) / 0.3); } }
.tasbih-chip-clear svg{ width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2.2; }

/* The dhikr block keeps its height reserved so the dial does not jump up
   the page the moment a dhikr is let go. */
.tasbih-dhikr[hidden]{ display: block !important; visibility: hidden; }

/* The free count in the list. */
.tasbih-row-free{ border-style: dashed; }
.tasbih-row-free.is-on{ border-style: solid; }
.tasbih-row-free-ic{
  display: grid; place-items: center;
  width: 30px; height: 30px; max-width: none;
  border-radius: 50%;
  background: rgb(var(--wash) / 0.11);
  color: rgb(var(--accent-ui));
}
.tasbih-row-free-ic svg{ width: 15px; height: 15px; fill: none; stroke: currentColor; }
.tasbih-row-free .tasbih-row-nums{ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ---- The number in the dial ------------------------------------------
   `.tasbih-num` is `inset:0` and centres its own text; `.tasbih-of` sits
   at 19% from the bottom of the same box. At the top of the clamp
   (4.6rem) on a small dial the two were close enough that a four-figure
   count — which is now reachable, since aṭ-Ṭafrījiyyah's traditional
   count is 4,444 — would have printed into "/ 4444" below it. The number
   is lifted and the label pinned lower, with the gap stated rather than
   left to arithmetic. */
.tasbih-num{ transform: translateY(-9%); }
.tasbih-of{ bottom: 16%; }
/* Four figures need the room; `ch` on a tabular face is exact. */
.tasbih-num{ font-size: clamp(2.6rem, 1.7rem + 5.2vw, 4.2rem); }

@media (max-width: 620px){
  .tasbih-chip{ max-width: 100%; }
  .tasbih-num{ font-size: clamp(2.4rem, 1.6rem + 5vw, 3.6rem); }
}

/* =========================================================================
   v12.2 — THE ADHKĀR SET PICKER

   Two controls for one job, one shown at a time:

     ≥761px   the strip, tidied — equal-width tiles, the Arabic leading,
              the two corner numerals gone.
     ≤760px   one full-width control and a sheet of all nine.

   See the long note above the markup in page-tasbih.php for why nine
   sets is past what a horizontal rail can carry.
   ========================================================================= */

/* ---- The strip, on a wide screen -------------------------------------- */
.adhkar-tabs{
  gap: 8px;
  margin-bottom: var(--sp-6);
  overflow-x: auto; scrollbar-width: none;
  padding-bottom: 4px;
  scroll-snap-type: x proximity;
}
.adhkar-tabs::-webkit-scrollbar{ display: none; }

.adhkar-tab{
  position: relative; scroll-snap-align: center;
  /* `1 1 0` rather than `0 0 auto`: equal tiles. A tile whose width is
     set by its own label is why the row read as ragged. */
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  border: 1px solid var(--hairline-strong); border-radius: var(--radius);
  background: rgb(var(--surface)); cursor: pointer;
  text-align: center;
  transition: border-color var(--dur-fast) var(--ease-soft),
              background var(--dur-fast) var(--ease-soft),
              transform var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .adhkar-tab:hover{ border-color: rgb(var(--wash) / 0.45); transform: translateY(-1px); } }
.adhkar-tab.is-on{
  border-color: rgb(var(--wash) / 0.75);
  background: rgb(var(--wash) / 0.09);
}
.adhkar-tab-ic{
  display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: rgb(var(--wash) / 0.1);
  color: rgb(var(--accent-ui));
}
.adhkar-tab.is-on .adhkar-tab-ic{ background: rgb(var(--wash) / 0.2); }
.adhkar-tab-ic svg{ width: 16px; height: 16px; fill: none; stroke: currentColor; }
/* The Arabic leads. It is the name of the thing. */
.adhkar-tab-ar{
  color: rgb(var(--heading));
}
.adhkar-tab-en{
  font-family: var(--font-ui); font-size: 0.68rem; font-weight: 500;
  letter-spacing: 0.02em;
  color: rgb(var(--text-muted)); line-height: 1.25;
}
.adhkar-tab.is-on .adhkar-tab-en{ color: rgb(var(--heading-soft)); }
/* One numeral, bottom centre, not two in opposite corners. */
.adhkar-tab-n{
  position: static; margin-top: 2px;
  font-family: var(--font-mono); font-size: 0.58rem; letter-spacing: 0.04em;
  color: rgb(var(--text-muted)); opacity: 0.8;
}
.adhkar-tab.is-on .adhkar-tab-n{ color: rgb(var(--accent-ui)); opacity: 1; }
.adhkar-tab-done{
  position: absolute; top: 6px; right: 8px;
  font-family: var(--font-mono); font-size: 0.55rem;
  color: rgb(var(--accent-ui)); opacity: 0.85;
}
.adhkar-tab-done.is-complete{
  color: rgb(var(--on-ink)); background: rgb(var(--accent-3, var(--accent)));
  border-radius: var(--radius-pill); padding: 1px 5px; opacity: 1;
}

/* The phone controls do not exist above the breakpoint. */


/* ---- The phone and the small tablet — v12.3 raised this from 760px.
   Between 761 and 900 there is not room for nine tabs, so the strip was
   a horizontal scroller with its Arabic labels clipped; that width is
   what "text coming out of place" was photographed at. --------------- */


/* ---- The sheet ------------------------------------------------------ */


/* The panel below no longer needs the strip's bottom margin. */


/* Scroll-locked while a bottom sheet is up. Shared, so any future sheet
   gets the same behaviour. */
body.pp-sheet-open{ overflow: hidden; }

@media (prefers-reduced-motion: reduce){
  
  
  @media (hover: hover){ .adhkar-tab:hover{ transform: none; } }
}

/* =========================================================================
   v12.2 — ARABIC TYPOGRAPHY, AND THE HEAD OF A BOOK

   THE REPORT: "the font used for الأحاديث النبوية text in main page and
   the 'Four collections, read straight through' is ugly, and I don't
   like that colour either… same for the font used to display the names
   of the books, and even when opening the book itself the Arabic is so
   small, ugly font & colour too."

   Every part of that was a real, findable fault:

   1. THE FONT WAS NOT A FONT. Arabic titles were being set in
      `--font-display`, which is Fraunces. Fraunces contains no Arabic
      glyphs whatsoever, so all of them fell through the stack to
      whatever the device's default serif happened to be — Times on a
      Mac, Droid Naskh on Android, something else again on Windows. The
      site had no control over any of it, which is precisely why it
      looked like an accident.

   2. THE SIZE WAS SET FOR LATIN. Naskh needs roughly 1.3× the point
      size of a Latin face beside it to read at the same weight, because
      the letterforms sit lower on the em and carry marks above and
      below. Every Arabic title here was set at parity or below.

   3. THE COLOUR WAS `--accent`. That is the mid gold, correct for a
      10px mono label and far too low-contrast for a heading — on
      parchment it reads as a watermark rather than as a title.

   The fix is a token, not a patch: `--font-arabic-display` (Aref Ruqaa
   over Amiri) for titles at 1.3rem and up, `--font-arabic` (Amiri) for
   everything else, heading ink for anything that is a title, and gold
   kept for the small labels it was designed for.
   ========================================================================= */

/* ---- The head of a book, and of the hadith index ---------------------- */
.book-unwan{
  border-radius: var(--radius-lg);
  box-shadow: var(--e2);
  overflow: hidden;
}
.book-unwan-rule{
  position: absolute; top: 0; left: 0; right: 0;
  background: linear-gradient(90deg,
    rgb(var(--ornament) / 0) 0%, rgb(var(--ornament) / 0.85) 22%,
    rgb(var(--ornament) / 0.85) 78%, rgb(var(--ornament) / 0) 100%);
}
.book-unwan-mark{
  display: grid; place-items: center;
  width: 56px; height: 56px; margin: 0 auto var(--sp-5);
  border-radius: 50%;
  background: rgb(var(--ornament) / 0.12);
  border: 1px solid rgb(var(--ornament) / 0.35);
  color: rgb(var(--accent-ui));
}
.book-unwan-mark svg{ width: 26px; height: 26px; fill: none; stroke: currentColor; }
.book-unwan-ar{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: clamp(1.9rem, 1.15rem + 3.4vw, 3.1rem);
  line-height: 1.8;
  color: rgb(var(--heading));
  margin: 0; letter-spacing: 0;
}
.book-unwan-en{
  font-family: var(--font-ui);
  font-size: var(--fs-2xs);
  letter-spacing: 0.18em; text-transform: uppercase;
  color: rgb(var(--text-muted));
  margin: 4px 0 0;
}
.book-unwan-divider{
  display: block; width: 88px; height: 1px; margin: var(--sp-5) auto;
  background: linear-gradient(90deg, transparent, rgb(var(--ornament) / 0.6), transparent);
}
.book-unwan-desc{
  max-width: 60ch; margin: 0 auto;
  font-size: var(--fs-base); line-height: 1.75;
  color: rgb(var(--text-muted));
}

@media (max-width: 600px){
  .book-unwan{ padding: calc(var(--sp-8) + 4px) var(--sp-4) var(--sp-6); }
  .book-unwan-mark{ width: 48px; height: 48px; margin-bottom: var(--sp-4); }
  .book-unwan-mark svg{ width: 22px; height: 22px; }
}

/* ---- A book's own name, on its collection page ------------------------ */
/* Replaces `.hadith-book-meta .eyebrow`, which was a mono uppercase label
   class carrying `direction:rtl` inside a `flex:1` box — so it rendered
   on its own line hard against the right edge of the header, detached
   from the English title it belonged to. */
.hadith-book-ar{
  text-align: start;
  margin-bottom: 2px;
  letter-spacing: 0;
}/* ---- The book names in the index grid --------------------------------- */
/* v12.3 — 1.55rem back to 1.32rem. "what I meant was the name of the book
   itself like صحيح مسلم on the page of that specific book": the request
   was about the FACE and the COLOUR of a book's name, not about making
   every Arabic string on the site bigger. The face and the ink stay; the
   size goes back to sitting with the English title rather than over it. */
.hadith-collection-arabic{
  unicode-bidi: isolate;
  margin-bottom: 2px;
}

/* ---- The Arabic inside a book ----------------------------------------- */
/* On a listing card. Was 1.12rem of Scheherazade, which against a
   0.98rem Latin excerpt reads SMALLER than the English it heads. */
.hadith-card-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 1.16rem;
  line-height: 2.05;
  color: rgb(var(--heading));
}

/* On the hadith's own page.
   v12.3 — back to the size it was. v12.2 raised this to a 24-31px clamp
   on the reasoning that vowelled Naskh needs 20px+ for its harakat to
   separate. That reasoning is sound for a SHORT vowelled dhikr and wrong
   for a hadith: a hadith carries its full isnād, so the Arabic block is
   often eight or ten lines, and at 31px it stopped being a paragraph and
   became a poster — you could no longer see a narration and its
   translation on one screen. Amiri at 22px already separates its harakat
   cleanly, which was the actual requirement. The face and the ink from
   v12.2 stay; only the size returns. */
.hadith-arabic{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 1.4rem;
  line-height: 2.2;
  color: rgb(var(--heading));
  border-color: rgb(var(--wash) / 0.22);
}
.hadith-single-chapter-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  color: rgb(var(--accent-ui));
}

@media (max-width: 620px){
  /* Doubled specificity to beat the older `.hadith-arabic.hadith-arabic`
     phone rule further up the file, which set 1.15em. */
  .hadith-arabic.hadith-arabic{
    font-size: 1.22rem; line-height: 2.15;
    padding: var(--sp-5) var(--sp-4);
  }
  .hadith-card-ar{ font-size: 1.12rem; }
  .hadith-collection-arabic{ font-size: 1.22rem; }
  .hadith-book-ar{ text-align: center; }
}

/* ---- Every other Arabic title that was falling through Fraunces ------- */
/* `.hero .sub` is --font-display italic. Wherever it carried Arabic —
   the Qur'an index, the tafsir room, the hadith index before this
   release — the browser had nothing to render it with. Any element
   marked `lang="ar"` inside a hero now gets a real Arabic face, at a
   size and colour chosen for it. */
/*
 * v12.3 — `.hero-content [lang="ar"]` IS GONE, AND THIS IS WHY.
 *
 * Reported as "under Home Page the verse disappeared! and on phone it
 * shows as weird characters".
 *
 * The homepage hero carries Sūrat al-ʿAnkabūt 29:69, and that text is
 * not ordinary Arabic — it is PUA-encoded Hafs glyphs out of
 * data/quran/, which render in exactly one font on earth: the
 * KFGQPC Hafs Smart face this theme ships (see the @font-face at the
 * top of this file). `.hero-ayah` asks for it by name.
 *
 * A blanket descendant selector on `[lang="ar"]` is more specific than
 * a single class, so it beat `.hero-ayah` and handed the verse to a
 * display face that has no PUA glyphs at all. Result: an empty box the
 * height of two lines on a desktop, and a row of tofu on a phone.
 *
 * The lesson is not "add an exception". It is that a font-family rule
 * must never be written against an attribute that content happens to
 * carry — the elements that need a face are named, one at a time.
 */
.hero .sub[lang="ar"],
.hero h1[lang="ar"],
.hero-content .eyebrow[lang="ar"]{
  font-family: var(--font-arabic-display);
  font-style: normal; font-weight: var(--ar-weight);
  line-height: 1.85;
  color: rgb(var(--heading));
}
.hero .sub[lang="ar"]{ font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.2rem); }

/* ---- The homepage shelf ----------------------------------------------- */
/* Six books, not thirteen — see front-page.php. A shelf rather than a
   grid of equal cards: the two Sahihs are the two Sahihs, and a layout
   that gives them the same weight as a forty-hadith anthology is telling
   the reader something untrue about the corpus. */
.hadith-shelf{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(228px, 1fr));
  gap: var(--sp-4);
}
.hadith-shelf-card{
  position: relative;
  display: flex; flex-direction: column;
  gap: 4px;
  padding: var(--sp-5) var(--sp-5) var(--sp-4);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius);
  background: rgb(var(--surface));
  overflow: hidden;
  transition: border-color var(--dur) var(--ease-soft),
              transform var(--dur) var(--ease-soft),
              box-shadow var(--dur) var(--ease-soft);
}
/* The gold rule along the top edge, as on every other book head on the
   site. It is the shelf's spine. */
.hadith-shelf-card::before{
  content: ''; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: linear-gradient(90deg,
    rgb(var(--ornament) / 0.15), rgb(var(--ornament) / 0.8), rgb(var(--ornament) / 0.15));
  opacity: 0.55;
  transition: opacity var(--dur) var(--ease-soft);
}
@media (hover: hover){
  .hadith-shelf-card:hover{
    border-color: rgb(var(--ornament) / 0.5);
    transform: translateY(-3px);
    box-shadow: var(--e3);
  }
  .hadith-shelf-card:hover::before{ opacity: 1; }
}
.hadith-shelf-card.is-major{
  background:
    radial-gradient(120% 130% at 50% 0%, rgb(var(--ornament) / 0.09), transparent 62%),
    rgb(var(--surface));
  border-color: rgb(var(--ornament) / 0.32);
}
.hadith-shelf-ic{
  width: 38px; height: 38px; margin-bottom: var(--sp-2);
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgb(var(--ornament) / 0.11);
  border: 1px solid rgb(var(--ornament) / 0.26);
  color: rgb(var(--accent-ui));
}
.hadith-shelf-ic svg{ width: 18px; height: 18px; fill: none; stroke: currentColor; }
.hadith-shelf-ar{
  direction: rtl; unicode-bidi: isolate; text-align: start;
}
.hadith-shelf-blurb{
  line-height: 1.6;
  color: rgb(var(--text-muted));
  margin-top: 2px;
}
.hadith-shelf-count{
  display: flex; align-items: center; gap: 6px;
  margin-top: auto; padding-top: var(--sp-3);
  font-family: var(--font-mono); font-size: 0.66rem;
  color: rgb(var(--accent-ui));
}
.hadith-shelf-count svg{ width: 12px; height: 12px; fill: none; stroke: currentColor; transition: transform var(--dur) var(--spring); }
@media (hover: hover){ .hadith-shelf-card:hover .hadith-shelf-count svg{ transform: translateX(3px); } }

@media (max-width: 620px){
  /* Two up. A single column turns six books into six full-width slabs
     and the section into most of the homepage; two keeps the shelf
     reading as a shelf. */
  .hadith-shelf{ grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); }
  .hadith-shelf-card{ padding: var(--sp-4) var(--sp-4) var(--sp-3); }
  .hadith-shelf-ic{ width: 32px; height: 32px; }
  .hadith-shelf-ic svg{ width: 15px; height: 15px; }
  .hadith-shelf-ar{ font-size: 1.26rem; }
  .hadith-shelf-title{ font-size: 0.92rem; }
  /* At two-up there is no room for a sentence under the title as well
     as the name in two scripts, and the name is the thing being chosen
     between. */
  .hadith-shelf-blurb{ display: none; }
}

@media (prefers-reduced-motion: reduce){
  @media (hover: hover){
    .hadith-shelf-card:hover{ transform: none; }
    .hadith-shelf-card:hover .hadith-shelf-count svg{ transform: none; }
  }
}

/* =========================================================================
   THE SĪRAH — the v12.2 timeline layer was DELETED in v12.5.

   It styled a gold spine, eight chapter bands, fifty-eight moment cards,
   the quotation frames inside them and the source lines under them — and
   not one of those elements exists any more: the authored moments they
   were written for are gone (see the note at the head of inc/seerah.php).

   Deleted rather than overridden. Six hundred lines of rules for markup
   that cannot be emitted is not dead weight so much as a trap: the next
   person to see `.seerah-moment` in this file would reasonably conclude
   there were moments. The section is rebuilt in the v12.5 layer at the
   foot of this file.
   ========================================================================= */

/* =========================================================================
   v12.2 — NOTHING TRANSIENT PRINTS OVER AN OPEN MENU

   Reported as: "make sure notifications don't overlap side menu on
   phone."

   The drawer is `z-index: 97` INSIDE `.site-header`'s stacking context,
   which is `z-index: 100` — so against the rest of the page the drawer
   effectively sits at 100. Every floating surface on this site was given
   a number above that, one at a time, each for a good local reason and
   none of them against the drawer:

       .pp-toast              200   the save confirmation
       .qa-bar                140   the recitation player
       .pp-pwa-banner         130   the install prompt
       .quran-siderail         70   the reading controls  (below — fine)
       .back-top               90   back to top           (below — fine)

   So on a phone, opening the menu with a recitation playing, or while
   the install prompt was up, drew a full-width panel straight across the
   bottom third of it.

   Raising the drawer is not the answer: its z-index is deliberately
   below the header's own bar so the close button stays reachable above
   it, and lifting it would break that. The answer is that a menu is a
   modal surface, and nothing announces itself over a modal surface. Each
   of these fades out while the drawer, the search palette, the
   appearance sheet or the adhkār sheet is open, and comes back when it
   closes — which is also the right behaviour for their own sake: a toast
   nobody can see is a toast nobody has been told.

   `body:has()` rather than a body class, because the drawer's open state
   is a class on `.main-nav` and adding a second source of truth for it
   in JavaScript is how the two come to disagree. The file already uses
   `:has()` for `.quran-siderail`.
   ========================================================================= */
body:has(.main-nav.open) .pp-toast,
body:has(.main-nav.open) .qa-bar,
body:has(.main-nav.open) .back-top,
body.pp-cmd-open .pp-toast,
body.pp-cmd-open .pp-pwa-banner,
body.pp-cmd-open .qa-bar,
body.pp-cmd-open .back-top,
body.theme-sheet-open .pp-toast,
body.theme-sheet-open .pp-pwa-banner,
body.theme-sheet-open .qa-bar,
body.theme-sheet-open .back-top,
body.pp-sheet-open .pp-toast,
body.pp-sheet-open .pp-pwa-banner,
body.pp-sheet-open .qa-bar,
body.pp-sheet-open .back-top {
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
  transition: opacity 0.18s var(--ease), visibility 0.18s var(--ease);
}

/* =========================================================================
   v12.2 — THE QUR'AN READER ON A PHONE

   Three faults, reported together, and they turn out to be one crowded
   bottom-right corner and one row of buttons that never went away.
   ========================================================================= */

/* ---- 1. The ayah tools open on a tap ---------------------------------
   See the long note at the foot of assets/quran.js. v10.1 made the row
   permanently visible on touch because it was permanently INvisible
   there; al-Baqarah then carried 286 of them, 1,144 buttons on one page.
   It now opens under the ayah you touched, and only that one. */
@media (hover: none){
  .quran-ayah{ position: relative; }
  .quran-ayah .quran-ayah-actions{
    opacity: 0;
    /* Collapsed, not merely transparent: a hidden row that still takes
       56px under every verse spaces the page as though the buttons were
       there, which was half of what looked wrong. */
    max-height: 0;
    margin-top: 0;
    overflow: hidden;
    pointer-events: none;
    transition: opacity 0.18s var(--ease-soft),
                max-height 0.24s var(--ease-out-expo),
                margin-top 0.24s var(--ease-out-expo);
  }
  .quran-ayah.is-open .quran-ayah-actions,
  .quran-ayah:focus-within .quran-ayah-actions{
    opacity: 1;
    max-height: 64px;
    pointer-events: auto;
  }
  /* The ayah you opened is marked, so it is obvious which verse the row
     belongs to when two are close together. */
  .quran-ayah.is-open{
    background: rgb(var(--wash) / 0.055);
    border-radius: var(--radius);
  }
  /* A saved ayah keeps its own quiet mark whether or not its row is
     open — the bookmark is a state of the verse, not of the menu. This
     replaces the always-on gold row that used to be the only way to see
     it. */
  .quran-ayah:has(.quran-ayah-save[aria-pressed="true"])::after{
    content: '';
    position: absolute; top: 14px; inset-inline-end: 2px;
    width: 6px; height: 6px; border-radius: 50%;
    background: rgb(var(--accent));
  }
}

@media (hover: none) and (prefers-reduced-motion: reduce){
  .quran-ayah .quran-ayah-actions{ transition: none; }
}

/* ---- 2. The arrow, a size smaller on a phone ------------------------- */
@media (max-width: 640px){
  .back-top{ width: 42px; height: 42px; }
}

/* ---- 3. The panel opens completely, and looks like something ---------
   "make sure full menu can be opened clearly without missing parts", and
   "make the menu more beautiful from the inside, for e.g. the buttons for
   choosing Ar / En".

   (Its height is the Aa popover's now — .pp-aa-pop, and the cap it gets
   when the recitation bar is docked, in v143-layer-20-post.css.) */
.quran-rail-panel{
  padding: var(--sp-4) var(--sp-3) var(--sp-3);
  border-radius: 20px;
  gap: 10px;
  border-color: rgb(var(--wash) / 0.24);
  /* A scroll shadow, so a panel taller than the space it has says so
     rather than simply ending. The two `local` gradients are the paper;
     the two `scroll` ones are the shadows, and they only show where the
     paper has been scrolled away from an edge. */
  background:
    linear-gradient(rgb(var(--surface)) 30%, rgb(var(--surface) / 0)) top / 100% 22px no-repeat local,
    linear-gradient(rgb(var(--surface) / 0), rgb(var(--surface)) 70%) bottom / 100% 22px no-repeat local,
    radial-gradient(farthest-side at 50% 0, rgb(var(--shadow) / 0.16), transparent) top / 100% 12px no-repeat scroll,
    radial-gradient(farthest-side at 50% 100%, rgb(var(--shadow) / 0.16), transparent) bottom / 100% 12px no-repeat scroll,
    rgb(var(--surface));
}
.quran-rail-label{
  font-size: 0.56rem; letter-spacing: 0.14em;
  color: rgb(var(--accent-ui)); opacity: 0.85;
}
.quran-rail-sep{
  width: 30px; height: 1px; margin: 3px 0;
  background: linear-gradient(90deg, transparent, rgb(var(--wash) / 0.4), transparent);
}

/* The Ar+En / Ar / En control. Three flat labels in a grey trough with a
   sliding gold pill behind them: the pill was right, the labels were not
   — 0.72rem of Inter in three words of unequal length, so the group read
   as a ragged column rather than as a segmented control. Equal cells now,
   each carrying the script it selects in that script's own letterforms,
   with the plain label under it. */


/* The "+" in the both-scripts cell is Latin punctuation between two
   letterforms from different scripts; without an isolate the bidi
   algorithm reorders it. */


.quran-rail-font-btn{
  width: 40px; height: 34px; border-radius: 12px;
  border-color: rgb(var(--heading) / 0.1);
  background: rgb(var(--ink) / 0.03);
}
.quran-rail-play{
  width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgb(var(--wash) / 0.12);
  border: 1px solid rgb(var(--wash) / 0.3);
  color: rgb(var(--accent-ui));
  transition: background var(--dur-fast) var(--ease-soft),
              color var(--dur-fast) var(--ease-soft),
              transform var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){
  .quran-rail-play:hover{ background: rgb(var(--accent)); color: rgb(var(--on-accent)); border-color: rgb(var(--accent)); }
}
.quran-rail-play:active{ transform: scale(0.94); }

/* The toggle itself: the mark it opens, rather than a bare "Aa". */
.quran-rail-toggle{
  border-color: rgb(var(--wash) / 0.26);
  box-shadow: 0 14px 34px -14px rgb(var(--shadow) / 0.45);
}
.quran-rail-toggle-text{ font-family: var(--font-display); font-size: 1.02rem; }

@media (prefers-reduced-motion: reduce){
  .quran-rail-play:active{ transform: none; }
}


/* =========================================================================
   =========================================================================
   v12.3
   =========================================================================
   ========================================================================= */


.btn-ghost:active{ box-shadow: none; }
.btn-ghost:focus-visible{
  outline: 2px solid rgb(var(--accent-ui));
  outline-offset: 3px;
}

/* On an INK panel — the subscribe band, the footer — a ghost button has to
   be drawn against the dark rather than the page, or it is a hole. */
.newsletter-band .btn-ghost,
.subscribe-band .btn-ghost,
.site-footer .btn-ghost,
.pp-on-ink .btn-ghost{
  border-color: rgb(var(--on-ink) / 0.28);
  color: rgb(var(--on-ink));
  background: rgb(var(--on-ink) / 0.06);
}
@media (hover: hover){
  .newsletter-band .btn-ghost:hover,
  .subscribe-band .btn-ghost:hover,
  .site-footer .btn-ghost:hover,
  .pp-on-ink .btn-ghost:hover{
    border-color: rgb(var(--on-ink) / 0.5);
    background: rgb(var(--on-ink) / 0.12);
    color: rgb(var(--on-ink));
  }
}

/* Everything that is ORNAMENT rather than action. Gold too — it is the
   same metal — but MATTE: a two-stop wash, no specular band, no bevel, no
   shadow. That is the whole distinction, and it is why one gold can do
   both jobs without the two collapsing into each other. */
.icon-badge,
.pp-badge-accent,
.quran-goal-ring-fill {
  background: linear-gradient(180deg, rgb(var(--gilt)), rgb(var(--gilt-deep)));
  color: rgb(var(--on-gilt));
  border-color: rgb(var(--gilt-edge) / 0.8);
}

/* The accent glow used by hover states across the site: the ornament's
   metal, because that is what a glow is — light, not paint. */
:root{ --glow-accent: 0 12px 32px -12px rgb(var(--gilt-edge) / 0.42); }


/* =========================================================================
   2. THE COVER, IN FOUR INDEPENDENT LAYERS

   See the long note in inc/cover-art.php. `.cover-art` was the <svg>; it
   is now the wrapper, and each layer is a sibling <svg> so no layer can
   inherit another's fitting.
   ========================================================================= */
.cover-art{
  display: block; position: relative;
  width: 100%; height: 100%;
  overflow: hidden;
}
.cover-art > svg{
  position: absolute; inset: 0;
  display: block; width: 100%; height: 100%;
}
/* The panel layer must not be clipped by anything: `meet` guarantees it
   fits, and `overflow:visible` guarantees nothing else undoes that. */
.cover-panel{ overflow: visible; }


/* =========================================================================
   3. THE ARABIC DISPLAY FACE IS BOLD, EVERYWHERE, BY CONSTRUCTION

   "try using Traditional Arabic but bold!! it MUST be bold"

   Traditional Arabic is a light face. Every rule that reaches for the
   display token already declares font-weight:700, but "already declares"
   is a promise about forty rules that a forty-first will break. This
   makes it structural instead: anything using the display face is bold,
   and a rule would have to say otherwise on purpose.
   ========================================================================= */
[lang="ar"], [dir="rtl"]{ font-kerning: normal; }
.seerah-unwan-ar, .seerah-chapter-ar, .seerah-names-ar, .seerah-single-ar,
.book-unwan-ar, .hadith-book-ar,
.hero .sub[lang="ar"], .hero h1[lang="ar"],
.sirah-book-title-ar, .sirah-book-chapter-ar, .sirah-book-unwan-ar{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  /* Traditional Arabic sits small on the em compared with Amiri, so a
     title set at the same nominal size renders visibly smaller on a
     machine that has it. A tenth of a line back. */
  letter-spacing: 0;
}


/* =========================================================================
   4. THE QUR'AN KEEPS ITS OWN FACE — A STRUCTURAL GUARANTEE

   "even in seerah use correct font for Qur'an please"

   Qur'anic text on this site comes out of data/quran/ as PUA-encoded
   Hafs glyphs. Exactly one font renders them. When some other rule wins
   the cascade the text does not fall back gracefully — it disappears, or
   becomes a row of tofu, which is what happened to the homepage verse in
   v12.2.

   So the face is pinned to the element that carries the glyphs, at a
   specificity nothing casual will beat, and every place Qur'an appears
   uses one of these two classes:

     .quran-glyphs  — PUA Hafs text (the only thing that may use it)
     .quran-unicode — ordinary Unicode Qur'anic Arabic

   A rule that wants to restyle Qur'an now has to name it.
   ========================================================================= */
.quran-glyphs,
.hero-ayah,
.adhkar-hero-ayah,
.quran-day-arabic,
.seerah-quran-ar,
.sirah-quran-ar{
  font-family: var(--font-quran-glyphs) !important;
  direction: rtl; unicode-bidi: isolate;
  font-weight: 400;
}
.quran-unicode{
  font-family: var(--font-quran);
  direction: rtl; unicode-bidi: isolate;
}


/* =========================================================================
   6. THE ADHKĀR SET STRIP, AND WHERE IT STOPS BEING THE RIGHT CONTROL

   "inside the adhkar page … (in hardship, salawat etc) there is text
   coming out of place & not clean enough"

   Measured at 820px before this change, with the browser:

     tab box              108 x 126
     الذِّكْرُ الْمُطْلَقُ وَجَوَامِعُ الدُّعَاء   153 wide   → 45px OUTSIDE its tab
     الصَّلَاةُ عَلَى النَّبِيِّ ﷺ            110 wide   →  2px outside
     أَذْكَارُ مَا بَعْدَ الصَّلَاة            107 wide   → touching

   The tab had no width constraint on its Arabic at all, so the name
   simply drew past the box and over the tab beside it. Two fixes, and
   the second is the one that matters:

     1. the strip now uses the SHORT Arabic name (inc/adhkar-data.php),
        so nothing is near the edge;
     2. and the label is clipped regardless, so a name added later
        cannot reintroduce this. A control whose correctness depends on
        every future label being short is not fixed.
   ========================================================================= */
.adhkar-tab{
  /* Was a fixed 108px. Tabs may now take the width their own label
     needs, within a range — which is what stops the strip reading as
     nine identical boxes with different amounts of empty space. */
  flex: 0 0 auto;
  min-width: 104px;
  max-width: 168px;
  padding: var(--sp-4) var(--sp-3);
}
.adhkar-tab-ar{
  display: block;
  max-width: 100%;
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 1.06rem;
  line-height: 1.95;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  unicode-bidi: isolate;
}
.adhkar-tab-en{
  display: block;
  max-width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/*
 * THE BREAKPOINT MOVED: 760 → 900.
 *
 * "on the phone version when I open adhkar the same old menu shows, but
 * when I went to counter page then went back to adhkar it shows me a
 * selection to make in a suitable way for phone" — the picker was real
 * and did work; what varied was the WIDTH the screenshot was taken at.
 * The strip was kept down to 761px, and between 761 and 900 there is
 * not room for nine tabs, so it was a scroller with clipped labels
 * exactly as reported. Below 900 the picker is simply the better
 * control, so that is where it starts.
 */
/*
 * The strip's own `display` switch lives with the rest of the phone
 * block further up this file, where the breakpoint was raised from 760
 * to 900 in place — overriding only `display` from down here would have
 * shown an unstyled control between the two widths.
 */

/* The adhkār panel is the widest thing in the nav: nine rows in two
   columns, each carrying an English name, an Arabic name and a count. At
   the shared 560px its Arabic column measured 151px and every one of the
   nine names was being cut with an ellipsis — which is most of what "too
   tight & not very appealing" was. 660px gives the names 202px, which is
   57px more than the longest of them needs. */


/* =========================================================================
   7. THE BOOK — ash-Shamāʾil al-Muḥammadiyya

   Templates: sirah-book.php, sirah-book-chapter.php.
   Data:      inc/sirah-book.php.

   ─── THE ONE IDEA ────────────────────────────────────────────────────
   The sīrah timeline is a SCROLL: a gold spine down the page, moments
   hanging off it in order, and scrolling is moving through twenty-three
   years. This is the other thing a manuscript can be — a CODEX. It has
   an ʿunwān leaf, a fihris with ruled leaders, numbered bābs, and pages
   you turn. The two share a hand (the same gold, the same roundels, the
   same Arabic-Indic numerals) and are not the same object, which is
   correct, because they are not the same kind of reading.

   The signature is the FIHRIS LEADER: the row of dots that carries the
   eye from a chapter's name to its count, the way a printed table of
   contents has done for five hundred years. It is drawn, not typed —
   a repeating radial gradient on a flex spacer — so it fills exactly
   the space left between the two ends at any width, in any language,
   and never wraps or falls short.
   ========================================================================= */

.sirah-book-page{ padding-bottom: var(--sp-10); }

/* ---- Where you are ---------------------------------------------------- */
.sirah-book-crumbs{
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0 0 var(--sp-6);
  font-family: var(--font-ui);
  font-size: var(--fs-2xs);
  letter-spacing: 0.1em; text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.sirah-book-crumbs a{ color: rgb(var(--accent-ui)); }
@media (hover: hover){ .sirah-book-crumbs a:hover{ text-decoration: underline; text-underline-offset: 3px; } }

/* =========================================================================
   THE ʿUNWĀN LEAF

   One object on one page. A manuscript's opening leaf carries the title
   and nothing that competes with it, so the rule, the mark, the title,
   the author and the figures are the entire header and the paragraph
   about the book begins below it.
   ========================================================================= */
.sirah-book-unwan{
  max-width: 760px; margin: 0 auto var(--sp-8);
  padding: var(--sp-9) var(--sp-6) var(--sp-7);
  text-align: center;
}
.sirah-book-unwan-rule{
  top: 0; left: 0; right: 0;
}
.sirah-book-unwan-mark{
  place-items: center;
  border-radius: 50%;
  background: rgb(var(--ornament) / 0.1);
  border: 1px solid rgb(var(--ornament) / 0.34);
}

.sirah-book-unwan-ar{
  margin: 0;
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: clamp(2rem, 1.2rem + 3.8vw, 3.2rem);
  line-height: 1.75;
  color: rgb(var(--heading));
  letter-spacing: 0;
}
.sirah-book-unwan-en{
  margin: 6px 0 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.1rem, 1rem + 0.6vw, 1.4rem);
  letter-spacing: -0.01em;
  color: rgb(var(--heading-soft));
}
.sirah-book-unwan-sub{
  margin: 4px 0 0;
  font-family: var(--font-ui);
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.sirah-book-unwan-divider{
  display: block; width: 96px; height: 1px;
  margin: var(--sp-5) auto;
  background: linear-gradient(90deg, transparent, rgb(var(--ornament) / 0.6), transparent);
}
.sirah-book-author{
  margin: 0;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
}
.sirah-book-author-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 1.16rem; line-height: 1.9;
  color: rgb(var(--heading-soft));
}
.sirah-book-author-en{
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  color: rgb(var(--text-muted));
}
.sirah-book-author-died{
  font-family: var(--font-mono); font-size: 0.68rem;
  letter-spacing: 0.04em;
  color: rgb(var(--text-muted)); opacity: 0.8;
}
.sirah-book-figures{
  margin: var(--sp-5) 0 0;
  display: flex; align-items: center; justify-content: center;
  gap: 10px; flex-wrap: wrap;
  font-family: var(--font-ui); font-size: var(--fs-2xs);
  letter-spacing: 0.1em; text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.sirah-book-figures strong{
  font-family: var(--font-mono); font-weight: 500;
  font-size: 0.86rem; letter-spacing: 0;
  color: rgb(var(--accent-ui));
}

/* ---- What the book is -------------------------------------------------- */
.sirah-book-about{
  max-width: 68ch; margin: 0 auto var(--sp-8);
  font-size: var(--fs-base); line-height: 1.8;
  color: rgb(var(--text));
}
.sirah-book-about p{ margin: 0 0 var(--sp-4); }
.sirah-book-about-lead{
  font-family: var(--font-display);
  font-size: clamp(1.16rem, 1.05rem + 0.5vw, 1.4rem);
  line-height: 1.5;
}
.sirah-book-about-note{
  font-size: var(--fs-sm);
  color: rgb(var(--text-muted));
}
.sirah-book-about-note a{ color: rgb(var(--accent-ui)); border-bottom: 1px solid rgb(var(--wash) / 0.35); }
@media (hover: hover){ .sirah-book-about-note a:hover{ border-bottom-color: rgb(var(--accent)); } }
.sirah-book-actions{
  display: flex; gap: 12px; flex-wrap: wrap;
  margin-top: var(--sp-6);
}
.sirah-book-resume-where{
  font-weight: 400;
  opacity: 0.75;
}
.sirah-book-resume-where::before{ content: '· '; }

/* ---- Search ------------------------------------------------------------ */
.sirah-book-search{
  display: flex; align-items: center; gap: 10px;
  max-width: 760px; margin: 0 auto var(--sp-7);
  padding: 6px 6px 6px var(--sp-4);
  border: 1px solid rgb(var(--heading) / 0.14);
  border-radius: var(--radius-pill, 999px);
  background: rgb(var(--surface));
  box-shadow: var(--e1);
  transition: border-color var(--dur) var(--ease-soft), box-shadow var(--dur) var(--ease-soft);
}
.sirah-book-search:focus-within{
  border-color: rgb(var(--wash) / 0.5);
  box-shadow: var(--e2);
}
.sirah-book-search-ic{
  width: 17px; height: 17px; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  color: rgb(var(--text-muted));
}
.sirah-book-search input{
  flex: 1 1 auto; min-width: 0;
  border: 0; background: transparent; padding: 8px 0;
  font-family: var(--font-ui); font-size: var(--fs-sm);
  color: rgb(var(--text));
}
.sirah-book-search input:focus{ outline: none; }
.sirah-book-search-clear{
  flex: 0 0 auto; padding-right: var(--sp-3);
  font-family: var(--font-ui); font-size: var(--fs-2xs);
  letter-spacing: 0.08em; text-transform: uppercase;
  color: rgb(var(--text-muted));
}
@media (hover: hover){ .sirah-book-search-clear:hover{ color: rgb(var(--accent-ui)); } }

/* ---- A section heading ------------------------------------------------- */
.sirah-book-section-head{
  margin: 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.1rem, 1rem + 0.5vw, 1.35rem);
  letter-spacing: -0.01em;
  color: rgb(var(--heading));
}

/* =========================================================================
   THE FIHRIS

   Two columns on a wide screen, one on a phone. Each row is an entry in
   a table of contents and is built like one: number, name, leader, count.
   ========================================================================= */
.sirah-book-contents{ max-width: 1080px; margin: 0 auto; }
.sirah-book-contents-head{
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); flex-wrap: wrap;
  margin-bottom: var(--sp-5);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid rgb(var(--wash) / 0.24);
}
.sirah-book-filter{
  display: flex; align-items: center; gap: 8px;
  padding: 7px var(--sp-4);
  border: 1px solid rgb(var(--heading) / 0.13);
  border-radius: var(--radius-pill, 999px);
  background: rgb(var(--surface));
}
.sirah-book-filter svg{
  width: 15px; height: 15px; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  color: rgb(var(--text-muted));
}
.sirah-book-filter input{
  border: 0; background: transparent; min-width: 180px;
  font-family: var(--font-ui); font-size: var(--fs-2xs);
  color: rgb(var(--text));
}
.sirah-book-filter input:focus{ outline: none; }
.sirah-book-filter:focus-within{ border-color: rgb(var(--wash) / 0.5); }

.sirah-book-toc{
  columns: 2; column-gap: var(--sp-8);
}
.sirah-book-toc-item{
  break-inside: avoid;
  /* `columns` lays out in the inline direction; without this a row can
     be split across the fold with its number on one side and its name
     on the other. */
  -webkit-column-break-inside: avoid;
}

/* The number, in the numerals the book is written in, on the gold
   roundel the timeline uses for its moments. Same hand, same section. */
.sirah-book-toc-n{
  place-items: center;
}
.sirah-book-toc-names{
  position: relative;
}
.sirah-book-toc-ar{
  /* Vowelled Naskh in a list: 1.9 is the floor at which one line's
     fatḥah stops landing in the next line's kasrah. */
  text-align: left;         /* second line of an LTR label — see the
                               adhkār menu note for the same reasoning */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sirah-book-toc-en{
  letter-spacing: 0.02em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── THE LEADER ──────────────────────────────────────────────────────
   The dots that carry the eye from the name to the number. Drawn as a
   repeating radial gradient on the flex gap, so it is exactly as long
   as the space left over — it cannot wrap, cannot fall short, and needs
   no dots in the markup for a screen reader to read aloud. */
.sirah-book-toc-count{
  position: relative;
}
.sirah-book-toc-count::before{
  position: absolute; right: calc(100% + 6px); left: -100vw;
  bottom: 0.42em; height: 3px;
  background-image: radial-gradient(circle, rgb(var(--wash) / 0.42) 1px, transparent 1.2px);
  background-size: 6px 3px;
  background-repeat: repeat-x;
  /* Clipped to the row: `left:-100vw` gives the dots somewhere to come
     from, and the row's own overflow decides where they start. */
  pointer-events: none;
}

.sirah-book-toc-none{
  margin: var(--sp-6) 0 0;
  font-size: var(--fs-sm); color: rgb(var(--text-muted));
}

@media (max-width: 860px){
  .sirah-book-toc{ columns: 1; }
  .sirah-book-contents-head{ flex-direction: column; align-items: stretch; }
  .sirah-book-filter input{ min-width: 0; flex: 1 1 auto; }
}

/* =========================================================================
   SEARCH RESULTS
   ========================================================================= */
.sirah-book-results{ max-width: 860px; margin: 0 auto; }
.sirah-book-result-list{ list-style: none; margin: var(--sp-6) 0 0; padding: 0; }
.sirah-book-result{
  padding: var(--sp-5) 0;
  border-top: 1px solid rgb(var(--heading) / 0.09);
}
.sirah-book-result:first-child{ border-top: 0; }
.sirah-book-result-where{
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin-bottom: var(--sp-3);
  font-family: var(--font-ui); font-size: var(--fs-2xs);
  letter-spacing: 0.08em; text-transform: uppercase;
  color: rgb(var(--text-muted));
}
@media (hover: hover){ .sirah-book-result-where:hover .sirah-book-result-name{ color: rgb(var(--accent-ui)); } }
.sirah-book-result-name{ color: rgb(var(--heading-soft)); letter-spacing: 0.02em; text-transform: none; font-size: var(--fs-sm); }
.sirah-book-result-num{ font-family: var(--font-mono); color: rgb(var(--accent-ui)); }
.sirah-book-result-ar{
  margin: 0 0 6px;
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 1.2rem; line-height: 2.1;
  color: rgb(var(--heading));
  unicode-bidi: isolate;
}
.sirah-book-result-en{
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-sm); line-height: 1.75;
  color: rgb(var(--text-muted));
}
.sirah-book-empty{
  margin: var(--sp-6) 0 0;
  font-size: var(--fs-base); color: rgb(var(--text-muted));
}

/* =========================================================================
   A CHAPTER
   ========================================================================= */
.sirah-book-reading .wrap-reading{ max-width: 780px; }

.sirah-book-bab{
  position: relative;
  margin: 0 0 var(--sp-7);
  padding: var(--sp-7) var(--sp-5) var(--sp-6);
  text-align: center;
  border-radius: var(--radius-lg);
  border: 1px solid rgb(var(--wash) / 0.24);
  background:
    radial-gradient(120% 130% at 50% 0%, rgb(var(--wash) / 0.08), transparent 60%),
    rgb(var(--bg-alt));
}
.sirah-book-bab-n{
  display: grid; place-items: center;
  width: 44px; height: 44px; margin: 0 auto var(--sp-4);
  border-radius: 50%;
  border: 1px solid rgb(var(--wash) / 0.42);
  background: rgb(var(--surface));
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 1.12rem; line-height: 1;
  color: rgb(var(--accent-ui));
  box-shadow: 0 4px 14px -8px rgb(var(--shadow) / 0.4);
}
.sirah-book-bab-ar{
  margin: 0;
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: clamp(1.4rem, 1.05rem + 1.5vw, 2.05rem);
  line-height: 1.95;
  color: rgb(var(--heading));
  letter-spacing: 0;
}
.sirah-book-bab-en{
  margin: var(--sp-3) 0 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.02rem, 0.96rem + 0.4vw, 1.2rem);
  color: rgb(var(--heading-soft));
}
.sirah-book-bab-meta{
  margin: var(--sp-3) 0 0;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--font-mono); font-size: 0.68rem;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: rgb(var(--text-muted));
}

/* ---- Arabic / English / both ------------------------------------------- */
.sirah-book-view{
  display: flex; gap: 4px; justify-content: center;
  margin: 0 auto var(--sp-7);
  padding: 4px;
  width: max-content; max-width: 100%;
  border-radius: 18px;
  background: rgb(var(--ink) / 0.055);
  border: 1px solid rgb(var(--heading) / 0.07);
}
.sirah-book-view-btn{
  display: flex; flex-direction: column; align-items: center; gap: 0;
  min-width: 64px; padding: 7px 12px;
  border: 0; border-radius: 14px; background: transparent;
  color: rgb(var(--text-muted));
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .sirah-book-view-btn:hover{ color: rgb(var(--heading-soft)); } }
.sirah-book-view-btn.is-on{
  background: rgb(var(--surface));
  color: rgb(var(--heading));
  box-shadow: 0 2px 8px -4px rgb(var(--shadow) / 0.4);
}
.sirah-book-view-glyph{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 1rem; line-height: 1.4;
}
.sirah-book-view-label{
  font-family: var(--font-ui); font-size: 0.55rem; font-weight: 600;
  letter-spacing: 0.09em; text-transform: uppercase;
  opacity: 0.8;
}

/* ---- The narrations ----------------------------------------------------- */
.sirah-book-hadiths{ list-style: none; margin: 0; padding: 0; }
.sirah-book-hadith{
  position: relative;
  padding: var(--sp-6) 0;
  border-top: 1px solid rgb(var(--heading) / 0.08);
  scroll-margin-top: calc(var(--header-h, 78px) + 24px);
}
.sirah-book-hadith:first-child{ border-top: 0; padding-top: 0; }
.sirah-book-hadith.is-found{
  background: rgb(var(--wash) / 0.07);
  border-radius: var(--radius);
  padding-inline: var(--sp-4);
  margin-inline: calc(var(--sp-4) * -1);
}
.sirah-book-hadith-head{
  display: flex; align-items: baseline; gap: 10px;
  margin-bottom: var(--sp-4);
}
.sirah-book-hadith-n{
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: rgb(var(--accent-ui));
  padding: 2px 8px;
  border-radius: var(--radius-pill, 999px);
  background: rgb(var(--wash) / 0.1);
}
.sirah-book-hadith-narrator{
  font-family: var(--font-ui);
  font-size: var(--fs-2xs);
  letter-spacing: 0.04em;
  color: rgb(var(--text-muted));
}
.sirah-book-hadith-ar{
  margin: 0;
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  /* The same size as a hadith on its own page, deliberately: this IS a
     hadith on a page, and a reader moving between the two should not
     feel the type change under them. */
  font-size: 1.34rem;
  line-height: 2.2;
  color: rgb(var(--heading));
  direction: rtl; unicode-bidi: isolate; text-align: right;
}
.sirah-book-hadith-en{
  margin: var(--sp-4) 0 0;
  font-family: var(--font-body);
  font-size: 1.02rem; line-height: 1.8;
  color: rgb(var(--text));
}
.sirah-book-hadith-foot{
  margin: var(--sp-3) 0 0;
}
.sirah-book-hadith-foot a{
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--font-ui); font-size: var(--fs-2xs);
  letter-spacing: 0.08em; text-transform: uppercase;
  color: rgb(var(--text-muted));
  opacity: 0.75;
  transition: color var(--dur-fast) var(--ease-soft), opacity var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .sirah-book-hadith-foot a:hover{ color: rgb(var(--accent-ui)); opacity: 1; } }
.sirah-book-hadith-foot svg{ width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2; }

/* The view switch. One class on the page, not four hundred style
   writes — see assets/sirah-book.js. */

/* ---- Turning the page ---------------------------------------------------- */
.sirah-book-turn{
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: stretch;
  gap: var(--sp-4);
  margin-top: var(--sp-8);
  padding-top: var(--sp-6);
  border-top: 1px solid rgb(var(--wash) / 0.24);
}
.sirah-book-turn-link{
  display: flex; flex-direction: column; gap: 2px;
  min-width: 0;
  padding: var(--sp-4) var(--sp-5);
  border: 1px solid rgb(var(--heading) / 0.1);
  border-radius: var(--radius);
  background: rgb(var(--surface));
  transition: border-color var(--dur) var(--ease-soft), transform var(--dur) var(--ease-out-expo), box-shadow var(--dur) var(--ease-soft);
}
@media (hover: hover){
  a.sirah-book-turn-link:hover{
    border-color: rgb(var(--wash) / 0.45);
    transform: translateY(-2px);
    box-shadow: var(--e2);
  }
}
.sirah-book-turn-link.is-next{ text-align: right; align-items: flex-end; }
.sirah-book-turn-link.is-empty{ border-color: transparent; background: transparent; }
.sirah-book-turn-link.is-end{ align-items: flex-end; text-align: right; }
.sirah-book-turn-dir{
  font-family: var(--font-ui); font-size: 0.58rem;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.sirah-book-turn-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 1.12rem; line-height: 1.85;
  color: rgb(var(--heading));
  unicode-bidi: isolate;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 100%;
}
.sirah-book-turn-en{
  font-family: var(--font-ui); font-size: var(--fs-2xs);
  color: rgb(var(--text-muted));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 100%;
}
.sirah-book-turn-toc{
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; flex: 0 0 auto;
  padding: var(--sp-4) var(--sp-5);
  border-radius: var(--radius);
  color: rgb(var(--text-muted));
  transition: color var(--dur-fast) var(--ease-soft), background-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .sirah-book-turn-toc:hover{ color: rgb(var(--accent-ui)); background: rgb(var(--wash) / 0.08); } }
.sirah-book-turn-toc svg{ width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.6; }
.sirah-book-turn-toc span{
  font-family: var(--font-ui); font-size: 0.58rem;
  letter-spacing: 0.12em; text-transform: uppercase;
}

@media (max-width: 620px){
  .sirah-book-unwan{ padding: var(--sp-7) var(--sp-4) var(--sp-6); }
  .sirah-book-unwan-mark{ width: 54px; height: 54px; }
  .sirah-book-unwan-mark svg{ width: 33px; height: 33px; }
  .sirah-book-actions .btn{ width: 100%; justify-content: center; }
  .sirah-book-search{ flex-wrap: wrap; border-radius: var(--radius-lg); padding: var(--sp-3); }
  .sirah-book-search input{ flex: 1 1 140px; }
  .sirah-book-bab{ padding: var(--sp-6) var(--sp-4) var(--sp-5); }
  .sirah-book-hadith-ar{ font-size: 1.2rem; line-height: 2.15; }
  .sirah-book-hadith-en{ font-size: 0.96rem; }
  /* Three panels in a row do not fit; the contents link moves under the
     two it separates rather than squeezing all three. */
  .sirah-book-turn{
    grid-template-columns: 1fr 1fr;
    grid-template-areas: "prev next" "toc toc";
  }
  .sirah-book-turn-link.is-prev{ grid-area: prev; }
  .sirah-book-turn-link.is-next, .sirah-book-turn-link.is-end{ grid-area: next; }
  .sirah-book-turn-toc{ grid-area: toc; flex-direction: row; gap: 8px; }
}

@media (prefers-reduced-motion: reduce){
  @media (hover: hover){ a.sirah-book-turn-link:hover{ transform: none; } }
}@media (max-width: 620px){
  .hadith-book-header-actions{ width: 100%; }
  .hadith-book-header-actions .btn{ flex: 1 1 auto; justify-content: center; }
}

/* ---- A dhikr with two transmitted counts — v12.3 ---------------------
   "so people can choose either 10 or 100". A pair of small numerals in a
   trough, beside the counter they set. Deliberately quiet: it is a
   setting, not an action, and the thing to press on this card is the
   count itself. */
.adhkar-card-times{
  display: inline-flex; align-items: center; gap: 2px;
  padding: 3px;
  border-radius: var(--radius-pill, 999px);
  background: rgb(var(--ink) / 0.06);
  border: 1px solid rgb(var(--heading) / 0.08);
}
.adhkar-times-opt{
  min-width: 40px; padding: 5px 9px;
  border: 0; border-radius: var(--radius-pill, 999px);
  background: transparent;
  font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0;
  color: rgb(var(--text-muted));
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft),
              color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .adhkar-times-opt:hover{ color: rgb(var(--heading-soft)); } }
.adhkar-times-opt.is-on{
  background: rgb(var(--surface));
  color: rgb(var(--accent-ui));
  box-shadow: 0 1px 4px -2px rgb(var(--shadow) / 0.45);
}
.adhkar-times-opt:focus-visible{ outline: 2px solid rgb(var(--btn)); outline-offset: 1px; }


/* =========================================================================
   8. ONE RULE FOR ARABIC INSIDE AN ENGLISH LAYOUT

   An Arabic name used as a LABEL — the second line under an English one,
   in a row that reads left to right — needs `dir="rtl"` for its shaping
   and must NOT take its alignment from that direction. Left to itself it
   resolves `text-align: start` to RIGHT, so it flies to the far edge of
   whatever box it is in and lands two hundred pixels from the English it
   belongs to, usually with a number in between.

   That is a labelling decision, not a typographic one: the label aligns
   with the label above it. Arabic set as CONTENT — a dhikr, an āyah, a
   narration, a bāb heading — is unaffected and stays right-aligned or
   centred, which is what those want.

   Four components had the fault independently before this was written
   down once.
   ========================================================================= */
.adhkar-tab-ar,
.seerah-bookcard-ar,
.sirah-book-toc-ar,
.sirah-book-turn-link.is-prev .sirah-book-turn-ar,
.hadith-collection-arabic {
  text-align: left;
}

/* ---- The seconds on the prayer clock — v12.3 -------------------------
   Small, mono, superscript, and half-lit. It is not information anybody
   needs; it is the proof that the four digits beside it are right, after
   a release in which they were not (the minute was being rounded, so the
   site disagreed with the reader's own phone for half of every minute).
   A clock that ticks is a clock you believe. */
.prayer-clock-sec{
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  color: rgb(var(--text-muted));
  opacity: 0.55;
  align-self: flex-start;
  margin-top: 0.55em;
  margin-inline-start: 3px;
}
/* The time and its seconds are one object. `.prayer-clock` is a flex
   COLUMN, so an inline-block seconds span is still a flex item and still
   lands on its own line under the time — they need a row of their own. */
.prayer-clock-row{
  display: flex; align-items: flex-start; justify-content: center;
  gap: 0;
}


/* =========================================================================
   THE HEADER SEAM — v12.4

   Reported as: "please fix the gap between the main website header and
   whatever is connected to it, I hate that small gap! for example tafseer
   header wth main header, small gap looks ugly".

   It was three faults stacked, and only the first is arithmetic:

   1. THE SLIVER. assets/main.js publishes --header-h as
      Math.ceil(header height). The header measures 68.8px (68px plus a
      0.8px hairline), so --header-h is 69px, and a bar pinned at
      `top: var(--header-h)` starts 0.2px BELOW the header's real bottom.
      Two tenths of a pixel of page background, which at most device
      pixel ratios resolves to a visible one-pixel light line.

      Ceil is right for what it was written for — reserving space so
      content never slides under the header — and wrong here, where the
      same number is also used to butt something up against it. So the
      bar now pins one whole pixel HIGHER and its first pixel row slides
      underneath the header, which is fixed and sits above it. There is
      no arithmetic left that can produce a gap, at any zoom, on any
      display.

   2. THE SHADOW. The header casts `0 2px 4px` and `0 4px 10px` downward.
      With nothing under it that is the page's own soft edge and it is
      right. With a bar welded to it, the header was dropping a shadow
      ONTO its own continuation — a dark band across the top of the bar,
      which is the "gap" as the eye actually reads it. A single object
      does not cast a shadow on itself, so when a bar is welded on, the
      shadow moves to the bottom of the assembly, where it belongs.

   3. THE COLOUR STEP. The header paints rgb(--surface / 0.88) behind a
      blur; the bar painted rgb(--surface) flat. Two different materials,
      so a seam showed even when they touched. The bar now takes the same
      translucent surface and the same blur, and the two are one material.

   :has() carries the "is a bar welded on" test so no template has to be
   edited to opt in. Where it is unsupported the page falls back to
   exactly the v12.3 appearance — a hairline between the two — which is
   the thing being fixed, not a thing being broken.
   ========================================================================= */

.tafsir-bar{
  top: calc(var(--header-h) - 1px);
  /* Replaces the pixel row that is now tucked under the header, so the
     bar's own contents do not shift up by one. */
  border-top: 1px solid transparent;
  background: rgb(var(--surface) / 0.88);
  -webkit-backdrop-filter: saturate(1.8) blur(20px);
  backdrop-filter: saturate(1.8) blur(20px);
  /* The bar carries the assembly's shadow now — see (2) above. */
  box-shadow: 0 2px 4px -1px rgb(var(--shadow) / 0.06),
              0 4px 10px -2px rgb(var(--shadow) / 0.07);
}


/* The header stops being a separate object the moment something is
   welded to its underside. */
body:has(.tafsir-bar) .site-header,
body:has(.pp-welded) .site-header{
  box-shadow: none;
  border-bottom-color: transparent;
}

/* The opt-in class, for any bar added later. Same contract as .tafsir-bar. */
.pp-welded{
  top: calc(var(--header-h) - 1px);
  border-top: 1px solid transparent;
  background: rgb(var(--surface) / 0.88);
  -webkit-backdrop-filter: saturate(1.8) blur(20px);
  backdrop-filter: saturate(1.8) blur(20px);
  box-shadow: 0 2px 4px -1px rgb(var(--shadow) / 0.06),
              0 4px 10px -2px rgb(var(--shadow) / 0.07);
}

/* WHEN THE HEADER RETREATS, WHAT IS WELDED TO IT GOES WITH IT.

   Found while fixing the seam, and much worse than the seam was: the
   header hides itself on scroll-down (html.pp-header-hidden), and the
   welded bar stayed pinned at var(--header-h). That left a 69px band
   above the bar with nothing in it — through which the page's own text
   scrolled, in full view, above a bar that was supposed to be the top of
   the screen.

   v12.5 also established that the rail is only welded on a PHONE. Above
   1100px it is a narrow sticky column beside the article, pinned 22px
   below the header, and an unscoped retreat sent the whole column to
   top:0 under the mini reading bar — Like and Save behind it. That is the
   "left side of the page is weirdly overlapping" in that report.

   BOTH of those are still true and both are still handled. HOW they are
   handled moved to v140-layer-60-chrome.css in v14.0, where the retreat
   became a `transform` instead of an animated `top` — see the long note
   there for the sixteen-pixel gap that the animated `top` was opening
   every time the header shrank. Nothing about the retreat is decided
   here any more. */


/* =========================================================================
   THE BOOK — SHAMĀʾIL AL-MUḤAMMADIYYA, v12.4

   "improve its page massively! make it super beautiful & nicer! in
    visuals, design, fonts, spacing and remove all ugly stuff and weird
    bad looking things … we want the sirah & shamail to be extremely
    beautiful, its the seerah & shamail of the best of creation!!"

   Four things, in the order they cost the page most.
   ========================================================================= */

/* ---- 1. THE CHAIN IS NOT THE REPORT ---------------------------------
   The single biggest change, and it is not a colour. A chapter opened
   with four lines of narrator names in the same face, size and ink as
   the description of his ﷺ blessed form. In a printed edition the isnād
   has never been given equal weight with the matn; it is set smaller, or
   lighter, or both, because it is the report's guarantee and not the
   report.

   Lighter, not smaller: shrinking vowelled Naskh costs legibility
   faster than it buys hierarchy, and the chain still has to be readable
   by anyone who wants it. The text itself is untouched and unbroken —
   see pp_sirah_book_split_isnad() for why this is only ever opacity. */
.sirah-book-isnad{
  color: rgb(var(--text-muted));
  opacity: 0.72;
}
.sirah-book-matn{ color: rgb(var(--heading)); }
/* A hair of air where the chain hands over to the report, so the eye has
   somewhere to start even in a solid block of justified Arabic. */
.sirah-book-hadith-ar.has-isnad .sirah-book-matn::before{
  content: "";
  display: inline-block; width: 0.6em;
}
/* Reading in Arabic only, the chain is what you came for as much as the
   matn — so the difference softens rather than disappears. */

/* ---- 2. THE STRAY TICK ----------------------------------------------
   .sirah-book-toc-link is a three-column grid and the "read" tick was
   its FOURTH child, so it had no column to sit in and grid put it on a
   row of its own — a lone ✓ hanging under chapter 26, breaking the run
   of the contents. It is a fourth column now, and it holds its width
   whether or not the chapter has been read, so no row moves when one is
   marked. */
.sirah-book-toc-read{
  margin-left: 0;
  justify-self: center;
  font-size: 0.72rem;
  line-height: 1;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-soft);
}
.sirah-book-toc-item.is-read .sirah-book-toc-read{ opacity: 1; }

/* ---- 3. THE ʿUNWĀN BREATHES -----------------------------------------
   The frontispiece is the one place in this book that earns full
   illumination, so it gets the room to be one: a taller plate, a wider
   gold rule under the title, and the medallion given its own space
   instead of being tucked against the top edge. */
.sirah-book-unwan{
  padding-block: clamp(38px, 7vw, 66px);
}
.sirah-book-unwan-mark{ margin-bottom: clamp(18px, 3vw, 28px); }
.sirah-book-title-ar{ line-height: 1.55; }
.sirah-book-unwan-en{ margin-top: 6px; }

/* ---- 4. THE HONORIFIC ------------------------------------------------
   ﷺ (U+FDFA) is one glyph carrying four words, so at small-caps sizes
   in a label it renders as a dense dark lozenge with no space around it
   — "THE BOOK OF HIS ﷺPERSON". It is given its own breathing room and
   pulled back from the surrounding weight wherever it appears inside
   spaced or uppercased UI text. */
.sirah-book-unwan-sub,
.sirah-book-bab-meta,
.eyebrow,
.crumb-line,
.sirah-book-crumbs{
  /* The ligature does not want the tracking the label around it has. */
  font-kerning: normal;
}
.sirah-book-unwan-sub{ letter-spacing: 0.14em; }

/* U+FDFA is one glyph carrying four words and Amiri draws it with almost
   no side bearing, so in a letter-spaced uppercase label it sits hard
   against whatever follows: "THE BOOK OF HIS (sws)PERSON". letter-spacing
   cannot fix it — that adds space AFTER every character including the
   one inside the ligature's own ink. word-spacing widens the gaps
   between words, which is exactly where the collision is.

   Applied to the letter-spaced caps labels only. Body text sets ﷺ at
   reading size with ordinary word spacing and has never had the
   problem. */
.sirah-book-unwan-sub,
.sirah-book-bab-meta,
.seerah-bookcard-eyebrow,
.eyebrow,
.prayer-now-label,
.prayer-clock-label{
  word-spacing: 0.16em;
}


/* =========================================================================
   PRAYER TIMES — THE INSTRUMENT, v12.4

   "I dont like the layout of prayer times, make it much more beautiful &
    visually appealing & attractive"

   The layout's problem was an inverted hierarchy, and everything else
   followed from it. The largest object on the page — 4rem of display
   serif — was the WALL CLOCK. Nobody opens a prayer-times page to find
   out what time it is; their phone has already told them, at the top of
   the same screen. They open it to find out how long they have.

   So the page is re-ranked to what it is actually asked:

     1. how long until the next prayer      (was third, now the hero)
     2. which prayer, and at what time      (was second)
     3. where in the day I am right now     (new — the arc, as a rail)
     4. all six times                       (was a flat row of grey boxes)
     5. what time it is now                 (was FIRST — now a caption)

   Nothing is removed. The clock still ticks its seconds, for the reason
   v12.3 added them. It is simply no longer the headline.
   ========================================================================= */

/* ---- 1. THE CLOCK STEPS BACK ---------------------------------------- */
.prayer-clock{
  flex-direction: row;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 6px 10px;
  margin-bottom: var(--sp-4);
  padding-bottom: var(--sp-4);
  border-bottom: 1px solid rgb(var(--wash) / 0.16);
}
.prayer-clock-time{
  /* From clamp(2.6rem … 4rem) to a caption. */
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: var(--fs-sm);
  letter-spacing: 0;
  color: rgb(var(--heading-soft));
}
.prayer-clock-sec{ font-size: 0.62em; }
.prayer-clock-label{ letter-spacing: 0.16em; }
.prayer-clock-place{ max-width: 26ch; }
/* The rule under the clock does the separating now. */
.prayer-now-rule{ display: none; }

/* ---- 2. THE COUNTDOWN IS THE HEADLINE -------------------------------
   Gold, because this is the one number the page exists to give, and gold
   is this site's colour for the thing you are meant to look at. Tabular
   figures so the digits do not jitter as the seconds tick. */
.prayer-now-countdown{
  margin-top: var(--sp-2);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.9rem, 1.7rem + 5vw, 4.6rem);
  line-height: 1;
  letter-spacing: -0.035em;
  color: rgb(var(--accent-ui));
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}
/* The countdown is emitted as .pc-num / .pc-unit / .pc-sec by
   assets/prayer-times.js - see the note there for why it is segmented
   rather than one string. The units and the seconds step right back so
   the figure itself carries the line. */
.prayer-now-countdown .pc-num{ font-size: 1em; }
.prayer-now-countdown .pc-unit{
  font-size: 0.32em; font-weight: 500; letter-spacing: 0.04em;
  color: rgb(var(--text-muted)); margin-right: 0.28em;
}
.prayer-now-countdown .pc-sec{
  font-family: var(--font-ui);
  font-size: 0.22em; font-weight: 500; letter-spacing: 0.06em;
  color: rgb(var(--text-muted)); margin-left: 0.2em;
}
.prayer-now-at{
  margin-top: var(--sp-2);
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  color: rgb(var(--text-muted));
  font-variant-numeric: tabular-nums;
}
/* The prayer's own name, above the number it belongs to. */
.prayer-now-ar{ font-size: clamp(1.55rem, 1.1rem + 1.8vw, 2.05rem); line-height: 1.6; }
.prayer-now-label{ letter-spacing: 0.2em; }

/* ---- 3. THE ARC, AS A RAIL ------------------------------------------
   v12.3 removed a decorative arc and left nothing in its place, so the
   page could tell you the countdown but not where in the day you were
   standing. This is that, made useful rather than ornamental: one line,
   filled from the last prayer to now, with the gap you are inside named
   at either end. --pp-progress is set by assets/prayer-times.js. */
.prayer-progress{
  --pp-progress: 0;
  margin: var(--sp-5) auto 0;
  max-width: 420px;
}
.prayer-progress-track{
  position: relative;
  height: 3px;
  border-radius: 999px;
  background: rgb(var(--heading) / 0.09);
  overflow: hidden;
}
.prayer-progress-fill{
  position: absolute; inset: 0 auto 0 0;
  width: calc(var(--pp-progress) * 100%);
  border-radius: 999px;
  background: linear-gradient(90deg, rgb(var(--gilt-edge) / 0.55), rgb(var(--gilt-deep)));
  transition: width 1s linear;
}
@media (prefers-reduced-motion: reduce){
  .prayer-progress-fill{ transition: none; }
}
.prayer-progress-ends{
  display: flex; justify-content: space-between; gap: 12px;
  margin-top: 7px;
  font-family: var(--font-mono);
  font-size: 0.6rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: rgb(var(--text-muted));
}

/* ---- 4. THE SIX TIMES BECOME A DAY, NOT SIX BOXES -------------------
   They were six identical panels in a row: no order, no direction, and
   nothing to say which had been and which was coming. A hairline runs
   behind them now and every prayer sits on it as a mark — the day as a
   line, which is what a day is. Past marks are filled and quiet, the
   next one is gold and raised. */
.prayer-grid{
  position: relative;
  gap: 6px;
  padding-top: 16px;
}
.prayer-grid::before{
  content: "";
  position: absolute; left: 6%; right: 6%; top: 5px;
  height: 1px;
  background: linear-gradient(90deg,
    transparent,
    rgb(var(--wash) / 0.32) 12%,
    rgb(var(--wash) / 0.32) 88%,
    transparent);
  pointer-events: none;
}
.prayer-grid > .prayer-card{
  position: relative;
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  padding-top: 16px;
}
/* The mark on the line. */
.prayer-grid > .prayer-card::before{
  content: "";
  position: absolute; top: -11px; left: 50%;
  width: 7px; height: 7px; margin-left: -3.5px;
  border-radius: 50%;
  background: rgb(var(--bg));
  border: 1.5px solid rgb(var(--wash) / 0.45);
  transition: background-color var(--dur) var(--ease-soft),
              border-color var(--dur) var(--ease-soft),
              transform var(--dur) var(--ease-soft);
}
.prayer-grid > .is-past::before{
  background: rgb(var(--wash) / 0.5);
  border-color: rgb(var(--wash) / 0.5);
}
.prayer-grid > .is-next::before{
  background: rgb(var(--gilt));
  border-color: rgb(var(--gilt-edge));
  transform: scale(1.5);
  box-shadow: 0 0 0 4px rgb(var(--gilt) / 0.18);
}
/* The one you are waiting for is the only card with a surface. */
.prayer-grid > .is-next{
  background: linear-gradient(180deg, rgb(var(--surface)), rgb(var(--bg-alt) / 0.7));
  border: 1px solid rgb(var(--gilt-edge) / 0.42);
  border-radius: var(--radius-sm);
  box-shadow: 0 8px 22px -14px rgb(var(--shadow) / 0.5);
}
.prayer-grid > .is-next .prayer-card-time{ color: rgb(var(--accent-ui)); font-weight: 700; }
.prayer-grid > .is-past{ opacity: 0.45; }
.prayer-grid > .is-past .prayer-card-time{ font-weight: 500; }
.prayer-card-time{ font-size: 0.95rem; }
.prayer-card-ar{ opacity: 0.8; }

/* The three that are not prayers, kept as a quiet footnote row. */
.prayer-extras{
  grid-column: 1 / -1;
  margin-top: var(--sp-4);
  padding-top: var(--sp-3);
  border-top: 1px dashed rgb(var(--heading) / 0.12);
}

@media (max-width: 700px){
  /* Six across is four too many on a phone. Two rows of three keeps the
     day's order reading left-to-right and top-to-bottom, which is the
     order it happens in. */
  .prayer-grid{ grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: 18px; }
  .prayer-grid::before{ display: none; }
  .prayer-grid > .prayer-card::before{ display: none; }
  .prayer-grid > .prayer-card{
    padding-top: 12px;
    background: rgb(var(--surface) / 0.6);
    border: 1px solid rgb(var(--heading) / 0.07);
    border-radius: var(--radius-sm);
  }
  .prayer-grid > .is-next{ border-color: rgb(var(--gilt-edge) / 0.45); }
  .prayer-progress{ max-width: none; }
}


/* =========================================================================
   KITĀB AL-MAGHĀZĪ — the second book on the sīrah shelf. v12.4

   Built from the Shamāʾil's components wherever it can be, so the two
   read as two books in one library rather than as two designs. What is
   here is only what the Shamāʾil has no equivalent of: a finding-list,
   and a contents made of parts rather than of bābs.
   ========================================================================= */

.maghazi-unwan-within{
  margin-top: 6px;
  font-family: var(--font-ui);
  font-size: var(--fs-2xs);
  color: rgb(var(--text-muted));
}
.maghazi-intro-note{
  margin-top: var(--sp-3);
  font-size: var(--fs-xs);
  color: rgb(var(--text-muted));
  font-style: italic;
}

/* ---- The finding-list ------------------------------------------------
   Twelve campaigns, in the order the book reaches them. Set as a
   two-column list of quiet chips rather than as cards: it is an index,
   and an index that looks like a menu of destinations competes with the
   contents underneath it. */
.maghazi-find{ margin-top: var(--sp-9); }
.maghazi-find-title{
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  color: rgb(var(--heading));
  margin: 0 0 4px;
}
.maghazi-find-note{
  margin: 0 0 var(--sp-4);
  font-size: var(--fs-xs);
  color: rgb(var(--text-muted));
  max-width: 62ch;
}
.maghazi-find-list{
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 4px 18px;
}
.maghazi-find-link{
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  transition: background-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .maghazi-find-link:hover{ background: rgb(var(--wash) / 0.08); } }
.maghazi-find-ar{
  grid-column: 1;
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 1.06rem; line-height: 1.8;
  color: rgb(var(--heading));
  /* dir="rtl" makes the span's own text right-to-left, which is correct,
     and ALSO right-aligns it inside its box, which is not: the English
     underneath is left-aligned and the two ended up at opposite ends of
     the row with the number stranded between them. isolate keeps the
     Arabic shaping and joining intact while the box stays left-aligned —
     the same pairing .sirah-book-toc-ar uses for the same reason. */
  text-align: left;
  unicode-bidi: isolate;
}
.maghazi-find-en{
  grid-column: 1;
  font-family: var(--font-ui);
  font-size: var(--fs-2xs);
  color: rgb(var(--text-muted));
}
.maghazi-find-at{
  grid-column: 2; grid-row: 1 / span 2;
  align-self: center;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: rgb(var(--accent-ui));
  font-variant-numeric: tabular-nums;
}

/* ---- The contents, in parts -----------------------------------------
   One column, not two: each row carries a quoted sentence, and a quoted
   sentence in a 50%-width column wraps to three lines and stops being a
   sentence. */
.maghazi-parts-note{
  margin: 0 0 var(--sp-4);
  font-size: var(--fs-xs);
  color: rgb(var(--text-muted));
  max-width: 64ch;
}
.maghazi-parts{ list-style: none; margin: 0; padding: 0; }
.maghazi-part-link{
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-4);
  padding: 13px 12px 13px 4px;
  border-radius: var(--radius-sm);
  border-bottom: 1px solid rgb(var(--heading) / 0.06);
  transition: background-color var(--dur-fast) var(--ease-soft);
}
.maghazi-part-item:last-child .maghazi-part-link{ border-bottom: none; }
@media (hover: hover){ .maghazi-part-link:hover{ background: rgb(var(--wash) / 0.07); } }
.maghazi-part-n{
  display: grid; place-items: center;
  width: 34px; height: 34px;
  border-radius: 50%;
  border: 1px solid rgb(var(--wash) / 0.32);
  background: rgb(var(--wash) / 0.07);
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 0.92rem; line-height: 1;
  color: rgb(var(--accent-ui));
}
.maghazi-part-body{ min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.maghazi-part-range{
  font-family: var(--font-ui);
  font-size: var(--fs-sm); font-weight: 600;
  color: rgb(var(--heading));
  font-variant-numeric: tabular-nums;
}
/* The book describing itself. Italic because it is a quotation, and
   clamped to two lines so a long opening cannot set the row's height
   against every other row. */
.maghazi-part-opening{
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-style: italic;
  line-height: 1.5;
  color: rgb(var(--text-muted));
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.maghazi-part-count{
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: rgb(var(--text-muted));
  font-variant-numeric: tabular-nums;
}

@media (max-width: 560px){
  .maghazi-part-link{ grid-template-columns: 30px minmax(0, 1fr) auto; gap: var(--sp-3); }
  .maghazi-part-n{ width: 30px; height: 30px; font-size: 0.84rem; }
  .maghazi-part-opening{ -webkit-line-clamp: 3; line-clamp: 3; }
}


/* =========================================================================
   =========================================================================
   v12.5
   =========================================================================
   ========================================================================= */


/* =========================================================================
   1. THE TOP OF EVERY PAGE

   "when opening a page … the page starts way below what I would like it
   to be, also the navigation Home > The Prophet ﷺ & His Companions bar is
   also weirdly placed, make sure to fix all this across the entire
   website please"

   Measured at 1440px before this change, from the bottom of the fixed
   header to the first word of the page's own title:

     /category/…    148px      /about/          116px
     /prayer-times/ 149px      /hadith/{book}/  209px
     /qibla/        149px      a post           140px
     /tasbih/       168px      /topics/         104px

   Eight different answers to one question, and the largest of them more
   than a third of a phone screen of nothing. The cause was that the gap
   was being paid for twice — once by the breadcrumb trail's own margin
   and once by whatever `.section-pad` the template happened to use — and
   nobody owned the sum.

   This owns it. `--page-lead` is the ONE gap between the trail and the
   page, everywhere, and it is applied to whatever element follows the
   trail rather than to a list of template classes, so a page added later
   inherits it without being named.
   ========================================================================= */

:root{
  --page-lead: 22px;
}
@media (max-width: 760px){
  :root{ --page-lead: 12px; }
}

/* The trail itself: closer to the header, and no bottom margin of its own
   — the gap below it belongs to --page-lead, in one place. */
.breadcrumbs{
  margin: 0;
  padding-block: 12px 0;
}

/* Whatever comes next, whatever it is. Specificity (0,2,1) so it beats
   `.wrap.section-pad` (0,2,0) and every single-class page shell, without
   needing !important anywhere. */
.site-main > .breadcrumbs + *{
  padding-top: var(--page-lead);
}
/* single.php nests the trail inside the article shell rather than putting
   it at the top level of <main>. */
.article-shell > .breadcrumbs + *{
  padding-top: var(--page-lead);
}

/* A page with NO trail — the front page, the tafsīr reading room — still
   needs its first element to start at a predictable place. */
.site-main > *:first-child:not(.breadcrumbs){
  padding-top: var(--page-lead);
}
/* …except the ones that are a full-bleed band of their own and already
   carry their own inset. */
.site-main > .hero:first-child,
.site-main > .tafsir-bar:first-child,
.site-main > .pp-welded:first-child{
  padding-top: 0;
}

/* The page heroes were each measured and each had a first line a long way
   below its own top edge. These are the internal figures, brought into
   one scale. */
.hero .hero-frame{ padding-block: clamp(30px, 4.4vw, 46px); }
@media (max-width: 760px){
  .hero .hero-frame{ padding-block: 26px; }
}


/* =========================================================================
   2. A SECOND BAR IS PART OF THE HEADER, NOT A THING UNDER IT

   "when there is a second header like reading progress bar or tafsir
   header etc etc, it has to stick to the main header and not leave that
   small gap which is visible as thats very ugly"

   v12.4 fixed this for the tafsīr bar and for the reading rail on a
   phone, and both of those are still correct. What it did not do was
   make the fix general, so every OTHER bar on the site still had the
   fault — and the one the report names first, the reading progress bar
   on a post, was among them.

   Three faults, exactly as v12.4 catalogued them, now applied to all of
   them at once through one class:

     1. THE SLIVER. --header-h is Math.ceil() of the header's real
        height, so a bar pinned at exactly that value starts a fraction
        of a pixel below the header's true bottom edge — which resolves
        to a visible light hairline at most device pixel ratios. Every
        welded bar pins one whole pixel higher and tucks its first row
        under the header, which is fixed and paints above it.

     2. THE SHADOW. The header drops a shadow downward. Onto its own
        continuation that is a dark band across the top of the bar,
        which is what the eye actually reads as "a gap". A single object
        does not cast a shadow on itself.

     3. THE COLOUR STEP. The header is a translucent surface behind a
        blur; a bar painting itself opaque is a different material, and
        a seam shows even where they touch.

   WHAT IS WELDED, as of v12.5: the tafsīr room's bar, the mini reading
   bar on a post, the reading rail on a phone, the resume-reading banner,
   the thirty-day prayer table's header row, and anything a later release
   marks .pp-welded.
   ========================================================================= */

/* (1) — the pixel row that is tucked under the header is given back, so
   the bar's own contents do not shift up by one. `--welded-top` and the
   retreat itself are set in v140-layer-60-chrome.css. */

/* (2) — the header stops being a separate object the moment something is
   welded to its underside. `.mini-bar` is present in the markup of every
   post whether or not it is on screen, so the test has to be for a bar
   that is actually SHOWING, which is what .show means here. */

/* (3) — one material. The mini bar was rgb(--surface / 0.96) with an 8px
   blur; the header is rgb(--surface / 0.88) with a 20px saturating blur. */

/* The resume banner and the month table's header row are sticky bars that
   sat at an arbitrary distance below the header. They are not welded —
   they scroll up from inside the page — but the offset they stop at
   should be the header's real bottom plus one considered gap, not a
   number picked per component. */

/* The reading progress hairline is drawn at the very top of the viewport,
   over the header rather than under it, so it is never part of the seam. */


/* =========================================================================
   3. THE READING RAIL ON A POST

   "see how in posts the left side of the page is weirdly overlapping
   this? and see these weird lines? please make this very clean &
   organized and fix all design issues here"

   Two faults, and the screenshot shows both.

   1. THE OVERLAP. The rail is a sticky column pinned below the header.
      When the header retreats on scroll-down the mini reading bar takes
      its place at the top of the screen — 45px tall, z-index 95 — and
      the rail was pinned to a number that did not know the bar existed.
      Like and Save were behind it. (The other half of that is the
      unscoped `top: 0` rule fixed above.)

   2. THE WEIRD LINES. The table of contents drew its vertical rule
      TWICE: `.toc-track`, a 2px column with the reading-progress fill in
      it, and then every `#tocList li a` carried its OWN
      `border-left: 2px` pulled back over the track with a negative
      margin. Two 2px rules a pixel apart, one of them only coloured in
      on the active item — which is exactly what a stray line looks like.

      There is one rule now. The track is it, the progress fills it, and
      the current heading is marked by a dot ON the track plus weight and
      colour on the label, which is one object saying one thing.
   ========================================================================= */


/* ---- one line, not two -------------------------------------------------- */

/* The marker sits ON the track — the same 2px column, 16px of it, at the
   height of the heading it belongs to. `left` is the track's own width
   plus the flex gap, negated. */

/* ---- the rest of the rail, tidied --------------------------------------- */
/* Everything in the rail sat at a different left inset: the buttons at
   10px of their own padding, the "Text" box at its border, the TOC label
   at 0. They line up now. */
.rail-fontsize{ padding-inline: 10px; }


/* =========================================================================
   4. THE DRAWER'S CURRENT ROW

   "the golden line (or whatever colour based on theme) should be distant
   enough from text and not too far, properly placed, not its a bit too
   close"

   It was `inset 3px 0 0` — a bar hard against the row's leading edge with
   the label starting 10px later, so seven pixels of gap and the bar
   running the full 52px height of the row whatever the label did. It is
   a spine now: inset from the edge, centred on the label's own height,
   rounded, with real space either side of it.
   ========================================================================= */


/* =========================================================================
   5. THE TAFSĪR LIBRARY — THE BOOK CARD, AND THE ROW AT THE TOP

   "these boxes dont look so beautiful (could be much more attractive) and
   are too repeated"

   See the long note above the card in tafsir-library.php. The plate, the
   arch, the struck roundel and the OPEN row are all gone; what is left is
   a hairline, a ground, and thirty-two Arabic titles that are different
   from one another — which is the only thing on these cards that ever
   distinguished one book from the next.
   ========================================================================= */


/* ---- the title, over the site's own double rule -------------------------- */
/* The double rule this site draws under every ʿunwān: a hairline, a gap,
   a thicker one, tapered at both ends. */

/* ---- the name, the author, the line -------------------------------------- */

/* ---- the century, and the way in ----------------------------------------- */


/* =========================================================================
   6. THE PICK ROW, AND THE POPOVERS BEHIND IT

   See the note above pp_tafsir_pickers() in inc/tafsir.php and `pickers()`
   in assets/tafsir.js. Two controls that used to open one full-screen
   sheet now open a popover each, the size of the answer.
   ========================================================================= */

.tafsir-lib-open{
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 10px 14px;
  margin-top: var(--sp-5);
}
.tafsir-lib-open-label{
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--text-muted));
}

.tafsir-pick{
  display: flex; align-items: center; gap: 6px;
  flex-wrap: wrap;
  min-width: 0;
}
.tafsir-pick-slot{ min-width: 0; }
.tafsir-pick-btn{
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 38px;
  padding: 0 10px 0 12px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline-strong);
  background: rgb(var(--surface));
  cursor: pointer;
  max-width: 100%;
  transition:
    border-color var(--dur-fast) var(--ease-soft),
    background-color var(--dur-fast) var(--ease-soft),
    box-shadow var(--dur-fast) var(--ease-soft);
}
.tafsir-pick-btn[aria-expanded="true"]{
  border-color: rgb(var(--wash) / 0.5);
  background: rgb(var(--wash) / 0.07);
}
@media (hover: hover){
  .tafsir-pick-btn:hover{
    border-color: rgb(var(--wash) / 0.5);
    background: rgb(var(--wash) / 0.07);
  }
}
.tafsir-pick-btn:focus-visible{
  outline: 2px solid rgb(var(--accent-ui));
  outline-offset: 2px;
}
.tafsir-pick-label{
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--text-muted));
  flex-shrink: 0;
}
.tafsir-pick-value{
  font-family: var(--font-ui);
  font-size: var(--fs-sm); font-weight: 600;
  color: rgb(var(--heading));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 15ch;
}
.tafsir-pick-caret{
  width: 14px; height: 14px; flex-shrink: 0;
  color: rgb(var(--text-muted));
  transition: transform var(--dur-fast) var(--ease-soft);
}
.tafsir-pick-btn[aria-expanded="true"] .tafsir-pick-caret{ transform: rotate(180deg); }

/* ---- the popover --------------------------------------------------------- */
.tafsir-pop{
  position: fixed; z-index: 300;
  width: min(360px, calc(100vw - 20px));
  display: flex; flex-direction: column;
  border-radius: var(--radius-lg);
  border: 1px solid var(--glass-border);
  background: var(--menu-bg);
  background-image: var(--menu-sheen);
  box-shadow: var(--e-overlay);
  overflow: hidden;
  opacity: 0; transform: translateY(-6px) scale(0.985);
  transition: opacity var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--ease-soft);
}
.tafsir-pop.is-in{ opacity: 1; transform: none; }
.tafsir-pop-head{
  display: flex; align-items: center; gap: 10px;
  padding: 12px 10px 12px 16px;
  border-bottom: 1px solid var(--hairline);
  flex-shrink: 0;
}
.tafsir-pop-title{
  flex: 1; min-width: 0;
  font-family: var(--font-ui);
  font-size: var(--fs-sm); font-weight: 600;
  color: rgb(var(--heading));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tafsir-pop-close{
  width: 32px; height: 32px; flex-shrink: 0;
  display: grid; place-items: center;
  border: none; background: transparent; border-radius: 50%;
  color: rgb(var(--text-muted)); cursor: pointer;
}
@media (hover: hover){ .tafsir-pop-close:hover{ background: rgb(var(--ink) / 0.07); color: rgb(var(--heading)); } }
.tafsir-pop-close svg{ width: 16px; height: 16px; }
.tafsir-pop-body{
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 10px;
}

/* the numbers */
.tafsir-pop-nums{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(46px, 1fr));
  gap: 6px;
}
.tafsir-pop-num{
  min-height: 40px;
  display: grid; place-items: center;
  border-radius: var(--radius-sm);
  border: 1px solid var(--hairline-faint);
  background: rgb(var(--surface) / 0.5);
  font-family: var(--font-mono); font-size: 0.82rem;
  color: rgb(var(--heading-soft));
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){
  .tafsir-pop-num:hover{ background: rgb(var(--wash) / 0.12); border-color: rgb(var(--wash) / 0.4); color: rgb(var(--accent-ui)); }
}

/* the escape hatch at the foot of the ayah grid */
.tafsir-pop-foot{
  display: flex; align-items: center; gap: 8px;
  width: 100%; margin-top: 10px;
  /* Always reachable. Sūrat al-Baqarah is 286 numbers; a way out that is
     286 rows below the fold is not a way out. */
  position: sticky; bottom: -10px; z-index: 1;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  min-height: 42px; padding: 0 12px;
  border: 1px dashed var(--hairline-strong);
  border-radius: var(--radius-sm);
  background: rgb(var(--surface) / 0.92);
  font-family: var(--font-ui); font-size: var(--fs-sm);
  color: rgb(var(--text-muted));
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .tafsir-pop-foot:hover{ background: rgb(var(--ink) / 0.05); color: rgb(var(--heading)); } }
.tafsir-pop-foot svg{ width: 15px; height: 15px; fill: none; stroke: currentColor; }

/* the filter */
.tafsir-pop-filter{
  position: relative; display: flex; align-items: center;
  margin-bottom: 8px;
}
.tafsir-pop-filter svg{
  position: absolute; inset-inline-start: 11px;
  width: 15px; height: 15px; pointer-events: none;
  fill: none; stroke: currentColor; color: rgb(var(--text-muted));
}
.tafsir-pop-filter input{
  width: 100%; min-height: 40px;
  padding: 0 12px 0 34px;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-pill);
  background: rgb(var(--surface));
  font-family: var(--font-ui); font-size: var(--fs-sm);
  color: rgb(var(--text));
}
.tafsir-pop-filter input:focus{
  outline: none; border-color: rgb(var(--wash) / 0.55);
  box-shadow: 0 0 0 3px rgb(var(--accent) / 0.14);
}

/* the rows */
.tafsir-pop-list{ display: flex; flex-direction: column; gap: 1px; }
.tafsir-pop-row{
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: 10px;
  width: 100%; min-height: 46px;
  padding: 7px 12px;
  border: none; border-radius: var(--radius-sm);
  background: transparent; cursor: pointer; text-align: left;
  transition: background-color var(--dur-fast) var(--ease-soft);
}
.tafsir-pop-list-books .tafsir-pop-row{ grid-template-columns: minmax(0, 1fr) auto; }
@media (hover: hover){ .tafsir-pop-row:hover{ background: rgb(var(--wash) / 0.09); } }
.tafsir-pop-row.is-current{ background: rgb(var(--wash) / 0.12); }
.tafsir-pop-row-n{
  font-family: var(--font-mono); font-size: 0.7rem;
  color: rgb(var(--text-muted));
  min-width: 2.2ch; text-align: right;
}
.tafsir-pop-row-main{ display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.tafsir-pop-row-en{
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 600;
  color: rgb(var(--heading));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tafsir-pop-row-count{
  font-size: var(--fs-2xs); color: rgb(var(--text-muted));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tafsir-pop-row-ar{
  font-family: var(--font-arabic-display); font-weight: var(--ar-weight);
  font-size: 1.05rem; line-height: 1.6;
  color: rgb(var(--accent-ui));
  direction: rtl; unicode-bidi: isolate;
  white-space: nowrap;
}
.tafsir-pop-shelf{ margin-bottom: 8px; }
.tafsir-pop-shelf-label{
  display: block; padding: 8px 12px 4px;
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.tafsir-pop-empty{
  margin: 14px 12px; font-size: var(--fs-sm); color: rgb(var(--text-muted));
}

/* On a phone it is a bottom sheet, because a 360px popover anchored to a
   38px button is most of the screen anyway and a sheet is easier to reach. */
@media (max-width: 620px){
  .tafsir-pop.is-sheet{
    inset: auto 0 0 0;
    width: 100%;
    max-height: min(78vh, 620px) !important;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    border-bottom: none;
    transform: translateY(12px);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .tafsir-pop.is-sheet.is-in{ transform: none; }
  .tafsir-pop-nums{ grid-template-columns: repeat(auto-fill, minmax(52px, 1fr)); }
  .tafsir-pop-num{ min-height: 46px; }
  /* v12.5 — the pick row on a phone. Four controls side by side at
     390px gave each of them about 88px, which is not enough for a surah
     name and a caret, so every one of them clipped. Two by two, with the
     button across the foot: the same sentence, laid out the way a phone
     lays out a sentence. */
  .tafsir-lib-open{ flex-direction: column; align-items: stretch; gap: 8px; }
  .tafsir-lib-open-label{ text-align: center; }
  .tafsir-pick{
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 8px;
  }
  .tafsir-pick-slot{ min-width: 0; }
  .tafsir-pick-slot-book{ grid-column: 1 / -1; }
  .tafsir-pick-btn{ width: 100%; justify-content: space-between; min-height: 44px; }
  .tafsir-pick-value{ max-width: none; }
  .tafsir-pick-go{ grid-column: 1 / -1; justify-content: center; min-height: 44px; }
}
body.tafsir-pick-sheet-open{ overflow: hidden; }


/* =========================================================================
   7. THE EDITOR'S NOTES, AS ONE CHIP

   "also the editors note is too big, I want there to be a very minimal
   clean thing, its also already there in 'Aa' button but other than that
   a clean minimal way which is convenient would be nice"

   It was a full-width dashed banner carrying two lines of explanation and
   a SHOW button, above every commentary that has an apparatus — which is
   most of them. The explanation is worth having once; it is not worth
   having at the head of every verse for the rest of the reader's life.

   What is left is a chip: the state, in two words, with a switch. The
   sentence it used to print is its accessible name and its tooltip, and
   the fuller version is still in the Aa popover, where it always was.
   ========================================================================= */
.tafsir-notesbar{
  display: inline-flex; gap: 8px;
  margin: 0 0 var(--sp-4);
  padding: 5px 6px 5px 11px;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-pill);
  background: transparent;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-soft), background-color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .tafsir-notesbar:hover{ border-color: rgb(var(--wash) / 0.45); background: rgb(var(--wash) / 0.06); } }
.tafsir-notesbar:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }
.tafsir-notesbar-ic{
  width: 14px; height: 14px; flex-shrink: 0;
  color: rgb(var(--text-muted));
}
.tafsir-notesbar-text{
  font-family: var(--font-ui); font-size: var(--fs-2xs);
  letter-spacing: 0.02em;
  color: rgb(var(--text-muted));
  white-space: nowrap;
}
.tafsir-notesbar-btn{
  min-height: 22px;
  border: none;
  background: rgb(var(--ink) / 0.08);
  font-family: var(--font-mono); font-size: 0.6rem;
  text-transform: uppercase;
  color: rgb(var(--heading-soft));
  pointer-events: none;   /* the whole chip is the control */
}
.tafsir-notesbar.is-on{ border-color: rgb(var(--wash) / 0.5); background: rgb(var(--wash) / 0.09); }
.tafsir-notesbar.is-on .tafsir-notesbar-ic,
.tafsir-notesbar.is-on .tafsir-notesbar-text{ color: rgb(var(--accent-ui)); }
.tafsir-notesbar.is-on .tafsir-notesbar-btn{
  background: rgb(var(--accent)); color: rgb(var(--on-accent));
}


/* =========================================================================
   8. THE SŪRAH NAMES, IN THE MUṢḤAF'S OWN HAND

   "in the Qur'an menu (from header) the font used to write the Surah
   names is quite ugly, use the same Hafs font used in the Mushaf (of the
   website) please, and make sure there arent useless gaps and that its
   not too close at the same time"

   v13.0 SETTLED FOR AMIRI QURAN. v13.1 DOES NOT HAVE TO.

   "in Qur'an menu the name of the suwar is in Amiri not Hafs!!!!"

   The reason it was Amiri: KFGQPC HAFS SMART, which every ayah on this
   site is set in, holds 2,754 codepoints of which 2,737 are Private Use.
   Its cmap contains no Arabic letters at all — not alif, not lām, not tāʾ
   marbūṭah. It renders the muṣḥaf because data/quran/ pairs every word
   with the font's own glyph codes; a surah NAME is ordinary Unicode, and
   set in Hafs Smart every letter of it is tofu. That is checked, not
   assumed — see the cmap assertion in tools/verify.py.

   What v13.1 found is that KFGQPC publishes the SAME HAND as a normal
   Unicode font: KFGQPC UTHMANIC SCRIPT HAFS, 43 Arabic letters, every
   ḥarakah, the dagger alif, the maddah. All 114 names in
   data/quran/index.json set in it with nothing missing. It is bundled as
   'PP Uthmani' (see the @font-face at the top of this file) and it leads
   --font-quran, so this is now literally the muṣḥaf's hand rather than
   the nearest available substitute — in the menu he reported it in, and
   in the index, the surah headers, the Bismillah and the tafsīr headings
   at the same time. Amiri Quran stays behind it as the fallback.

   THE GAPS. The Arabic sat in a 56px centred column, so a two-letter name
   (طه) and a seven-letter one (العَنكبُوت) were centred in the same box and
   the space between each name and the English beside it changed on every
   row. It is a right-aligned column now, sized to the widest name the
   list holds, with one gap that is the same on every row.
   ========================================================================= */

:root{
  --font-surah: 'PP Uthmani', 'Amiri Quran', 'Amiri', 'Noto Naskh Arabic', serif;
}

.quran-card-ar,
.tafsir-surah-ar,
.tafsir-pop-row-ar,
.quran-index-ar,
.pp-res-surah-ar {
  font-family: var(--font-surah);
  direction: rtl; unicode-bidi: isolate;
  font-weight: 400;
  /* Vowelled Qur'anic Naskh carries marks a long way above and below the
     baseline. Anything under 1.75 puts one row's fatḥah into the next
     row's kasrah, which is the smudge in the screenshot. */
  line-height: 1.8;
}

/* One gap, on every row, between the name and what it means. The column
   is sized to the widest name in the list rather than to a guess, so no
   row is padded out and none is squeezed. */


/* =========================================================================
   9. A LATIN WORD AND AN ARABIC WORD ON ONE LINE

   "see how 'surah سور' and 'أجزاء juz'' image is? the text is not properly
   placed! across many different places of the website"

   Two faults, and the segmented control in the tafsīr browser had both.

   1. THE THUMB DID NOT FIT EITHER TAB. The white thumb behind the active
      segment is `width: calc(50% - 3px)` and slides by 100%, which is
      only correct if the two tabs are the same width. "Sūrah سُوَر" and
      "Juzʾ أَجْزَاء" are not: measured at 1440px they were 96px and 118px,
      so the thumb was 11px narrower than one tab and 11px wider than the
      other and never lined up with what it was highlighting.

   2. BASELINE ALIGNMENT ACROSS TWO SCRIPTS IS NOT ALIGNMENT. The pair sat
      on `align-items: baseline`. Latin and Naskh do not share a baseline
      position within the em — Amiri's sits noticeably lower — so the
      Arabic hung below its neighbour, and the harakāt above it pushed the
      optical centre the other way again. Centring the two boxes and
      trimming the Arabic's own line box is what actually lines them up.

   Both fixes are written against a shared class so the next pair added
   anywhere gets them for free.
   ========================================================================= */

.tafsir-browse-tabs{ display: flex; }
.tafsir-browse-tab{
  flex: 1 1 0;
  min-width: 0;
  justify-content: center;
  align-items: center;     /* not baseline — see above */
  gap: 8px;
}
.tafsir-browse-tab-en{ line-height: 1; }
.tafsir-browse-tab-ar{
  font-family: var(--font-surah);
  font-size: 0.98rem;
  line-height: 1;
  /* The mark stack sits above the letters; a hair of optical lift puts the
     word's own body on the same centre line as the Latin beside it. */
  transform: translateY(0.06em);
  opacity: 0.8;
  direction: rtl; unicode-bidi: isolate;
}

/* The same pairing wherever else it occurs. */
.hadith-book-header .hadith-book-ar,
.tafsir-shelf-ar,
.seerah-books-ar{
  line-height: 1.7;
}
.tafsir-shelf-head{ align-items: center; }
.tafsir-shelf-titles{ display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.tafsir-shelf-titles h2{ margin: 0; line-height: 1.2; }
.tafsir-shelf-ar{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  color: rgb(var(--accent-ui));
  direction: rtl; unicode-bidi: isolate;
}


/* =========================================================================
   10. THE SĪRAH — A SHELF, NOT A TIMELINE

   "under sirah I did not want to gather something you wrote as its
   sensitive and important as you know, I want to remove these sections
   (Except shama'il here its nice), and replace it with an actual book or
   something else thats really suitable, think of something & properly
   design it (both Arabic & English)"

   Five books, in reading order, each one a real kitāb whose every word is
   in the corpus this theme ships. See the head of inc/seerah.php for what
   was removed and why, and inc/sirah-kutub.php for what replaced it.

   THE FORM. A shelf of five is not a grid of five: order matters here —
   the descent, then Makkah and the migration, then Madinah, then who he
   ﷺ was — so they are a numbered list, one to a row, wide enough to read
   the line that says what each one is. Each row is a book seen edge-on: a
   gilt ordinal, the Arabic title over the double rule this site draws
   under every ʿunwān, and the English under that.
   ========================================================================= */

.seerah{
  max-width: 1120px;
  margin: 0 auto;
  padding-bottom: var(--sp-10);
}

/* ---- the ʿunwān ---------------------------------------------------- */
.seerah-unwan{
  position: relative;
  text-align: center;
  padding: var(--sp-9) var(--sp-8) var(--sp-8);
  border: 1px solid rgb(var(--ornament) / 0.28);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(120% 70% at 50% 0%, rgb(var(--ornament) / 0.07), transparent 62%),
    rgb(var(--surface) / 0.6);
}
.seerah-unwan-mark{
  display: grid; place-items: center;
  width: 58px; height: 58px;
  margin: 0 auto var(--sp-4);
  border-radius: 50%;
  border: 1px solid rgb(var(--ornament) / 0.3);
  background: rgb(var(--ornament) / 0.08);
  color: rgb(var(--accent));
}
.seerah-unwan-mark svg{ width: 34px; height: 34px; }
.seerah-unwan-eyebrow{
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  word-spacing: 0.16em;
  color: rgb(var(--accent-ui));
  margin-bottom: var(--sp-3);
}
.seerah-unwan-ar{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: clamp(2.1rem, 1.5rem + 3vw, 3.2rem);
  line-height: 1.6;
  color: rgb(var(--heading));
  margin: 0;
  direction: rtl; unicode-bidi: isolate;
}
.seerah-unwan-tr{
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--text-muted));
  margin: 2px 0 var(--sp-5);
}
.seerah-unwan-salawat{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 1.14rem; line-height: 2;
  color: rgb(var(--accent-ui));
  margin: 0 0 var(--sp-5);
  direction: rtl; unicode-bidi: isolate;
}
.seerah-unwan-rule{
  display: block;
  width: min(180px, 46%); height: 5px;
  margin: 0 auto var(--sp-5);
  background:
    linear-gradient(to right, transparent, rgb(var(--ornament) / 0.8) 18%, rgb(var(--ornament) / 0.8) 82%, transparent) top / 100% 1px no-repeat,
    linear-gradient(to right, transparent, rgb(var(--ornament) / 0.4) 28%, rgb(var(--ornament) / 0.4) 72%, transparent) bottom / 100% 1px no-repeat;
}
.seerah-unwan-lead{
  max-width: 68ch;
  margin: 0 auto;
  font-size: var(--fs-base);
  line-height: 1.75;
  color: rgb(var(--text-muted));
}

/* ---- the section headings ------------------------------------------- */
.seerah-shelf,
.seerah-names,
.seerah-further{ margin-top: var(--sp-9); }

.seerah-shelf-title,
.seerah-names-title,
.seerah-further-title{
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-4);
  margin: 0 0 var(--sp-2);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--hairline);
  font-size: clamp(1.3rem, 1.1rem + 0.8vw, 1.6rem);
  line-height: 1.2;
}
.seerah-shelf-title-ar,
.seerah-names-title-ar,
.seerah-further-title-ar{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: 1.15rem;
  color: rgb(var(--accent-ui));
  direction: rtl; unicode-bidi: isolate;
}

/* ---- the shelf ------------------------------------------------------- */
.seerah-shelf-list{
  list-style: none;
  margin: var(--sp-5) 0 0;
  padding: 0;
  display: flex; flex-direction: column;
  gap: var(--sp-3);
  counter-reset: none;
}
.seerah-shelf-item{ margin: 0; }

.seerah-bookcard{
  position: relative;
  display: grid;
  grid-template-columns: 54px minmax(0, 1fr) auto;
  /* start, not center: the ordinal belongs beside the title it numbers,
     not floating halfway down a card whose height is set by the line of
     description under it. */
  align-items: start;
  gap: var(--sp-5);
  padding: var(--sp-5) var(--sp-6);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background:
    linear-gradient(180deg, rgb(var(--surface)) 0%, rgb(var(--surface) / 0.5) 100%);
  color: inherit;
  overflow: hidden;
  transition:
    border-color var(--dur) var(--ease-soft),
    box-shadow var(--dur) var(--ease-soft),
    transform var(--dur) var(--ease-out-expo);
}
/* The spine: a gilt edge on the leading side, the way a bound book shows
   itself on a shelf. Drawn as a pseudo-element so the card keeps one
   border and one radius. */
.seerah-bookcard::before{
  content: "";
  position: absolute; inset-inline-start: 0; top: 0; bottom: 0;
  width: 4px;
  background: linear-gradient(180deg,
    rgb(var(--wash) / 0.2) 0%, rgb(var(--wash) / 0.85) 20%,
    rgb(var(--wash) / 0.85) 80%, rgb(var(--wash) / 0.2) 100%);
  transition: width var(--dur) var(--ease-soft);
}
@media (hover: hover){
  .seerah-bookcard:hover{
    border-color: rgb(var(--wash) / 0.45);
    box-shadow: var(--e2);
    transform: translateY(-2px);
  }
  .seerah-bookcard:hover::before{ width: 6px; }
}
.seerah-bookcard:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }

.seerah-bookcard-n{
  display: grid; place-items: center;
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid rgb(var(--wash) / 0.28);
  background: rgb(var(--wash) / 0.07);
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 1.1rem;
  color: rgb(var(--accent-ui));
  flex-shrink: 0;
}
.seerah-bookcard-main{ display: flex; flex-direction: column; min-width: 0; gap: 2px; }
.seerah-bookcard-ar{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: clamp(1.35rem, 1.1rem + 0.9vw, 1.7rem);
  line-height: 1.6;
  color: rgb(var(--heading));
  direction: rtl; unicode-bidi: isolate;
  /* This site sets a stray Arabic phrase inside an LTR column flush left,
     so a one-word title and a four-word title start at the same place —
     see the note beside .seerah-bookcard-ar earlier in this file. */
  text-align: left;
}
.seerah-bookcard-rule{
  display: block;
  width: min(110px, 40%); height: 3px;
  margin: 4px 0 8px;
  background:
    linear-gradient(to right, rgb(var(--ornament) / 0.7), transparent) top / 100% 1px no-repeat,
    linear-gradient(to right, rgb(var(--ornament) / 0.35) 60%, transparent) bottom / 100% 1px no-repeat;
  transition: width var(--dur) var(--ease-soft);
}
@media (hover: hover){ .seerah-bookcard:hover .seerah-bookcard-rule{ width: min(150px, 58%); } }
.seerah-bookcard-en{
  font-family: var(--font-display);
  font-size: 1.06rem; font-weight: 600;
  color: rgb(var(--heading));
  line-height: 1.3;
}
.seerah-bookcard-sub{
  font-size: var(--fs-sm);
  color: rgb(var(--accent-ui));
  line-height: 1.5;
}
.seerah-bookcard-lead{
  margin-top: 6px;
  font-family: var(--font-body);
  font-size: var(--fs-sm); line-height: 1.7;
  color: rgb(var(--text-muted));
  max-width: 62ch;
}
.seerah-bookcard-facts{
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: var(--sp-3);
  font-family: var(--font-mono); font-size: 0.66rem;
  letter-spacing: 0.04em;
  color: rgb(var(--text-muted));
}
.seerah-bookcard-facts > * + *::before{
  content: "·";
  margin-inline-end: 10px;
  opacity: 0.6;
}
.seerah-bookcard-go{
  width: 20px; height: 20px; flex: 0 0 auto;
  align-self: center;
  fill: none; stroke: currentColor; stroke-width: 2;
  color: rgb(var(--accent-ui));
  transition: transform var(--dur) var(--ease-out-expo);
}
@media (hover: hover){ .seerah-bookcard:hover .seerah-bookcard-go{ transform: translateX(4px); } }

/* ---- his ﷺ names ------------------------------------------------------ */
.seerah-names-grid{
  list-style: none; margin: var(--sp-5) 0 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--sp-3);
}
.seerah-name{
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: var(--sp-4) var(--sp-3);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: rgb(var(--surface) / 0.5);
  text-align: center;
}
.seerah-name-ar{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: 1.5rem; line-height: 1.7;
  color: rgb(var(--heading));
  direction: rtl; unicode-bidi: isolate;
}
.seerah-name-tr{
  font-family: var(--font-display);
  font-style: italic;
  font-size: 0.92rem;
  color: rgb(var(--accent-ui));
}
.seerah-name-en{
  font-size: var(--fs-2xs);
  line-height: 1.5;
  color: rgb(var(--text-muted));
}
.seerah-names-source{
  margin: var(--sp-4) 0 0;
  font-size: var(--fs-2xs);
  color: rgb(var(--text-muted));
}
.seerah-names-source a{ color: rgb(var(--accent-ui)); text-decoration: underline; text-underline-offset: 3px; }

/* ---- and the sīrah itself --------------------------------------------- */
.seerah-further-note{
  margin: var(--sp-4) 0 var(--sp-5);
  max-width: 74ch;
  font-size: var(--fs-sm); line-height: 1.75;
  color: rgb(var(--text-muted));
}
.seerah-further-list{
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--sp-3);
}
.seerah-further-item{
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 4px;
  padding: var(--sp-4);
  border: 1px solid var(--hairline-faint);
  border-radius: var(--radius);
  background: rgb(var(--bg-alt) / 0.45);
}
.seerah-further-ar{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: 1.22rem; line-height: 1.7;
  color: rgb(var(--heading));
  direction: rtl; unicode-bidi: isolate;
  text-align: left;
}
.seerah-further-body{ display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.seerah-further-en{
  font-family: var(--font-display);
  font-size: 0.98rem; font-weight: 600;
  color: rgb(var(--heading-soft));
}
.seerah-further-who{
  font-family: var(--font-mono); font-size: 0.64rem;
  letter-spacing: 0.04em;
  color: rgb(var(--accent-ui));
}
.seerah-further-blurb{
  margin-top: 4px;
  font-size: var(--fs-sm); line-height: 1.6;
  color: rgb(var(--text-muted));
}

/* ---- the sīrah menu in the bar ---------------------------------------- */

@media (max-width: 760px){
  .seerah-bookcard{
    grid-template-columns: 38px minmax(0, 1fr);
    gap: var(--sp-4);
    padding: var(--sp-4);
  }
  .seerah-bookcard-n{ width: 34px; height: 34px; font-size: 0.95rem; }
  .seerah-bookcard-go{ display: none; }
  .seerah-unwan{ padding: var(--sp-7) var(--sp-4) var(--sp-6); }
  .seerah-names-grid{ grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--sp-2); }
  .seerah-name{ padding: var(--sp-3) var(--sp-2); }
  .seerah-name-ar{ font-size: 1.3rem; }
  .seerah-further-list{ grid-template-columns: minmax(0, 1fr); }
  .seerah-shelf-title,
  .seerah-names-title,
  .seerah-further-title{ font-size: 1.2rem; }
}
@media (prefers-reduced-motion: reduce){
  .seerah-bookcard{ transform: none; }
  @media (hover: hover){
    .seerah-bookcard:hover{ transform: none; }
    .seerah-bookcard:hover .seerah-bookcard-go{ transform: none; }
  }
}


/* =========================================================================
   11. THE ADHKĀR PAGE, DECLUTTERED

   "adhkar page is cluttered, people want to directly access and have
   everything perfectly and beautifully & conveniently accessible, it has
   too much clutter … the Harakat on arabic characters isnt suitable on
   the menu as seen on the pic, and the font use is ugly I prefer
   traditional Arabic bold, and numbers look ugly there! and dont make
   spacing absurd!"

   Measured at 1440px before this change, from the bottom of the header to
   the first word of the first dhikr: 1,148px. Six full-width blocks got
   in the way — a 604px ʿunwān, a thirteen-box rail, a search field, a
   panel head repeating the set's name at 2.4rem, its note, its progress,
   and a row of section chips.

   Four of the six were saying something the reader had already been told.
   What is left is: a short ʿunwān with the ayah on it, ONE bar carrying
   the set picker and the search, and then the adhkār. The same measure
   after: 476px.
   ========================================================================= */

/* ---- the ʿunwān, at half the height --------------------------------- */
.adhkar-unwan{ padding-block: var(--sp-7) var(--sp-6); }
.adhkar-unwan-mark{ width: 46px; height: 46px; margin-bottom: var(--sp-3); }
.adhkar-unwan-mark svg{ width: 22px; height: 22px; }
.adhkar-title{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: clamp(2.1rem, 1.5rem + 2.6vw, 3rem);
  line-height: 1.65;
  margin: 0;
}
.adhkar-unwan-sub{ margin: 0 0 var(--sp-4); }
.adhkar-unwan-divider{ margin-block: var(--sp-3); }
.adhkar-hero-en{ margin-block: 6px; }
.adhkar-unwan-desc{
  margin: var(--sp-4) auto 0;
  max-width: 52ch;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.03em;
  color: rgb(var(--text-muted));
}

/* ---- the rail is gone at every width -------------------------------- */
.adhkar-tabs{ display: none !important; }

/* ---- one bar: the picker, and the search ---------------------------- */


/* The picker itself. Its rules were written for a phone; on a wide screen
   it is the same object at a calmer size. */


/* ---- the sheet: a bottom sheet on a phone, a card on a desktop ------- */

/* THE NUMBERS. They were bare mono digits floating at the right-hand edge
   of a row, at 0.6rem, with nothing to sit against. A count is a figure
   and a unit: it gets a trough, so it reads as one object rather than as
   a stray numeral. */


/* ---- the panel head, slimmed ----------------------------------------- */
.adhkar-panel-head{ padding-block: var(--sp-4); }
.adhkar-panel-id h2{
  font-size: clamp(1.4rem, 1.1rem + 1.2vw, 1.9rem);
  margin: 0;
}

/* ---- the section chips ------------------------------------------------ */
/* Above the phone the chips WRAP rather than scroll. A sideways scroller
   is the right control when there is not room for the row and a way of
   hiding half the contents when there is: measured at 1440px, the "Before
   sleep" set's three chips ran to 1,492px inside a 1,220px column and the
   third was off the right edge of a page with 700px of space beside it. */


/* =========================================================================
   12. THE SITE'S OWN DIALOGS AND MENUS

   "never use device menus, those are usually ugly especially on phones,
   make sure the website has their own native beautiful menus, also same
   for reset counter etc its not nice for the device to show its ugly
   confirmation, all this and similar things must be done in a beautiful
   nice way on the site, suits different devices perfectly too!!"

   The behaviour is in assets/ui.js and the reasoning is at the head of
   that file. What is here is the surface: a card, a scrim, a list, and
   the two shapes each of them takes — anchored to its control on a wide
   screen, and a sheet from the bottom edge on a phone, which is where a
   thumb is.
   ========================================================================= */

body.pp-modal-open{ overflow: hidden; }

/* ---- the confirmation --------------------------------------------------- */
.pp-dialog{
  position: fixed; inset: 0; z-index: 400;
  display: grid; place-items: center;
  padding: 20px;
}
.pp-dialog-scrim{
  position: absolute; inset: 0;
  background: var(--scrim, rgb(0 0 0 / 0.45));
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-soft);
}
.pp-dialog.is-in .pp-dialog-scrim{ opacity: 1; }
.pp-dialog-card{
  position: relative;
  width: min(420px, 100%);
  padding: var(--sp-6) var(--sp-6) var(--sp-5);
  border-radius: var(--radius-lg);
  border: 1px solid var(--glass-border);
  background: rgb(var(--surface));
  box-shadow: var(--e-overlay);
  text-align: center;
  opacity: 0;
  transform: translateY(12px) scale(0.97);
  transition: opacity var(--dur) var(--ease-soft), transform var(--dur) var(--spring);
}
.pp-dialog.is-in .pp-dialog-card{ opacity: 1; transform: none; }
.pp-dialog-title{
  margin: 0 0 var(--sp-3);
  font-family: var(--font-display);
  font-size: 1.22rem; font-weight: 600; line-height: 1.25;
  color: rgb(var(--heading));
}
.pp-dialog-body{
  margin: 0 0 var(--sp-5);
  font-size: var(--fs-sm); line-height: 1.65;
  color: rgb(var(--text-muted));
}
.pp-dialog-actions{
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--sp-3);
}
.pp-dialog-btn{
  min-height: 46px;
  padding: 0 var(--sp-4);
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline-strong);
  background: transparent;
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 600;
  color: rgb(var(--heading));
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft),
              border-color var(--dur-fast) var(--ease-soft),
              transform var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .pp-dialog-btn:hover{ background: rgb(var(--heading) / 0.06); border-color: rgb(var(--heading) / 0.4); } }
.pp-dialog-btn:active{ transform: scale(0.985); }
.pp-dialog-btn:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }
/* The affirmative takes the page's own action colour, so a confirmation
   looks like the rest of the site and not like a browser. */
.pp-dialog-go{
  background: linear-gradient(180deg, rgb(var(--btn)), rgb(var(--btn-deep)));
  color: rgb(var(--on-btn));
  border-color: rgb(var(--btn-edge) / 0.55);
  box-shadow: 0 1px 2px rgb(var(--shadow) / 0.16), inset 0 1px 0 rgb(var(--btn-edge) / 0.28);
}
@media (hover: hover){
  .pp-dialog-go:hover{
    background: linear-gradient(180deg, rgb(var(--btn)) 0%, rgb(var(--btn)) 42%, rgb(var(--btn-deep)) 100%);
    border-color: rgb(var(--btn-edge) / 0.95);
    color: rgb(var(--on-btn));
  }
}
/* A destructive one says so in the one place the eye is already looking. */
.pp-dialog.is-danger .pp-dialog-go{
  background: linear-gradient(180deg, rgb(var(--accent-2)), rgb(var(--accent-2) / 0.85));
  border-color: rgb(var(--accent-2));
  color: rgb(var(--on-accent));
  box-shadow: 0 10px 24px -14px rgb(var(--accent-2) / 0.6);
}
@media (hover: hover){
  .pp-dialog.is-danger .pp-dialog-go:hover{
    background: rgb(var(--accent-2));
    color: rgb(var(--on-accent));
  }
}
@media (max-width: 420px){
  .pp-dialog-actions{ grid-template-columns: minmax(0, 1fr); }
  /* The affirmative first on a phone: it is where the thumb rests, and a
     two-row stack reads top-down. */
  .pp-dialog-go{ order: -1; }
}
@media (prefers-reduced-motion: reduce){
  .pp-dialog-card, .pp-dialog-scrim{ transition: none; }
}

/* ---- the select --------------------------------------------------------- */
/* The real control stays in the DOM as the value — see assets/ui.js — and
   is taken out of the picture without being taken out of the document. */
select.pp-select-native{
  /*
   * v14.0 - EVERY declaration here is !important, and that is the point.
   *
   * This rule's whole job is to take a <select> that PPPicker has already
   * replaced with its own button OUT of the layout. Its specificity is
   * (0,1,1) - one class and one type - so any component that styles its
   * own selects with two classes beats it. `.prayer-select.prayer-select-sm`
   * does exactly that, and the result was a 375px-wide invisible select
   * laid out inside a 297px column on the prayer settings: the page
   * scrolled 38px sideways, on a control nobody can see. (items 17, 46)
   *
   * A visually-hidden helper is not a style, it is a removal, and a
   * removal that a later rule can partly undo is worse than none.
   */
  position: absolute !important;
  width: 1px !important; height: 1px !important;
  min-width: 0 !important; max-width: none !important;
  margin: -1px !important; padding: 0 !important; border: 0 !important;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
  pointer-events: none;
  appearance: none;
  background: none !important;
}
.pp-select{
  display: inline-flex; align-items: center; justify-content: space-between;
  gap: 10px;
  min-height: 40px;
  padding: 0 12px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline-strong);
  background: rgb(var(--surface));
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 500;
  color: rgb(var(--heading));
  cursor: pointer;
  max-width: 100%;
  transition: border-color var(--dur-fast) var(--ease-soft),
              background-color var(--dur-fast) var(--ease-soft);
}
.pp-select[aria-expanded="true"]{
  border-color: rgb(var(--wash) / 0.5);
  background: rgb(var(--wash) / 0.06);
}
@media (hover: hover){
  .pp-select:hover{
    border-color: rgb(var(--wash) / 0.5);
    background: rgb(var(--wash) / 0.06);
  }
}
.pp-select:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }
.pp-select:disabled{ opacity: 0.5; cursor: default; }
.pp-select-label{
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pp-select-caret{
  width: 14px; height: 14px; flex: 0 0 auto;
  color: rgb(var(--text-muted));
  transition: transform var(--dur-fast) var(--ease-soft);
}
.pp-select[aria-expanded="true"] .pp-select-caret{ transform: rotate(180deg); }

.pp-menu{
  position: fixed; z-index: 420;
  min-width: 180px; max-width: min(360px, calc(100vw - 16px));
  display: flex; flex-direction: column;
  border-radius: var(--radius-lg);
  border: 1px solid var(--glass-border);
  background: var(--menu-bg, rgb(var(--surface)));
  background-image: var(--menu-sheen);
  box-shadow: var(--e-overlay);
  overflow: hidden;
  opacity: 0; transform: translateY(-6px) scale(0.985);
  transition: opacity var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--ease-soft);
}
.pp-menu.is-in{ opacity: 1; transform: none; }
.pp-menu-list{
  overflow-y: auto; overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 6px;
}
.pp-menu-item{
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; min-height: 42px;
  padding: 6px 10px;
  border: none; border-radius: var(--radius-sm);
  background: transparent; cursor: pointer; text-align: left;
  font-family: var(--font-ui); font-size: var(--fs-sm);
  color: rgb(var(--heading-soft));
  transition: background-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){ .pp-menu-item:hover{ background: rgb(var(--wash) / 0.09); color: rgb(var(--heading)); } }
.pp-menu-item:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: -2px; }
.pp-menu-item.is-on{ background: rgb(var(--wash) / 0.12); color: rgb(var(--accent-ui)); font-weight: 600; }
.pp-menu-label{ min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.pp-menu-tick{
  width: 15px; height: 15px; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 2.4;
  opacity: 0;
}
.pp-menu-item.is-on .pp-menu-tick{ opacity: 1; }
.pp-menu-sep{
  display: block; padding: 10px 10px 4px;
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--text-muted));
}

/* On a phone it is a sheet from the bottom edge. */
.pp-menu-scrim{
  position: fixed; inset: 0; z-index: 410;
  background: var(--scrim, rgb(0 0 0 / 0.42));
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  opacity: 0; transition: opacity var(--dur) var(--ease-soft);
}
.pp-menu-scrim.is-in{ opacity: 1; }
.pp-menu.is-sheet{
  inset: auto 0 0 0;
  width: 100%; max-width: none;
  max-height: min(70svh, 520px);
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  border-bottom: none;
  padding-bottom: env(safe-area-inset-bottom);
  transform: translateY(14px);
}
.pp-menu.is-sheet.is-in{ transform: none; }
.pp-menu-head{
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  padding: 14px 10px 12px 18px;
  border-bottom: 1px solid var(--hairline);
}
.pp-menu-head span{
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.pp-menu-close{
  width: 34px; height: 34px; flex: 0 0 auto;
  display: grid; place-items: center;
  border: none; border-radius: 50%;
  background: rgb(var(--ink) / 0.06);
  color: rgb(var(--heading-soft));
  cursor: pointer;
}
.pp-menu-close svg{ width: 15px; height: 15px; fill: none; stroke: currentColor; }
.pp-menu.is-sheet .pp-menu-item{ min-height: 50px; font-size: var(--fs-base); }
@media (prefers-reduced-motion: reduce){
  .pp-menu, .pp-menu-scrim{ transition: none; }
}


/* =========================================================================
   13. THE QIBLA

   "in qibla there are so many issues, for example it never really
   calibrates, and pressing calibrate doesnt do anything on camera page,
   also its not clear phone has to be vertical or horizontal or what and
   its also not clear how the 8 movement is, other than the many bugs and
   glitches and errors in qibla itself etc and it never getting calibrated
   etc etc etc, this needs a lot of work!"

   Four faults. Three are in assets/qibla.js and are documented there — the
   ring that could not fill, the sheet that fought the camera's scroll
   lock, and the automatic prompt that nagged forever. The fourth is here,
   and it is one number.
   ========================================================================= */

/* ---- 1. PRESSING CALIBRATE ON THE CAMERA PAGE DID NOTHING ------------
   It did exactly what it does everywhere else: it opened the calibration
   sheet. `.qibla-calibrate` is `z-index: 210`. `.qibla-camera-view` is
   `z-index: 500`. So the sheet opened, correctly, completely, behind a
   full-screen opaque video — and the only thing the reader could observe
   was that the button did nothing.

   620 puts it above the camera and above the nav drawer (100), the search
   palette (240) and the lightbox (250), which is where a modal that can
   be opened from inside a full-screen overlay has to be. */
.qibla-calibrate{ z-index: 620; }

/* ---- 2. HOW TO HOLD IT ------------------------------------------------ */
.qibla-hold{
  display: flex; align-items: flex-start; gap: 9px;
  margin: var(--sp-4) auto 0;
  max-width: 46ch;
  padding: 10px 14px;
  border: 1px dashed rgb(var(--wash) / 0.35);
  border-radius: var(--radius);
  background: rgb(var(--wash) / 0.05);
  font-size: var(--fs-2xs);
  line-height: 1.55;
  color: rgb(var(--text-muted));
  text-align: start;
}
.qibla-hold svg{
  width: 15px; height: 15px; flex: 0 0 auto; margin-top: 1px;
  fill: none; stroke: currentColor;
  color: rgb(var(--accent-ui));
}

/* ---- 3. THE CALIBRATE BUTTON ON THE CAMERA ---------------------------
   Always present now (see the note in assets/qibla.js), and louder only
   while the compass is actually untrustworthy. */
.qibla-cam-calibrate.is-urgent{
  background: rgb(var(--accent-2) / 0.92);
  border-color: rgb(var(--accent-2));
  color: #fff;
  animation: qiblaCalPulse 2.4s var(--ease-soft) infinite;
}
@keyframes qiblaCalPulse{
  0%, 100%{ box-shadow: 0 0 0 0 rgb(var(--accent-2) / 0.5); }
  50%{ box-shadow: 0 0 0 7px rgb(var(--accent-2) / 0); }
}
@media (prefers-reduced-motion: reduce){
  .qibla-cam-calibrate.is-urgent{ animation: none; }
}

/* ---- 4. THE FIGURE OF EIGHT ------------------------------------------
   The steps under it are four now rather than three and the first one is
   the longest, so the list has to be able to wrap without the numeral
   sliding out from beside its own sentence. */
.qibla-calibrate-steps li{
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 10px;
  text-align: start;
}
.qibla-calibrate-steps .qibla-cal-n{ margin-top: 1px; }

/* The sheet is a scrolling card on a short screen; four steps and a ring
   do not fit in 640px of height otherwise. */
.qibla-calibrate-card{
  max-height: min(92svh, 760px);
}


/* =========================================================================
   14. BROWSING A COLLECTION BY NUMBER AND BY CHAPTER

   "people should be able to browse hadiths with numbers & chapters more
   comfortably & conveniently! but in a clean nice way, make it perfect,
   and accurate!!"

   Markup and the reasoning: hadith-collection.php. The old chapter rail
   is gone with it — a horizontal scroller is the right control for four
   chapters and the wrong one for ninety-seven.
   ========================================================================= */


/* v13.2 — the toolbar, the "go to a number" field and the chapter index
   are described ONCE, in v132-layer-20-hadith at the foot of this file.
   What stood here was the v12.5 generation of all three, and it was not
   dead: `.hadith-toolbar{flex-direction:column}` in its own media query
   plus `.hadith-toolbar .hadith-search{flex:1 1 320px}` — two classes,
   so it outranked the newer one-class rule — made flex-basis a HEIGHT on
   a phone, and the search box rendered as a 320px-tall circle. That is
   what an old layer left in place actually costs. */

/* The reading room's bar is seven controls on one line; the library's pick
   row is three on a line of its own. They share a component and must not
   share a width budget — so the labels come off ONLY inside the bar, and
   only where there is genuinely no room for them. */
@media (max-width: 760px){
  .tafsir-bar .tafsir-pick-room .tafsir-pick-label{ display: none; }
  .tafsir-bar .tafsir-pick-room .tafsir-pick-value{ max-width: 8ch; }
  .tafsir-bar .tafsir-pick-room .tafsir-pick-btn{ padding: 0 8px 0 10px; gap: 4px; }
}

/* A table of contents with nothing in it draws no rule. See the note
   beside `.is-empty` in assets/main.js. */

/* ---- "Also a page of" — a narration that is part of a sīrah book ------
   See the note in hadith-single.php. A quiet, whole-width link, the same
   shape as the shelf's own cards so the two read as one library. */
.hadith-in-book{
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: var(--sp-4);
  margin: var(--sp-6) 0 var(--sp-2);
  padding: var(--sp-4) var(--sp-5);
  border: 1px solid rgb(var(--wash) / 0.28);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(120% 200% at 0% 50%, rgb(var(--wash) / 0.08), transparent 60%),
    rgb(var(--surface) / 0.6);
  color: inherit;
  transition: border-color var(--dur) var(--ease-soft), box-shadow var(--dur) var(--ease-soft);
}
@media (hover: hover){ .hadith-in-book:hover{ border-color: rgb(var(--wash) / 0.5); box-shadow: var(--e2); } }
.hadith-in-book-ic{
  display: grid; place-items: center;
  width: 42px; height: 42px; flex: 0 0 auto;
  border-radius: 50%;
  background: rgb(var(--wash) / 0.12);
  border: 1px solid rgb(var(--wash) / 0.26);
  color: rgb(var(--accent-ui));
}
.hadith-in-book-ic svg{ width: 19px; height: 19px; fill: none; stroke: currentColor; }
.hadith-in-book-main{ display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.hadith-in-book-eyebrow{
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.hadith-in-book-ar{
  font-family: var(--font-arabic-display); font-weight: var(--ar-weight);
  font-size: 1.24rem; line-height: 1.75;
  color: rgb(var(--heading));
  direction: rtl; unicode-bidi: isolate; text-align: left;
}
.hadith-in-book-en{
  font-size: var(--fs-sm); color: rgb(var(--text-muted)); line-height: 1.5;
}
.hadith-in-book-go{
  width: 18px; height: 18px; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 2;
  color: rgb(var(--accent-ui));
  transition: transform var(--dur) var(--ease-out-expo);
}
@media (hover: hover){ .hadith-in-book:hover .hadith-in-book-go{ transform: translateX(4px); } }
@media (max-width: 620px){
  .hadith-in-book{ grid-template-columns: auto minmax(0, 1fr); padding: var(--sp-4); }
  .hadith-in-book-go{ display: none; }
}

/* ==== BEGIN GENERATED COVERS — do not edit by hand ==== */
/* Run `python tools/gen_palettes.py --write`. See COVER_VARIANTS.

   THE ATTRIBUTE SELECTORS BELOW ARE NOT A TRICK, THEY ARE THE
   MECHANISM. inc/cover-art.php emits ordinary SVG presentation
   attributes — fill="rgb(var(--cv-a))" — and a browser will
   never substitute a custom property inside one of those: a
   presentation attribute is parsed as an attribute value, not as
   CSS. So the attribute is ignored, and these rules, which ARE
   CSS, supply the colour. The whole 900-line drawing file needed
   no change, the covers repaint in the same frame as the palette,
   and nothing moves. */
.cover-art,.cover-mark{
  --cv-leaf: var(--gilt);
  --cv-lit:  var(--gilt-hi);
  --cv-deep: var(--gilt-deep);
}
[fill="rgb(var(--cv-a))"]{ fill: rgb(var(--cv-a)); }
[fill="rgb(var(--cv-b))"]{ fill: rgb(var(--cv-b)); }
[fill="rgb(var(--cv-ink))"]{ fill: rgb(var(--cv-ink)); }
[fill="rgb(var(--cv-foil))"]{ fill: rgb(var(--cv-foil)); }
[fill="rgb(var(--cv-leaf))"]{ fill: rgb(var(--cv-leaf)); }
[fill="rgb(var(--cv-lit))"]{ fill: rgb(var(--cv-lit)); }
[fill="rgb(var(--cv-deep))"]{ fill: rgb(var(--cv-deep)); }
[stroke="rgb(var(--cv-leaf))"]{ stroke: rgb(var(--cv-leaf)); }
[stroke="rgb(var(--cv-lit))"]{ stroke: rgb(var(--cv-lit)); }
[stroke="rgb(var(--cv-deep))"]{ stroke: rgb(var(--cv-deep)); }
[stop-color="rgb(var(--cv-a))"]{ stop-color: rgb(var(--cv-a)); }
[stop-color="rgb(var(--cv-b))"]{ stop-color: rgb(var(--cv-b)); }
[stop-color="rgb(var(--cv-ink))"]{ stop-color: rgb(var(--cv-ink)); }
[stop-color="rgb(var(--cv-ink) / 0)"]{ stop-color: rgb(var(--cv-ink) / 0); }
[stop-color="rgb(var(--cv-ink) / 0.68)"]{ stop-color: rgb(var(--cv-ink) / 0.68); }
[stop-color="rgb(var(--cv-leaf))"]{ stop-color: rgb(var(--cv-leaf)); }
[stop-color="rgb(var(--cv-lit))"]{ stop-color: rgb(var(--cv-lit)); }
[stop-color="rgb(var(--cv-deep))"]{ stop-color: rgb(var(--cv-deep)); }
[stop-color="rgb(var(--cv-foil))"]{ stop-color: rgb(var(--cv-foil)); }
[stroke="rgb(var(--cv-ink))"]{ stroke: rgb(var(--cv-ink)); }
[stroke="rgb(var(--cv-foil))"]{ stroke: rgb(var(--cv-foil)); }
[stroke="rgb(var(--cv-a))"]{ stroke: rgb(var(--cv-a)); }
[data-theme="saffron"] .cv-0{ --cv-a:32 93 60; --cv-b:64 163 110; --cv-ink:14 36 24; --cv-foil:20 57 37; }
[data-theme="saffron"] .cv-1{ --cv-a:30 74 45; --cv-b:65 142 90; --cv-ink:13 29 18; --cv-foil:22 54 33; }
[data-theme="saffron"] .cv-2{ --cv-a:36 112 76; --cv-b:67 183 129; --cv-ink:16 43 30; --cv-foil:19 58 40; }
[data-theme="saffron"] .cv-3{ --cv-a:37 93 52; --cv-b:71 161 95; --cv-ink:16 36 21; --cv-foil:22 55 30; }
[data-theme="saffron"] .cv-4{ --cv-a:35 80 53; --cv-b:72 145 101; --cv-ink:15 31 21; --cv-foil:23 53 35; }
[data-theme="saffron"] .cv-5{ --cv-a:36 99 68; --cv-b:69 168 119; --cv-ink:16 38 27; --cv-foil:20 56 38; }
[data-theme="saffron"] .cv-6{ --cv-a:42 111 63; --cv-b:76 179 107; --cv-ink:18 43 26; --cv-foil:21 56 31; }
[data-theme="saffron"] .cv-7{ --cv-a:33 77 52; --cv-b:68 143 101; --cv-ink:14 30 21; --cv-foil:23 54 36; }
[data-theme="frost"] .cv-0{ --cv-a:24 72 101; --cv-b:49 129 178; --cv-ink:11 28 39; --cv-foil:132 51 67; }
[data-theme="frost"] .cv-1{ --cv-a:24 37 81; --cv-b:53 75 154; --cv-ink:11 15 31; --cv-foil:132 68 51; }
[data-theme="frost"] .cv-2{ --cv-a:25 123 121; --cv-b:49 201 198; --cv-ink:12 48 47; --cv-foil:132 51 99; }
[data-theme="frost"] .cv-3{ --cv-a:101 66 29; --cv-b:175 117 57; --cv-ink:39 26 13; --cv-foil:51 132 128; }
[data-theme="frost"] .cv-4{ --cv-a:39 29 86; --cv-b:77 60 157; --cv-ink:16 13 33; --cv-foil:132 101 51; }
[data-theme="frost"] .cv-5{ --cv-a:27 108 106; --cv-b:53 184 181; --cv-ink:12 42 41; --cv-foil:132 51 99; }
[data-theme="frost"] .cv-6{ --cv-a:32 121 83; --cv-b:60 195 138; --cv-ink:14 47 33; --cv-foil:132 51 131; }
[data-theme="frost"] .cv-7{ --cv-a:83 73 26; --cv-b:156 137 56; --cv-ink:32 28 12; --cv-foil:51 112 132; }
[data-theme="rose"] .cv-0{ --cv-a:101 24 55; --cv-b:178 49 101; --cv-ink:39 11 22; --cv-foil:51 132 54; }
[data-theme="rose"] .cv-1{ --cv-a:81 24 24; --cv-b:154 53 53; --cv-ink:31 11 11; --cv-foil:51 132 86; }
[data-theme="rose"] .cv-2{ --cv-a:123 25 104; --cv-b:201 49 172; --cv-ink:48 12 41; --cv-foil:82 132 51; }
[data-theme="rose"] .cv-3{ --cv-a:101 66 29; --cv-b:175 117 57; --cv-ink:39 26 13; --cv-foil:51 132 127; }
[data-theme="rose"] .cv-4{ --cv-a:86 51 29; --cv-b:157 98 60; --cv-ink:33 21 13; --cv-foil:51 132 118; }
[data-theme="rose"] .cv-5{ --cv-a:51 27 108; --cv-b:92 53 184; --cv-ink:21 12 42; --cv-foil:132 110 51; }
[data-theme="rose"] .cv-6{ --cv-a:103 32 121; --cv-b:167 60 195; --cv-ink:40 14 47; --cv-foil:114 132 51; }
[data-theme="rose"] .cv-7{ --cv-a:83 72 26; --cv-b:156 136 56; --cv-ink:32 28 12; --cv-foil:51 113 132; }
[data-theme="emerald"] .cv-0{ --cv-a:24 101 73; --cv-b:49 178 131; --cv-ink:11 39 29; --cv-foil:132 51 127; }
[data-theme="emerald"] .cv-1{ --cv-a:24 79 81; --cv-b:53 151 154; --cv-ink:11 30 31; --cv-foil:132 51 94; }
[data-theme="emerald"] .cv-2{ --cv-a:25 123 48; --cv-b:49 201 84; --cv-ink:12 48 20; --cv-foil:105 51 132; }
[data-theme="emerald"] .cv-3{ --cv-a:101 55 29; --cv-b:175 100 57; --cv-ink:39 22 13; --cv-foil:51 132 116; }
[data-theme="emerald"] .cv-4{ --cv-a:29 61 86; --cv-b:60 115 157; --cv-ink:13 24 33; --cv-foil:132 51 62; }
[data-theme="emerald"] .cv-5{ --cv-a:27 66 108; --cv-b:53 117 184; --cv-ink:12 27 42; --cv-foil:132 51 56; }
[data-theme="emerald"] .cv-6{ --cv-a:47 121 32; --cv-b:82 195 60; --cv-ink:20 47 14; --cv-foil:73 51 132; }
[data-theme="emerald"] .cv-7{ --cv-a:83 64 26; --cv-b:156 122 56; --cv-ink:32 25 12; --cv-foil:51 125 132; }
[data-theme="obsidian"] .cv-0{ --cv-a:118 90 28; --cv-b:194 150 53; --cv-ink:46 35 13; --cv-foil:57 136 147; }
[data-theme="obsidian"] .cv-1{ --cv-a:90 96 29; --cv-b:159 169 58; --cv-ink:35 37 13; --cv-foil:57 100 147; }
[data-theme="obsidian"] .cv-2{ --cv-a:140 61 29; --cv-b:208 104 62; --cv-ink:54 25 13; --cv-foil:57 147 122; }
[data-theme="obsidian"] .cv-3{ --cv-a:117 58 33; --cv-b:191 100 62; --cv-ink:45 24 15; --cv-foil:57 147 122; }
[data-theme="obsidian"] .cv-4{ --cv-a:68 101 34; --cv-b:120 172 65; --cv-ink:27 39 15; --cv-foil:57 64 147; }
[data-theme="obsidian"] .cv-5{ --cv-a:31 124 80; --cv-b:59 198 132; --cv-ink:14 48 32; --cv-foil:143 57 147; }
[data-theme="obsidian"] .cv-6{ --cv-a:137 36 48; --cv-b:200 76 90; --cv-ink:53 16 20; --cv-foil:57 147 86; }
[data-theme="obsidian"] .cv-7{ --cv-a:99 71 31; --cv-b:171 126 61; --cv-ink:38 28 14; --cv-foil:57 145 147; }
[data-theme="midnight"] .cv-0{ --cv-a:28 70 118; --cv-b:53 120 194; --cv-ink:13 28 46; --cv-foil:147 57 61; }
[data-theme="midnight"] .cv-1{ --cv-a:29 34 96; --cv-b:58 66 169; --cv-ink:13 15 37; --cv-foil:147 89 57; }
[data-theme="midnight"] .cv-2{ --cv-a:29 126 140; --cv-b:62 190 208; --cv-ink:13 49 54; --cv-foil:147 57 97; }
[data-theme="midnight"] .cv-3{ --cv-a:117 81 33; --cv-b:191 135 62; --cv-ink:45 32 15; --cv-foil:57 147 147; }
[data-theme="midnight"] .cv-4{ --cv-a:56 34 101; --cv-b:100 65 172; --cv-ink:23 15 39; --cv-foil:147 125 57; }
[data-theme="midnight"] .cv-5{ --cv-a:31 124 115; --cv-b:59 198 184; --cv-ink:14 48 45; --cv-foil:147 57 117; }
[data-theme="midnight"] .cv-6{ --cv-a:36 137 109; --cv-b:76 200 166; --cv-ink:16 53 43; --cv-foil:147 57 133; }
[data-theme="midnight"] .cv-7{ --cv-a:99 90 31; --cv-b:171 156 61; --cv-ink:38 35 14; --cv-foil:57 120 147; }
[data-theme="velvet"] .cv-0{ --cv-a:118 28 59; --cv-b:194 53 103; --cv-ink:46 13 24; --cv-foil:57 147 64; }
[data-theme="velvet"] .cv-1{ --cv-a:96 32 29; --cv-b:169 63 58; --cv-ink:37 14 13; --cv-foil:57 147 100; }
[data-theme="velvet"] .cv-2{ --cv-a:140 29 112; --cv-b:208 62 172; --cv-ink:54 13 44; --cv-foil:86 147 57; }
[data-theme="velvet"] .cv-3{ --cv-a:117 83 33; --cv-b:191 137 62; --cv-ink:45 33 15; --cv-foil:57 145 147; }
[data-theme="velvet"] .cv-4{ --cv-a:101 64 34; --cv-b:172 113 65; --cv-ink:39 26 15; --cv-foil:57 147 136; }
[data-theme="velvet"] .cv-5{ --cv-a:31 124 116; --cv-b:59 198 186; --cv-ink:14 48 45; --cv-foil:147 57 116; }
[data-theme="velvet"] .cv-6{ --cv-a:122 36 137; --cv-b:181 76 200; --cv-ink:47 16 53; --cv-foil:122 147 57; }
[data-theme="velvet"] .cv-7{ --cv-a:99 91 31; --cv-b:171 158 61; --cv-ink:38 35 14; --cv-foil:57 118 147; }
[data-theme="juniper"] .cv-0{ --cv-a:28 118 75; --cv-b:53 194 127; --cv-ink:13 46 30; --cv-foil:143 57 147; }
[data-theme="juniper"] .cv-1{ --cv-a:29 96 91; --cv-b:58 169 161; --cv-ink:13 37 35; --cv-foil:147 57 115; }
[data-theme="juniper"] .cv-2{ --cv-a:29 140 43; --cv-b:62 208 81; --cv-ink:13 54 18; --cv-foil:107 57 147; }
[data-theme="juniper"] .cv-3{ --cv-a:117 90 33; --cv-b:191 148 62; --cv-ink:45 35 15; --cv-foil:57 137 147; }
[data-theme="juniper"] .cv-4{ --cv-a:34 79 101; --cv-b:65 137 172; --cv-ink:15 31 39; --cv-foil:147 57 79; }
[data-theme="juniper"] .cv-5{ --cv-a:124 60 31; --cv-b:198 103 59; --cv-ink:48 25 14; --cv-foil:57 147 124; }
[data-theme="juniper"] .cv-6{ --cv-a:64 137 36; --cv-b:110 200 76; --cv-ink:26 53 16; --cv-foil:71 57 147; }
[data-theme="juniper"] .cv-7{ --cv-a:99 97 31; --cv-b:171 168 61; --cv-ink:38 38 14; --cv-foil:57 110 147; }
:root{ --cv-a:32 93 60; --cv-b:64 163 110; --cv-ink:14 36 24; --cv-foil:20 57 37; }
/* ==== END GENERATED COVERS ==== */

/* ==== BEGIN v13.0 LAYER — assembled by tools, see CHANGELOG-v13.0.md ==== */
/* ---- v130-layer-10-home.css ---- */

/* =========================================================================
   1. "A MOMENT TO REFLECT" — SPACING, AND A REAL PANEL. v13.0.

   "on PC 'A moment to reflect' is sticked to hadith of the day way too
   closely, make sure its placed properly.. also make its design even more
   beautiful!!!"

   TWO FAULTS, AND THE SECOND ONE CAUSED THE FIRST TO LOOK WORSE.

   · SPACING. The section carried `padding-top:8px` inline, the same as
     the two panels above it. Eight pixels is the gap between two cards in
     ONE stack; this is a different kind of object and needed the gap that
     says so.

   · WIDTH. `.reflection-band` was `max-width:820px` while the ayah and
     the hadith above it run the full width of the wrap. So a narrower
     card was tucked under two wider ones with no gap — which reads as a
     piece that fell off the panel above it rather than as its own thing.

   It is now the same width as the two panels it follows, with a real gap
   above, and it is drawn as an illuminated leaf: a gold rule inside the
   ink, corner brackets like the hero frame and the covers, and a large
   shamsa held in the right-hand margin the way a manuscript holds one.
   ========================================================================= */

.reflection-section{ padding-top: 34px !important; }

.reflection-band{
  /* Full width, so it lines up with the ayah and the hadith above. */
  max-width: none;
  margin: 0;
}

.reflection-band .reflection-card{
  padding: 34px 38px 30px;
  border-radius: var(--radius-lg);
  border: 1px solid rgb(var(--gilt) / 0.28);
}

/* The gold rule INSIDE the ink, and the four corner brackets. Drawn with
   one pseudo-element and a pair of gradients rather than four elements. */
.reflection-band .reflection-card::before{
  content: "";
  position: absolute;
  inset: 10px;
  border: 1px solid rgb(var(--gilt) / 0.34);
  border-radius: calc(var(--radius-lg) - 8px);
  pointer-events: none;
  z-index: 1;
}
.reflection-corner{
  position: absolute;
  width: 18px; height: 18px;
  border: 0 solid rgb(var(--gilt) / 0.85);
  pointer-events: none;
  z-index: 2;
}
.reflection-corner.tl{ top: 10px;    left: 10px;  border-top-width: 2px; border-left-width: 2px;  border-top-left-radius: 5px; }
.reflection-corner.tr{ top: 10px;    right: 10px; border-top-width: 2px; border-right-width: 2px; border-top-right-radius: 5px; }
.reflection-corner.bl{ bottom: 10px; left: 10px;  border-bottom-width: 2px; border-left-width: 2px;  border-bottom-left-radius: 5px; }
.reflection-corner.br{ bottom: 10px; right: 10px; border-bottom-width: 2px; border-right-width: 2px; border-bottom-right-radius: 5px; }

/* The shamsa in the margin. It replaces the giant typographic quotation
   mark that used to sit here: a Latin curly quote is the one ornament on
   this page that belongs to no part of the tradition it draws from. */
.reflection-mark{
  position: absolute;
  right: 26px;
  top: 44%;
  translate: 0 -50%;
  width: 132px; height: 132px;
  color: rgb(var(--gilt));
  opacity: 0.085;
  pointer-events: none;
  z-index: 0;
}
.reflection-card::after{ content: none; }

.reflection-band .quote-text{
  font-size: clamp(1.2rem, 2.1vw, 1.45rem);
  line-height: 1.62;
  max-width: 46ch;
  margin-top: 18px;
  z-index: 2;
}
.reflection-head .eyebrow{ z-index: 2; }
.reflection-controls{ z-index: 2; margin-top: 26px; }

/* The gold thread under the count, in the action metal rather than in an
   accent that changes hue from palette to palette. */
.reflection-fill{
  background: linear-gradient(90deg, rgb(var(--gilt-deep)), rgb(var(--gilt-hi)));
}
.reflection-head .eyebrow,
.reflection-star{ color: rgb(var(--gilt)); }

@media (max-width: 860px){
  .reflection-section{ padding-top: 22px !important; }
  .reflection-band .reflection-card{ padding: 26px 22px 22px; }
  .reflection-mark{ width: 140px; height: 140px; right: -40px; opacity: 0.09; }
  .reflection-band .quote-text{ max-width: none; }
}

/* ---- v130-layer-20-adhkar.css ---- */

/* =========================================================================
   2. THE ADHKĀR INDEX — v13.0. THE MENU IS THE PAGE.

   See the long note in page-tasbih.php for what this replaces and why.
   What matters here is the SPACING, which was the third of the three
   complaints ("so messy and cluttered and spaced wrongly"):

     · one tile is a three-line block on a 16px baseline — Arabic name,
       English name, then count and window on one quiet line — with 14px
       between the emblem and the text and 18px inside the tile. Nothing
       floats in the middle distance any more;
     · the count reads "27 adhkār" beside the window it belongs with,
       rather than as a bare numeral halfway across the row;
     · and the grid is a real grid, so every tile is the same width. The
       v12.2 rail sized each box by its own label, which is why the row
       read as ragged.
   ========================================================================= */

.adhkar-index{
  margin: 0 0 var(--sp-7);
}

.adhkar-index-head{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  margin: 0 0 18px;
}
.adhkar-index-title{
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.18rem;
  font-weight: 600;
  color: rgb(var(--heading));
  letter-spacing: -0.01em;
}

/* Search — inside the index's own head, at the size of a secondary
   control rather than at the size of the menu itself. */
.adhkar-find{
  position: relative;
  flex: 1 1 240px;
}
.adhkar-find-ic{
  position: absolute; left: 13px;
  pointer-events: none;
}
.adhkar-find input{
  padding: 10px 38px 10px 38px;
  border-radius: 999px;
  transition: border-color var(--dur) var(--ease-soft), box-shadow var(--dur) var(--ease-soft);
}
.adhkar-find input::-webkit-search-cancel-button{ display: none; }
.adhkar-find input:focus{
  border-color: rgb(var(--gilt-edge) / 0.55);
  box-shadow: 0 0 0 3px rgb(var(--gilt) / 0.2);
}
.adhkar-find-clear{
  position: absolute; right: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 50%;
  border: 0; background: rgb(var(--heading) / 0.08);
  color: rgb(var(--text-muted)); cursor: pointer;
}
.adhkar-find-clear svg{ width: 13px; height: 13px; }
.adhkar-find-count{
  position: absolute; right: 40px;
  font-family: var(--font-mono); font-size: 0.68rem;
  color: rgb(var(--text-muted));
  pointer-events: none;
}

/* ---- the tiles --------------------------------------------------------- */
/* =========================================================================
   3. THE QUR'AN READING LINES — v13.0.

   "keep the default as translation + transliteration + Arabic, but allow
   an option to keep only arabic etc in a seriously nice clean way, also
   make sure its properly positioned and not too big and reasonable"

   Three switches in the reading rail, one per line, any combination. See
   assets/quran.js for why a segmented Both / Arabic / English picker was
   the wrong shape and what replaced it.

   "NOT TOO BIG" is the constraint that decides the design here: the rail
   is a floating panel about 190px wide and this is one of four controls
   in it. So each switch is a 34px row — a glyph in the line's own script,
   its name, and a tick — and the whole group is 108px tall. The picker it
   replaces was 132px and had a sliding indicator behind it.
   ========================================================================= */

.quran-lines{
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 3px;
  border-radius: 14px;
  background: rgb(var(--heading) / 0.06);
}

.quran-line-btn{
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) 16px;
  align-items: center;
  gap: 8px;
  padding: 7px 8px;
  border: 0;
  border-radius: 11px;
  background: transparent;
  color: rgb(var(--text-muted));
  font-family: var(--font-ui);
  font-size: 0.74rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition:
    background var(--dur) var(--ease-soft),
    color var(--dur) var(--ease-soft);
}
@media (hover: hover){ .quran-line-btn:hover{ background: rgb(var(--heading) / 0.06); color: rgb(var(--heading)); } }
.quran-line-btn:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 1px; }

.quran-line-btn.is-on{
  background: rgb(var(--gilt) / 0.22);
  color: rgb(var(--heading));
}

.quran-line-glyph{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  line-height: 1;
  color: rgb(var(--text-muted));
  transition: color var(--dur) var(--ease-soft);
}
/* Keyed on the switch's own name, not on its position: the row lost a
   member in v13.2 and an nth-child selector would have moved with it. */
.quran-line-btn[data-line="ar"] .quran-line-glyph{
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: 1.06rem;
}
.quran-line-btn[data-line="en"] .quran-line-glyph,
.quran-line-btn[data-line="tr"] .quran-line-glyph{
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.02em;
}
.quran-line-btn.is-on .quran-line-glyph{ color: rgb(var(--gilt-edge)); }

.quran-line-name{ min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.quran-line-tick{
  width: 15px; height: 15px;
  fill: none; stroke: currentColor; stroke-width: 2.4;
  color: rgb(var(--gilt-edge));
  opacity: 0;
  transition: opacity var(--dur) var(--ease-soft);
}
.quran-line-btn.is-on .quran-line-tick{ opacity: 1; }

/* The last line on cannot be turned off — see quran.js. The refusal is a
   single flinch rather than a message, because a message about why a
   toggle did not move is longer than the thing it is explaining. */
@keyframes ppLineRefuse{
  0%, 100%{ transform: translateX(0); }
  25%{ transform: translateX(-3px); }
  75%{ transform: translateX(3px); }
}
.quran-line-btn.is-refusing{ animation: ppLineRefuse 240ms var(--ease-soft); }
@media (prefers-reduced-motion: reduce){
  .quran-line-btn.is-refusing{ animation: none; }
}

/* ---- what the switches actually hide ----------------------------------- */
.quran-reader[data-show-ar="0"] .quran-ayah-ar{ display: none; }
.quran-reader[data-show-en="0"] .quran-ayah-en{ display: none; }

/* Two named switches, Arabic and Translation. 132px is the width at
   which the longer of the two fits at 0.74rem without ellipsing. */
.quran-lines{ width: 132px; }
@media (max-width: 620px){
  .quran-lines{ width: 128px; }
  .quran-line-btn{ font-size: 0.72rem; padding: 8px 8px; }
}

/* =========================================================================
   THE LANDING'S HERO SEARCH — v13.0.

   The search box was a full-width section of its own, four blocks down.
   Inside the hero it has to be narrower than the hero and wider than a
   button, and it has to sit under the two calls to action rather than
   competing with them — so it is 520px, centred, with real air above it.
   ========================================================================= */

.quran-hero-search{
  max-width: 520px;
  margin: 30px auto 0;
  text-align: left;
}
.quran-hero-search .quran-search-box{ margin: 0; }
.quran-hero-search .quran-search-results{ margin-top: 10px; text-align: left; }

@media (max-width: 620px){
  .quran-hero-search{ margin-top: 22px; }
}

/* "Ways to keep at it" — the heading the three moved panels sit under, so
   they read as a group rather than as three things that happen to follow
   the surah list. */
.quran-more{ border-top: 1px solid rgb(var(--gilt-edge) / 0.18); }
.quran-more-head{ margin-bottom: var(--sp-6); }
.quran-more-head h2{
  margin: 6px 0 0;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2rem);
  color: rgb(var(--heading));
}
.quran-more .section-pad-sm{ padding-block: 0; }

/* =========================================================================
   READ A PASSAGE — the tafsīr range. v13.0.

   One line at the foot of a commentary. It has to be findable and it has
   to be ignorable, which means: a label, three small pills, and nothing
   that looks like a primary action.
   ========================================================================= */

.tafsir-range{
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px 14px;
  margin: var(--sp-6) 0 0;
  padding: 14px 18px;
  border-radius: 999px;
  border: 1px dashed rgb(var(--gilt-edge) / 0.35);
  background: rgb(var(--gilt) / 0.07);
}
.tafsir-range-label{
  font-family: var(--font-mono);
  font-size: 0.64rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.tafsir-range-opts{ display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.tafsir-range-opt{
  display: inline-flex;
  align-items: center;
  padding: 6px 13px;
  border-radius: 999px;
  border: 1px solid rgb(var(--heading) / 0.12);
  background: rgb(var(--surface) / 0.8);
  color: rgb(var(--heading-soft));
  font-family: var(--font-ui);
  font-size: 0.78rem;
  font-weight: 600;
  text-decoration: none;
  transition:
    border-color var(--dur) var(--ease-soft),
    background var(--dur) var(--ease-soft),
    color var(--dur) var(--ease-soft);
}
@media (hover: hover){
  .tafsir-range-opt:hover{
    border-color: rgb(var(--gilt-edge) / 0.5);
    background: rgb(var(--gilt) / 0.18);
    color: rgb(var(--heading));
  }
}
.tafsir-range-opt.is-on{
  border-color: rgb(var(--gilt-edge) / 0.7);
  background: rgb(var(--gilt) / 0.3);
  color: rgb(var(--heading));
}
.tafsir-range-one{ border-style: dashed; }

/* Each further ayah in a range: its own rule with the reference set into
   it, then the text, then the commentary — the same shape as the first
   one above it, without the tools that only make sense once per page. */
.tafsir-more-ayah{ margin-top: var(--sp-7); }
.tafsir-more-rule{
  text-align: center;
  margin-bottom: var(--sp-5);
}
.tafsir-more-rule::before{
  left: 0; right: 0;
  border-top: 1px solid rgb(var(--gilt-edge) / 0.28);
}
.tafsir-more-rule span{
  position: relative;
  display: inline-block;
  padding: 3px 14px;
  border-radius: 999px;
  background: rgb(var(--bg));
  border: 1px solid rgb(var(--gilt-edge) / 0.35);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  color: rgb(var(--accent-ui));
}

/* ---- v130-layer-40-reading.css ---- */

/* =========================================================================
   4. THE TYPE SCALE — ONE CONTROL, FOUR PLACES. v13.0.

   "also replace this ugly A-/A+ thing on posts etc with something much
   more beautiful!! maybe you change their place or whatever it may be,
   just beautiful"

   WHAT WAS UGLY, precisely, because "make it beautiful" has an answer
   here and it is not a matter of taste:

     · The two glyphs were "A−" (U+2212) and "A+" (ASCII), which are
       different widths and different weights, so two buttons that should
       have been a matched pair never looked like one.
     · Neither button said where in the range you were. Pressing the plus
       five times and pressing it six times looked identical, so the only
       way to find the size you wanted was to overshoot and come back.
     · And there were FOUR of them — the post rail, the Qur'an rail, and
       the two tafsīr popovers — laid out three different ways, one of
       them vertically with the dots running largest-to-smallest downward.

   The replacement is the control every reading application converged on,
   because it needs no label: the same letter at two sizes, with the steps
   between them drawn as a track. The size is a POSITION, and you can see
   it. The small A is on the left because that is the direction the value
   increases in — the Qur'an rail's version had to be read bottom-to-top.
   ========================================================================= */

.pp-typesize{
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 6px;
  border-radius: 999px;
  background: rgb(var(--heading) / 0.055);
  border: 1px solid rgb(var(--heading) / 0.08);
}

.pp-typesize-btn{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 26px; height: 26px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgb(var(--surface));
  box-shadow: 0 1px 2px rgb(var(--shadow) / 0.14);
  color: rgb(var(--heading));
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  line-height: 1;
  cursor: pointer;
  transition:
    background var(--dur) var(--ease-soft),
    color var(--dur) var(--ease-soft),
    transform var(--dur-fast) var(--ease-soft),
    box-shadow var(--dur) var(--ease-soft);
}
.pp-typesize-btn.is-big{ font-size: 1.02rem; }
@media (hover: hover){
  .pp-typesize-btn:hover:not(:disabled){
    background: rgb(var(--gilt) / 0.35);
    color: rgb(var(--on-gilt));
    transform: translateY(-1px);
    box-shadow: 0 3px 8px rgb(var(--shadow) / 0.2);
  }
}
.pp-typesize-btn:active:not(:disabled){ transform: translateY(0) scale(0.94); }
.pp-typesize-btn:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }
.pp-typesize-btn:disabled{ opacity: 0.32; cursor: default; box-shadow: none; }

.pp-typesize-track{
  display: flex;
  align-items: center;
  gap: 5px;
  flex: 1 1 auto;
  justify-content: center;
  min-width: 0;
}
.pp-typesize-track i{
  display: block;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: rgb(var(--heading) / 0.2);
  transition: background var(--dur) var(--ease-soft), transform var(--dur) var(--ease-soft);
}
.pp-typesize-track i.is-on{
  background: rgb(var(--gilt-edge));
  transform: scale(1.18);
}

/* In the two Aa popovers the control is the full width of the popover;
   in the two rails it is the width of the rail. Both are handled by the
   flex above — this only stops it from stretching absurdly wide inside a
   popover that has grown for another reason. */
.tafsir-reading-pop .pp-typesize,
.qa-tafsir-reading-pop .pp-typesize{ width: 100%; }

/* =========================================================================
   5. THE POST RAIL'S READING GROUP — the size, and one even ink.
   ========================================================================= */


/* "Standard colours". A rail button like the others, so it is part of the
   column rather than an appliance bolted to the end of it, and it turns
   gold when it is on — the same state colour every switch on this site
   uses. It hides itself on any palette but the default light one; see
   window.ppSyncFlatten() in assets/main.js. */
.rail-flat.is-on{
  border-color: rgb(var(--gilt-edge) / 0.5);
  background: rgb(var(--gilt) / 0.18);
  color: rgb(var(--heading));
}
.rail-flat.is-on svg{ color: rgb(var(--gilt-edge)); }

/* =========================================================================
   6. WHAT "STANDARD COLOURS" ACTUALLY DOES.

   The rules that normalise a post's own colours already exist (search for
   data-flatten). What is here is the LINK case they missed: a link the
   writer coloured is still a link, and flattening it to body ink would
   take away the one signal that it can be clicked. So links keep a colour
   — the palette's own — rather than losing one.
   ========================================================================= */

html[data-flatten="1"] .entry-content a:not(.wp-block-button__link){
  color: rgb(var(--accent-ui)) !important;
  text-decoration-color: rgb(var(--wash) / 0.45);
}
@media (hover: hover){
  html[data-flatten="1"] .entry-content a:not(.wp-block-button__link):hover{
    color: rgb(var(--accent-2)) !important;
  }
}

/* =========================================================================
   THE READING GROUP ON A PHONE — v13.0.

   Below 1100px the post rail stops being a column beside the article and
   becomes a horizontal strip above it, and `.rail-actions` inside it is a
   scroller. A three-line column dropped into that strip made the whole
   bar 113px tall and pushed itself off the right-hand edge.

   In the strip it is a row: the type scale, then the colour switch, both
   at the strip's own 44px touch height. The strip scrolls, which is what
   it is for.
   ========================================================================= */

@media (max-width: 1100px){
  .pp-typesize{ flex: 0 0 auto; padding: 3px 5px; }
  .pp-typesize-btn{ width: 30px; height: 30px; }
  .pp-typesize-track{ gap: 4px; padding: 0 2px; }
  .rail-flat.rail-flat{ min-width: 44px; min-height: 44px; }
}

/* Below 520px the dots are the first thing that can go: two A's and a
   switch is the control, and the track is the part of it that only
   confirms what the A's just did. */

/* The strip is a scroller and has been since v8.0, but nothing said so:
   the last icon simply stopped at the edge. A soft fade on the right is
   the cue every horizontal scroller uses, and it costs one mask.

   `mask-image` rather than an overlaid gradient, because the strip sits
   on a panel whose colour changes with the palette and an overlay would
   have to know it. A mask knows nothing and is always right. */

/* ---- v130-layer-50-book.css ---- */

/* =========================================================================
   7. THE SHAMĀʾIL, READ AS A BOOK — REBUILT. v13.0.

   "in hadith allow two options: read shamail as ahadith or as a book, and
   completely generate a new design for the book page, its currently very
   ugly & bland & basic, I want something SUPER beautiful, in aesthetics,
   in design & logical order & proper spacing and beautiful designs, in
   navigation, in beauty, in organization & being clean and nice"

   See the long note at the head of sirah-book-chapter.php for what was
   there. What is here is the furniture: a running head, an ʿunwān, a leaf
   per narration with an illuminated numeral, and a turn that names the
   chapters either side.
   ========================================================================= */

/* ---- 7.1  THE SWITCH between the two ways of reading it ---------------- */

.hadith-mode{
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin: 0 0 var(--sp-6);
  padding: 5px;
  border-radius: calc(var(--radius) + 5px);
  background: rgb(var(--heading) / 0.05);
  border: 1px solid rgb(var(--heading) / 0.08);
}
.hadith-mode-side{
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: var(--radius);
  text-decoration: none;
  color: rgb(var(--text-muted));
  transition:
    background var(--dur) var(--ease-soft),
    color var(--dur) var(--ease-soft),
    box-shadow var(--dur) var(--ease-soft);
}
@media (hover: hover){ .hadith-mode-side:hover{ background: rgb(var(--surface) / 0.7); color: rgb(var(--heading)); } }
.hadith-mode-side.is-on{
  background: rgb(var(--surface));
  color: rgb(var(--heading));
  box-shadow: 0 1px 2px rgb(var(--shadow) / 0.12), inset 0 0 0 1px rgb(var(--gilt-edge) / 0.28);
}
.hadith-mode-ic{
  width: 34px; height: 34px;
  padding: 6px;
  border-radius: 10px;
  background: rgb(var(--wash) / 0.12);
  color: rgb(var(--accent-ui));
  fill: none; stroke: currentColor;
}
.hadith-mode-side.is-on .hadith-mode-ic{
  background: rgb(var(--gilt) / 0.3);
  color: rgb(var(--gilt-edge));
}
.hadith-mode-text{ display: block; min-width: 0; }
.hadith-mode-name{
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.3;
  color: rgb(var(--heading));
}
.hadith-mode-note{
  display: block;
  font-size: 0.76rem;
  line-height: 1.4;
  color: rgb(var(--text-muted));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (max-width: 620px){
  .hadith-mode{ grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .hadith-mode-side{ padding: 11px 12px; gap: 10px; }
}

/* ---- 7.2  THE RUNNING HEAD --------------------------------------------
   A book you are twenty chapters into should say so without your having
   to scroll back. Sticky under the site header, 44px, and a thread along
   its foot for the whole book — not for this chapter's scroll, which is
   not progress through a book. */

.book-runner{
  position: sticky;
  top: var(--welded-top, var(--header-h, 68px));
  z-index: 3;
  background: rgb(var(--bg) / 0.92);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid rgb(var(--heading) / 0.08);
  margin-bottom: var(--sp-7);
}
.book-runner-in{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  height: 44px;
}
.book-runner-home,
.book-runner-toc{
  display: inline-flex;
  align-items: center;
  gap: 7px;
  text-decoration: none;
  color: rgb(var(--heading-soft));
  font-family: var(--font-ui);
  font-size: 0.78rem;
  font-weight: 600;
  transition: color var(--dur) var(--ease-soft);
}
@media (hover: hover){
  .book-runner-home:hover,
  .book-runner-toc:hover{ color: rgb(var(--accent-ui)); }
}
.book-runner-home svg,
.book-runner-toc svg{
  width: 15px; height: 15px;
  fill: none; stroke: currentColor; stroke-width: 2;
  flex: 0 0 auto;
}
.book-runner-title{
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: 1.02rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: min(46ch, 42vw);
}
.book-runner-folio{
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
  white-space: nowrap;
}
.book-runner-thread{
  display: block;
  height: 2px;
  background: rgb(var(--heading) / 0.08);
}
.book-runner-thread i{
  display: block;
  height: 100%;
  background: linear-gradient(90deg, rgb(var(--gilt-deep)), rgb(var(--gilt-hi)));
}
@media (max-width: 620px){
  .book-runner-folio{ display: none; }
  .book-runner-title{ max-width: 52vw; }
}

/* ---- 7.3  THE ʿUNWĀN --------------------------------------------------
   What an illuminated chapter opening actually is: a double rule, the
   chapter's numeral in a medallion breaking the rule, the title, and a
   second rule under it. It replaces a grey rounded rectangle. */

.book-unwan{
  position: relative;
  text-align: center;
  padding: 0;
  margin: 0 0 var(--sp-7);
  background: none;
  border: 0;
}
.book-unwan-rule{
  display: block;
  height: 5px;
  border-top: 1.5px solid rgb(var(--gilt-edge) / 0.55);
  border-bottom: 0.5px solid rgb(var(--gilt-edge) / 0.3);
}
.book-unwan-rule.is-top{ margin-bottom: 0; }
.book-unwan-rule.is-foot{ margin-top: 22px; }

.book-unwan-medallion{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px; height: 46px;
  /* Pulled up ONTO the rule it breaks. The negative top margin has
     to be in this shorthand rather than in a rule of its own above
     it, or the shorthand resets it. */
  margin: -28px auto 14px;
  position: relative;
  z-index: 1;
  border-radius: 50%;
  background:
    radial-gradient(circle at 38% 32%, rgb(var(--gilt-hi)), rgb(var(--gilt)) 58%, rgb(var(--gilt-deep)) 100%);
  /* The last ring is the PAGE's own colour, so the double rule behind
     the medallion stops at it instead of running through it — which is
     how an illuminator sets a medallion into a rule. */
  box-shadow:
    0 0 0 1px rgb(var(--gilt-edge) / 0.6),
    0 0 0 5px rgb(var(--bg)),
    0 0 0 6px rgb(var(--gilt) / 0.3),
    0 4px 10px -4px rgb(var(--shadow) / 0.4);
}
.book-unwan-numeral{
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: 1.16rem;
  line-height: 1;
  color: rgb(var(--on-gilt));
}

.book-unwan .sirah-book-bab-ar{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: clamp(1.5rem, 3.4vw, 2.1rem);
  line-height: 1.95;
  color: rgb(var(--heading));
  margin: 0 0 10px;
  max-width: 28ch;
  margin-inline: auto;
}
.book-unwan .sirah-book-bab-en{
  font-family: var(--font-display);
  font-size: 1.06rem;
  font-weight: 600;
  color: rgb(var(--heading-soft));
  margin: 0 0 8px;
}
.book-unwan .sirah-book-bab-meta{
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
  margin: 0;
}

/* ---- 7.4  THE LINE SWITCHES ------------------------------------------- */

.book-lines{
  width: auto;
  max-width: 340px;
  margin: 0 auto var(--sp-7);
  flex-direction: row;
  gap: 3px;
}
.book-lines .quran-line-btn{
  grid-template-columns: 20px minmax(0, 1fr) 15px;
  padding: 8px 12px;
  font-size: 0.76rem;
}
@media (max-width: 520px){
  .book-lines{ max-width: none; }
}

/* ---- 7.5  A LEAF ------------------------------------------------------
   One narration. The numeral sits in the margin on a wide screen, the way
   a folio number does, and moves above the text on a phone where there is
   no margin to sit in. */

.book-leaves{
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: none;
}
.book-leaf{
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr);
  gap: 20px;
  padding: 0 0 var(--sp-7);
  margin: 0 0 var(--sp-7);
  border-bottom: 1px solid rgb(var(--gilt-edge) / 0.16);
}
.book-leaf:last-child{ border-bottom: 0; margin-bottom: var(--sp-5); }

.book-leaf-n{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px; height: 38px;
  border-radius: 50%;
  background: rgb(var(--gilt) / 0.16);
  border: 1px solid rgb(var(--gilt-edge) / 0.34);
  color: rgb(var(--gilt-edge));
  font-family: var(--font-mono);
  font-size: 0.74rem;
  font-weight: 600;
  line-height: 1;
}

.book-leaf-body{ min-width: 0; }

.book-leaf-narrator{
  font-family: var(--font-ui);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: rgb(var(--accent-ui));
  margin: 0 0 14px;
}

.book-leaf-ar{
  margin: 0;
  padding: 18px 20px;
  border-radius: var(--radius);
  background: rgb(var(--surface) / 0.6);
  border: 1px solid rgb(var(--heading) / 0.06);
  border-right: 3px solid rgb(var(--gilt) / 0.55);
}
.book-leaf-en{
  margin: 16px 0 0;
  padding-top: 16px;
  border-top: 1px solid rgb(var(--gilt-edge) / 0.18);
}
/* With the Arabic switched off the translation is the leaf, so it does
   not want a rule above it dividing it from nothing. */
.sirah-book-page[data-show-ar="0"] .book-leaf-en{
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

.book-leaf-foot{ margin: 14px 0 0; }
.book-leaf-foot a{
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 0.64rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
  text-decoration: none;
  transition: color var(--dur) var(--ease-soft);
}
@media (hover: hover){ .book-leaf-foot a:hover{ color: rgb(var(--accent-ui)); } }
.book-leaf-foot svg{
  width: 13px; height: 13px;
  fill: none; stroke: currentColor; stroke-width: 2;
  transition: transform var(--dur) var(--ease-out-expo);
}
@media (hover: hover){ .book-leaf-foot a:hover svg{ transform: translateX(3px); } }

@media (max-width: 720px){
  .book-leaf{ grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .book-leaf-n{ width: 32px; height: 32px; font-size: 0.68rem; }
  .book-leaf-ar{ padding: 14px 15px; }
}

/* ---- 7.6  WHAT THE SWITCHES HIDE -------------------------------------- */
.sirah-book-page[data-show-ar="0"] .sirah-book-hadith-ar,
.sirah-book-page[data-show-en="0"] .sirah-book-hadith-en{ display: none; }
.sirah-book-page[data-show-en="0"] .sirah-book-isnad{ opacity: 0.85; }

/* ---- 7.7  TURNING THE PAGE -------------------------------------------- */

.book-turn{
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: stretch;
  gap: 12px;
  margin-top: var(--sp-8);
  padding-top: var(--sp-6);
  border-top: 1.5px solid rgb(var(--gilt-edge) / 0.4);
}
.book-turn .sirah-book-turn-link{
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 16px 18px;
  border-radius: var(--radius);
  border: 1px solid rgb(var(--heading) / 0.09);
  background: rgb(var(--surface) / 0.55);
  text-decoration: none;
  transition:
    border-color var(--dur) var(--ease-soft),
    background var(--dur) var(--ease-soft),
    transform var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){
  .book-turn a.sirah-book-turn-link:hover{
    border-color: rgb(var(--gilt-edge) / 0.45);
    background: rgb(var(--surface));
    transform: translateY(-2px);
  }
}
.book-turn .sirah-book-turn-link.is-next{ text-align: right; align-items: flex-end; }
.book-turn .sirah-book-turn-link.is-empty{
  border: 0;
  background: none;
  pointer-events: none;
}
.book-turn .sirah-book-turn-link.is-end{
  pointer-events: none;
  border-style: dashed;
  border-color: rgb(var(--gilt-edge) / 0.35);
  background: rgb(var(--gilt) / 0.06);
  align-items: center;
  text-align: center;
}
.book-turn .sirah-book-turn-dir{
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.book-turn .sirah-book-turn-dir svg{
  width: 13px; height: 13px;
  fill: none; stroke: currentColor; stroke-width: 2;
}
.book-turn .sirah-book-turn-ar{
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: 1.14rem;
  line-height: 1.6;
  color: rgb(var(--heading));
}
.book-turn .sirah-book-turn-en{
  font-size: 0.84rem;
  color: rgb(var(--text-muted));
}
.book-turn .sirah-book-turn-toc{
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 14px 16px;
  border-radius: var(--radius);
  border: 1px solid rgb(var(--gilt-edge) / 0.3);
  background: rgb(var(--gilt) / 0.1);
  color: rgb(var(--heading-soft));
  text-decoration: none;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  transition: background var(--dur) var(--ease-soft), color var(--dur) var(--ease-soft);
}
@media (hover: hover){ .book-turn .sirah-book-turn-toc:hover{ background: rgb(var(--gilt) / 0.22); color: rgb(var(--heading)); } }
.book-turn .sirah-book-turn-toc svg{
  width: 18px; height: 18px;
  fill: none; stroke: currentColor; stroke-width: 1.7;
}

@media (max-width: 720px){
  .book-turn{ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .book-turn .sirah-book-turn-toc{ grid-column: 1 / -1; order: -1; flex-direction: row; }
  .book-turn .sirah-book-turn-link{ padding: 13px 14px; }
  .book-turn .sirah-book-turn-en{ font-size: 0.78rem; }
}

/* ---- v130-layer-60-qibla.css ---- */

/* =========================================================================
   8. THE QIBLA PAGE — v13.0.

   "huge qibla glitches.. HUGE... figure them all out and fix one by one"

   The four found are written out at the head of the patch that fixed
   them; two of them are here.
   ========================================================================= */

/* ---- 8.1  THE CAMERA BUTTON --------------------------------------------
   It was `linear-gradient(accent → accent-2)` under a flat 42% black
   scrim. The arithmetic behind that was sound — it guaranteed 4.98:1 for
   the label on every palette — and the result on Parchment was gold over
   vermilion under black, which is a muddy maroon that appears nowhere
   else on this site. It is the same burnished gold every other primary
   action is now, and the contrast question answers itself: the label is
   the page's own ink on gold, proved on all ten palettes by
   tools/gen_palettes.py. */


/* ---- 8.2  "NO COMPASS HERE" -------------------------------------------
   A fourth accuracy level, for a device that has no magnetometer at all.
   It is not a warning — nothing is wrong — so it is drawn as the quiet
   state rather than as the red one. */

.qibla-accuracy[data-level="none"]{
  color: rgb(var(--text-muted));
}
.qibla-accuracy[data-level="none"] .qibla-accuracy-bars i{
  background: rgb(var(--heading) / 0.16);
}
.qibla-accuracy[data-level="none"] .qibla-accuracy-text{
  color: rgb(var(--text-muted));
}
/* Nothing on the page can be calibrated into existence, so the offer to
   calibrate goes away with it. */
.qibla-app:has(.qibla-accuracy[data-level="none"]) .qibla-recalibrate-btn{ display: none; }

/* ---- 8.3  THE DIAL BEFORE THERE IS A BEARING --------------------------
   With no location there is no bearing, so the needle sat at 0° — which
   is a direction, and looks exactly like an answer. Dimmed until there is
   something to point at. The page already carries `is-unset` on the app
   while step 1 is unanswered. */

.qibla-app.is-unset .qibla-arrow,
.qibla-app.is-unset .qibla-kaaba{
  opacity: 0.28;
  filter: saturate(0.2);
}
.qibla-app.is-unset .qibla-compass{
  position: relative;
  /* Room for the caption below it, which is absolutely positioned
     and would otherwise land on the empty bearing line. */
  margin-bottom: 68px;
}
/* With no bearing there is nothing for these to say. An em-dash and
   a caption reading "clockwise from true north" under an empty
   number is three pieces of furniture around an absence. */
.qibla-app.is-unset .qibla-degrees,
.qibla-app.is-unset .qibla-degrees-note,
.qibla-app.is-unset .qibla-distance{ display: none; }
.qibla-app.is-unset .qibla-compass::after{
  content: attr(data-unset-note);
  position: absolute;
  left: 50%; bottom: -6px;
  translate: -50% 100%;
  width: max-content;
  max-width: 22ch;
  text-align: center;
  font-family: var(--font-ui);
  font-size: 0.78rem;
  line-height: 1.4;
  color: rgb(var(--text-muted));
}

/* ---- v130-layer-65-prayer.css ---- */

/* =========================================================================
   THE PRAYER PANEL BEFORE THERE IS A LOCATION — v13.0.

   The same fault as the Qibla dial, on the page beside it: with no
   location there are no times, so the hero showed "NOW —", "NEXT PRAYER
   —" and a countdown of "—". A dash under "NEXT PRAYER" is not an empty
   field; it reads as an answer, and the answer it reads as is "nothing".

   The rows go, and one line takes their place. `is-unset` is set by
   assets/prayer-times.js and removed the moment a location arrives.
   ========================================================================= */

.prayer-app.is-unset .prayer-now,
.prayer-app.is-unset .prayer-grid,
.prayer-app.is-unset .prayer-foot-row,
.prayer-app.is-unset .prayer-panel-actions{ display: none !important; }

.prayer-app.is-unset .prayer-hero-panel{
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-height: 150px;
  padding-block: var(--sp-7);
  text-align: center;
}
.prayer-app.is-unset .prayer-hero-panel::after{
  content: attr(data-unset-note);
  max-width: 34ch;
  font-family: var(--font-ui);
  font-size: 0.92rem;
  line-height: 1.6;
  color: rgb(var(--text-muted));
}

/* ---- v130-layer-70-arabic.css ---- */

/* =========================================================================
   9. ARABIC SIZE — THE LAST THREE PLACES IT WAS STILL SMALLER. v13.0.

   "make sure its always sized correctly and looks visually perfect, not
   smaller than Eng as usual, across the entire website"

   Most of this was answered structurally: the bundled faces carry
   `size-adjust: 124%` (see THE ARABIC FACES at the top of this file), so
   Arabic at the same font-size now has the same apparent size as the
   Latin beside it, everywhere, without a single per-component number.

   Three places still measured smaller, because their font-size was
   explicitly set LOWER than the English they sit next to. Found by
   walking every `[lang="ar"]` element on twenty-two routes at three
   widths and comparing its computed font-size with its nearest
   non-Arabic sibling's — see the audit probe in the release notes.
   ========================================================================= */

/* The chapter name under a narration's title. It was 1.25rem against an
   h1 of 1.4–1.44rem. */
.hadith-single-chapter-ar{
  /* The h1 above it is clamp(1.4rem, 3.2vw, 1.8rem); this tracks it
     rather than picking a number, so the two cannot drift apart at a
     width nobody tested. */
  font-size: clamp(1.45rem, 3.3vw, 1.85rem);
  line-height: 1.9;
}

/* The shelf headings in the tafsīr library: the Arabic name of a shelf
   was 0.9× the English heading it belongs to. */
.tafsir-shelf-ar{
  font-size: 1.28rem;
  line-height: 1.7;
}

/* A book's author, in Arabic, under a line of English prose about it. */

/* ---- v130-layer-80-emblems.css ---- */

/* =========================================================================
   10. THE EMBLEMS, AT THE SIZE THEY WERE DRAWN FOR. v13.0.

   The marks in inc/emblems.php carry real structure — a ḥizām across the
   Kaʿbah, five petals on the rose, tread on al-Muwaṭṭaʾ's road — and they
   were being drawn at 16px inside a 32px tile, where all of that averages
   out to a smudge. 20px in the same tile is where each one becomes the
   book it means, and it is still comfortably inside the tile.

   These are the two places a book emblem appears: the mega-panel row in
   the header, and the card in the hadith index.
   ========================================================================= */


/* The adhkār tiles already draw theirs at 22px — see the adhkār index. */
/* ==== END v13.0 LAYER ==== */

/* ==== BEGIN v13.1 LAYER — assembled by tools, see CHANGELOG-v13.1.md ==== */
/* ---- v131-layer-05-chrome.css ---- */

/* =========================================================================
   v13.1 — 1. THE LIGHT/DARK BUTTON.

   "make it easier for people to switch light to dark! they have to go to
    that theme then dark then pick which is not that convenient"

   One button in the bar, beside the palette. It shows the side you are
   NOT on, because an icon on a control is an instruction, not a label:
   a moon means "go dark", and showing a moon while you are already dark
   is the commonest bug in this control on the whole web.

   Both icons are in the markup and one is hidden, rather than swapping
   `href` in script — so it is correct in the very first painted frame,
   before main.js has run, the same way the palette itself is.
   ========================================================================= */

/* The moon gets a hair of rotation so it reads as a crescent hung in the
   bar rather than as a letter C, and the sun is left square. */

/* ---- v131-layer-20-tafsir.css ---- */

/* =========================================================================
   v13.1 — THE TAFSĪR BOOK CARDS ARE BOOKS NOW.

   "replace these boxes which tafsir books are in, make it MUCH more
    beautiful, and not too repetitive also, make a really beautiful
    design!!"

   See the note in scratchpad/p08 and inc/tafsir.php: the card gains a
   metal SPINE with the century on it, its own illuminated DEVICE (drawn
   per book by pp_tafsir_crest()), and the grid alternates between two
   papers so a wall of thirty-two is not one flat sheet.
   ========================================================================= */

/* ---- the spine ---------------------------------------------------------- */
/* The century was tried ON the spine, set vertically, the way a shelf
   mark is. At 0.8rem a single Arabic-Indic digit turned sideways reads as
   a smudge, not as a number, so the spine is bare metal and the book's
   full year stays where it was, in the foot. */

/* ---- the device --------------------------------------------------------- */

/* ---- two papers, checkered across the grid ------------------------------ */
/* nth-child(4n+1) and (4n+4) alternate in a four-column grid AND still
   alternate at three, two and one column, because the pattern is on the
   source order rather than on a column. */


/* ---- v131-layer-25-tafsir-room.css ---- */

/* =========================================================================
   v13.1 — THE TAFSĪR READING ROOM: THE RAIL, THE COLUMNS, THE PASSAGE.

   See inc/tafsir-rail.php for what the rail holds and why, and
   assets/tafsir-rail.js for how the passage and the comparison work.
   ========================================================================= */

/* ---- 1. THE READING SIZE ------------------------------------------------
   "Aa button on tafsir page doesnt change size of anything."

   It set an inline font-size on ONE element. Every commentary body now
   multiplies the breakpoint's own size by --tafsir-fs, which the button
   sets on <html> — so a passage of forty ayat and all three columns of a
   comparison move together, including the ones that had not loaded yet
   when the button was pressed. */
/* v13.2 — the sizes moved to layer 50, where the AYAH scales with the
   commentary at the same rate. Only the reason is kept here. */

/* ---- 2. THE EDITOR'S-NOTES PILL ----------------------------------------
   "in editors note see how 'off' is not properly placed and centered in
    box? I already said this.."

   The pill was an inline-block on the row's text baseline, so its box was
   the height of a line of text and its label sat on that baseline rather
   than in the middle of the box. It is a fixed-height flex centre now,
   the same height and the same width whether it says On or Off. */
.tafsir-notesbar-btn{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 3.1em;
  height: 22px;
  padding: 0 9px;
  border-radius: 999px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  /* The row itself is a flex line; without this the pill is stretched to
     the row's height and centred inside THAT, which is the same bug one
     level up. */
  align-self: center;
  flex: 0 0 auto;
}
.tafsir-notesbar{ align-items: center; }

/* ---- 3. THE PAGE BECOMES TWO COLUMNS ------------------------------------
   Above 1180px only. The rail is 232px and the reading measure is
   untouched — the page had that much margin already at this width, which
   is the whole of "not taking absurd space". */
@media (min-width: 1180px){
  .tafsir-page{
    display: grid;
    grid-template-columns: 232px minmax(0, 1fr);
    gap: clamp(20px, 3vw, 46px);
    align-items: start;
  }
  .tafsir-rail{ display: block; }
  /* sticky + max-height: layer 50. */
}

/* Below that the same panel is a sheet, opened from the bar. ONE copy of
   the markup: a second copy for phones is two things to keep in step. */
@media (max-width: 1179px){
  .tafsir-rail{
    position: fixed;
    /* 96, and BELOW the header at 100 — the same rule every other overlay
       on this site follows (see the long note at .nav-backdrop). An
       overlay that covers the site header takes away the way out of
       itself. It therefore also starts BELOW the header rather than at
       the top of the window. */
    z-index: 96;
    inset-block: var(--header-h) 0;
    inset-inline-start: 0;
    width: min(320px, 88vw);
    transform: translateX(-102%);
    transition: transform var(--dur) var(--ease-out-expo);
    background: rgb(var(--surface));
    border-inline-end: 1px solid var(--hairline);
    box-shadow: var(--e-overlay);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  [dir="rtl"] .tafsir-rail{ transform: translateX(102%); }
  .tafsir-rail.is-open{ transform: none; }
  body.tafsir-rail-open{ overflow: hidden; }
  body.tafsir-rail-open::after{
    content: '';
    position: fixed; inset: var(--header-h) 0 0 0; z-index: 95;
    background: rgb(var(--ink) / 0.42);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
  }
}
@media (prefers-reduced-motion: reduce){
  .tafsir-rail{ transition: none; }
}

/* v13.2 — the rail is described once, in the v132 tafsir layer
   at the foot of this file. What stood here was the v13.1 half of it,
   and half of a description is how a stylesheet ends up with five live
   definitions of one label (see the note in v132-layer-30-menus). */

/* ---- 5. THE COLUMNS ----------------------------------------------------- */
/* The head names the book. With one column the book is already named by
   the frontispiece at the top of the page and by the bar, so it is not
   said a third time. */
/* Two or three commentaries side by side need a smaller measure or the
   lines run to 90 characters. */

.tafsir-loading{
  margin: 0; padding: 18px 0;
  font-family: var(--font-mono); font-size: 0.72rem;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--text-muted));
  text-align: center;
  opacity: 0.7;
}
.tafsir-more-ayah.is-lazy .tafsir-loading{ animation: pp-pulse 1.6s ease-in-out infinite; }
@keyframes pp-pulse{ 0%,100%{ opacity: 0.35 } 50%{ opacity: 0.8 } }
@media (prefers-reduced-motion: reduce){
  .tafsir-more-ayah.is-lazy .tafsir-loading{ animation: none; }
}

/* ---- 6. ONE AYAH FROM THE NEXT ------------------------------------------
   "it would be nice to make a distinction between an Ayah's tafsir and
    the one after it when a range is selected but in a clean minimal
    beautiful way".

   A hairline across the measure with the ayah's own number in a roundel
   sitting on it — a muṣḥaf's own device, and the least a page can do and
   still be unambiguous. */
.tafsir-more-rule{
  position: relative;
  display: flex; align-items: center; justify-content: center;
  margin: clamp(38px, 6vw, 68px) 0 clamp(18px, 3vw, 28px);
}
.tafsir-more-rule::before{
  content: '';
  position: absolute; inset-inline: 0; top: 50%;
  height: 1px;
  background: linear-gradient(90deg,
    transparent 0%,
    rgb(var(--gilt-edge) / 0.32) 18%,
    rgb(var(--gilt-edge) / 0.32) 82%,
    transparent 100%);
}
.tafsir-more-num{
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 34px; height: 34px; padding: 0 8px;
  border-radius: 999px;
  border: 1px solid rgb(var(--gilt-edge) / 0.45);
  background: rgb(var(--bg));
  color: rgb(var(--gilt-edge));
  font-family: var(--font-mono); font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 0 0 4px rgb(var(--bg));
}

/* ---- 7. THE FOOT OF A PASSAGE ------------------------------------------- */
.tafsir-range{ align-items: center; }
.tafsir-range-label{ font-variant-numeric: tabular-nums; }

/* ---- 8. THE BAR'S RAIL BUTTON ------------------------------------------- */
.tafsir-bar-rail{
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: 0 0 auto;
  border-radius: 10px;
  border: 1px solid var(--hairline);
  background: rgb(var(--surface) / 0.6);
  color: rgb(var(--heading-soft));
  cursor: pointer;
  transition: border-color var(--dur) var(--ease-soft), color var(--dur) var(--ease-soft);
}
@media (hover: hover){ .tafsir-bar-rail:hover{ border-color: rgb(var(--wash) / 0.45); color: rgb(var(--accent-ui)); } }
.tafsir-bar-rail svg{ width: 17px; height: 17px; }


/* ---- 9. WHAT THE TWO WIDTHS DO NOT SHARE --------------------------------
   Last in the file on purpose. Both of these are `display:none` against a
   `display:flex`/`display:inline-flex` declared further up at the same
   specificity, and at equal specificity the later rule wins — so putting
   them inside the min-width block where they logically belong left the
   sheet's own header and the bar's sheet button visible on a desktop,
   which is exactly what the first build did. */
@media (min-width: 1180px){
  /* Two classes, because the ordinary `.tafsir-rail-head` rule below is
     later in the file and would otherwise win on source order. */
  .tafsir-rail .tafsir-rail-head{ display: none; }
  .tafsir-bar-rail{ display: none; }
}

/* ---- v131-layer-30-hadith.css ---- */

/* =========================================================================
   v13.1 — THE HADITH COLLECTION PAGE.

   14  the chapters, uncluttered
   15  "go to no." made into one control
   16  Random reduced to an icon in the corner

   See the note at the head of scratchpad/p14 for the reasoning; what is
   here is the layout half of it.
   ========================================================================= */

/* ---- 16. RANDOM ---------------------------------------------------------
   A labelled button on the top line of the card, beside the name of the
   book. It is a round icon in the corner now: the same act, a tenth of
   the weight. */
.hadith-random-btn{
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px;
  border-radius: 50%;
  border: 1px solid var(--hairline);
  background: rgb(var(--surface) / 0.7);
  color: rgb(var(--heading-soft));
  transition:
    border-color var(--dur) var(--ease-soft),
    color var(--dur) var(--ease-soft),
    transform var(--dur) var(--spring);
}
.hadith-random-btn svg{ width: 17px; height: 17px; }
@media (hover: hover){
  .hadith-random-btn:hover{
    border-color: rgb(var(--wash) / 0.5);
    color: rgb(var(--accent-ui));
    transform: rotate(-12deg);
  }
}
.hadith-random-btn:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce){
  @media (hover: hover){ .hadith-random-btn:hover{ transform: none; } }
}

/* ---- v131-layer-40-shamail.css ---- */

/* =========================================================================
   v13.1 — ASH-SHAMĀʾIL AL-MUḤAMMADIYYA ﷺ.

   "completely redesign it from scratch and make it the MOST BEAUTIFUL
    thing in this UNIVERSE! its so messy, not beautifully navigatable, ugly
    dashed lines, design errors and hidden things due to overlap errors,
    the Ar En is so ugly there too it should be on that Aa with default
    being both, also the mini header is not sticking to the upper ones"

   See scratchpad/p17 for the full reasoning. This is the layout half.
   ========================================================================= */

/* ---- 1. THE FRONTISPIECE ------------------------------------------------
   Five stacked paragraphs with rules between them become one illuminated
   panel: the mark, the double rule, the title, the ṣalawāt on its own
   rule, the author, the figures — and the four corner-pieces a manuscript
   frontispiece has. */
.sirah-book-unwan{
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: var(--radius-lg);
  border: 1px solid rgb(var(--gilt-edge) / 0.3);
  background:
    radial-gradient(120% 90% at 50% -10%, rgb(var(--gilt) / 0.09), transparent 62%),
    linear-gradient(180deg, rgb(var(--surface)) 0%, rgb(var(--bg-alt) / 0.75) 100%);
  box-shadow:
    inset 0 0 0 1px rgb(var(--gilt-hi) / 0.16),
    0 18px 44px -30px rgb(var(--shadow) / 0.5);
}
/* The corner-pieces: two rules meeting, with the metal's own gradient
   running along them, drawn INSIDE the panel's padding so they never
   collide with the text. */
.sirah-book-unwan-corner{
  position: absolute;
  width: 42px; height: 42px;
  pointer-events: none;
  z-index: 0;
  border-style: solid;
  border-color: rgb(var(--gilt-edge) / 0.55);
  border-width: 0;
}
.sirah-book-unwan-corner.is-tl{ top: 14px; left: 14px; border-top-width: 2px; border-left-width: 2px; border-top-left-radius: 6px; }
.sirah-book-unwan-corner.is-tr{ top: 14px; right: 14px; border-top-width: 2px; border-right-width: 2px; border-top-right-radius: 6px; }
.sirah-book-unwan-corner.is-bl{ bottom: 14px; left: 14px; border-bottom-width: 2px; border-left-width: 2px; border-bottom-left-radius: 6px; }
.sirah-book-unwan-corner.is-br{ bottom: 14px; right: 14px; border-bottom-width: 2px; border-right-width: 2px; border-bottom-right-radius: 6px; }

/* The mark leads, and it is bigger — a frontispiece opens with its
   shamsa, not with a rule. */
.sirah-book-unwan-mark{
  position: relative; z-index: 1;
  display: block;
  width: 74px; height: 74px;
  margin: 0 auto 6px;
}
.sirah-book-unwan-mark svg{ width: 100%; height: 100%; }

/* The double rule under it: heavy, then hairline, then the diamond. */
.sirah-book-unwan-rule{
  position: relative; z-index: 1;
  display: block;
  width: min(320px, 72%);
  height: 7px;
  margin: 10px auto 18px;
  background:
    linear-gradient(90deg, transparent, rgb(var(--gilt-edge) / 0.55) 22%, rgb(var(--gilt-edge) / 0.55) 78%, transparent) top/100% 1.6px no-repeat,
    linear-gradient(90deg, transparent, rgb(var(--gilt-edge) / 0.28) 30%, rgb(var(--gilt-edge) / 0.28) 70%, transparent) bottom/100% 1px no-repeat;
}
.sirah-book-unwan-rule::after{
  content: '';
  position: absolute; left: 50%; top: 50%;
  width: 7px; height: 7px;
  margin: -3.5px 0 0 -3.5px;
  transform: rotate(45deg);
  background: rgb(var(--gilt));
  box-shadow: 0 0 0 3px rgb(var(--surface));
}

.sirah-book-unwan-ar,
.sirah-book-unwan-en,
.sirah-book-author,
.sirah-book-figures,
.sirah-book-salawat{ position: relative; z-index: 1; }

/* ---- 2. THE ṢALAWĀT -----------------------------------------------------
   "مع تظيم وتبجيل وتوقير سيد السادات وأفخم الموجودات سيدنا محمد صلى الله
    عليه وآله وسلم"

   In gold, on its own rule, directly under his ﷺ book's name — which is
   where a scribe puts it and where it belongs. It is set larger than the
   author's line beneath it, because nothing on this page should be in a
   smaller voice than this. */
.sirah-book-salawat{
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(10px, 2vw, 20px);
  margin: 16px auto 20px;
  max-width: 640px;
}
.sirah-book-salawat-rule{
  flex: 1 1 auto;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgb(var(--gilt-edge) / 0.4));
}
.sirah-book-salawat-rule:last-child{
  background: linear-gradient(90deg, rgb(var(--gilt-edge) / 0.4), transparent);
}
.sirah-book-salawat-text{
  flex: 0 0 auto;
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: clamp(1.05rem, 0.85rem + 1.1vw, 1.5rem);
  line-height: 2;
  letter-spacing: 0;
  color: rgb(var(--gilt-edge));
  text-shadow: 0 1px 0 rgb(var(--gilt-hi) / 0.35);
  unicode-bidi: isolate;
}

/* ---- 3. THE LEAD LINE ---------------------------------------------------
   Quiet, centred, and no longer competing with the ṢALAWĀT above it. */
.sirah-book-about-lead{
  text-align: center;
  max-width: 46ch;
  margin-inline: auto;
  font-style: normal;
  color: rgb(var(--heading));
}

/* ---- 4. THE CONTENTS ----------------------------------------------------
   "ugly dashed lines". The leader dots ran from every chapter's name to
   its count, drawn as a repeating radial gradient across the flex gap.
   They belong in a printed index where the page number is two inches
   away; here the number is already beside the name. Gone, and the list is
   two columns of quiet rows with the count in a pill — the same shape the
   hadith chapter list uses, so the two indexes of this same book match. */
.sirah-book-toc{
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px;
  list-style: none;
  margin: 0;
  padding: 0;
}
@media (max-width: 720px){
  .sirah-book-toc{ grid-template-columns: 1fr; }
}
.sirah-book-toc-item{ margin: 0; }
.sirah-book-toc-link{
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  min-height: 56px;
  padding: 9px 12px;
  border-radius: 11px;
  border: 1px solid transparent;
  color: inherit;
  overflow: visible;
  transition: background var(--dur) var(--ease-soft), border-color var(--dur) var(--ease-soft);
}
@media (hover: hover){
  .sirah-book-toc-link:hover{
    background: rgb(var(--wash) / 0.07);
    border-color: rgb(var(--wash) / 0.24);
  }
}
.sirah-book-toc-n{
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; flex: 0 0 auto;
  border-radius: 50%;
  border: 1px solid rgb(var(--gilt-edge) / 0.42);
  background: rgb(var(--gilt) / 0.1);
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: 0.76rem;
  line-height: 1;
  color: rgb(var(--gilt-edge));
}
.sirah-book-toc-names{ display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.sirah-book-toc-ar{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: 1.02rem;
  line-height: 1.75;
  color: rgb(var(--heading));
  unicode-bidi: isolate;
  overflow-wrap: break-word;
}
.sirah-book-toc-en{
  font-family: var(--font-ui);
  font-size: 0.76rem;
  line-height: 1.4;
  color: rgb(var(--text-muted));
  overflow-wrap: break-word;
}
.sirah-book-toc-count{
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.5em; height: 22px; padding: 0 7px;
  flex: 0 0 auto;
  border-radius: 999px;
  background: rgb(var(--heading) / 0.06);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-variant-numeric: tabular-nums;
  color: rgb(var(--text-muted));
  letter-spacing: 0;
  padding-left: 7px;
}
/* The leader is GONE from the markup as well as from here; this kills any
   cached copy of the old rule. */
.sirah-book-toc-count::before{ content: none; }

.sirah-book-toc-read{
  position: absolute;
  inset-inline-end: 6px;
  inset-block-start: 6px;
  width: 15px; height: 15px;
  margin: 0;
  color: rgb(var(--accent-ui));
}
.sirah-book-toc-read svg{ width: 100%; height: 100%; }
.sirah-book-toc-link{ position: relative; }

/* ---- 5. THE RUNNER STICKS ----------------------------------------------
   "the mini header is not sticking to the upper ones". It is pinned to
   --header-live, which is the header's height while the header is on
   screen and 0 while it is hidden — correct, but it JUMPED, because the
   header animates away over 300ms and this moved in one frame. The same
   transition the other pinned bars on this site carry. */
.book-runner{
  transition: top 0.3s var(--ease);
  border-top: 1px solid rgb(var(--heading) / 0.04);
}

/* ---- 6. READING SETTINGS ------------------------------------------------ */
.book-reading{ position: relative; flex: 0 0 auto; }
.book-runner-aa{
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px;
  border-radius: 10px;
  border: 1px solid var(--hairline);
  background: rgb(var(--surface) / 0.65);
  color: rgb(var(--heading-soft));
  font-family: var(--font-display);
  font-size: 0.82rem;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease-soft), color var(--dur) var(--ease-soft);
}
@media (hover: hover){ .book-runner-aa:hover{ border-color: rgb(var(--wash) / 0.45); color: rgb(var(--accent-ui)); } }
.book-reading-pop{
  position: absolute;
  z-index: 20;
  inset-inline-end: 0;
  top: calc(100% + 8px);
  width: 250px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  background: rgb(var(--surface));
  box-shadow: var(--e-overlay);
  opacity: 0;
  transform: translateY(-6px) scale(0.98);
  transition: opacity var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--ease-soft);
}
.book-reading-pop.is-open{ opacity: 1; transform: none; }
.book-reading-label{
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}
/* The two switches were 150px wide in a 232px popover and both labels
   ended in an ellipsis. Stacked and full width, each says its whole
   name. */
.book-reading-pop .book-lines{
  width: 100%;
  max-width: none;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.book-reading-pop .book-lines .quran-line-btn{
  width: 100%;
  justify-content: flex-start;
  gap: 9px;
}
.book-reading-pop .book-lines .quran-line-name{
  flex: 1 1 auto;
  overflow: visible;
  text-overflow: clip;
  white-space: nowrap;
}

/* The size the popover sets. Every narration on the page reads it, which
   is why it is a multiplier on the root and not a font-size on one
   element. */
.book-leaf-ar{ font-size: calc(1.42rem * var(--book-fs, 1)); }
.book-leaf-en{ font-size: calc(1.02rem * var(--book-fs, 1)); }
@media (max-width: 620px){
  .book-leaf-ar{ font-size: calc(1.24rem * var(--book-fs, 1)); }
  .book-leaf-en{ font-size: calc(0.98rem * var(--book-fs, 1)); }
}
/* ==== END v13.1 LAYER ==== */

/* v14.0 — the primary button is described once, in
   v140-layer-10-button at the foot of this file. The v13.2 metal
   version that stood here is gone, not overridden: see CLAUDE-NOTES §4
   on what a half-superseded layer costs. */

/* ---- v132-layer-10-arabic.css ---- */

/* =========================================================================
   v13.2 — ARABIC AND ENGLISH ARE THE SAME SIZE, AND THE MUṢḤAF'S HAND IS
   USED FOR EVERYTHING THAT BELONGS TO THE MUṢḤAF.

   Three separate reports, one root cause each.

   (2) "in many places Eng & Arabic are not same size! sometimes this
        bigger sometimes the other!!!!??"

       Every paired label on this site — a chapter title, a set name, a
       menu row — is an English line and an Arabic line one above the
       other. They were written at different times by different rules, so
       one was 0.95rem and the other 1.3rem, and which one was larger
       changed from component to component.

       The fix is a rule, not a list: A PAIRED ARABIC LABEL IS 1em. It
       inherits the size of the row it is in, so it is by construction the
       same size as its English partner, and it stays that way when the
       row's size changes. The three bundled naskh faces already carry a
       `size-adjust` that equalises their x-height against the Latin, so
       1em really does look level rather than merely measuring the same.

       --ar-optical is the one dial for the whole site if that judgement
       ever needs a nudge; it is 1 and should stay 1.

   (5) "basmalah in mushaf (other than tawbah ofc) must be in Hafs!!"
   (9) "suwar name on qur'an must be written in Hafs..."

       The Bismillah heading was set in --font-arabic (Scheherazade) and
       the surah title at the head of the reader in the same. Both are
       muṣḥaf furniture and both are in the muṣḥaf's hand now: the surah
       name in --font-surah (KFGQPC Uthmanic Script HAFS), the Bismillah
       in --font-quran-glyphs, which is the ayah font itself, because the
       Bismillah it prints is now the real glyph run out of
       data/quran/surah/1.json rather than typed Unicode.

       NO WEIGHT IS EVER APPLIED TO --font-quran-glyphs. That file has one
       cut and a synthesised bold on it is a smear. See CLAUDE-NOTES §7.

   (19) "suwar names & basmalah … fix their size!! its a bit too big"

       The surah title ran to 3.4rem and the Bismillah to 2.5rem, which on
       a 1440px screen is larger than the h1 of any other page on the
       site. Both come down about a fifth, and the Bismillah is now
       smaller than the name above it, which is the order a muṣḥaf's own
       opening leaf puts them in.
   ========================================================================= */

:root{
  /* One dial for how large a paired Arabic label sits against its
     English partner. 1 = identical. */
  --ar-optical: 1;
}

/* ---- the surah reader's own head ------------------------------------- */
.quran-surah-header-ar{
  font-family: var(--font-surah);
  font-weight: 400;
  font-size: clamp(2rem, 4.4vw, 2.7rem);
  line-height: 1.55;
  margin-bottom: 2px;
}
.quran-surah-header-en{ margin-top: 2px; }

/* ---- the Bismillah --------------------------------------------------- */
.quran-bismillah{
  font-family: var(--font-quran-glyphs);
  font-weight: 400;                 /* never synthesise a bold on this face */
  line-height: 1.9;
  letter-spacing: 0;
  margin: 30px 0 28px;
  padding-bottom: 20px;
  color: rgb(var(--heading));
}
.quran-bismillah::after{ width: 54px; }

@media (max-width: 620px){
  .quran-surah-header-ar{ font-size: clamp(1.75rem, 8vw, 2.3rem); }
  .quran-bismillah{
    margin: 22px 0 22px;
    padding-bottom: 16px;
  }
}

/* =========================================================================
   THE PAIRED LABEL RULE.

   Anywhere the site prints an English line and an Arabic line as two
   halves of the same label, the Arabic takes the row's own size. These
   are all of them; each was carrying its own hand-set size before.
   ========================================================================= */
/* HOW 1em ACTUALLY WORKS HERE, because getting this wrong is what made
   the header menus mismatch for five releases: `em` resolves against the
   element's INHERITED size — its parent's — not against its sibling's. So
   an Arabic label at 1em beside an English label at 0.85rem is NOT level;
   it is 1rem beside 0.85rem, which is exactly the 16px-vs-13px the adhkār
   panel was showing.

   The rule is therefore: THE ROW OWNS THE SIZE. Every component that
   pairs the two scripts sets one font-size on the row, and both labels
   inside it are 1em. Each component layer does that for its own row; this
   is the shared half. */
.hadith-chapter-ar,
.hadith-collection-arabic,
.adhkar-card-ar {
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: calc(1em * var(--ar-optical));
  line-height: 1.5;
  direction: rtl;
  unicode-bidi: isolate;
}

/* ---- v132-layer-20-hadith.css ---- */

/* =========================================================================
   v13.2 — THE HADITH COLLECTION LANDING.

   "the hadith book page landing is so ugly and cluttered and you haven't
    fixed it! chapters cant be layed out all like this! make it very
    clean, minimal, easily navigatable, feature dense, very beautiful"

   The markup half is in hadith-collection.php and the reasoning is
   written out there. This is the layout.
   ========================================================================= */

/* ---- the book's head, centred ---------------------------------------- */
.hadith-book-header{
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0;
  position: relative;
  overflow: hidden;
  padding: var(--sp-8) var(--sp-6) var(--sp-7);
  margin-bottom: var(--sp-6);
  background:
    radial-gradient(120% 96% at 50% 0%, rgb(var(--wash) / 0.09), transparent 64%),
    rgb(var(--surface));
  border: 1px solid rgb(var(--wash) / 0.24);
  border-radius: var(--radius-lg);
  box-shadow: var(--e2);
}
.hadith-book-header .hadith-random-btn{
  position: absolute;
  top: 14px; inset-inline-end: 14px;
  z-index: 1;
}
.hadith-book-icon{
  width: 52px; height: 52px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgb(var(--wash) / 0.10);
  border: 1px solid rgb(var(--wash) / 0.30);
  color: rgb(var(--accent-ui));
  margin-bottom: 14px;
}
.hadith-book-icon svg{ width: 25px; height: 25px; }

/* The book's own name, in the display face at 700 — this is the one
   place on the page Amiri Bold earns its keep. */
.hadith-book-ar{
  display: block;
  font-family: var(--font-arabic-display);
  font-weight: 700;
  font-size: clamp(1.5rem, 3.4vw, 2rem);
  line-height: 1.7;
  color: rgb(var(--accent-ui));
  direction: rtl; unicode-bidi: isolate;
}
.hadith-book-title{
  font-size: clamp(1.5rem, 3.2vw, 2rem);
  line-height: 1.2;
  letter-spacing: -0.015em;
  margin: 2px 0 0;
}
.hadith-book-author{
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  margin: 8px 0 0;
  font-size: 0.87rem;
  line-height: 1.6;
  color: rgb(var(--text-muted));
  max-width: 52ch;
}
.hadith-book-author-ar{
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: 1em;            /* the paired-label rule: level with the English */
  direction: rtl; unicode-bidi: isolate;
}
.hadith-book-figures{
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 8px;
  margin: 12px 0 0;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.hadith-book-figures strong{
  font-weight: 600;
  color: rgb(var(--heading-soft));
  font-variant-numeric: tabular-nums;
}

/* ---- the control strip ------------------------------------------------ */
.hadith-toolbar{
  display: flex;
  gap: 10px;
  align-items: stretch;
  flex-wrap: wrap;
  margin-bottom: var(--sp-4);
}
.hadith-search,
.hadith-goto{
  height: 46px;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  background: rgb(var(--surface));
  transition: border-color var(--dur) var(--ease-soft), box-shadow var(--dur) var(--ease-soft);
}
.hadith-search{
  flex: 1 1 260px; min-width: 0;
  display: flex; align-items: center; gap: 10px;
  padding: 0 6px 0 16px;
}
.hadith-goto-hash{
  font-family: var(--font-mono);
  font-size: 0.95rem;
  color: rgb(var(--text-muted));
  opacity: 0.7;
  padding-inline-end: 6px;
}
.hadith-goto{
  flex: 0 0 auto;
  min-width: 186px;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  padding: 0 6px 0 14px;
}
.hadith-search:focus-within,
.hadith-goto:focus-within{
  border-color: rgb(var(--wash) / 0.5);
  box-shadow: 0 0 0 3px rgb(var(--accent) / 0.10);
}
.hadith-search > svg{ width: 16px; height: 16px; flex: 0 0 auto; color: rgb(var(--text-muted)); }
.hadith-search input,
.hadith-goto input{
  flex: 1 1 auto; width: 100%; min-width: 0; height: 100%;
  border: 0; background: transparent; color: rgb(var(--heading));
  font-family: var(--font-ui); font-size: 0.88rem;
}
.hadith-goto input{ font-family: var(--font-mono); font-size: 0.88rem; -moz-appearance: textfield; }
/* A number input draws a spinner that is 20px of chrome nobody taps on a
   phone, and it sits exactly where the arrow button goes. */
.hadith-goto input::-webkit-outer-spin-button,
.hadith-goto input::-webkit-inner-spin-button{ -webkit-appearance: none; margin: 0; }
.hadith-goto input::placeholder,
.hadith-search input::placeholder{ color: rgb(var(--text-muted)); opacity: 0.72; }
.hadith-search input:focus,
.hadith-goto input:focus{ outline: none; }

/* Both fields end in the same object: a small quiet circle that becomes
   the page's metal on hover. Neither of them is a primary action. */
.hadith-field-go{
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: 0 0 auto;
  border-radius: 50%;
  border: 1px solid rgb(var(--gilt-edge) / 0.34);
  cursor: pointer;
  transition: background var(--dur) var(--ease-soft), border-color var(--dur) var(--ease-soft);
}
.hadith-field-go svg{ width: 15px; height: 15px; }
.hadith-field-go:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }

/* ---- the chapter menu ------------------------------------------------- */
/* v14.0 — the inline grid of ninety-seven cells is gone; the chapters are
   the site's own sheet now (assets/ui.js, assets/picker.js). What is left
   on the page is ONE row saying where you are. See v140-layer-25-chapters
   at the foot of this file. */

/* ---- the narration list ----------------------------------------------- */
.hadith-where,
.hadith-result-count{
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
  margin: 0 0 12px;
}
/* ---- v132-layer-30-menus.css ---- */

/* =========================================================================
   v13.2 — THE HEADER MEGA PANELS. ONE DESCRIPTION, IN ONE PLACE.

   "tafsir menu is so ugly and text close and overlapping almost and
    mismatching text sizes on adhkar (I mean menu from header), make it
    extremely beautiful, same for adhkar menu (from header).. (this is
    EXTREMELY important)"

   THE ACTUAL FAULT WAS NOT A MEASUREMENT. It was that there were FIVE
   live definitions of `.site-header .adhkar-menu-ar` in this stylesheet,
   from v11.5, v12.3, v13.0 (twice) and v13.1, at 0.9rem, 0.95rem,
   1.05rem, 1em and 1em-with-!important, each written to fix the last one
   and none of them deleted. Whichever won depended on where in the file
   it happened to sit, so the Arabic in one panel was a fifth larger than
   the English beside it and in another was level with it, and the line
   boxes disagreed too — which is the "text close and overlapping".

   All five are gone. This is the only place the panels are described.

   THE RULES:
     · A ROW IS ONE OBJECT: mark, then a stack of names. Nothing floats.
     · THE TWO NAMES OF ONE THING ARE THE SAME SIZE. The Arabic is 1em of
       its row and is distinguished by COLOUR, never by scale.
     · NOTHING WRAPS IN A MENU. A name that will not fit is ellipsed; the
       full name is one tap away on the page it opens.
     · THE HARAKĀT ARE ALREADY GONE, at the source, via pp_ar_plain() in
       header.php. With no marks to clear, 1.5 is a generous line box —
       the 1.9 the old rules carried was what made the panels tall.
   ========================================================================= */

/* ---- the panel ------------------------------------------------------- */

/* ---- a row ----------------------------------------------------------- */
/* The quiet second line, whatever it holds: an Arabic title, a count, a
   sentence. One size, one colour, one line box, all four panels. */

/* ---- the Qur'an panel ------------------------------------------------ */
/* A fixed Arabic gutter, sized to what the six names in it actually need,
   so every English title starts on the same vertical line. */

/* ---- the tafsīr panel ------------------------------------------------ */
/* Eight books, two lines each: the book's English name, and its Arabic
   name under it at the same size. The family tag that used to follow the
   Arabic behind a middot is gone from the markup — see header.php. */

/* ---- the adhkār panel ------------------------------------------------ */
/* Thirteen sets in three columns of one-line rows: about 300px of panel
   rather than the 700 it was. */

/* The set whose window is open now: a gold spine on the leading edge. A
   tinted row beside twelve untinted ones reads as a stuck hover. */


/* The drawer lays every panel out in one column and sets its own padding;
   none of the widths above apply there. */
/* ---- v132-layer-40-adhkar.css ---- */

/* =========================================================================
   v13.2 — THE ADHKĀR PAGE.

   "you did not clean up & tidy the adhkar landing page and even the
    choices of adhkar sets are so cluttered and just all layed out like
    this, make it very clean, tidy & beautiful"
   "the text size became messed up and not alligned"

   Two things: the set tiles (below), and the Aa control that decides
   which of the three lines a dhikr shows (further below, item 6).
   ========================================================================= */

/* v14.0 — the thirteen set tiles are gone: the sets are the site's own
   menu now (page-tasbih.php + assets/adhkar.js + assets/picker.js). What
   is left on the page is one bar. See v140-layer-30-adhkar. */

/* v14.0 — the floating Aa is shared by every reading page now; see
   v140-layer-50-aa at the foot of this file. */

/* ---- what the switches hide ------------------------------------------ */
.adhkar-app[data-show-ar="0"] .adhkar-card-ar,
.adhkar-app[data-show-ar="0"] .adhkar-ayah-ar{ display: none; }
.adhkar-app[data-show-tr="0"] .adhkar-card-tr{ display: none; }
.adhkar-app[data-show-en="0"] .adhkar-card-en,
.adhkar-app[data-show-en="0"] .adhkar-ayah-en{ display: none; }
/* With the Arabic hidden, the line that follows it has no line above to
   clear. */
.adhkar-app[data-show-ar="0"] .adhkar-card-tr,
.adhkar-app[data-show-ar="0"] .adhkar-card-en{ margin-top: 0; }

/* The zen/print views have no floating controls. */
body.pp-zen .adhkar-aa{ display: none; }
@media print{ .adhkar-aa{ display: none; } }
/* ---- v132-layer-50-tafsir.css ---- */

/* =========================================================================
   v13.2 — ARABIC AS A TITLE KEEPS THE BOLD.

   --ar-weight came down to 400 at the top of this file (see the note
   there). These are the places where Arabic is a TITLE rather than
   something to read, and a title is 700. It is exactly the set of
   selectors that already name --font-arabic-display, plus the two
   ʿunwāns — kept together in one rule so the list cannot drift.
   ========================================================================= */
.book-unwan-ar,
.hadith-book-ar,
.hero .sub[lang="ar"],
.hero h1[lang="ar"],
.hero-content .eyebrow[lang="ar"],
.seerah-unwan-ar,
.seerah-chapter-ar,
.seerah-names-ar,
.seerah-single-ar,
.seerah-shelf-title-ar,
.seerah-names-title-ar,
.seerah-further-title-ar,
.seerah-bookcard-ar,
.seerah-name-ar,
.seerah-further-ar,
.sirah-book-unwan-ar,
.sirah-book-bab-ar,
.sirah-book-salawat-text,
.sirah-book-toc-ar,
.tafsir-pop-row-ar,
.tafsir-shelf-ar,
.adhkar-title,
.adhkar-panel-id h2,
.hadith-in-book-ar {
  font-weight: var(--ar-weight-strong);
}

/* =========================================================================
   v13.2 — THE COMMENTARY AND THE AYAH GROW AT THE SAME RATE.

   "when increasing font on tafsir, and any other suitable place across
    the entire website where this exists, make sure both Qur'an and
    tafsir size increase in an identical rate, not quran stays small and
    slowly inc while tafsir becomes huge...!"

   Exactly what was happening. --tafsir-fs was applied to .tafsir-body
   and to nothing else, so pressing A+ four times took the commentary
   from 1.26rem to 2.0rem while the ayah above it stayed at whatever
   its clamp() had settled on. Two things on one page, one of them
   growing.

   Everything the reading size touches is listed here, and every one of
   them is `base × var(--tafsir-fs)`. Same multiplier, same rate, by
   construction — and because it is a multiplier on each element's own
   base, the ayah stays larger than the commentary at every step, which
   is the relationship the page was designed with.
   ========================================================================= */
.tafsir-body{
  /* THE COMMENTARY READS LIKE THE MUṢḤAF PAGE, NOT LIKE A HEADLINE.
     400, not 700 (see --ar-weight), and justified naskh at the line
     height the ayah above it uses. */
  font-weight: var(--ar-weight);
  font-size: calc(1.26rem * var(--tafsir-fs, 1));
  line-height: 2.1;
}
@media (max-width: 900px){
  .tafsir-body{ font-size: calc(1.18rem * var(--tafsir-fs, 1)); }
}
@media (max-width: 560px){
  .tafsir-body{ font-size: calc(1.14rem * var(--tafsir-fs, 1)); }
}
/* An ayah quoted inside a commentary is still an ayah: it takes the same
   weight as the running text around it, never a bold. */
.tafsir-body .qa-tafsir-ayah{ font-weight: inherit; }

/* =========================================================================
   v13.2 — THE RAIL.

   "the menu on left side on tafsir page is a disaster, its design is so
    ugly and its not tidy & clean, completely fix this, and make sure as
    you scroll down it comes with you and make sure you dont need to
    scroll inside the menu itself and make sure its working fine and very
    cleanly on phone too!!!! please master it.."

   WHAT MADE IT UGLY: four bordered, tinted, rounded BOXES stacked inside
   a fifth. Five nested frames in 232px is a filing cabinet, and every one
   of them cost 24px of border and padding — which is also why it was too
   tall to fit and had to scroll inside itself.

   THE FRAMES ARE GONE. One panel, four sections, hairline rules between
   them, a small mono label on each. That is about 150px shorter, which is
   the whole of "you dont need to scroll inside the menu itself": at
   900px of window the rail is now ~470px in a ~700px well.

   `overflow-y:auto` is KEPT as a floor, for a 600px-tall laptop window
   where nothing would fit — a control you cannot reach is worse than a
   scrollbar you never see.
   ========================================================================= */
@media (min-width: 1180px){
  /* The head is a sheet's head: a title and a close button. As a column
     the rail has nothing to close, and 57px of chrome saying "Reading
     tools" above four sections already labelled is what pushed the rail
     past the height of the window. */
  .tafsir-rail-head{ display: none; }
  .tafsir-rail-inner{
    /* It comes with you. Sticky under the header AND the tafsīr bar,
       both of which are sticky above it. */
    position: sticky;
    top: calc(var(--header-h) + 58px);
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    border: 1px solid var(--hairline);
    border-radius: var(--radius);
    background: rgb(var(--surface) / 0.6);
  }
}
.tafsir-rail-inner{
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0;
}
.tafsir-rail-head{
  display: flex; align-items: center; justify-content: space-between;
  padding: 11px 13px;
  border-bottom: 1px solid var(--hairline);
}

/* A section: a label, then its controls. No box. */
.tr-block{
  display: flex; flex-direction: column; gap: 9px;
  padding: 13px;
  border: 0;
  border-radius: 0;
  background: none;
}
.tr-block + .tr-block{ border-top: 1px solid var(--hairline); }
.tr-h{
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
  opacity: 0.9;
}

/* where you are — one line, and it goes to the muṣḥaf */
.tr-where{
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: 9px;
  padding: 8px 10px;
  border-radius: 10px;
  background: rgb(var(--wash) / 0.06);
  border: 1px solid rgb(var(--wash) / 0.16);
  color: inherit;
  transition: background var(--dur) var(--ease-soft), border-color var(--dur) var(--ease-soft);
}
@media (hover: hover){
  .tr-where:hover{
    background: rgb(var(--wash) / 0.11);
    border-color: rgb(var(--wash) / 0.34);
  }
}
.tr-where-ar{
  font-family: var(--font-surah);
  font-weight: 400;
  line-height: 1.7;
  color: rgb(var(--heading));
  white-space: nowrap;
}

/* the passage — two numbers on one line with the button beside them,
   not under them */

/* The rail's own buttons are quiet. The page has one gold object on it
   and it is not four of them in a 232px column. */
/* The rail's buttons are QUIET. The page has one gold object on it and
   it is the primary action; four gilded pills in a 232px column is what
   made the rail read as a toolbar. Same metal, a fifth of the weight. */

/* compare — the fixed first row is a caption, not a control */

/* reading */

@media (max-width: 1179px){
  /* On a phone the same markup is a sheet. It gets the panel's own
     background and scrolls as a whole; the sections keep their rules. */
  .tafsir-rail-inner{ min-height: 100%; }
  .tafsir-rail-head{ position: sticky; top: 0; z-index: 1; background: rgb(var(--surface)); }
}

/* ---- the parts of the rail v13.2 did not need to change --------- */
.tafsir-rail-title{
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.tafsir-rail-close{
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 10px;
  border: 1px solid var(--hairline);
  background: transparent; color: rgb(var(--text-muted)); cursor: pointer;
}
.tafsir-rail-close svg{ width: 17px; height: 17px; }
.tr-where-main{ display: flex; flex-direction: column; min-width: 0; }
.tr-where-ref{
  font-family: var(--font-mono); font-size: 0.68rem;
  color: rgb(var(--text-muted)); letter-spacing: 0.02em;
}
.tr-where-go{ width: 16px; height: 16px; color: rgb(var(--accent-ui)); opacity: 0.7; }
.tr-steps{ display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.tr-step{
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  min-height: 34px; padding: 0 8px;
  border: 1px solid var(--hairline); border-radius: 9px;
  font-family: var(--font-ui); font-size: 0.74rem; font-weight: 600;
  color: rgb(var(--heading-soft));
  background: rgb(var(--surface));
  transition: border-color var(--dur) var(--ease-soft), color var(--dur) var(--ease-soft);
}
@media (hover: hover){ .tr-step:hover{ border-color: rgb(var(--wash) / 0.45); color: rgb(var(--accent-ui)); } }
.tr-step svg{ width: 14px; height: 14px; }
.tr-step.is-off{ opacity: 0; pointer-events: none; }

/* =========================================================================
   v13.2 — THE PASSAGE PICKER IN THE AYAH POPOVER (item 14).

   Two modes on one segmented control; in Passage mode the first tap
   marks the start and the numbers up to the cursor light as a span. See
   renderAyat() in assets/tafsir.js.
   ========================================================================= */


/* ---- v132-layer-60-prayer.css ---- */

/* =========================================================================
   v13.2 — ONE DATE LINE.

   The foot of the "today" panel used to carry a Hijri date and a 19-word
   apology for it, and a dashed line under that with tomorrow's Fajr on
   it. It carries the day the times are for: the word "Tomorrow" when it
   is tomorrow, the weekday and date, then the Hijri date. Nothing on the
   panel can disagree with anything else on it, because there is only one
   of each thing now. See renderDateLine() in assets/prayer-times.js.
   ========================================================================= */
.prayer-foot-row{
  display: flex;
  align-items: baseline;
  gap: 9px;
  flex-wrap: wrap;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid rgb(var(--heading) / 0.08);
}
.prayer-daytag{
  display: inline-flex; align-items: center;
  padding: 2px 9px 3px;
  border-radius: 999px;
  background: rgb(var(--gilt) / 0.85);
  color: rgb(var(--on-gilt));
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.prayer-date{
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.95rem;
  color: rgb(var(--heading));
}
.prayer-date-sep{ color: rgb(var(--text-muted)); opacity: 0.6; }
.prayer-hijri{
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.95rem;
  color: rgb(var(--accent-ui));
}

/* Friday's midday prayer is Jumuʿah, and it is worth noticing. */
.prayer-card.is-jumuah .prayer-card-name{ color: rgb(var(--accent-ui)); }

@media (max-width: 520px){
  .prayer-foot-row{ gap: 7px; }
  .prayer-date, .prayer-hijri{ font-size: 0.88rem; }
  .prayer-date-sep{ display: none; }
  .prayer-hijri{ flex-basis: 100%; }
}

/* ---- v132-layer-70-qibla.css ---- */

/* =========================================================================
   v13.2 — THE CALIBRATION SHEET, OVER THE CAMERA.

   "calibrate when pressed on camera its hidden until cam is closed!"

   The z-index was already right (620 over 500) and the sheet was still
   losing on a phone. Two reasons, both handled in openCalibrate() in
   assets/qibla.js — it is moved to <body> so no ancestor can trap it,
   and it takes `is-over-camera`, which is the half that lives here.

   A LIVE <video> IS ITS OWN COMPOSITING LAYER and WebKit will paint it
   over an element carrying `backdrop-filter`. So over the camera there
   is no backdrop-filter: a solid scrim instead, which is also the right
   look (blurring a moving camera frame is expensive and reads as a
   smear), plus `translateZ(0)` to put the sheet on a layer of its own.
   ========================================================================= */
.qibla-calibrate.is-over-camera{
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  background: rgb(0 0 0 / 0.78);
  transform: translateZ(0);
  will-change: opacity;
}

/* Nothing of the camera's own chrome competes with the sheet while it is
   up: the reticle, the turn arrow and the accuracy band all go. The video
   stays, dimmed by the scrim, so it is obvious the camera is still open
   and this is a step inside it rather than a different page. */
.qibla-camera-view.is-calibrating .qibla-camera-overlay,
.qibla-camera-view.is-calibrating .qibla-camera-turn,
.qibla-camera-view.is-calibrating .qibla-cam-warn,
.qibla-camera-view.is-calibrating .qibla-camera-top{
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease-soft);
}

/* On a phone the card is the sheet: full width at the bottom, thumb-first,
   rather than a dialog floating in the middle of a camera view. */
@media (max-width: 620px){
  .qibla-calibrate{ padding: 0; align-items: flex-end; }
  .qibla-calibrate-card{
    width: 100%;
    max-height: 88svh;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    padding-bottom: calc(22px + env(safe-area-inset-bottom));
  }
  .qibla-calibrate.in .qibla-calibrate-card{ transform: none; }
  .qibla-calibrate .qibla-calibrate-card{ transform: translateY(18px); }
}

/* The "no compass at all" state of the banner under the dial. Quiet: it
   is not a warning, nothing is wrong, and the two methods that need no
   sensor are directly below it. */
.qibla-cal[data-state="none"]{
  color: rgb(var(--text-muted));
  border-color: rgb(var(--heading) / 0.10);
  background: rgb(var(--heading) / 0.03);
}
.qibla-cal[data-state="none"] .qibla-cal-text strong{ color: rgb(var(--heading-soft)); }
.qibla-cal[data-state="none"] .qibla-cal-path{ opacity: 0.10; }
.qibla-cal[data-state="none"] .qibla-cal-dot{ opacity: 0.25; animation: none; }
.qibla-cal[data-state="none"] .qibla-cal-meter{ display: none; }

/* ---- v132-layer-80-surah-names.css ---- */

/* =========================================================================
   v13.2 — EVERY SURAH NAME, IN THE MUṢḤAF'S HAND, AT THE SIZE OF THE NAME
   BESIDE IT.

   Items 2 and 9, and they turned out to be the same list of places.

   "suwar name on qur'an must be written in Hafs..."

   v13.1 bundled KFGQPC Uthmanic Script HAFS as --font-surah and applied
   it to five selectors. There are NINE places on this site that print a
   surah's Arabic name, and the other four — the index cards, the juzʾ
   page, the reader's own <h1>, the tafsīr rail — were still Scheherazade.
   Every one of them is here, in one rule, so the tenth cannot be missed.

   "in many places Eng & Arabic are not same size!"

   And each of them was also a different size from the English it stands
   beside: 1.30rem against 1.02, 1.42 against 0.72, 1.18 against 0.85.
   The rule from layer 10 applies — THE ROW OWNS THE SIZE, both labels are
   1em — with one exception, stated below.
   ========================================================================= */

.quran-surah-ar,
.quran-unit-surah-ar,
.quran-card-ar,
.tafsir-surah-ar,
.tafsir-pop-row-ar,
.quran-index-ar,
.pp-res-surah-ar,
.tr-where-ar {
  font-family: var(--font-surah);
  /* NEVER a weight on this face. It has one cut; a synthesised bold on a
     muṣḥaf hand is a smear. See CLAUDE-NOTES §7. */
  font-weight: 400;
  direction: rtl;
  unicode-bidi: isolate;
  /* Vowelled Qurʾanic naskh carries marks a long way above and below the
     baseline; under 1.7 one row's fatḥah lands in the next row's kasrah. */
  line-height: 1.75;
}

/* ---- the index card: name beside name ------------------------------- */
.quran-surah-card{ font-size: 1.02rem; }
.quran-surah-translit{ font-size: 1em; }
.quran-surah-ar{ font-size: 1em; color: rgb(var(--heading)); }

/* ---- the juzʾ page's surah heads ------------------------------------ */
.quran-unit-surah-link{ font-size: 1rem; }
.quran-unit-surah-ar{ font-size: 1em; }
.quran-unit-surah-en{ font-size: 0.74em; }

/* ---- the Qur'an panel in the header --------------------------------- */
/* THE ONE EXCEPTION, and it is deliberate. Here the Arabic is not the
   second half of a label — it is a right-aligned GUTTER, the first thing
   in the row, with the English title to its right. Level with the title
   it would be the smallest muṣḥaf type on the site, so it keeps one step
   (1.12em) and no more. It used to be 1.39x. */

/* ---- the tafsīr rail's "where you are" ------------------------------ */
.tr-where{ font-size: 0.85rem; }
.tr-where-ar{ font-size: 1.15em; }
.tr-where-surah{
  font-family: var(--font-ui); font-size: 1em; font-weight: 600;
  color: rgb(var(--heading));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ---- v132-layer-90-header-phone.css ---- */

/* =========================================================================
   v13.2 — THE SITE'S NAME FITS ON A PHONE.

   At 375px the bar read "Prophetic P…". The row is: the mark and the
   name (144px available), then four 40px buttons and their gaps (183px).
   The name needed about 160 and had 100.

   TWO CHANGES, and the first one is the real one:

   1. THE SUN/MOON BUTTON COMES OFF BELOW 430px. It is one tap between
      light and dark — but the button immediately beside it opens the
      appearance panel, whose first control is a Light/Dark segment that
      does exactly the same thing. Two ways to do one thing, costing
      44px, on the narrowest screen the site is read on. Nothing is lost
      and the name is readable.
   2. The mark and the name come down one step, which they can afford:
      at 30px the mark is still the largest thing in the bar.
   ========================================================================= */

/* ---- v132-layer-95-tafsir-bar-phone.css ---- */

/* =========================================================================
   v13.2 — THE SŪRAH'S NAME IS READABLE ON A PHONE.

   At 375px the bar's second row carried seven controls: the two pickers,
   a search, the rail button, Aa and two step arrows. Measured, the sūrah
   slot came out at 61px — a caret, two paddings and 33px for the name —
   so "Al-Baqarah" rendered as "A…". A picker that cannot show what is
   picked is not a picker.

   TWO CHANGES, and the first buys the space for the second.

   1. THE SEARCH ICON COMES OFF BELOW 560px. It opens the jump sheet,
      which is the sūrah/juzʾ browser with a search box on top — and the
      two controls immediately to its left ARE that browser's sūrah and
      ayah pickers. On a phone it is a third door into a room you are
      already standing in, costing 40px on the one row that has none.
      (It stays on every wider screen, where the row has room and typing
      "mercy" is genuinely faster than tapping.)
   2. THE SŪRAH SLOT TAKES WHAT IS FREED. The ayah slot stays at its own
      width — it holds a number — and everything left over goes to the
      name.
   ========================================================================= */
@media (max-width: 560px){
  .tafsir-bar .tafsir-bar-where{ display: none; }
  /* GRID, NOT FLEX, for the two slots. As a wrapping flex row with both
     slots at `flex:1 1 auto` they split the width evenly — a name and a
     number given the same 82px, which is how "Al-Baqarah" became "A…"
     next to a very roomy "1". Two grid columns say the thing directly:
     the name takes what is left, the number takes what it needs. */
  .tafsir-bar .tafsir-pick-room{
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 6px;
    flex: 1 1 auto;
    min-width: 0;
  }
  .tafsir-bar .tafsir-pick-room .tafsir-pick-slot{ min-width: 0; }
  .tafsir-bar .tafsir-pick-room .tafsir-pick-btn{ width: 100%; }
  .tafsir-bar .tafsir-pick-room .tafsir-pick-value{ max-width: none; }
  .tafsir-bar .tafsir-pick-btn{ padding: 0 8px 0 10px; gap: 5px; }
}

/* ---- v140-layer-05-mark.css ---- */

/* =========================================================================
   v14.0 — THE MARK IS STRUCK IN THE PALETTE'S OWN METAL.  (item 26)

   "for EVERY singular theme, light dark etc, make a BEAUTIFUL design of
    the current logo to match the colours and make sure it actually changes
    based on the selected theme smoothly and perfectly! for example see how
    the icy theme logo colour is mismatching?"

   tools/gen_logo.py writes the header's <symbol> with every colour spelled
   `rgb(var(--mark-*))`. A browser NEVER resolves a custom property inside
   an SVG presentation attribute, so those attributes are inert markers and
   the rules below are what actually paint. Identical mechanism to the
   cover art (see the GENERATED COVERS block above and CLAUDE-NOTES §10);
   it is why the mark repaints in the same frame as the palette, with no
   JavaScript and nothing to keep in step.

   The tokens themselves are generated per palette by tools/gen_palettes.py
   from that palette's own METAL row — ice on Frost, rose gold on Rose,
   champagne on Velvet, gold on Saffron and Obsidian.
   ========================================================================= */
[stop-color="rgb(var(--mark-hi))"]{ stop-color: rgb(var(--mark-hi)); }
[stop-color="rgb(var(--mark-mid))"]{ stop-color: rgb(var(--mark-mid)); }
[stop-color="rgb(var(--mark-deep))"]{ stop-color: rgb(var(--mark-deep)); }
[stop-color="rgb(var(--mark-pale-a))"]{ stop-color: rgb(var(--mark-pale-a)); }
[stop-color="rgb(var(--mark-pale-b))"]{ stop-color: rgb(var(--mark-pale-b)); }
[stop-color="rgb(var(--mark-ground-a))"]{ stop-color: rgb(var(--mark-ground-a)); }
[stop-color="rgb(var(--mark-ground-b))"]{ stop-color: rgb(var(--mark-ground-b)); }
[fill="rgb(var(--mark-deep))"]{ fill: rgb(var(--mark-deep)); }
[fill="rgb(var(--mark-dot))"]{ fill: rgb(var(--mark-dot)); }
[stroke="rgb(var(--mark-deep))"]{ stroke: rgb(var(--mark-deep)); }

/* ---- v140-layer-10-button.css ---- */

/* =========================================================================
   v14.0 — THE PRIMARY BUTTON. THE SIXTH ATTEMPT, AND THE FIRST ONE THAT
   CHANGES THE ARGUMENT INSTEAD OF THE MODELLING.  (item 7)

   "I have been telling you since forever to completely ditch this ugly
    yellow button for the default saffron theme, there are major issues for
    me with it, its super ugly and has really weird texture, can you design
    something shiny, beautiful, gorgeous and smooth and nice and clean??
    and choose a MUCH nicer texture and colour and theme??? … same for
    other themes, keep it a standard feeling for the button but suitable
    colours and designs of course"

   FIVE RELEASES HAVE REDRAWN A GOLD BUTTON AND IT HAS COME BACK EVERY
   TIME. The reason is arithmetic rather than taste. Saffron's paper is
   255/245/222; its metal is 230/178/96. Those are the same hue two steps
   apart, so whatever is done to the surface — a specular band, a bevel, a
   sheen, a four-stop ramp — the object never separates from the page. It
   reads as a raised patch of background. "Mustard", "weird texture" and
   "super ugly" have all been describing that one fact.

   SO THE GROUND CHANGES. The button is the palette's ACCENT — the one
   colour in every palette that exists specifically to be a FILL carrying
   text, and the only one proved at 4.5:1 for a label on all three of its
   own stops (tools/gen_palettes.py, `on-cta on cta*`). On Saffron that is
   a burnt sienna on golden paper. On Frost a deep glacier blue on ice. On
   Rose a madder crimson. ON OBSIDIAN IT IS STILL GOLD, because gold on
   black already is a different object — nothing is lost where it worked.

   THE METAL DOES NOT GO ANYWHERE. It is still the ornament, the rules, the
   frames, the covers, and it is still this button's HAIRLINE: an
   illuminator outlines a coloured field in gold, which is rule 2 of
   CLAUDE-NOTES §10. What changed is which of the two is the ground and
   which is the line round it.

   WHAT MAKES IT SHINE, and none of it is texture:
     · a smooth vertical ramp — a 7% lift at the crown falling to the
       accent by a third of the way down, and a little depth at the foot.
       No band, no hard stop, nothing to see as a stripe.
     · a wide soft GLOW beneath it in the button's own colour. This is the
       whole of "shiny": a saturated object on a pale page throws colour
       onto what is under it, and that is what the eye reads as gloss.
     · one hairline of the palette's metal, at 45%, which is the only
       gold left on it and the thing that makes it look set rather than
       printed.
     · NO INSET SHADOW ANYWHERE. The white-top/dark-bottom pair is the
       2007 bevel and was rejected by name in v13.2.
     · NO SHEEN. Rejected by name in v13.2, and it never ran anyway.
   ========================================================================= */

.btn-primary,
.subscribe-form button[type="submit"],
.pp-gold,
.qibla-camera-cta{
  position: relative;
  isolation: auto;
  overflow: visible;
  border-radius: 999px;
  border: 1px solid rgb(var(--gilt-edge) / 0.45);
  color: rgb(var(--on-cta));
  font-weight: 600;
  letter-spacing: 0.008em;
  text-shadow: none;
  background-color: rgb(var(--cta));
}

/* Kills any ::before a superseded layer still declares for these. */
.btn-primary::before,
.subscribe-form button[type="submit"]::before,
.pp-gold::before,
.qibla-camera-cta::before{ content: none !important; }

@media (hover: hover){
  .btn-primary:hover,
  .subscribe-form button[type="submit"]:hover,
  .pp-gold:hover,
  .qibla-camera-cta:hover{
    color: rgb(var(--on-cta));
    background-image:
      linear-gradient(180deg,
        rgb(var(--cta-lift)) 0%,
        rgb(var(--cta-lift)) 12%,
        rgb(var(--cta))      44%,
        rgb(var(--cta))      78%,
        rgb(var(--cta-deep)) 100%);
  }
}

.btn-primary:active,
.subscribe-form button[type="submit"]:active,
.pp-gold:active,
.qibla-camera-cta:active{
  /* Pressed: the ramp inverts and the glow pulls in under it. The object
     is lit from further away; it is not repainted a different colour. */
  background-image:
    linear-gradient(180deg,
      rgb(var(--cta-deep)) 0%,
      rgb(var(--cta))      88%);
}

.btn-primary:focus-visible,
.subscribe-form button[type="submit"]:focus-visible,
.pp-gold:focus-visible,
.qibla-camera-cta:focus-visible{
  box-shadow:
    0 0 0 5px rgb(var(--cta) / 0.24),
    0 8px 20px -8px rgb(var(--cta) / 0.55);
}

.btn-primary:disabled,
.btn-primary[aria-disabled="true"],
.subscribe-form button[type="submit"]:disabled,
.pp-gold:disabled,
.pp-gold[aria-disabled="true"]{
  background-image: none;
  background-color: rgb(var(--wash) / 0.38);
  border-color: rgb(var(--gilt-edge) / 0.18);
  box-shadow: none;
  transform: none;
  opacity: 1;
  cursor: default;
}

/* The arrow leans forward when the button is reached for — the smallest
   possible way of saying the button goes somewhere. */
.btn-primary svg,
.pp-gold svg{ transition: transform var(--dur) var(--ease-out-expo); }
@media (hover: hover){
  .btn-primary:hover svg,
  .pp-gold:hover svg{ transform: translateX(3px); }
}

@media (prefers-reduced-motion: reduce){
  .btn-primary:active, .pp-gold:active{ transform: none; }
  @media (hover: hover){
    .btn-primary:hover,
    .pp-gold:hover,
    .qibla-camera-cta:hover{ transform: none; }
    .btn-primary:hover svg,
    .pp-gold:hover svg{ transform: none; }
  }
}

/* The camera CTA's own furniture rides the same colour. */
.qibla-camera-cta-badge{
  background: rgb(var(--on-cta) / 0.16) !important;
  border-color: rgb(var(--on-cta) / 0.22) !important;
}
.qibla-camera-cta-badge svg{ color: rgb(var(--on-cta)) !important; }
.qibla-camera-cta-ring{ border-color: rgb(var(--on-cta) / 0.26) !important; }
.qibla-camera-cta,
.qibla-camera-cta-title{ color: rgb(var(--on-cta)); }
.qibla-camera-cta-sub{ color: rgb(var(--on-cta) / 0.80); }
.qibla-camera-cta-arrow{ color: rgb(var(--on-cta) / 0.72); }

/* ---- THE SECOND BUTTON, still quiet ---------------------------------- */
.btn-ghost{
  border-color: rgb(var(--heading) / 0.20);
  color: rgb(var(--heading));
  background: rgb(var(--surface) / 0.55);
  box-shadow: none;
}
@media (hover: hover){
  .btn-ghost:hover{
    border-color: rgb(var(--heading) / 0.34);
    background: rgb(var(--heading) / 0.05);
    color: rgb(var(--heading));
    transform: translateY(-1px);
  }
}
.btn-ghost:active{ transform: translateY(0); }

/* Anything that painted itself from the METAL because it was echoing the
   old button now echoes the new one. These are the small round "go"
   affordances beside a field. */
.hadith-field-go{
  border-color: rgb(var(--wash) / 0.34);
  background: rgb(var(--wash) / 0.12);
  color: rgb(var(--cta-edge));
}
@media (hover: hover){
  .hadith-field-go:hover{
    background: rgb(var(--wash) / 0.20);
    border-color: rgb(var(--wash) / 0.58);
  }
}
[data-scheme="dark"] .hadith-field-go { color: rgb(var(--cta)); }
/* ---- v140-layer-15-quran-size.css ---- */

/* =========================================================================
   v14.0 — THE OTHER HALF OF THE size-adjust.  (item 1)

   Adding `size-adjust: 118%` to KFGQPC Hafs Smart (see the @font-face at
   the top of this file) made every ayah on the site 18% larger overnight.
   That is the correct RELATIONSHIP — an ayah and a hadith at the same
   font-size are finally the same size — but it is the wrong absolute size
   on pages that were tuned against the old rendering.

   So every rule that sets an ayah's size comes down by 1/1.18 = 0.847 in
   the same release. The reading page, the tafsīr room and the adhkār look
   exactly as they did; what changed is that the Qur'an no longer shrinks
   away from the English and the Arabic beside it.

   The one place a size is NOT scaled down is the pair on the home page,
   which is the fault that was reported: the ayah of the day and the hadith
   of the day now carry ONE size between them and sit at the same weight on
   the page.
   ========================================================================= */

/* ---- the reader ------------------------------------------------------ */
/* assets/quran.js writes --quran-font-size from AR_BASE; the base moved
   there rather than here so the size CONTROL still spans the same range. */
.quran-ayah-ar{ font-size: var(--quran-font-size, 1.7rem); }

/* ---- the tafsīr room ------------------------------------------------- */
.tafsir-ayah-ar{
  font-size: calc(clamp(1.22rem, 0.93rem + 1.44vw, 1.74rem) * var(--tafsir-fs, 1));
}
.qa-tafsir-verse{ font-size: 1.27rem; }

/* ---- the adhkār ------------------------------------------------------ */
.adhkar-hero-ayah{ font-size: clamp(1.14rem, 0.85rem + 1.44vw, 1.65rem); }

/* ---- the Bismillah --------------------------------------------------- */
.quran-bismillah{ font-size: clamp(1.23rem, 2.88vw, 1.65rem); }
@media (max-width: 620px){
  .quran-bismillah{ font-size: clamp(1.1rem, 5.4vw, 1.44rem); }
}

/* =========================================================================
   THE TWO PANELS ON THE HOME PAGE, WHICH IS WHERE IT WAS REPORTED.

   The ayah of the day and the hadith of the day are the same kind of
   thing seen twice — one line of Arabic, one line of English, one
   citation — so they take one size between them. Before this they were
   both nominally 25.6px and looked a fifth apart, because one of them was
   in the face with no size-adjust.
   ========================================================================= */
.hero-ayah,
.quran-day-arabic,
.hadith-day-arabic{
  font-size: clamp(1.16rem, 0.9rem + 1.3vw, 1.6rem);
  line-height: 2.05;
}
.hadith-day.is-compact .hadith-day-arabic,
.hadith-day.is-compact .quran-day-arabic{
  font-size: clamp(1.06rem, 2.4vw, 1.38rem);
  line-height: 1.95;
}
/* And their English lines, likewise one size. */
.hadith-day-english,
.quran-day-english,
.hero-ayah-en{
  font-size: 0.97rem;
  line-height: 1.75;
}

/* =========================================================================
   THE HADITH SHELF ON THE HOME PAGE.  (item 2)

   "in the hadith collection in home page the Arabic is once again much
    bigger than English visually, also its font is not nice I prefer bold
    traditional arabic here! (and the hadith main page, but NOT the hadith
    text itself)"

   It was 1.5rem of Scheherazade over 1.02rem of Fraunces — a 47% gap, and
   the two are the same label. THE ROW OWNS THE SIZE (CLAUDE-NOTES §7) and
   both are 1em of it.

   And the face: a book's TITLE is display type, so it is Amiri at 700 —
   the Bulaq naskh with real stroke contrast, which is what "bold
   traditional arabic" is asking for. The hadith TEXT is untouched and
   stays in Scheherazade, which is the face made to be read for an hour.
   ========================================================================= */
.hadith-shelf-card{ font-size: 1.06rem; }
.hadith-shelf-ar{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight-strong);
  font-size: 1em;
  line-height: 1.62;
  color: rgb(var(--heading));
}
.hadith-shelf-title{
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1em;
  line-height: 1.32;
  color: rgb(var(--heading-soft));
}
.hadith-shelf-blurb{ font-size: 0.72rem; }
@media (max-width: 720px){
  .hadith-shelf-card{ font-size: 0.98rem; }
  .hadith-shelf-ar,
  .hadith-shelf-title{ font-size: 1em; }
}

/* The same pairing on the hadith index, where the collection cards say the
   same two things. The book's name is a title there too. */
.hadith-collection-card{ font-size: 1.06rem; }
.hadith-collection-card h3,
.hadith-collection-title{ font-size: 1em; line-height: 1.32; }
/* ---- v140-layer-20-unwan.css ---- */

/* =========================================================================
   v14.0 — THE ILLUMINATED HEADPIECE, REDRAWN.  (items 3, 4, 34, 45)

   "there is a very ugly design above the (الْأَحَادِيثُ النَّبَوِيَّة) and other
    major issues like the حركات on Arabic looking ugly there and text size
    and very weak visual beauty & aesthetics, same for الشمائل المحمدية 'as
    a book page' … and the very weird lines (not nice currently!)"

   FOUR THINGS WERE WRONG AND THEY WERE ALL THE SAME MISTAKE: the panel was
   assembled from ornaments that each announced themselves, and none of
   them was doing any work.

     1. A 3px GRADIENT BAR welded across the top edge. That is a progress
        bar, not an illumination. Real gilding on a headpiece is a HAIRLINE
        — often two, a hair apart — never a slab.
     2. A 56px CIRCLE with a line icon in it, floating above the title. It
        is the same badge the tool pages use for a control; on a
        frontispiece it reads as a button somebody forgot to make clickable.
     3. THE TITLE FULLY VOCALISED at 3.1rem. الْأَحَادِيثُ النَّبَوِيَّة carries nine
        marks; at display size in a high-contrast Bulaq naskh they collide
        with the letters above and below them and the word turns to lace.
        CLAUDE-NOTES §7 already says menu NAMES are unvocalised — a title
        set at 50px is the same case, and more so. The markup is
        unvocalised now.
     4. A LOOSE HAIRLINE floating between the title and the description,
        going nowhere.

   WHAT IT IS INSTEAD, and every part of it earns its place:

     · a DOUBLE GOLD RULE, 1px and 0.5px two pixels apart, inset from the
       edge — the rule this site already draws under every ʿunwān, on every
       cover, and round its own mark. Three scales rather than one slab
       (CLAUDE-NOTES §10 rule 3);
     · the four CORNER BRACKETS the frontispiece uses;
     · the title, unvocalised, in Amiri at 700, at a size that leaves the
       descenders room;
     · under it a rule that MEETS A LOZENGE at its centre, which is the
       traditional way a headpiece separates the title from what follows —
       a line with a reason to stop;
     · and a warm radial bloom behind the title only, so the panel is lit
       from where the writing is.
   ========================================================================= */

.book-unwan,
.adhkar-unwan{
  position: relative;
  isolation: isolate;
  text-align: center;
  padding: var(--sp-8) var(--sp-7) var(--sp-7);
  border-radius: var(--radius-lg);
  box-shadow: var(--e2);
  overflow: hidden;
}

/* The double rule, inset. ::before is the frame; the second hairline is a
   box-shadow on the same element, which is what keeps them exactly 2px
   apart at every zoom level. */
.book-unwan::before,
.adhkar-unwan::before{
  content: '';
  position: absolute;
  inset: 9px;
  border: 1px solid rgb(var(--gilt-edge) / 0.42);
  border-radius: calc(var(--radius-lg) - 7px);
  box-shadow: inset 0 0 0 3px rgb(var(--gilt) / 0.16);
  pointer-events: none;
  z-index: -1;
}

/* The corner brackets: four short right angles sitting ON the rule, which
   is what stops a plain rectangle reading as a table cell. */
.book-unwan-rule::before,
.book-unwan-rule::after,
.adhkar-unwan-rule::before,
.adhkar-unwan-rule::after{
  content: '';
  position: absolute;
  width: 26px; height: 26px;
  border: 0 solid rgb(var(--gilt-edge) / 0.85);
}
.book-unwan-rule::before,
.adhkar-unwan-rule::before{
  border-top-width: 2px; border-left-width: 2px;
  border-top-left-radius: calc(var(--radius-lg) - 7px);
}
.book-unwan-rule::after,
.adhkar-unwan-rule::after{
  border-bottom-width: 2px; border-right-width: 2px;
  border-bottom-right-radius: calc(var(--radius-lg) - 7px);
}
/* The other two corners, on the mark's element, which no longer draws a
   circle. Same shape, opposite pair. */
.book-unwan-mark,
.adhkar-unwan-mark{
  position: absolute;
  inset: 9px;
  width: auto; height: auto;
  margin: 0;
  background: none;
  border: 0;
  border-radius: 0;
  pointer-events: none;
  z-index: -1;
}
.book-unwan-mark > svg,
.adhkar-unwan-mark > svg{ display: none; }
.book-unwan-mark::before,
.book-unwan-mark::after,
.adhkar-unwan-mark::before,
.adhkar-unwan-mark::after{
  content: '';
  position: absolute;
  width: 26px; height: 26px;
  border: 0 solid rgb(var(--gilt-edge) / 0.85);
}
.book-unwan-mark::before,
.adhkar-unwan-mark::before{
  top: -1px; right: -1px;
  border-top-width: 2px; border-right-width: 2px;
  border-top-right-radius: calc(var(--radius-lg) - 7px);
}
.book-unwan-mark::after,
.adhkar-unwan-mark::after{
  bottom: -1px; left: -1px;
  border-bottom-width: 2px; border-left-width: 2px;
  border-bottom-left-radius: calc(var(--radius-lg) - 7px);
}

/* ---- the title ------------------------------------------------------- */
.book-unwan-ar,
.adhkar-title{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight-strong);
  font-size: clamp(1.75rem, 1.1rem + 2.6vw, 2.55rem);
  line-height: 1.68;
  color: rgb(var(--heading));
  margin: 0;
  letter-spacing: 0;
}
.book-unwan-en,
.adhkar-unwan-sub{
  font-family: var(--font-mono);
  font-size: 0.64rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgb(var(--gilt-edge));
  margin: 6px 0 0;
}
.adhkar-unwan .eyebrow{ margin-bottom: 2px; }

/* ---- the divider that has a reason to stop --------------------------- */
.book-unwan-divider,
.adhkar-unwan-divider{
  position: relative;
  display: block;
  width: min(220px, 62%);
  height: 9px;
  margin: var(--sp-5) auto var(--sp-4);
  background: none;
}
.book-unwan-divider::before,
.adhkar-unwan-divider::before{
  content: '';
  position: absolute; top: 4px; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg,
    rgb(var(--gilt) / 0) 0%,
    rgb(var(--gilt-edge) / 0.55) 22%,
    rgb(var(--gilt-edge) / 0.55) 78%,
    rgb(var(--gilt) / 0) 100%);
}
/* The lozenge: a small square on its point, in the palette's metal, with
   the fine dark outline every gilded shape on this site carries. */
.book-unwan-divider::after,
.adhkar-unwan-divider::after{
  content: '';
  position: absolute; top: 0; left: 50%;
  width: 9px; height: 9px; margin-left: -4.5px;
  transform: rotate(45deg);
  background: rgb(var(--gilt));
  border: 1px solid rgb(var(--gilt-edge) / 0.75);
}

.book-unwan-desc,
.adhkar-unwan-desc{
  max-width: 54ch;
  margin: 0 auto;
  font-size: 0.94rem;
  line-height: 1.72;
  color: rgb(var(--text-muted));
}
.book-unwan-ctas{ margin-top: var(--sp-5); }

@media (max-width: 600px){
  .book-unwan,
  .adhkar-unwan{ padding: var(--sp-7) var(--sp-4) var(--sp-6); }
  .book-unwan::before,
  .adhkar-unwan::before,
  .book-unwan-rule,
  .adhkar-unwan-rule,
  .book-unwan-mark,
  .adhkar-unwan-mark{ inset: 7px; }
  .book-unwan-rule::before, .book-unwan-rule::after,
  .book-unwan-mark::before, .book-unwan-mark::after,
  .adhkar-unwan-rule::before, .adhkar-unwan-rule::after,
  .adhkar-unwan-mark::before, .adhkar-unwan-mark::after{ width: 18px; height: 18px; }
  .book-unwan-desc,
  .adhkar-unwan-desc{ font-size: 0.9rem; }
}

/* ---- v140-layer-25-chapters.css ---- */

/* =========================================================================
   v14.0 — WHAT IS LEFT OF THE CHAPTER INDEX ON THE PAGE.  (item 39)

   One row. It says how many chapters the book has, which one you are in,
   and how many narrations that is — and it opens the menu. The
   ninety-seven cells are gone from the page and from the DOM; see
   hadith-collection.php and assets/ui.js.
   ========================================================================= */
.hadith-chapters{
  margin-bottom: var(--sp-5);
}
.hadith-chapters-btn{
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: rgb(var(--surface) / 0.7);
  cursor: pointer;
  text-align: left;
  transition:
    border-color var(--dur) var(--ease-soft),
    background var(--dur) var(--ease-soft);
}
@media (hover: hover){
  .hadith-chapters-btn:hover{
    border-color: rgb(var(--wash) / 0.42);
    background: rgb(var(--surface));
  }
}
.hadith-chapters-btn:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }
.hadith-chapters-ic{
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 9px;
  background: rgb(var(--wash) / 0.11);
  color: rgb(var(--cta-edge));
}
[data-scheme="dark"] .hadith-chapters-ic{ color: rgb(var(--cta)); }
.hadith-chapters-ic svg{ width: 16px; height: 16px; }
.hadith-chapters-label{ display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.hadith-chapters-kicker{
  font-family: var(--font-mono);
  font-size: 0.63rem; letter-spacing: 0.11em; text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.hadith-chapters-current{
  font-family: var(--font-ui);
  font-size: 0.94rem; font-weight: 600;
  color: rgb(var(--heading));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hadith-chapters-n{
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
  color: rgb(var(--text-muted));
}
.hadith-chapters-chev{
  width: 16px; height: 16px;
  fill: none; stroke: currentColor; stroke-width: 2;
  color: rgb(var(--text-muted));
  transform: rotate(-90deg);
}
/* ---- v140-layer-30-adhkar.css ---- */

/* =========================================================================
   v14.0 — THE ADHKĀR PAGE.  (items 18, 22, 34)

   THE SET BAR replaces thirteen tiles. It is not a menu you have to know
   is there — the fault v13.0 was written to fix — because it carries the
   set you are in, its mark, its Arabic name and the word "Change", at
   full width, directly under the head. See page-tasbih.php for the
   reasoning and assets/adhkar.js for what it opens.
   ========================================================================= */

.adhkar-index{
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 22rem);
  align-items: center;
  gap: var(--sp-4);
  margin-bottom: var(--sp-5);
  padding: 0;
  border: 0;
  background: none;
}

.adhkar-pick{
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 13px 16px;
  border-radius: var(--radius);
  border: 1px solid rgb(var(--wash) / 0.28);
  background:
    linear-gradient(180deg, rgb(var(--wash) / 0.09), rgb(var(--wash) / 0.05)),
    rgb(var(--surface));
  cursor: pointer;
  text-align: left;
  transition:
    border-color var(--dur) var(--ease-soft),
    box-shadow var(--dur) var(--ease-soft);
}
@media (hover: hover){
  .adhkar-pick:hover{
    border-color: rgb(var(--wash) / 0.52);
    box-shadow: 0 10px 24px -14px rgb(var(--cta) / 0.55);
  }
}
.adhkar-pick:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }

.adhkar-pick-ic{
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  border-radius: 13px;
  background: rgb(var(--wash) / 0.14);
  border: 1px solid rgb(var(--wash) / 0.24);
  color: rgb(var(--cta-edge));
}
[data-scheme="dark"] .adhkar-pick-ic{ color: rgb(var(--cta)); }
.adhkar-pick-ic svg{ width: 22px; height: 22px; }

/* THE ROW OWNS THE SIZE — the English name and the Arabic name are the
   two halves of one label, so they are 1em of the same row. */
.adhkar-pick-text{
  display: flex; flex-direction: column; gap: 1px; min-width: 0;
  font-size: 1.02rem;
}
.adhkar-pick-kicker{
  font-family: var(--font-mono);
  font-size: 0.6rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.adhkar-pick-name{
  font-family: var(--font-display); font-weight: 600;
  font-size: 1em; line-height: 1.3;
  color: rgb(var(--heading));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.adhkar-pick-ar{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight-strong);
  font-size: 1em; line-height: 1.5;
  color: rgb(var(--text-muted));
  direction: rtl; unicode-bidi: isolate; text-align: left;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.adhkar-pick-change{
  font-family: var(--font-ui);
  font-size: 0.76rem; font-weight: 600;
  color: rgb(var(--cta-edge));
}
[data-scheme="dark"] .adhkar-pick-change{ color: rgb(var(--cta)); }
.adhkar-pick-chev{
  width: 16px; height: 16px;
  fill: none; stroke: currentColor; stroke-width: 2;
  color: rgb(var(--text-muted));
  transform: rotate(-90deg);
}

.adhkar-find{
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 9px;
  height: 46px;
  padding: 0 14px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: rgb(var(--surface));
  max-width: none;
}
.adhkar-find:focus-within{ border-color: rgb(var(--wash) / 0.5); }
.adhkar-find-ic{ width: 16px; height: 16px; color: rgb(var(--text-muted)); }
.adhkar-find input{
  width: 100%; min-width: 0; height: 100%;
  border: 0; background: transparent; color: rgb(var(--heading));
  font-family: var(--font-ui); font-size: 0.9rem;
}
.adhkar-find input:focus{ outline: none; }

@media (max-width: 860px){
  .adhkar-index{ grid-template-columns: minmax(0, 1fr); gap: var(--sp-3); }
}
@media (max-width: 520px){
  .adhkar-pick{ padding: 11px 13px; gap: 11px; }
  .adhkar-pick-ic{ width: 40px; height: 40px; border-radius: 12px; }
  .adhkar-pick-text{ font-size: 0.96rem; }
  /* "Change" is the chevron's job on a phone; the word is what pushes the
     set's own name into an ellipsis at 375px. */
  .adhkar-pick-change{ display: none; }
}

/* =========================================================================
   THE WORDS THEMSELVES.  (item 22)

   "the text in adhkar in Arabic became tiny (fix En too) and no proper
    line spacing! make it perfect & make the adhkar pages all extremely
    beautiful!!"

   Two things had happened to it. --ar-weight came down to 400 in v13.2,
   which is right for reading and does make the same size look smaller;
   and the line box was 2.35 on Arabic that carries every ḥarakah, which
   sounds generous and is not — a fully vocalised line needs the marks
   ABOVE one row to clear the marks BELOW the row above it, and 2.35 on a
   1.35rem line is 3.17rem of leading for about 2.6rem of ink.

   Bigger, and with a line box measured against the marks rather than
   against the letters. The English comes up with it: the two are read
   together and one of them was two steps smaller than the other.
   ========================================================================= */

/* The ayah that used to sit in the head now closes the page. */
.adhkar-closing{
  max-width: 62ch;
  margin: var(--sp-9) auto 0;
  padding-top: var(--sp-7);
  border-top: 1px solid var(--hairline);
  text-align: center;
}
.adhkar-closing .adhkar-hero-ayah{ margin: 0 0 var(--sp-4); }
.adhkar-closing .adhkar-hero-en{
  font-size: 0.95rem; line-height: 1.75;
  color: rgb(var(--text-muted));
  margin: 0 0 6px;
}
.adhkar-closing .adhkar-hero-ref{
  font-family: var(--font-mono);
  font-size: 0.66rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: rgb(var(--gilt-edge));
  margin: 0;
}
/* ---- v140-layer-40-tafsir.css ---- */

/* =========================================================================
   v14.0 — ARABIC THAT ELLIPSES MUST STILL BE WHOLE.  (item 13)

   "in MANY places of the website like the tafsir menu from header, there
    is text which is not properly displayed, for example see the word
    مفاتيح الغيب how the ح is only partially showing, same for many other
    places and many other letters"

   It is the same bug in every one of those places and it is not the
   ellipsis. `overflow: hidden` clips in BOTH directions. Latin sits almost
   entirely between the baseline and the cap line, so a 1.4 line box holds
   it; Arabic does not — ح, ج, خ, ع, غ, م, ي and ن all swing well BELOW the
   baseline, و and ر hang, and a vocalised word puts a kasrah under that
   again. At 1.4 the box is shorter than the letter and the bowl of the ح
   is cut off by the element's own overflow.

   A one-line Arabic label therefore needs a line box measured against the
   DESCENDER, not against the x-height: 1.75 is the floor where a bare ح
   clears, and it is the floor everywhere below. Where the label can carry
   ḥarakāt it is 1.9 (CLAUDE-NOTES §7 already says this for the menus and
   it had not been applied to every one of them).
   ========================================================================= */
.tafsir-shelf-ar,
.tafsir-pop-row-ar,
.tr-where-ar,
.hadith-chapter-ar,
.adhkar-pick-ar,
.pp-picker-item-sub[lang="ar"] {
  line-height: 1.85;
  /* An element that clips has to be tall enough to clip nothing. */
  padding-block: 1px;
}

/* And where a nowrap label is inside a grid row, the ROW has to allow the
   taller line box rather than capping it. */
.hadith-chapters-btn,
.adhkar-pick { align-items: center; }

/* =========================================================================
   v14.0 — THE HEADER'S TAFSĪR MENU.  (item 27)

   "improve the tafsir header menu, it has big gaps between other books
    and also its visually ugly, make it stunning!"

   The gap was not between the rows — it was inside them. Each row was a
   single column holding an English title and an Arabic title stacked, in a
   560px panel, so every row was 92px of box carrying 40px of writing and
   the whole right-hand half of the panel was empty.

   Two columns per row instead: the book's Arabic name in a right-aligned
   gutter, its English name beside it — the same shape the Qur'an panel
   uses for the surahs, which is the panel this one sits next to. The
   Arabic leads because on a shelf of thirty-two books the Arabic title is
   what a reader recognises.
   ========================================================================= */
/* The resume row spans both columns, because it is not a book. */

/* =========================================================================
   v14.0 — "THE SAME AYAH, IN ANOTHER COMMENTARY".  (item 14)

   "there is overlapping text in the boxes, also please choose a much more
    beautiful design for the way these tafasir are layed out!!"

   THE OVERLAP: each chip was a centred column holding an Arabic title at
   0.95rem/1.4 and an English name at 0.66rem, with `gap: 1px`. 1.4 on
   Arabic is shorter than the Arabic (see item 13 above), so the descenders
   of the title ran into the cap line of the name a pixel below it. Two
   lines that touch are two lines that overlap.

   THE DESIGN: thirty-two identical pills wrapping across four shelves is
   a tag cloud. These are BOOKS, so they are drawn as one: a card with a
   gilt spine down its leading edge, the Arabic title over the English
   name, and the shelf's own colour on the spine. Four shelves, four
   spines, and the one you are reading is filled rather than outlined.
   ========================================================================= */
/* The spine. Gilt, with the fine dark line every gilded shape here
   carries — CLAUDE-NOTES §10 rule 2. */

/* =========================================================================
   v14.0 — THE LIBRARY'S BOOK CARDS.  (item 40)

   "in tafsir page the book boxes on the (/tafsir/) are very ugly, choose
    an extremely attractive beautiful design, unique for each book if
    feasible, and very beautiful and stunning!!!!"

   They were flat cream rectangles with a small identical sun on each, and
   the author's name — the one line that is genuinely different from card
   to card — was clipped mid-word by an ellipsis.

   They are BOUND VOLUMES now, and the drawing follows the four rules in
   CLAUDE-NOTES §10:

     · A GILT SPINE down the leading edge, with the century struck on it in
       Arabic numerals — a real spine, four stops, outlined.
     · THE CREST, which inc/tafsir.php already draws per book and which had
       nowhere to sit; it is on the spine's head now, in gold on the page.
     · THE TITLE in Amiri at 700 over a DOUBLE RULE, which is the ʿunwān
       this site draws everywhere else.
     · The author WHOLE. An Arabic name broken by an ellipsis is not a
       name; it wraps to a second line instead.
     · And the whole card lifts on a gilt-tinted shadow rather than
       changing colour, so thirty-two of them read as a shelf.
   ========================================================================= */

/* THE SPINE */


/* The double rule under the title. */

/* WHOLE. It wraps; it does not ellipse. */


/* =========================================================================
   v14.0 — A COMPARISON READS RIGHT TO LEFT.  (item 41)

   "make sure when comparing multiple books on tafsir the arabic text &
    titles are properly placed on the right and not starting from left"

   Each column is Arabic: the book's title, its author, and the commentary
   itself. The commentary had `direction: rtl` and the two headings above
   it did not, so a column of Arabic began at the left edge and the text
   under it at the right.
   ========================================================================= */

/* =========================================================================
   v14.0 — THE READING ROOM ON A PHONE.  (item 43)

   "on phone fix the spacing issues & clutterness on tafsir page, and text
    being on border of boxes etc etc!!!!"

   The ayah card and the commentary both carried desktop padding at 375px,
   so a 34-character line of Uthmani ran to within 14px of the border on
   both sides and the card read as full. And the commentary's own measure
   was set in `ch`, which on Arabic is the width of a ZERO — a unit that
   means nothing for a script with no zero in it.
   ========================================================================= */
@media (max-width: 560px){
  .tafsir-ayah{
    padding: var(--sp-4) var(--sp-4) var(--sp-3);
    border-radius: var(--radius);
  }
  .tafsir-ayah-ar{ max-width: none; padding-inline: 2px; }
  .tafsir-body{
    padding-inline: 2px;
    text-align: right;
    text-align-last: right;
  }
  .tafsir-page{ padding-inline: 0; }
  .tafsir-ayah-tools{ gap: 6px; margin-top: var(--sp-4); padding-top: var(--sp-3); }
}
/* ---- v140-layer-50-aa.css ---- */

/* =========================================================================
   v14.0 — ONE READING BUTTON, BOTTOM RIGHT.  (items 3, 12, 15, 49)

   "the weird Aa button placing (which must be bottom right, standard
    website theme)"                                              (item 3)
   "keep the Aa on bottom right as always"                       (item 15)
   "on phones Aa is not visible, its really hidden on posts!!"   (item 49)

   Five pages had reading controls and put them in five places, one of
   which — the post's left rail — is display:none below 1180px, so on a
   phone the control did not exist at all.

   assets/aa.js moves whatever a page marked `data-pp-aa` into this
   floating popover. The controls are the page's own, with their own ids
   and their own listeners; only the placement is shared.
   ========================================================================= */
.pp-aa{
  position: fixed;
  inset-inline-end: calc(24px + env(safe-area-inset-right));
  bottom: calc(24px + env(safe-area-inset-bottom));
  z-index: 91;
  transition: bottom 0.25s var(--ease-out-expo);
}
.pp-aa.has-arrow{ bottom: calc(24px + 44px + 10px + env(safe-area-inset-bottom)); }


.pp-aa-pop{
  position: absolute;
  bottom: calc(100% + 10px);
  inset-inline-end: 0;
  width: max-content;
  min-width: 232px;
  max-width: min(320px, calc(100vw - 40px));
  max-height: min(70vh, 560px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 12px;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  background: var(--glass-bg-strong, rgb(var(--surface)));
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  box-shadow: 0 22px 46px -20px rgb(var(--shadow) / 0.55);
}

/* Whatever was moved in is a plain stack now: it has left behind whatever
   its old container did to it (a rail column, a bar popover, a sheet). */
.pp-aa-body{
  display: flex !important;
  flex-direction: column;
  gap: 12px;
  position: static !important;
  inset: auto !important;
  width: auto !important;
  min-width: 0;
  max-width: none !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
  box-shadow: none !important;
  transform: none !important;
  opacity: 1 !important;
  visibility: visible !important;
  pointer-events: auto;
  overflow: visible !important;
  max-height: none !important;
}
.pp-aa-label,
.pp-aa-body .rail-reading-label,
.pp-aa-body .quran-rail-label,
.pp-aa-body .tafsir-reading-label{
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
  margin: 0;
}
.pp-aa-body .quran-rail-sep{ display: none; }
.pp-aa-body .pp-typesize{ width: 100%; }
/*
 * v14.0 - THE DOTS COME BACK.
 *
 * A phone rule hides the type-size track below 520px:
 *
 *     @media (max-width: 520px){ .rail-reading .pp-typesize-track{ display: none } }
 *
 * That was right when `.rail-reading` was a cramped horizontal strip
 * across the top of an article on a phone - two A's and a switch was the
 * control, and the dots only confirmed what the A's had just done. It is
 * wrong now that the same element lives in this popover, which is 216px
 * of its own and has room for all five. Without them the stepper is two
 * letters with an empty pill between them, giving no sign of where the
 * size currently is or that there is anywhere left to go.
 */
.pp-aa-body .pp-typesize-track{ display: flex !important; flex: 1; }
.pp-aa-body .quran-lines,
.pp-aa-body .book-lines,
.pp-aa-body .adhkar-aa-pop{
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 100%;
  max-width: none;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
  border-radius: 0;
}
.pp-aa-body .quran-line-btn,
.pp-aa-body .adhkar-aa-opt,
.pp-aa-body .pp-aa-opt{
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) 16px;
  align-items: center;
  gap: 9px;
  width: 100%;
  min-height: 38px;
  padding: 0 10px;
  border-radius: 9px;
  border: 1px solid transparent;
  background: transparent;
  color: rgb(var(--text-muted));
  font-family: var(--font-ui);
  font-size: 0.82rem;
  text-align: start;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){
  .pp-aa-body .quran-line-btn:hover,
  .pp-aa-body .adhkar-aa-opt:hover,
  .pp-aa-body .pp-aa-opt:hover{ background: rgb(var(--heading) / 0.06); color: rgb(var(--heading)); }
}
.pp-aa-body .quran-line-btn.is-on,
.pp-aa-body .adhkar-aa-opt.is-on,
.pp-aa-body .pp-aa-opt.is-on{
  background: rgb(var(--wash) / 0.12);
  border-color: rgb(var(--wash) / 0.3);
  color: rgb(var(--heading));
}

/* =========================================================================
   THE GLYPHS.  (item 12)

   "please replace the ugly arabic and english choices, and keep it very
    minimal and very clear and very beautiful and nice, the ع is ugly! and
    same for En! and remove the long text!"

   ع was chosen for "ʿarabī" and reads as a lone throat letter with a
   hollow in it — at 13px in a naskh it is a comma. أ is the first letter
   of the alphabet, closed, upright and unmistakable, and it is what an
   Arabic keyboard key shows. EN in caps was shouting next to it; En is
   the same word at the same weight as the Arabic beside it.

   And the names are one word each: Arabic, Sound, Meaning. "Transliteration"
   is nineteen characters describing a line the reader can simply see.
   ========================================================================= */
.pp-aa-body .adhkar-aa-glyph,
.pp-aa-body .quran-line-glyph,
.pp-aa-body .pp-aa-glyph{
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px;
  border-radius: 7px;
  background: rgb(var(--heading) / 0.05);
  font-family: var(--font-ui);
  font-size: 0.78rem; font-weight: 600;
  line-height: 1;
  color: inherit;
}
.pp-aa-body .adhkar-aa-opt[data-line="ar"] .adhkar-aa-glyph,
.pp-aa-body .quran-line-btn[data-line="ar"] .quran-line-glyph{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight-strong);
  font-size: 1.02rem;
}
.pp-aa-body .adhkar-aa-opt[data-line="tr"] .adhkar-aa-glyph{
  font-family: var(--font-display); font-style: italic;
}
.pp-aa-body .quran-line-btn.is-on .quran-line-glyph,
.pp-aa-body .adhkar-aa-opt.is-on .adhkar-aa-glyph,
.pp-aa-body .pp-aa-opt.is-on .pp-aa-glyph{
  background: rgb(var(--wash) / 0.18);
  color: rgb(var(--cta-edge));
}
/* An icon in a glyph box is drawn, not set: it takes the box's ink and
   the box's optical size, so a palette and the letter أ sit at the same
   weight in the same column. */
.pp-aa-body .pp-aa-glyph svg{
  width: 15px; height: 15px;
  fill: none; stroke: currentColor; stroke-width: 1.9;
  stroke-linecap: round; stroke-linejoin: round;
}
[data-scheme="dark"] .pp-aa-body .quran-line-btn.is-on .quran-line-glyph,
[data-scheme="dark"] .pp-aa-body .adhkar-aa-opt.is-on .adhkar-aa-glyph,
[data-scheme="dark"] .pp-aa-body .pp-aa-opt.is-on .pp-aa-glyph{ color: rgb(var(--cta)); }

.pp-aa-body .adhkar-aa-name,
.pp-aa-body .quran-line-name,
.pp-aa-body .pp-aa-name{
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-weight: 600;
}
.pp-aa-body .adhkar-aa-tick,
.pp-aa-body .quran-line-tick,
.pp-aa-body .pp-aa-tick{
  width: 15px; height: 15px;
  fill: none; stroke: currentColor; stroke-width: 2.4;
  color: rgb(var(--cta));
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-soft);
}
.pp-aa-body .adhkar-aa-opt.is-on .adhkar-aa-tick,
.pp-aa-body .quran-line-btn.is-on .quran-line-tick,
.pp-aa-body .pp-aa-opt.is-on .pp-aa-tick{ opacity: 1; }
.pp-aa-body .adhkar-aa-opt.is-refusing,
.pp-aa-body .quran-line-btn.is-refusing{ animation: ppLineRefuse 240ms var(--ease-soft); }

/* =========================================================================
   THE ONE BUTTON IN HERE THAT IS NOT A SETTING.

   "preferrably beautiful icons and properly centered play audio etc"

   Everything else in this panel answers "how should the page be set?" and
   is a row you tick. Listening is not a setting — it is an ACTION, and it
   was a bare 16px play triangle pinned to the left margin under a heading
   reading "Listen", which is neither centred nor obviously a button.

   So it is the one filled control in the panel: full width, the palette's
   own call-to-action ground, the mark centred with its name beside it. It
   is different from the rows because it does something different.
   ========================================================================= */
.pp-aa-body .quran-rail-play{
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  width: 100%;
  min-height: 40px;
  padding: 0 14px;
  border-radius: 10px;
  border: 1px solid rgb(var(--cta-edge) / 0.45);
  background: linear-gradient(180deg, rgb(var(--cta-lift)), rgb(var(--cta-deep)));
  color: rgb(var(--on-cta));
  font-family: var(--font-ui);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.005em;
  box-shadow: inset 0 1px 0 rgb(var(--on-cta) / 0.22),
              0 6px 14px -8px rgb(var(--cta-edge) / 0.6);
  cursor: pointer;
  transition: filter var(--dur-fast) var(--ease-soft),
              box-shadow var(--dur) var(--ease-soft);
}
@media (hover: hover){ .pp-aa-body .quran-rail-play:hover{ filter: brightness(1.05); } }
.pp-aa-body .quran-rail-play:active{ filter: brightness(0.96); }
.pp-aa-body .quran-rail-play svg{
  width: 15px; height: 15px; flex: 0 0 auto;
  fill: currentColor; stroke: none;
}
.pp-aa-body .quran-rail-play:focus-visible{
  outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px;
}

/* A rail button that has come along for the ride keeps working. */
.pp-aa-body .rail-btn{
  display: flex; align-items: center; gap: 9px;
  width: 100%; min-height: 38px; padding: 0 10px;
  border-radius: 9px; border: 1px solid var(--hairline);
  background: rgb(var(--surface));
  color: rgb(var(--heading));
  font-family: var(--font-ui); font-size: 0.82rem; font-weight: 600;
  cursor: pointer;
}
.pp-aa-body .rail-btn svg{ width: 15px; height: 15px; flex: 0 0 auto; }
.pp-aa-body .rail-btn.is-on{
  background: rgb(var(--wash) / 0.12);
  border-color: rgb(var(--wash) / 0.3);
}

/* =========================================================================
   THE OLD TRIGGERS COME OFF.

   Each of these opened the panel that has moved. Left in place they are
   buttons that open nothing, which is worse than no button.
   ========================================================================= */
.quran-siderail .quran-rail-toggle,
.tafsir-bar .tafsir-bar-aa,
.book-bar-aa,
#bookReadingBtn{ display: none !important; }
/* The rail on the Qur'an page was a tab welded to the edge holding one
   panel; with the panel gone the tab has nothing to be. */
.quran-siderail{ display: none !important; }
/* A post's rail keeps its table of contents; the reading block left. */

body.pp-zen .pp-aa{ display: none; }
@media print{ .pp-aa{ display: none; } }
@media (prefers-reduced-motion: reduce){ .pp-aa{ transition: none; } }

@media (max-width: 520px){
  .pp-aa{
    inset-inline-end: calc(16px + env(safe-area-inset-right));
    bottom: calc(16px + env(safe-area-inset-bottom));
  }
  .pp-aa.has-arrow{ bottom: calc(16px + 42px + 9px + env(safe-area-inset-bottom)); }
  .pp-aa-pop{ min-width: 216px; }
}


/* ---- v140-layer-60-chrome.css ---- */

/* =========================================================================
   v14.0 — THE SEAM, FOR THE LAST TIME.  (item 28)

   "you are obsessed with keeping gaps between secondary headers or bars
    and the main header, it must remain connected perfectly always! with 0
    gaps!! always!! please fix this fully"

   v12.4 catalogued three causes and fixed all three: the sub-pixel sliver
   (a welded bar pins one pixel HIGH and tucks its first row under the
   header), the shadow the header was dropping onto its own continuation,
   and the colour step between two different materials. Those three are
   still right and are still in force above.

   THE FOURTH CAUSE, which is the one that survived, is a race.

   --header-h is measured from the live element by assets/main.js. The
   header SHRINKS the moment the page scrolls — `.site-header.scrolled
   .header-inner` drops its vertical padding from 18px to 10px — so
   --header-h falls by about 16px at the exact instant scrolling starts.
   The welded bars carried `transition: top 0.3s`, written for the retreat.
   So the header jumped up 16px in one frame and the bar followed it over
   three hundred milliseconds: a gap that opens to sixteen pixels and
   closes again, EVERY TIME the reader starts to scroll. That is why it
   looked like the gap was never fixed. It was fixed, and then re-opened
   by an animation on the wrong property.

   The fix is to animate the right property. `top` is now instantaneous —
   it is a measurement, and a measurement should never lag behind what it
   measures — and the retreat is a `transform`, which is what the header
   itself uses. Same property, same duration, same easing, so the two
   travel as one object and the overlap between them is a constant 1px at
   every frame of the animation, not just at the ends.
   ========================================================================= */


/* The rail is only a welded bar on a phone. Above 1100px it is a column
   beside the article, pinned 22px below the header with a deliberate gap
   — see the v12.5 note. */

/* The two bars that are NOT welded — they stop at a considered distance
   below the header rather than against it — had the same lagging `top`
   for the same reason, and the same 16px wobble. They snap now too. */


/* =========================================================================
   THE PHONE STOPS DRAWING ON THE PAGE.  (item 36)

   "on phone when I long click or even click sometimes on many things of
    the app/website, the phone draws a blue box around that item and shows
    a link and stuff, please make sure this doesnt happen and is very
    clean and nice!! and also make sure this genuinly doesnt happen"

   Three separate pieces of device chrome, and only one of them was
   switched off anywhere on this site:

     · the TAP HIGHLIGHT — a translucent slab the colour of the system
       accent, painted over the whole element's box for ~200ms on touch.
       This is the blue box.
     · the CALLOUT — the sheet a long press raises over a link, with the
       URL and Copy / Share / Open. This is the "shows a link and stuff".
     · the DRAG GHOST — a half-opaque copy of an image that follows the
       finger when a press turns into a drag.

   All three are off, everywhere, and the site draws its own feedback
   instead: a real :active state on everything tappable, because removing
   the system's feedback without replacing it leaves a control that gives
   no sign it was pressed, which is a worse fault than the one being
   fixed.

   `user-select` is deliberately NOT touched on running text. A reader
   long-pressing a hadith, an ayah or a duʿāʾ to copy it must still be
   able to; only the chrome — buttons, cards, tiles, nav, the tab strips —
   refuses selection, because selecting the label of a button is never
   what the press meant.
   ========================================================================= */

html{
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}
a, button, summary, label,
[role="button"], [role="tab"], [role="option"], [role="menuitem"]{
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  touch-action: manipulation;
}
img, svg, picture, canvas{
  -webkit-touch-callout: none;
  -webkit-user-drag: none;
  user-select: none;
}
/* The chrome does not offer itself for selection. Running text does — the
   article body, the Arabic, the translations, the transliterations, the
   references — and is listed explicitly so no later component can lose it
   by inheriting from a wrapper. */
.site-footer,
.mini-bar,
.tafsir-bar,
.pp-welded,
.article-rail,
.pp-aa,
.pp-picker,
.theme-panel,
.pp-cmd,
.btn,
.arrow-btn,
.rail-btn,
.chip,
.pill,
.tab,
.tabs,
.topic-tile,
.topic-card,
.value-card,
.breadcrumbs,
.pagination,
.adhkar-pick,
.hadith-chapters-btn {
  -webkit-user-select: none;
  user-select: none;
}
:is(.article-body, .entry-content, .quran-ayah, .quran-text, .quran-tr,
    .hadith-text, .hadith-ar, .hadith-en, .tafsir-body, .book-body,
    .adhkar-card-ar, .adhkar-card-tr, .adhkar-card-en, .adhkar-ayah,
    .pp-selectable),
:is(.article-body, .entry-content, .quran-ayah, .quran-text, .quran-tr,
    .hadith-text, .hadith-ar, .hadith-en, .tafsir-body, .book-body,
    .adhkar-card-ar, .adhkar-card-tr, .adhkar-card-en, .adhkar-ayah,
    .pp-selectable) *{
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

/* THE REPLACEMENT FEEDBACK. A press has to be visible within one frame or
   the control feels broken; 90ms is under the ~100ms threshold at which a
   response stops reading as instant. Only on devices that actually touch,
   so a mouse keeps its hover states unaltered. */
@media (hover: none){
  a:active,
button:active,
[role="button"]:active,
.topic-tile:active,
.topic-card:active,
.card:active,
.tile:active {
    transition: transform 90ms var(--ease-out-expo, ease-out),
                filter 90ms var(--ease-out-expo, ease-out);
  }
  .btn:active,
.arrow-btn:active,
.pp-aa-btn:active,
.adhkar-pick:active,
.hadith-chapters-btn:active,
.topic-tile:active,
.topic-card:active {
    transform: scale(0.978);
  }
  .rail-btn:active,
.quran-line-btn:active,
.adhkar-aa-opt:active,
.pp-picker-row:active {
    filter: brightness(0.94);
  }
}
@media (prefers-reduced-motion: reduce){
  @media (hover: none){
    .btn:active,
.arrow-btn:active,
.pp-aa-btn:active,
.adhkar-pick:active,
.hadith-chapters-btn:active,
.topic-tile:active,
.topic-card:active {
      transform: none;
    }
  }
}


/* =========================================================================
   THE TOPIC ROWS ARE WHOLE AGAIN.  (item 38)

   "under topics on phone the topics show starting from almost the middle
    of the topic icon, make sure everything is seen fully & beautifully and
    no missing parts"

   The phone layout turns each topic into a three-column row —
   [icon] [name over count] [chevron] — and places every child by hand.
   It placed `.topic-card-arrow` into column three. But that arrow is not
   a child of the card: it is inside `.topic-card-foot`, so it was never a
   grid item and `grid-column: 3` addressed nothing. It stayed in the
   normal flow inside the foot, below the count, and pushed the row from
   66px to 94px — a third line that nothing else in the row is aligned to,
   with the icon centred against all three. That is the row "starting from
   the middle of the icon": the name had risen above the icon's top edge
   to make room for a chevron that was in the wrong place.

   This is the same fault the v8.0 note above describes for `.topic-tile`
   on the home page, in the component next to it, unfixed. `display:
   contents` dissolves the wrapper so its two children become grid items
   of the card, which is what every rule here already assumed they were.
   ========================================================================= */
@media (max-width: 640px){
  .topic-card .topic-card-foot.topic-card-foot{
    display: contents;
  }
  .topic-card .topic-card-count{
    grid-column: 2; grid-row: 2;
    margin-top: 1px;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    color: rgb(var(--text-muted));
  }
  .topic-card .topic-card-arrow{
    grid-column: 3; grid-row: 1 / 3;
    align-self: center; justify-self: end;
    width: 15px; height: 15px;
    opacity: 0.55;
    color: rgb(var(--card-accent));
  }
}


/* ---- v140-layer-70-boxes.css ---- */

/* =========================================================================
   v14.0 — NOTHING COMES OUT OF ITS BOX.  (items 37, 43, 46, 50)

   "phone spacing & text has massive issues, sometimes too close sometimes
    too far, sometimes text too small, sometimes page too cluttered and
    sometimes things coming out of boxes"

   Every instance of the last one on this site — and they were found by
   walking nine pages at 375px and measuring, not by looking — is the same
   two-line mistake, in nine places:

       grid-template-columns: 1fr;      (or `auto`, or a flex child)
       ... white-space: nowrap;          (somewhere inside it)

   `1fr` is shorthand for `minmax(auto, 1fr)`, and `auto` as a MINIMUM
   means min-content. A track whose content refuses to wrap has a
   min-content as wide as its longest unbroken string, so the track grows
   past its own container and takes the row with it. The container is
   usually `overflow: hidden`, so what the reader sees is not a scrollbar:
   it is a word cut in half at the edge of a card.

   The fix is `minmax(0, 1fr)` — the same track, allowed to be narrower
   than its contents — plus `min-width: 0` down the flex chain, plus a
   decision at the bottom about what a too-long string should DO. Two
   answers, and which one applies is not a matter of taste:

     · An English label ELLIPSISES. "397 cities built in, plus worldwide…"
       is still that sentence when it is cut.
     · An ARABIC NAME WRAPS. It is never ellipsised anywhere on this site.
       Half of الجامع لأحكام القرآن is not the name of a book, and a
       title cut mid-word is the "overlapping / cut off text" in the
       report as often as a genuine overlap is.
   ========================================================================= */

/* ---- 1. The drawer -----------------------------------------------------
   Measured: the Qur'an accordion's rows wanted 327px inside a 297px panel
   and the whole drawer scrolled sideways, which is the horizontal
   scrollbar visible under the menu on a phone. */

/* ---- 2. The Qur'an reader's header row --------------------------------- */
.quran-surah-header-top{ min-width: 0; flex-wrap: wrap; row-gap: 8px; }
.quran-surah-header-top > *{ min-width: 0; }

/* ---- 3. The Shamāʾil's contents and its turn-the-page links ------------
   Both are two-line rows whose English line was set nowrap inside a track
   that could not grow. A chapter title is not a label; it wraps. */
.sirah-book-toc-en,
.sirah-book-turn-en{
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  min-width: 0;
}
.sirah-book-toc-item,
.book-turn > a,
.book-turn > span{ min-width: 0; }

/* ---- 4. The location chooser on Prayer Times and Qibla ----------------
   "397 cities built in, plus worldwide search" is a sentence, and a
   sentence may wrap. It was one nowrap line in a 206px box. */
.pp-choice-value{ min-width: 0; }
@media (max-width: 560px){
  .pp-choice-value{
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.35;
  }
}

/* ---- 5. "The same ayah, in another commentary" ------------------------
   The card design landed in v14.0 (see the note above). What it kept from
   the chips it replaced was `white-space: nowrap` on both lines, so
   الجامع لأحكام القرآن arrived as الجامع لأحكام… — an ellipsis through the
   title of a book, in a section whose entire job is to name books.
   The card is a grid row and can be as tall as it needs to be. */

/* ---- 6. The adhkār ʿunwān's medallion ---------------------------------
   A 52px circle straddling the top edge of the old full-bleed ʿunwān. The
   v14.0 hero is a card with its own frame and no edge for a medallion to
   straddle, so the span was inheriting `display:block` with no width and
   laying out as an invisible 320px box clipped by the card. It is not
   part of the drawing any more, so it does not draw. */
.adhkar-unwan-mark{ display: none; }

/* ---- 7. The general guard ---------------------------------------------
   Not a catch-all: these are the exact wrappers on this site that hold a
   two-line label beside something fixed-width. Declared once, so the next
   component built from the same pattern inherits the fix instead of the
   bug. */
.pp-picker-row-main,
.pp-choice-main,
.adhkar-pick-main,
.hadith-chapters-main,
.lib-row-main,
.prayer-row-main { min-width: 0; }


/* =========================================================================
   THE SUBMENU OPENS WHERE THE READER CAN SEE IT.  (item 37)

   "and do not forget the menu's submenu/options for e.g. under qur'an etc
    and that it shows on the screen and isnt hidden!"

   The accordion works — the Qur'an panel is 487px of rows. That is the
   problem: on a 743px drawer, opening the Hadith or Adhkār accordion,
   which sit low in the list, unfolds several hundred pixels BELOW the
   fold. The row is tapped, the drawer does not appear to move, and the
   submenu is "hidden".

   assets/main.js scrolls the opened item to the top of the drawer, which
   is a JS change; what belongs here is the room for it to scroll into.
   ========================================================================= */


/* ---- v140-layer-80-tafsir.css ---- */

/* =========================================================================
   v14.0 — THE RAIL IS LAID OUT, NOT SCROLLED.  (item 15)

   "the left menu of the tafsir page should come down with you when you
    scroll down the page, and not be overlapped by any of the bars on top,
    also this menu on the left should not be scrollable, it should be
    fully layed out!!"

   Three requests, and the first two were already true: the rail is
   `position: sticky` under the header AND the tafsīr bar, so it travels
   and nothing lands on top of it.

   The third was not, and could not be, because the rail was too tall for
   the window. It ended with a Reading block — a text-size stepper and the
   editor's-notes switch — that by v14.0 is in the floating Aa at the
   bottom right of the page. Removing the duplicate (see the note in
   inc/tafsir-rail.php) takes about 150px off the rail, which is what it
   needed to fit; so the scrollbar goes, and what is left is the whole
   rail, always, at every scroll position.

   `max-height` stays as a LAST RESORT at 100vh so that a very short
   window — a laptop in a video call, a phone in landscape — degrades to a
   scroll rather than to a rail with its bottom cut off. On any ordinary
   window it is never reached.
   ========================================================================= */
@media (min-width: 1180px){
  .tafsir-rail-inner{
    max-height: none;
    overflow: visible;
  }
  /* The floor. Only a window under about 620px tall can reach it. */
  @media (max-height: 640px){
    .tafsir-rail-inner{
      max-height: calc(100vh - var(--header-h) - 76px);
      overflow-y: auto;
      overscroll-behavior: contain;
      scrollbar-width: thin;
    }
  }
}


/* =========================================================================
   A RANGE, IN THE AYAH MENU.  (item 16)

   "in the ayah menu I want the user to be able to directly choose a range
    of ayat without having to go to the passage section, implement this
    beautifully and make it easier to access and more convenient and
    interactive!"

   Two controls, because there are two kinds of reader. See jumpRange() in
   assets/tafsir-rail.js for the reasoning; this is how they are drawn.

   THE STRIP sits directly under the search box, in the same well, so it
   reads as part of the one control rather than as a second form: a quiet
   label, two numbers with an en dash between them, and a verb.

   THE PASSAGE CARD appears above the search results the moment what has
   been typed IS a range. It is the largest thing in the sheet while it is
   there, because when a reader types 2:255–260 there is no ambiguity
   about what they want and the answer should not be one row in a list.
   ========================================================================= */

.tafsir-jump-passage{
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) 18px;
  align-items: center;
  gap: 14px;
  margin-top: 12px;
  padding: 14px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid rgb(var(--wash) / 0.45);
  background: rgb(var(--wash) / 0.09);
  color: rgb(var(--heading));
  text-decoration: none;
  animation: ppPassageIn 220ms var(--ease-out-expo) both;
}
@media (hover: hover){ .tafsir-jump-passage:hover{ background: rgb(var(--wash) / 0.15); } }
.tafsir-jump-passage-ref{
  font-family: var(--font-mono);
  font-size: 1.02rem;
  font-weight: 600;
  color: rgb(var(--cta-edge));
  letter-spacing: 0.01em;
}
[data-scheme="dark"] .tafsir-jump-passage-ref{ color: rgb(var(--cta)); }
.tafsir-jump-passage-say{
  font-family: var(--font-ui);
  font-size: 0.86rem;
  color: rgb(var(--text-muted));
}
.tafsir-jump-passage svg{
  width: 16px; height: 16px;
  fill: none; stroke: currentColor; stroke-width: 2;
  color: rgb(var(--cta));
}
@keyframes ppPassageIn{
  from{ opacity: 0; transform: translateY(-4px); }
  to{ opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce){
  .tafsir-jump-passage{ animation: none; }
}


/* =========================================================================
   THE TAFSĪR MENU IN THE HEADER.  (item 27)

   "improve the tafsir header menu, it has big gaps between other books
    and also its visually ugly, make it stunning!"

   THE GAPS WERE A SELECTOR THAT ADDRESSED NOTHING. The row was given two
   columns — a 7.4em right-aligned gutter for the Arabic title, the
   English beside it — and the Arabic was told `grid-row: 1; order: -1` to
   put it in the first. But `.tafsir-menu-ar` is not a child of the row:
   it is inside `.hadith-menu-main`, one level down, so neither property
   applied to anything. What actually rendered was an EMPTY 100px column
   on every row, with both lines stacked into the 185px left over beside
   it. That is the gap, on all eight rows, and the doubled row height
   (66px for two lines that fit on one) is the rest of it.

   `display: contents` dissolves the wrapper so its two children become
   the row's own grid items, which is what every rule here already assumed
   they were. The Arabic returns to its gutter, right-aligned against the
   English, and eight books take 8 × 40px instead of 8 × 66px.
   ========================================================================= */
/* A hairline between the gutter and the names, so eight Arabic titles
   read as a column rather than as eight loose words. It is drawn on the
   row rather than on the gutter so it runs the row's full height. */
/* In the drawer the gutter would take a third of a 297px panel, so the
   two lines stack there — which is what the row shape was originally
   written for. */


/* =========================================================================
   A COMPARISON READS RIGHT TO LEFT.  (item 41)

   "make sure when comparing multiple books on tafsir the arabic text &
    titles are properly placed on the right and not starting from left"

   The commentary itself was already `dir="rtl"` — every column's body is
   Arabic and sits correctly against the right edge of its column. The
   HEAD above it was not: a left-to-right flex row, so the book's Arabic
   name began at the left margin while the Arabic under it began at the
   right. Two alignments in one column, three columns wide.

   The head takes the column's own direction. The Arabic title leads from
   the right, the English name follows it inward, and the rule under them
   ends where the text does.
   ========================================================================= */
/* One column is not a comparison and its head is hidden anyway; this is
   only ever seen at two and three. */


/* =========================================================================
   THE TAFSĪR ROOM ON A PHONE.  (item 43)

   "on phone fix the spacing issues & clutterness on tafsir page, and text
    being on border of boxes etc etc"

   Measured at 375px: the ayah card and the commentary both ran their text
   to within 12px of the card's edge while the page's own gutter is 20px,
   so the words sat closer to the border of the box than the box did to
   the screen — which is what "text being on border of boxes" is. And the
   sheets stacked five blocks of chrome above the first line of Arabic.
   ========================================================================= */
@media (max-width: 620px){
  .tafsir-ayah,
  .tafsir-text{
    padding-inline: 16px;
  }
  .tafsir-page{ padding-block: var(--sp-4) var(--sp-8); }
  /* The shelf of other commentaries is a two-up grid at this width; at
     178px minimum it was one card and a gap. */
  .tafsir-jump-passage{
    grid-template-columns: minmax(0, 1fr) 16px;
    gap: 4px 12px;
    padding: 12px 14px;
  }
  .tafsir-jump-passage-ref{ grid-column: 1; grid-row: 1; }
  .tafsir-jump-passage-say{ grid-column: 1; grid-row: 2; font-size: 0.8rem; }
  .tafsir-jump-passage svg{ grid-column: 2; grid-row: 1 / 3; align-self: center; }
}


/* ---- v140-layer-85-unwan.css ---- */

/* =========================================================================
   v14.0 — THE ʿUNWĀN LOSES ITS CORNERS.  (item 3)

   "there is a very ugly design above the (الْأَحَادِيثُ النَّبَوِيَّة) …
    and the very weird lines (not nice currently!)"

   v13.2 drew a frame inside the card out of four corner brackets: two on
   a span called `.book-unwan-rule` and two on a span called
   `.book-unwan-mark`, each an absolutely-positioned box inset 7px with
   two borders on two of its sides and a rounded corner between them.

   Three things were wrong with it and all three are in the screenshot.
   The brackets sit 7px inside a card that ALREADY has a border, so every
   corner of the ʿunwān is two lines a hair apart. The radii do not agree
   — `calc(var(--radius-lg) - 7px)` against the card's own `--radius-lg`
   — so the two curves cross rather than nest. And the four brackets are
   the heaviest marks on the card, which puts the eye in the corners when
   the thing being introduced is in the middle.

   A frontispiece does not need a frame drawn twice. What it needs is what
   this card already has BELOW the title and did not have above it: a fine
   double rule with a lozenge on it. So the two decorative spans become
   that — one head rule above the Arabic, matching the divider under it —
   and the card keeps its own single border and nothing else.

   The result is symmetrical: rule, title, name, rule. Which is how a
   muṣḥaf's ʿunwān is set, and is the shape the rest of this site already
   uses.
   ========================================================================= */

/* The corners are not drawn. */
.book-unwan-rule::before,
.book-unwan-rule::after,
.book-unwan-mark::before,
.book-unwan-mark::after,
.adhkar-unwan-rule::before,
.adhkar-unwan-rule::after,
.adhkar-unwan-mark::before,
.adhkar-unwan-mark::after{
  content: none;
}
/* …and the box that held two of them is not a box. */
.book-unwan-mark,
.adhkar-unwan-mark{ display: none; }

/* THE HEAD RULE. Same drawing as .book-unwan-divider below the title, so
   the two read as a pair: a hairline that fades at both ends, with a
   small lozenge of the palette's metal struck on its centre. */
.book-unwan-rule,
.adhkar-unwan-rule{
  position: relative;
  inset: auto;
  display: block;
  width: min(220px, 62%);
  height: 9px;
  margin: 0 auto var(--sp-5);
  background: none;
  border: 0;
  z-index: auto;
  pointer-events: none;
}
.book-unwan-rule::before,
.adhkar-unwan-rule::before{
  content: '';
  position: absolute; top: 4px; left: 0; right: 0; bottom: auto;
  /* `width: auto` is load-bearing. The v13.2 phone rule sizes these two
     pseudo-elements as 18x18 corner brackets, and on an absolutely
     positioned box a stated WIDTH beats a stated `right` - so without
     this the head rule renders as an 18px stub against the left edge,
     which is the orange dash the first screenshot of this fix showed. */
  width: auto; height: 1px;
  background: linear-gradient(90deg,
    rgb(var(--gilt) / 0) 0%,
    rgb(var(--gilt-edge) / 0.55) 22%,
    rgb(var(--gilt-edge) / 0.55) 78%,
    rgb(var(--gilt) / 0) 100%);
  border: 0;
}
.book-unwan-rule::after,
.adhkar-unwan-rule::after{
  content: '';
  position: absolute; top: 0; left: 50%; right: auto; bottom: auto;
  width: 9px; height: 9px; margin-left: -4.5px;
  transform: rotate(45deg);
  background: rgb(var(--gilt));
  border: 1px solid rgb(var(--gilt-edge) / 0.75);
  border-radius: 0;
}

/* ONE FRAME, NOT TWO.

   The inner gilt double rule is the frame a frontispiece has, and it is
   the better of the two: a hairline with a soft 3px gold band inside it,
   held exactly parallel by a box-shadow rather than by a second element.
   The card's own border was drawn at the same weight 9px outside it, so
   every edge of the panel was two gold lines a hair apart. It becomes the
   quiet edge of the paper instead - just enough to separate the card from
   the page, not enough to be read as a rule. */
.book-unwan,
.adhkar-unwan{
  border: 1px solid rgb(var(--gilt-edge) / 0.12);
  background:
    radial-gradient(120% 92% at 50% 0%, rgb(var(--gilt) / 0.07), transparent 58%),
    rgb(var(--surface));
}

@media (max-width: 600px){
  .book-unwan-rule,
  .adhkar-unwan-rule{ width: min(180px, 66%); margin-bottom: var(--sp-4); }
}


/* =========================================================================
   ICONS IN THE DARK.  (item 44)

   "on phone when on dark theme, sometimes the icons (on multiple pages)
    become dull and ugly, make sure this is properly and beautifully
    fixed!!"

   Not a contrast failure — the emblems are gold on a near-black surface
   and measure about 6:1. It is HALATION: a light stroke on a dark ground
   is optically thinner than the same stroke dark-on-light, so a 1.5px
   line drawn for a parchment page arrives on Obsidian looking scratched
   and faint. Every book emblem, every set icon and every badge on this
   site is a 1.5px line drawing, which is why the report says "on multiple
   pages".

   The stroke width itself cannot be reached: the emblems are `<symbol>`s
   pulled in with `<use>`, so document CSS only crosses into them through
   INHERITED properties, and `stroke-width` is set as a presentation
   attribute on the shape. `color` does inherit — currentColor is what
   every one of them strokes with — and `filter` applies to the host
   element and therefore to everything the `<use>` renders.

   So the compensation is made where it can be:

     · the ink goes up to the palette's LIFTED accent rather than its
       text accent, which is the same move v14.0 made for every other
       gold mark on a dark ground;
     · the tile behind a badge goes from 0.12 to 0.17, so the badge is a
       shape rather than a smudge;
     · and a half-pixel drop shadow in the icon's own colour puts back
       the optical weight the dark ground takes off. Half a pixel: enough
       to read as a solid line, not enough to read as a glow.
   ========================================================================= */
[data-scheme="dark"] :is(
  .hadith-collection-icon,
  .topic-icon, .topic-card-icon,
  .quran-menu-ic, .adhkar-menu-ic,
  .lib-ic, .value-icon,
  .book-unwan-mark, .seerah-unwan-mark,
  .prayer-tool-ic, .qibla-tool-ic,
  .adhkar-pick-ic, .hadith-chapters-ic
){
  color: rgb(var(--accent-light, var(--cta-lift)));
  background-color: rgb(var(--accent-light, var(--cta-lift)) / 0.17);
}
[data-scheme="dark"] :is(
  .hadith-collection-icon,
  .topic-icon, .topic-card-icon,
  .quran-menu-ic, .adhkar-menu-ic,
  .lib-ic, .value-icon,
  .prayer-tool-ic, .qibla-tool-ic,
  .adhkar-pick-ic, .hadith-chapters-ic,
  .nav-link-icon,
  .mega-item > svg
) > svg,
[data-scheme="dark"] :is(
  .hadith-collection-icon,
  .topic-icon, .topic-card-icon,
  .adhkar-pick-ic, .hadith-chapters-ic
) svg{
  filter: drop-shadow(0 0 0.5px currentColor);
}
/* The nav's own icons and the emblems in a menu row take the lift too;
   they are the same drawings at a smaller size, where the thinning is
   worse rather than better. */


/* ---- v140-layer-90-polish.css ---- */

/* =========================================================================
   v14.0 — A LINK IN A LEDE LOOKS LIKE A LINK.  (item 17)

   The prayer page's opening line ends "Qibla direction →", and that
   phrase is an anchor to /qibla/. It was painted in the lede's own muted
   grey with no underline and no colour, so on the one page whose job is
   to send a reader to the compass, the way there read as a full stop.
   Every other link on this site is either a button or underlined; this
   one was neither.
   ========================================================================= */
.page-lede a,
.hero-sub a{
  color: rgb(var(--cta-edge));
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: rgb(var(--wash) / 0.45);
  font-weight: 600;
  transition: text-decoration-color var(--dur) var(--ease-soft),
              color var(--dur) var(--ease-soft);
}
[data-scheme="dark"] .page-lede a,
[data-scheme="dark"] .hero-sub a{ color: rgb(var(--cta)); }
@media (hover: hover){
  .page-lede a:hover,
  .hero-sub a:hover{ text-decoration-color: rgb(var(--cta)); }
}


/* ---- v141-layer-10-text.css ---- */

/* =========================================================================
   v14.1 — TEXT STOPS WRAPPING EARLY.  (item 6)

   "a big issue I am facing is that on many places of the website, the
    text starts a new line even if there is so much space on the
    right/left side, make sure it doesnt do new lines randomly like this"

   It was `overflow-wrap: anywhere`, in nine places.

   `anywhere` and `break-word` break a too-long word identically. They
   differ in ONE way, and it is not visible until the element is inside a
   flex or grid container: `anywhere` is allowed to affect INTRINSIC
   SIZING, so the element's min-content width becomes a single character.
   A flex item whose min-content is one character can be squeezed to
   almost nothing by anything else in the row — and the text inside it
   then wraps after two or three words with half the row empty beside it.

   Measured on /tafsir/ at 375px before this change:
   `.tafsir-book-author` — an Arabic author's name — was laid out over
   THREE lines, each using 53% of the width it had been given.

   `break-word` breaks the same words in the same places and leaves
   intrinsic sizing alone, so the parent reserves the width the text
   actually wants. All nine were changed at source; this block is the
   rule for anything written later.
   ========================================================================= */
:where(p, h1, h2, h3, h4, h5, li, dd, dt, figcaption, blockquote, .card, [class*="-title"], [class*="-name"], [class*="-note"], [class*="-desc"]){
  overflow-wrap: break-word;
}
/* Never `anywhere` on this site. If a string genuinely has to be broken
   mid-character — a URL in running text — say so on that element. */
.pp-break-anywhere{ overflow-wrap: anywhere; }

/* A text child of a flex or grid row keeps its own natural width as its
   minimum instead of collapsing to one character. Declared for the
   families this site actually builds rows out of, not as a blanket. */
.adhkar-card-body,
.adhkar-panel-id,
.prayer-location,
.quran-surah-names {
  min-width: 0;
}


/* =========================================================================
   THE SQUARE BOX ROUND EVERY SEARCH FIELD IS THE PLATFORM'S.  (item 17)

   "there is an ugly squary bar around many search bars, COMPLETELY
    remove it"

   It is not a border this site draws. `<input type="search">` with
   `appearance: auto` is rendered by the browser with the operating
   system's own field decoration — on Blink a square-cornered inset rect,
   drawn INSIDE whatever pill the site has put round it. That is why it
   reads as a second, differently-shaped box: it IS a different box, and
   it belongs to Windows, not to the page.

   `appearance: none` on every text-like field, everywhere, plus the two
   WebKit pseudo-elements that survive it — the magnifier and the round
   grey clear button, both of which this site draws itself in its own
   hand where it wants them.

   The focus ring is NOT removed with it: a field that cannot show focus
   is an accessibility failure, so one is drawn here in the palette's own
   colour, on the element the site actually styles as the field.
   ========================================================================= */
input[type="search"],
input[type="text"],
input[type="email"],
input[type="number"],
input[type="tel"],
input[type="url"],
input[type="password"],
textarea{
  appearance: none;
  -webkit-appearance: none;
  background-clip: padding-box;
}
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-results-button,
input[type="search"]::-webkit-search-results-decoration{
  -webkit-appearance: none;
  appearance: none;
  display: none;
}
/* Chrome draws its own clear "✕" inside a search field on some builds
   even with the decoration off; the site has its own clear button. */
input[type="search"]::-webkit-textfield-decoration-container{ padding: 0; }

/* A field that sits inside a wrapper the site already draws must not draw
   a second one. The wrapper keeps the border, the ground and the ring;
   the input is only the text. */
:is(.adhkar-find, .pp-picker-search, .sirah-book-search, .sirah-book-filter,
    .tafsir-jump-form, .pp-cmd-field, .lib-search, .hadith-search) input{
  border: 0;
  box-shadow: none;
  background: transparent;
  outline: none;
}
/* …and the wrapper is what shows focus, so focus is never lost. */
:is(.adhkar-find, .pp-picker-search, .sirah-book-search, .sirah-book-filter,
    .tafsir-jump-form, .pp-cmd-field, .lib-search, .hadith-search):focus-within{
  border-color: rgb(var(--wash) / 0.55);
  box-shadow: 0 0 0 3px rgb(var(--cta) / 0.16);
}
/* A bare field with no wrapper draws its own ring, in the same language. */
input:not(:is(.adhkar-find, .pp-picker-search, .sirah-book-search, .sirah-book-filter,
              .tafsir-jump-form, .pp-cmd-field, .lib-search, .hadith-search) input):focus-visible,
textarea:focus-visible{
  outline: 2px solid rgb(var(--cta) / 0.7);
  outline-offset: 1px;
}


/* ---- v141-layer-20-adhkar.css ---- */

/* =========================================================================
   v14.1 — THE ADHKĀR ARE SET AT THE SIZE THE QURʾAN IS.  (item 4)

   "you made the Arabic absolutely massive, and before tiny! choose a
    reasonable size in Arabic, also make sure its visually similar to the
    qur'an text size (not only by size, visually too)"

   v14.0 took the duʿāʾ line to clamp(1.5rem … 2.05rem) — which at a wide
   window is 2.05rem against the Qurʾan reader's own 1.7rem. The adhkār
   were being set a fifth LARGER than the Qurʾan, on the same site.

   "not only by size, visually too" is the harder half, and it is already
   solved in this file: every Arabic face here carries a `size-adjust` on
   its @font-face, measured so that one `font-size` produces one apparent
   size in all of them. Scheherazade at 1.7rem and the Ḥafṣ glyph face at
   1.7rem are the same height of ink. So the two only have to be given
   the same NUMBER — and the safest way to give two things the same number
   is not to write it twice.

   The duʿāʾ line is therefore sized from the Qurʾan reader's own token.
   If that ever changes, this changes with it, and the two can never drift
   apart again.
   ========================================================================= */
.adhkar-card-ar{
  font-size: calc(var(--quran-font-size, 1.7rem) * 0.96 * var(--adhkar-fs, 1));
  line-height: 2.15;
  margin-bottom: var(--sp-4);
}
/* An ayah inside a dhikr is the Qurʾan, so it is set at the Qurʾan's size
   exactly — no 0.96. The duʿāʾ sits a hair under it on purpose: they are
   not the same kind of speech and the page should not say they are. */
.adhkar-ayah-ar{
  font-size: calc(var(--quran-font-size, 1.7rem) * var(--adhkar-fs, 1));
  line-height: 2.15;
}
.adhkar-card-tr{
  font-size: calc(0.98rem * var(--adhkar-fs, 1));
  line-height: 1.85;
  margin-bottom: var(--sp-3);
}
.adhkar-card-en{
  font-size: calc(1.02rem * var(--adhkar-fs, 1));
  line-height: 1.8;
  margin-bottom: var(--sp-3);
}
.adhkar-ayah-en{
  font-size: calc(1rem * var(--adhkar-fs, 1));
  line-height: 1.8;
}
@media (max-width: 520px){
  .adhkar-card-ar{
    font-size: calc(var(--quran-font-size-mobile, 1.6rem) * 0.96 * var(--adhkar-fs, 1));
    line-height: 2.05;
  }
  .adhkar-ayah-ar{
    font-size: calc(var(--quran-font-size-mobile, 1.6rem) * var(--adhkar-fs, 1));
    line-height: 2.05;
  }
  .adhkar-card-tr{ font-size: calc(0.94rem * var(--adhkar-fs, 1)); line-height: 1.8; }
  .adhkar-card-en{ font-size: calc(0.98rem * var(--adhkar-fs, 1)); line-height: 1.75; }
  .adhkar-ayah-en{ font-size: calc(0.96rem * var(--adhkar-fs, 1)); }
}


/* =========================================================================
   THE PANEL HEAD STOPS REPEATING THE BAR ABOVE IT.  (item 3)

   "you did not minimize & clean the adhkar page right after landing
    area!! where it says (Evening / from ʿAṣr until ʿIshāʾ / The window
    runs from after ʿAṣr into the night; before sunset is best…)"

   See the note in page-tasbih.php for what was removed and why. What is
   left is one row: the progress bar, the count, the single line of
   guidance, and the way to start again. It is a caption under the bar,
   not a second header — so it is set at caption weight and the rule under
   it is the only thing separating it from the first dhikr.
   ========================================================================= */
.adhkar-panel-head{
  margin-bottom: var(--sp-5);
  border-bottom: 1px solid var(--hairline-faint);
}
.adhkar-panel.is-untracked .adhkar-panel-head{
  padding: 0;
  margin-bottom: var(--sp-4);
  border-bottom: 0;
}
.adhkar-progress{
  flex-direction: column;
  width: 100%;
}
.adhkar-progress-row{
  display: flex; align-items: baseline; gap: var(--sp-3);
  flex-wrap: wrap;
}
.adhkar-panel-note{
  flex: 1 1 14rem;
  min-width: 0;
  margin: 0;
  max-width: 62ch;
  font-family: var(--font-ui);
  font-size: 0.82rem;
  line-height: 1.55;
  color: rgb(var(--text-muted));
}
/* On an untracked set there is no progress row for the line to sit in, so
   it stands on its own with room round it. */
.adhkar-reset{ margin-inline-start: auto; }

@media (max-width: 520px){
  .adhkar-progress-row{ gap: var(--sp-2) var(--sp-3); }
  .adhkar-panel-note{ flex-basis: 100%; order: 3; font-size: 0.8rem; }
  .adhkar-reset{ margin-inline-start: auto; }
}


/* =========================================================================
   THE ʿUNWĀN OPENS ON THE AYAH AGAIN.  (item 3)

   "also the direct landing on adhkar was nice from before, with the
    Ayah! and clean and organized, also make its design much more
    beautiful"

   It is an inscription, not a caption: the Qurʾanic face on a ground of
   its own inside the headpiece, held between two hairlines, with the
   meaning under it at reading size and the reference struck small
   beneath. The panel is narrower than the card it sits in, which is what
   makes it read as set INTO the page rather than laid on top of it.
   ========================================================================= */
.adhkar-unwan-ayah .adhkar-hero-ayah{
  margin: 0 0 var(--sp-3);
  font-family: var(--font-quran-glyphs), var(--font-quran);
  font-size: clamp(1.25rem, 0.95rem + 1.3vw, 1.62rem);
  line-height: 2.25;
  color: rgb(var(--heading));
  text-align: center;
}
.adhkar-unwan-ayah .adhkar-hero-en{
  margin: 0 0 var(--sp-2);
  font-family: var(--font-display);
  font-size: 0.98rem;
  line-height: 1.7;
  color: rgb(var(--text));
  text-align: center;
  max-width: 44ch;
  margin-inline: auto;
}
.adhkar-unwan-ayah .adhkar-hero-ref{
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgb(var(--gilt-edge));
  text-align: center;
}
[data-scheme="dark"] .adhkar-unwan-ayah .adhkar-hero-ref{ color: rgb(var(--cta)); }
/* The count line follows the ayah rather than preceding it. */
.adhkar-unwan .adhkar-unwan-desc{ margin-top: var(--sp-4); }

@media (max-width: 520px){
  .adhkar-unwan-ayah{
    margin-top: var(--sp-4);
    padding: var(--sp-4) var(--sp-3) var(--sp-3);
  }
  .adhkar-unwan-ayah .adhkar-hero-en{ font-size: 0.94rem; }
}


/* ---- v141-layer-30-chrome.css ---- */

/* =========================================================================
   v14.1 — THE LAST FOUR PIXELS.  (item 10)

   "the secondary headers or bars are NOT fully connected to the upper
    headers!!! there are clear visible gaps"

   Measured, at the top of /tafsir/{book}/{surah}/{ayah}/, at both 375px
   and 1440px: the header's bottom edge at 68.80, the tafsīr bar's top at
   73.00. A gap of 4.2 pixels — and it was not the weld that was wrong.

   v14.0 fixed how a welded bar behaves once it is STUCK: `top` is
   instantaneous, the retreat is a transform, and the stuck position is
   `--header-h - 1px`, which tucks a pixel under the header. All of that
   is right and none of it applies at scroll zero, because a sticky
   element that has not reached its threshold is simply in normal flow —
   and the flow put it 4px lower, because

       .site-main{ padding-top: calc(var(--header-h-static) + 4px); }

   Four pixels of breathing space, which is right for every page whose
   first element is a heading and wrong for the one kind of element that
   is supposed to be touching the header. So it lands on a reader at the
   top of the page, which is where every reader starts, and closes the
   moment they scroll — which is exactly why it kept being reported and
   kept looking fixed.

   The gap is a named number now, and a bar that welds itself to the
   header cancels it exactly. Scoped to a bar that LEADS the page, so a
   bar further down never pulls itself over what is above it.
   ========================================================================= */
:root{ --main-gap: 4px; }
.site-main{ padding-top: calc(var(--header-h-static) + var(--main-gap)); }

/* `:first-child` on the BAR, not on its wrapper: .site-main's first child
   is an empty zero-height <span>, so `.site-main > :first-child` never
   matched the room the bar lives in. A welded bar is always the first
   thing inside whatever holds it — that is what makes it the page's top
   bar — so this is the honest test, and a bar further down the page still
   cannot pull itself over what is above it. */
.tafsir-bar:first-child,
.pp-welded:first-child{
  margin-top: calc(var(--main-gap) * -1);
}

/* The same at the other end of the weld: a bar's own top hairline must
   not draw a line where the header's bottom hairline already is. */
.tafsir-bar,
.pp-welded{ border-top: 0; }


/* =========================================================================
   THE LOGO TURNS AGAIN.  (item 5)

   "the nice logo movement is now gone, when I place my mouse on the logo
    (top left) the nice old movement of the logo doesnt happen, now it
    became a weird twitch"

   A twitch is an animation with no duration. The mark has turned 45° on
   hover since v3 —

       .logo-mark{ transition: transform 0.5s var(--ease); }
       .logo:hover .logo-mark{ transform: rotate(45deg); }

   — and a later layer added a filter transition to the same element:

       .logo-mark{ transition: filter var(--dur) var(--ease-soft); }

   `transition` is a shorthand. Declaring it a second time REPLACES the
   first, so the mark kept the rotation and lost the half second it was
   supposed to take: it now snapped to 45° in one frame and snapped back
   in one frame. That is the twitch, and it is the same shorthand trap
   that cost this stylesheet the header's padding once before.

   Both properties, in one declaration, at the speed the turn was drawn
   for. A shamsa turning an eighth of a revolution should take long
   enough to be seen doing it.
   ========================================================================= */
.logo-mark{
  transition:
    transform 0.5s cubic-bezier(0.22, 1, 0.36, 1),
    filter var(--dur) var(--ease-soft);
}
.logo:focus-visible .logo-mark{ transform: rotate(45deg); }
@media (hover: hover){ .logo:hover .logo-mark{ transform: rotate(45deg); } }
@media (prefers-reduced-motion: reduce){
  .logo-mark{ transition: filter var(--dur) var(--ease-soft); }
  @media (hover: hover){ .logo:hover .logo-mark{ transform: none; } }
}


/* =========================================================================
   THE TOAST STOPS SITTING ON THE CONTROLS.  (item 12)

   "fix the notifications (Inside the app messages like continue from
    where you left etc) overlapping the arrow"

   The resume toast is `position: fixed; left: 16px; right: 16px;
   bottom: 16px; z-index: 130` — which is the same corner the back-to-top
   arrow and the Aa button occupy, at z-index 90 and 91. A full-width bar
   at 130 covers both of them completely.

   An announcement does not get to cover a control. The toast stands ABOVE
   the floating stack instead: one arrow's height plus its gap, so the two
   read as a column in the corner rather than as one thing buried under
   another. On a wide screen it keeps its 440px measure and simply sits
   clear of them.

   How often it may appear at all is decided in assets/main.js — twelve
   hours, in localStorage, so relaunching the app is not a way to reset
   the clock. See ppToastDue().
   ========================================================================= */
/* On a page that has neither control there is nothing to clear, so the
   toast sits where a toast belongs. */


/* ---- v141-layer-40-button.css ---- */

/* =========================================================================
   v14.1 — THE BUTTON IS MADE OF METAL AGAIN, AND IT SHINES.  (item 1)

   "which applies to buttons also, and btw massively upgrade buttons, they
    are too bad, and weird texture, make them very very shiny and glowy
    also!"

   v14.0 moved the button's ground OFF the gold because gold on gold paper
   could not be separated — paper 255/245/222, metal 230/178/96, the same
   hue two steps apart. That was true, and it is no longer the situation:
   Saffron's ink is LAPIS now, so there is a colour on the page that can
   outline a gold field and seat it. The button he has asked for since
   v12.3 is finally drawable, and it is drawn here.

   WHAT MAKES IT LOOK LIKE POLISHED METAL, and every one of these is a
   property of light rather than a texture:

     1. THE RAMP IS THE MEASURED LADDER. On a metal palette --cta-lift,
        --cta, --cta-deep and --cta-edge are the palette's own gilt stops
        (tools/gen_palettes.py, _cta_ladder) — a near-white crown, a
        saturated 22-carat body, a deep foot. Mixing a gold with white
        produces a grey-gold; a real metal's highlight is WARMER than its
        body. That is why this is a measured ladder and not a tint.

     2. A SPECULAR CROWN. One soft radial highlight, centred above the
        button and falling off before the middle. This is the single
        thing that separates polished metal from paint — and it is NOT
        the swept band that was rejected in v13.2: it does not move, it
        has no edge, and it is symmetrical about the centre, which is
        what a light source overhead actually does.

     3. TWO GLOWS, NOT ONE. A tight, dark seat directly under the button
        so it sits ON the page, and a wide saturated bloom in the
        button's own colour so the page catches its light. Gloss is
        light that leaves the object; a single drop shadow can only ever
        say "raised".

     4. AN INK RING. --cta-ring is the accent on a metal palette and the
        gilt edge on a coloured one, so a gold field is outlined in lapis
        and a coloured field is outlined in gold. That is rule 2 of
        CLAUDE-NOTES §10 read in both directions, and it is what stops
        the gold button dissolving into the gold paper.

   STILL NOT PRESENT, all rejected by name in earlier releases: an inset
   white-top/dark-bottom bevel (v13.2), a sheen that sweeps across the
   face (v13.2), a flat fill with a white label (v12.4), a black ground
   (v12.5).
   ========================================================================= */

.btn-primary,
.subscribe-form button[type="submit"],
.pp-gold,
.qibla-camera-cta{
  border-color: rgb(var(--cta-ring) / 0.55);
  background-image:
    /* (2) the specular crown — soft, centred, gone by 60% */
    radial-gradient(120% 88% at 50% -26%,
      rgb(255 255 255 / 0.62) 0%,
      rgb(255 255 255 / 0.20) 34%,
      rgb(255 255 255 / 0) 62%),
    /* (1) the measured ladder */
    linear-gradient(180deg,
      rgb(var(--cta-lift)) 0%,
      rgb(var(--cta))      36%,
      rgb(var(--cta))      70%,
      rgb(var(--cta-deep)) 100%);
  box-shadow:
    /* (3a) the seat */
    0 1px 2px rgb(var(--shadow) / 0.34),
    0 2px 6px -2px rgb(var(--shadow) / 0.24),
    /* (3b) the bloom */
    0 10px 26px -10px rgb(var(--cta) / 0.75),
    0 18px 44px -22px rgb(var(--cta) / 0.55);
  transition:
    transform 180ms var(--ease-out-expo),
    box-shadow 240ms var(--ease-out-expo),
    border-color 220ms linear,
    filter 200ms linear;
}

@media (hover: hover){
  .btn-primary:hover,
  .subscribe-form button[type="submit"]:hover,
  .pp-gold:hover,
  .qibla-camera-cta:hover{
    transform: translateY(-1px);
    border-color: rgb(var(--cta-ring) / 0.72);
    /* Brighter, not different: the same ladder lifted, so the object does
       not change material when the pointer arrives. */
    filter: brightness(1.045) saturate(1.04);
    box-shadow:
      0 2px 3px rgb(var(--shadow) / 0.34),
      0 3px 8px -2px rgb(var(--shadow) / 0.26),
      0 16px 34px -12px rgb(var(--cta) / 0.85),
      0 26px 60px -26px rgb(var(--cta) / 0.6);
  }
}
.btn-primary:active,
.subscribe-form button[type="submit"]:active,
.pp-gold:active,
.qibla-camera-cta:active{
  transform: translateY(0);
  filter: brightness(0.975);
  box-shadow:
    0 1px 2px rgb(var(--shadow) / 0.38),
    0 6px 16px -8px rgb(var(--cta) / 0.6);
}
.btn-primary:focus-visible,
.subscribe-form button[type="submit"]:focus-visible,
.pp-gold:focus-visible,
.qibla-camera-cta:focus-visible{
  outline: 2px solid rgb(var(--cta-ring));
  outline-offset: 3px;
}

/* A dark palette's page cannot catch a bloom the way paper does — there
   is nothing under it to light up — so the bloom is tightened and the
   seat does the work instead. Without this the button wears a halo. */
[data-scheme="dark"] :is(.btn-primary, .subscribe-form button[type="submit"], .pp-gold, .qibla-camera-cta){
  box-shadow:
    0 1px 2px rgb(0 0 0 / 0.5),
    0 10px 24px -12px rgb(var(--cta) / 0.5);
}
@media (hover: hover){
  [data-scheme="dark"] :is(.btn-primary, .subscribe-form button[type="submit"], .pp-gold, .qibla-camera-cta):hover{
    box-shadow:
      0 2px 4px rgb(0 0 0 / 0.5),
      0 16px 34px -14px rgb(var(--cta) / 0.62);
  }
}

@media (prefers-reduced-motion: reduce){
  .btn-primary, .subscribe-form button[type="submit"], .pp-gold, .qibla-camera-cta{
    transition: none;
  }
  @media (hover: hover){
    .btn-primary:hover,
    .subscribe-form button[type="submit"]:hover,
    .pp-gold:hover,
    .qibla-camera-cta:hover{ transform: none; }
  }
}

/* The secondary button follows the ring, so the pair read as one family:
   an outlined field where the primary is a filled one. */
.btn-ghost,
.btn-secondary{
  border-color: rgb(var(--cta-ring) / 0.34);
}
@media (hover: hover){
  .btn-ghost:hover,
  .btn-secondary:hover{
    border-color: rgb(var(--cta-ring) / 0.6);
    background: rgb(var(--wash) / 0.09);
  }
}


/* ---- v141-layer-60-tafsir-menu.css ---- */

/* =========================================================================
   v14.1 — THE TAFSĪR MENU SHOWS THE WHOLE NAME.  (item 16)

   "tafsir menu from header is quite ugly and doesnt show full text, and
    has a bar on the top which is too long, very ugly"

   Both faults were introduced by v14.0's own fix for item 27. That one
   was right about the cause — the Arabic was not a grid item, so every
   row carried an empty 100px column — and it over-corrected in two ways:

     · THE GUTTER WAS FIXED AT 7.4em and the Arabic inside it was set
       `nowrap / ellipsis`. 7.4em is wide enough for تفسير الجلالين and
       not for الجامع لأحكام القرآن, so the longest and most recognisable
       titles are exactly the ones that were cut. An Arabic book title is
       never ellipsised on this site (see v14.0 layer 70) and this was the
       one place still doing it.

     · THE HEAD is a full-width bar carrying "Tafsīr · 32 commentaries" on
       the left and "All books" on the right, at the panel's own width.
       On a 580px panel that is a 580px rule above eight 40px rows: the
       heaviest thing in the menu is the label of the menu.

   The gutter sizes to its content now, up to a ceiling, so every title is
   whole; and the head is a quiet line rather than a bar.
   ========================================================================= */
/* The rule between the two columns followed the old fixed gutter, so it
   would now fall in the wrong place. The row is the shape; it does not
   need a line drawn down it. */

/* The head: a label, not a bar. No border, no ground, and the escape
   hatch beside it rather than pushed to the far edge. */


/* ---- v141-layer-70-shamail.css ---- */

/* =========================================================================
   v14.1 — A CHAPTER YOU HAVE READ IS NOT GREYED OUT.  (item 20)

   "when I open a page in شمائل المحمدية it greys out later (the box
    outside) which is not nice"

   It is the read mark. Opening a chapter records it, and on the contents
   the row it belongs to was then set back — the English at 0.62 opacity
   and a wash over the whole link. So the effect a reader sees is exactly
   as described: they read a chapter, come back, and the box for it has
   gone grey. Having read something is not a reason for it to look faded.

   v14.0 already removed the tick from these rows for the same reason
   ("the weird tick icon showing on some pages (I dont want that)"). This
   is the other half of it: nothing about a read chapter is subtracted.
   What is added instead is a short gold rule at its leading edge — the
   mark an illuminator makes beside a line already recited, positive and
   quiet, and it cannot be mistaken for the row being disabled.
   ========================================================================= */
.sirah-book-toc-item.is-read .sirah-book-toc-en{ opacity: 1; }
.sirah-book-toc-item.is-read .sirah-book-toc-link{ background: none; }
.sirah-book-toc-item.is-read .sirah-book-toc-link{ position: relative; }
.sirah-book-toc-item.is-read .sirah-book-toc-link::after{
  content: '';
  position: absolute;
  inset-inline-start: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 1.6em;
  border-radius: 0 2px 2px 0;
  background: linear-gradient(180deg, rgb(var(--gilt-hi)), rgb(var(--gilt-deep)));
}


/* =========================================================================
   THE CHAPTER OPENS ON THE CHAPTER.  (item 18)

   "in شمائل المحمدية as a book page so many design errors, some boxes too
    cluttered, some sticking to each other, etc etc!!"

   Measured at 375px: the bāb card is 470px tall — the whole of the first
   screen — before a single narration. It carries a 74px roundel, the bāb
   in Arabic at three lines, the English title, a count and a lozenge,
   with 40px of padding round all of it. Every one of those is worth
   having and not at that size on a phone; the card is a frontispiece for
   a chapter, not for a book.

   And the trail above it ("Home · Hadith · Shamāʾil al-Muḥammadiyya · As
   a book · chapter 1") runs to three lines at this width, which is more
   text about where you are than the chapter's own title.
   ========================================================================= */
@media (max-width: 640px){
  .sirah-book-bab{
    padding: var(--sp-5) var(--sp-4) var(--sp-4);
    margin-bottom: var(--sp-5);
  }
  .sirah-book-bab .sirah-book-chapter-n,
  .sirah-book-bab .book-unwan-mark{
    width: 46px; height: 46px;
    margin-bottom: var(--sp-3);
    font-size: 0.94rem;
  }
  .sirah-book-bab .sirah-book-chapter-ar{
    font-size: clamp(1.24rem, 0.96rem + 1.2vw, 1.5rem);
    line-height: 1.95;
  }
  .sirah-book-bab .sirah-book-chapter-en{ font-size: 1.02rem; }
  /* The trail keeps the two ends that orient a reader and drops the
     middle, which is the page they are already on. */
  .sirah-book-page .breadcrumbs-inner > *:nth-child(n+5):nth-last-child(n+2){ display: none; }
}

/* Narrations were separated by margin alone, so at the point where one
   ends in a short line and the next begins with a long one they read as
   one block. A hairline between them, and the room it needs on both
   sides. */
.sirah-book-hadith + .sirah-book-hadith{
  margin-top: var(--sp-6);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--hairline-faint);
}
@media (max-width: 640px){
  .sirah-book-hadith + .sirah-book-hadith{
    margin-top: var(--sp-5);
    padding-top: var(--sp-5);
  }
}


/* ---- v141-layer-80-chapters.css ---- */

/* =========================================================================
   v14.1 — SEVERAL CHAPTERS.  (item 19)

   "allow to browse all other hadith books as a book, to view all ahadith
    in a chapter for example or choose mutliple chapters conveinetly and
    in a clean minimal way"

   The chapter MENU beside this is how one chapter is chosen and it is
   already the right control for that. This is the other half: a run of
   them, which no menu of ninety-seven checkboxes would ever be a clean
   way to ask for.

   It is drawn as a footnote to the chapter bar rather than as a second
   control of equal weight — a quiet label, a short field carrying its own
   notation, a verb, and the range it accepts. The reader who wants one
   chapter never has to notice it.
   ========================================================================= */
.hadith-span{
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 10px;
  margin-top: 8px;
  padding: 9px 13px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--hairline-faint);
  background: rgb(var(--bg-alt) / 0.5);
}
.hadith-span-label{
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.hadith-span input{
  width: 8.5em;
  min-width: 0;
  padding: 6px 10px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline-strong);
  background: rgb(var(--surface));
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: rgb(var(--heading));
}
.hadith-span input::placeholder{ color: rgb(var(--text-muted)); opacity: 0.8; }
.hadith-span input:focus-visible{
  outline: none;
  border-color: rgb(var(--wash) / 0.6);
  box-shadow: 0 0 0 3px rgb(var(--cta) / 0.14);
}
.hadith-span-go{
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid rgb(var(--wash) / 0.4);
  background: rgb(var(--wash) / 0.1);
  color: rgb(var(--cta-edge));
  font-family: var(--font-ui);
  font-size: 0.76rem;
  font-weight: 600;
  cursor: pointer;
}
@media (hover: hover){ .hadith-span-go:hover{ background: rgb(var(--wash) / 0.18); } }
[data-scheme="dark"] .hadith-span-go{ color: rgb(var(--cta)); }
.hadith-span-hint{
  margin-inline-start: auto;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  color: rgb(var(--text-muted));
}
@media (max-width: 520px){
  .hadith-span{ padding: 8px 11px; }
  .hadith-span-hint{ margin-inline-start: 0; flex-basis: 100%; }
}


/* ---- v141-layer-90-picker.css ---- */

/* =========================================================================
   v14.1 — THE CHAPTER LIST IS A LIST OF CHAPTERS.

   "chapters were too crammed up and not organized & clean"

   Ninety-seven rows, each an English name with an Arabic one under it and
   nothing else — no number, no count, no rule between them, the same
   weight from the first to the last. At that length a list stops being
   readable and becomes a wall, and the eye has nothing to count by.

   What it needed was not more space but STRUCTURE, and the structure was
   already in the data and being thrown away (see rowsFor() in
   assets/ui.js). Three columns: the chapter's number struck on a quiet
   roundel, its name in both scripts, and how many narrations are in it.
   A reader can now find the seventh chapter by looking for a seven — and
   can read a number off a row to type into the "read several" field,
   which was impossible before.

   The rest is air: a hairline between rows, the group headings set back
   to a quiet rule rather than a full-width band, and the sticky heading
   given the ground it needs not to collide with what scrolls under it.
   ========================================================================= */
.pp-picker-row{
  gap: 12px;
  padding: 9px 14px;
  align-items: center;
}
.pp-picker-list .pp-picker-row + .pp-picker-row{
  border-top: 1px solid var(--hairline-faint);
}

/* The number. Round, quiet, and the same hand the Names and the Shamāʾil
   number their leaves in, so one device counts everywhere on this site. */
.pp-picker-row-badge{
  order: -1;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  min-width: 1.7rem;
  height: 1.7rem;
  padding: 0 6px;
  border-radius: 999px;
  background: rgb(var(--gilt) / 0.13);
  border: 1px solid rgb(var(--gilt-edge) / 0.22);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  line-height: 1;
  color: rgb(var(--gilt-edge));
}
[data-scheme="dark"] .pp-picker-row-badge{ color: rgb(var(--gilt)); }
/* The badge sits beside the whole row, not inside the title line. */
.pp-picker-row-title-line{
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.pp-picker-row{ display: flex; }
.pp-picker-row-main{ flex: 1 1 auto; min-width: 0; }
.pp-picker-row-title{ min-width: 0; overflow-wrap: break-word; }
/* 1.55, not the 1.8 running Arabic needs: this is a NAME in a list, it
   carries no ḥarakāt (pp_ar_plain strips them for menus), and at 1.8 a
   ninety-seven-row list is three thousand pixels of leading. */
.pp-picker-row-sub{
  display: block;
  margin-top: 0;
  line-height: 1.55;
  color: rgb(var(--text-muted));
}

/* How many narrations. A figure, set as a figure. */
.pp-picker-row-aside{
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 0.64rem;
  letter-spacing: 0.04em;
  color: rgb(var(--text-muted));
  font-variant-numeric: tabular-nums;
}

/* The group heading: a rule with a word on it, not a band. */
/* v14.2 - NOT STICKY, AND NOT A GRADIENT.
   "when scrolling down through menus for e.g. adhkar and others, there
    are weird light yellow lines covering some text and not properly
    implemented"
   That is this rule. A sticky heading whose ground is a gradient fading
   to TRANSPARENT leaves a pale band travelling down the list with the
   rows showing faintly through it — which is what a half-opaque strip
   sitting over moving text looks like. A heading in a list of ninety-
   seven is a divider, not a pinned label: it scrolls with what it
   introduces, and it has no ground at all. */
.pp-picker-group-label{
  position: static;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 14px 6px;
  background: none;
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.pp-picker-group-label::after{
  content: '';
  flex: 1 1 auto;
  height: 1px;
  background: var(--hairline-faint);
}
.pp-picker-group + .pp-picker-group{ margin-top: 2px; }

/* The search field inside a sheet takes the quiet ring, not the loud one
   the page's own fields use — it is already inside a focused surface. */
.pp-picker-search:focus-within{
  border-color: rgb(var(--wash) / 0.45);
  box-shadow: 0 0 0 2px rgb(var(--cta) / 0.1);
}


/* ---- v141-layer-95-hadith-shelf.css ---- */

/* =========================================================================
   v14.1 — THE HADITH LANDING IS A SHELF.

   "make the hadith landing extremely elegant, premium, and beautiful!"

   It was thirteen identical cream cards in a three-across grid, each a
   centred column of emblem, Arabic name, English name, a sentence of
   blurb and a count. Nothing on a card distinguished it from the card
   beside it except the words, and the emblem — the one thing per book
   that IS unique, drawn per collection in inc/emblems.php — was the
   smallest element on it.

   THIRTEEN BOOKS ON A SHELF, then, and the drawing follows the four rules
   in CLAUDE-NOTES §10:

     · A GILT SPINE down the leading edge of every card, so the row reads
       as bound volumes standing together rather than as tiles.
     · THE EMBLEM IS THE SUBJECT. It doubles in size and moves onto the
       spine's head, in the metal, which is where a binder stamps a
       device.
     · THE ARABIC TITLE LEADS, at display weight over a double rule —
       the ʿunwān this site draws on every other book page — with the
       English under it as the translation it is.
     · THE BLURB IS A FOOTNOTE, not a paragraph: one line, quiet, and it
       stops competing with the two names above it.
     · AND THE CARD LIFTS ON A GILT-TINTED SHADOW rather than changing
       colour, so thirteen of them read as one shelf and not as thirteen
       states.

   The SIX major collections are given the wider cards, because they are
   what a reader has come for; the forties and the adab sit two-up beside
   them. That is the shape of the library, not a decoration on it.
   ========================================================================= */
.hadith-grid{
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr));
  gap: 14px;
}
.hadith-collection-card{
  position: relative;
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  gap: 8px;
  padding: calc(var(--sp-5) + 2px) var(--sp-5) var(--sp-4);
  text-align: start;
  border-radius: var(--radius);
  border: 1px solid rgb(var(--gilt-edge) / 0.2);
  background:
    radial-gradient(120% 76% at 50% 0%, rgb(var(--gilt) / 0.08), transparent 58%),
    rgb(var(--surface));
  box-shadow: 0 1px 2px rgb(var(--shadow) / 0.05);
  overflow: hidden;
  transition:
    transform var(--dur) var(--spring),
    box-shadow var(--dur) var(--ease-soft),
    border-color var(--dur) var(--ease-soft);
}
/* v14.1 - NO SPINE.
   "the left golden bar is quite ugly! make the design much nicer for
    them!"
   A 7px gilt bar down the edge of thirteen cards is thirteen vertical
   stripes in a grid, and at that weight the brightest thing on the page
   is a decoration rather than a book. What replaces it is the device this
   site opens every ʿunwān with: a fine rule across the CROWN of the card
   that fades out at both ends, so the card reads as a leaf with a ruled
   head rather than as a tile with a tab. It is one pixel tall at its
   centre and nothing at its corners. */
.hadith-collection-card::before{
  content: '';
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 2px;
  background: linear-gradient(90deg,
    rgb(var(--gilt) / 0) 0%,
    rgb(var(--gilt)) 26%,
    rgb(var(--gilt-hi)) 50%,
    rgb(var(--gilt)) 74%,
    rgb(var(--gilt) / 0) 100%);
  opacity: 0.85;
}
@media (hover: hover){
  .hadith-collection-card:hover::before{ opacity: 1; }
  .hadith-collection-card:hover{
    transform: translateY(-3px);
    border-color: rgb(var(--gilt-edge) / 0.42);
    box-shadow: 0 20px 42px -22px rgb(var(--gilt-edge) / 0.5),
                0 2px 6px -2px rgb(var(--shadow) / 0.18);
  }
}

/* The emblem, at the size a stamped device is. */
.hadith-collection-icon{
  width: 46px; height: 46px;
  margin: 0 0 var(--sp-2);
  display: grid; place-items: center;
  border-radius: 12px;
  background: rgb(var(--gilt) / 0.14);
  border: 1px solid rgb(var(--gilt-edge) / 0.22);
  color: rgb(var(--gilt-edge));
}
[data-scheme="dark"] .hadith-collection-icon{ color: rgb(var(--gilt)); }
.hadith-collection-icon svg{ width: 26px; height: 26px; }

/* The Arabic title leads, over the double rule. */
.hadith-collection-arabic{
  display: block;
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight-strong);
  font-size: 1.34rem;
  line-height: 1.9;
  color: rgb(var(--heading));
  /* v14.2 - "in hadith book names keep arabic from right not left! and
     leave Eng". v14.1 pinned it left to line up with the English column;
     he reads the Arabic first and wants it where Arabic starts. So the
     card is bilingual in the honest way: the Arabic name runs from the
     right, the English from the left, and the gold rule under them is
     what ties the two together. */
  direction: rtl;
  text-align: right;
  padding-bottom: 7px;
  border-bottom: 1px solid rgb(var(--gilt-edge) / 0.3);
  box-shadow: 0 3px 0 -2px rgb(var(--gilt) / 0.45);
}
.hadith-collection-card h3{
  margin: 6px 0 0;
  font-family: var(--font-display);
  font-size: 1.04rem;
  font-weight: 600;
  line-height: 1.35;
  color: rgb(var(--heading-soft));
}
.hadith-collection-card p{
  margin: 2px 0 0;
  font-family: var(--font-ui);
  font-size: 0.82rem;
  line-height: 1.55;
  color: rgb(var(--text-muted));
}
.hadith-collection-card .topic-count{
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--hairline-faint);
  display: flex; align-items: center; gap: 7px;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.04em;
  color: rgb(var(--text-muted));
}
.hadith-collection-card .topic-count svg{
  width: 13px; height: 13px;
  margin-inline-start: auto;
  fill: none; stroke: currentColor; stroke-width: 2;
  color: rgb(var(--cta));
  transition: transform var(--dur) var(--ease-out-expo);
}
@media (hover: hover){ .hadith-collection-card:hover .topic-count svg{ transform: translateX(3px); } }

@media (prefers-reduced-motion: reduce){
  .hadith-collection-card{ transition: none; }
  @media (hover: hover){ .hadith-collection-card:hover{ transform: none; } }
}

@media (max-width: 640px){
  .hadith-grid{ gap: 10px; }
  .hadith-collection-card{
    padding: calc(var(--sp-4) + 2px) var(--sp-4) var(--sp-3);
  }
  .hadith-collection-icon{ width: 40px; height: 40px; }
  .hadith-collection-icon svg{ width: 23px; height: 23px; }
  .hadith-collection-arabic{ font-size: 1.22rem; }
}


/* ---- v142-layer-10-ayah-size.css ---- */

/* =========================================================================
   v14.2 — AN AYAH IS THE SIZE OF THE SENTENCE IT IS IN.  (item: tafsīr)

   "in many tafasir, the ayah font size is not standard, and often the
    ayah is too small or too big to the tafsir text, this is completely
    unacceptable!"

   Measured on /tafsir/qurtubi/2/255/ at 1100px, before this:

       .tafsir-body                20.16px   PP Naskh
       .tafsir-body p.arabic-text  24.19px   PP Naskh      ×1.20
       .qa-ayah-glyph              22.98px   Hafs Smart    ×1.14

   Three sizes in one paragraph, and both multipliers were compensations
   for something that is no longer true:

   1. `.arabic-text` is the class assets/main.js puts on a paragraph of a
      POST that turns out to be Arabic, and it steps the size up because
      an Arabic paragraph in an English article needs it. A tafsīr body is
      Arabic from end to end and its size is already decided by the
      breakpoint and by --tafsir-fs. Applying the step there is a second
      multiplication of a number that was already right.

   2. `.qa-ayah-glyph` carried `font-size: 1.12em` with a comment
      explaining that the Ḥafṣ glyphs "sit on a smaller optical body than
      Scheherazade at the same declared size". That was true and it is the
      exact thing v14.0 fixed AT THE FONT, by adding `size-adjust: 118%`
      to that @font-face. The 1.12 became a second correction on top of a
      correction — 1.18 × 1.12 — which is why the ayah now reads too big.

   So both multipliers go, and what is left is ONE deliberate step: an
   ayah is set 6% up from the prose, which is enough to read as a
   quotation and not enough to read as a different size of type.

   THE ONE REAL COMPENSATION THAT STAYS. `PP Uthmani` genuinely renders
   smaller than `PP Naskh` at the same declared size — measured, same
   word, same size: 261px against 305px, so 0.856. A Unicode ayah set in
   it therefore takes 1.17em to sit on the prose's optical line. The glyph
   face does not need one, because `size-adjust` already gave it one.
   ========================================================================= */

/* (1) the prose is the size the room set. */
.tafsir-body .arabic-text,
.qa-tafsir-body .arabic-text{ font-size: 1em; }

/* (2) one step, for the quotation. */
.tafsir-body .qa-tafsir-ayah,
.qa-tafsir-body .qa-tafsir-ayah,
.qa-tafsir-ayah{ font-size: 1.06em; }

/* (3) the glyph face is already normalised at the @font-face. */
.qa-ayah-glyph{ font-size: 1em; line-height: 1; }

/* (4) …and the Unicode muṣḥaf face is not. 1.17 is 1 / 0.856, measured. */
.qa-tafsir-ayah.is-plain,
.tafsir-body .qa-tafsir-ayah.is-plain,
.qa-tafsir-body .qa-tafsir-ayah.is-plain{ font-size: 1.17em; }

/* The brackets are the edition's punctuation and follow the ayah. */
.qa-ayah-brk{ font-size: 0.92em; }


/* ---- v142-layer-20-chrome.css ---- */

/* =========================================================================
   v14.2 — NO BOX INSIDE A SEARCH BAR.

   "when I press search qur'an bar in the quran page there must not be
    that ugly box inside the search bar"

   v14.1 removed the platform's own field decoration everywhere
   (`appearance: none`) and, because a field that cannot show focus is an
   accessibility failure, drew a ring instead — on the WRAPPER for the
   search bars it knew about, and on the input itself for everything else.

   The Qurʾan page's search was not on that list. So its input drew a 2px
   ring INSIDE the pill the page had already drawn: a box inside a box,
   visible only while it is focused, which is exactly "when I press".

   The list is gone. A field that sits inside anything named like a field
   — search, find, box, field — hands its ring to that wrapper, whatever
   the component is called and whoever writes it next.
   ========================================================================= */
:is([class*="search"], [class*="find"], [class*="-field"], [class*="-box"]) > input,
:is([class*="search"], [class*="find"], [class*="-field"], [class*="-box"]) input[type="search"],
:is([class*="search"], [class*="find"], [class*="-field"], [class*="-box"]) input[type="text"]{
  outline: none !important;
  box-shadow: none;
  border: 0;
  background: transparent;
}
:is(.adhkar-find, .pp-picker-search, .quran-search-box, .sirah-book-search,
    .sirah-book-filter, .tafsir-jump-form, .pp-cmd-field, .lib-search,
    .hadith-search, .hadith-toolbar-field):focus-within{
  border-color: rgb(var(--wash) / 0.5);
  box-shadow: 0 0 0 3px rgb(var(--cta) / 0.13);
}


/* =========================================================================
   THE NAV SITS ON THE PAGE'S CENTRE.

   "also make the header slightly towards the right for PC, so that it can
    be more centered and easily navigatable (the text header)"

   The bar is three tracks — logo, nav, actions — and the nav is centred
   BETWEEN them rather than on the page, because the actions row (~319px)
   is half as wide again as the logo lockup (~211px). So the nav's centre
   sits about 54px left of the window's, which is what reads as off.

   Half the difference, as a nudge that scales with the window and stops
   at the width where the nav leaves the bar anyway.
   ========================================================================= */


/* =========================================================================
   MENUS ON A DARK PALETTE ARE LIT, NOT GREY.

   "on obsidian some menus are grey and weirdly greyed out, make it shiny
    & beautiful & vibrant & lively & attractive EVERYWHERE!!!"

   `--menu-bg` is the palette's surface and `--menu-sheen` is a wash of
   the accent at 5.5%. On a light palette the surface is nearly white, so
   5.5% of gold over it is clearly visible and the panel reads as lifted.
   On Obsidian the surface is 30/29/25 — nearly black — and 5.5% of gold
   over near-black is about two levels of grey. The rule was written for
   the light palettes and does nothing on the dark ones, which is why they
   look flat.

   A dark panel needs THREE things a light one does not: a ground lifted
   off the page rather than equal to it, a sheen strong enough to survive
   on a dark ground, and a lit top edge — because on dark the eye reads an
   edge catching light as "raised", where on light it reads a shadow.
   ========================================================================= */
[data-scheme="dark"]{
  /* Lifted off the page: the surface plus a little of the metal, so a
     panel is a different material from what is behind it. */
  --menu-bg: rgb(var(--surface));
  --menu-sheen: linear-gradient(
    180deg,
    rgb(var(--gilt) / 0.10) 0%,
    rgb(var(--gilt) / 0.035) 38%,
    rgb(var(--gilt) / 0.012) 72%,
    rgb(var(--gilt) / 0) 100%
  );
  --menu-border: rgb(var(--gilt-edge) / 0.34);
}
[data-scheme="dark"] :is(.site-header .mega-panel, .theme-panel, .pp-picker-sheet,
    .pp-tasbih-pop, .qa-bar-inner, .pp-aa-pop){
  border-color: var(--menu-border);
  /* The lit edge. One inset hairline of the metal along the top, which is
     what a raised surface looks like when the light is above it. */
  box-shadow:
    inset 0 1px 0 rgb(var(--gilt) / 0.16),
    var(--e-overlay, 0 22px 60px -24px rgb(0 0 0 / 0.7));
}
/* The rows inside them stop being grey-on-grey: a hover that can be seen,
   and a selected row that is clearly the metal. */
@media (hover: hover){
  [data-scheme="dark"] :is(.mega-item, .hadith-menu-row, .pp-picker-row,
      .adhkar-menu-row, .quran-menu-resume):hover{
    background: rgb(var(--gilt) / 0.09);
  }
}
[data-scheme="dark"] .pp-picker-row.is-selected,
[data-scheme="dark"] .pp-picker-row[aria-selected="true"]{
  background: rgb(var(--wash) / 0.15);
  box-shadow: inset 2px 0 0 rgb(var(--cta));
}
[data-scheme="dark"] .pp-picker-group-label{ color: rgb(var(--gilt) / 0.75); }


/* =========================================================================
   THE WHOLE TOPIC BOX IS THE LINK.

   "keep it so that when I press the box of the topic on phone that it
    opens it, same on PC pls"

   Both components already ARE one anchor round everything — verified at
   375px and 1200px. What was missing is any sign that a press landed: on
   a phone v14.1 removed the platform's tap highlight from the whole site,
   and a card whose only feedback was a `:hover` gives a touch reader
   nothing back. So a tap that DID work looked like a tap that did not.

   Nothing inside either card can swallow a pointer, and both answer a
   press within a frame.
   ========================================================================= */
.topic-card > *,
.topic-tile > *,
.topic-tile-inner > *{ pointer-events: none; }
.topic-card, .topic-tile{ -webkit-tap-highlight-color: transparent; }
@media (hover: none){
  .topic-card:active, .topic-tile:active{
    background: rgb(var(--wash) / 0.07);
    transition: background 80ms linear;
  }
}


/* ---- v142-layer-40-menus.css ---- */

/* =========================================================================
   v14.2 — "All books" IS A DOOR, NOT A FOOTNOTE.

   "and all books is a bit too small maybe some people miss it, yet dont
    make it too big"

   It was 0.62rem in the muted ink — the same size as the panel's own
   kicker, which is a LABEL and not something to press. The one link in
   the panel that leaves it should not be the smallest thing in it.

   Up two steps, in the action colour, with the chevron every other "go
   somewhere" control on this site carries. Still a quiet line; now an
   obviously pressable one.
   ========================================================================= */


/* =========================================================================
   THE ADHKĀR ʿUNWĀN'S AYAH IS AN INSCRIPTION, NOT A BOX.

   "the ayah being in the yellow box is a very weird design, fix it
    please (in adhkar)"

   v14.1 set it on its own tinted ground inside the headpiece, so the
   card had a second card in it and the ayah looked pasted on. An
   inscription is not a box: it is text held between two rules, with the
   ground of the page behind it. That is how this site already sets the
   ʿunwān's own divider, and it is what the ayah should have been.
   ========================================================================= */
.adhkar-unwan-ayah{
  max-width: 44rem;
  margin: var(--sp-5) auto var(--sp-2);
  padding: var(--sp-4) 0 var(--sp-3);
  background: none;
  border-radius: 0;
  border-block: 0;
  position: relative;
}
/* One fine gilt rule above and one below, each fading at both ends —
   the same drawing as the divider on every other ʿunwān here. */
.adhkar-unwan-ayah::before,
.adhkar-unwan-ayah::after{
  content: '';
  position: absolute;
  left: 12%;
  right: 12%;
  height: 1px;
  background: linear-gradient(90deg,
    rgb(var(--gilt) / 0) 0%,
    rgb(var(--gilt-edge) / 0.45) 24%,
    rgb(var(--gilt-edge) / 0.45) 76%,
    rgb(var(--gilt) / 0) 100%);
}
.adhkar-unwan-ayah::before{ top: 0; }
.adhkar-unwan-ayah::after{ bottom: 0; }

/* ---- v142-layer-50-tafsir-shelf.css ---- */

/* =========================================================================
   v14.2 — THE TAFSIR SHELF, WITHOUT THE GOLD BAR.

   "further beautify the designs of the boxes in tafsir page (of the
    books), they are very ugly to be frank!"

   The cards carried a 14px SOLID GOLD BAR down their leading edge with
   the century set vertically inside it. That is the same device that was
   already rejected once, on the hadith landing:

       "the left golden bar is quite ugly! make the design much nicer
        for them!"

   Thirty-six of them in a grid is thirty-six vertical stripes, and the
   brightest thing on the page ends up being a decoration rather than a
   book. It was fixed on the hadith shelf in v14.1 and never carried
   across to this one, which is why the same complaint arrived twice.

   So this layer brings the two shelves into one language — the reader
   should not be able to tell which page they are on from the card:

     · NO SPINE. A fine gilt rule across the CROWN of the card instead,
       two pixels at its centre and nothing at its corners, which is the
       device every ʿunwān on this site already opens with.
     · THE CENTURY STAYS HIDDEN. It was switched off in an earlier layer
       for a good reason that still holds — "a single Arabic-Indic digit
       turned sideways reads as a smudge" — and the book's full year is
       already in the foot of the card. Moving it out of the spine would
       have printed the same fact twice.
     · THE CREST IS A STAMPED DEVICE, at the size and in the frame the
       hadith shelf gives its emblem, so a commentary and a collection
       are drawn by the same hand.
     · And the card lifts on the same gilt-tinted shadow.
   ========================================================================= */

/* The spine is retired. §14.7: the layer that stops using an element has
   to switch it OFF, not merely stop styling it — otherwise it survives as
   an invisible box with a background. */

/* The card no longer reserves a gutter for a bar it does not have. */

/* The crown rule — the same one the hadith shelf wears. */

/* The crest, framed as a stamped device. */


/* ---- v142-layer-60-inline-arabic.css ---- */

/* =========================================================================
   v14.2 — AN ARABIC PHRASE INSIDE AN ENGLISH SENTENCE.

   "on phone on posts its not Hafs!!"

   Measured on the live site, on a phone: <em>اليوم أكملت لكم دينكم</em>
   — Qurʾan 5:3 — was rendering in Newsreader, the English serif, running
   left-to-right at 17.44px. See the long note in assets/main.js for why
   nothing reached it.

   main.js now marks those fragments .arabic-inline. This sets them.

   THE SIZE IS THE PROBLEM WORTH NAMING. An Arabic face at the English
   body size reads small: the letterforms carry their weight below the
   baseline and the English x-height is not the Arabic one. Every Arabic
   face here is already normalised with size-adjust (CLAUDE-NOTES §7), so
   the remaining difference is the optical one, and 1.06em covers it
   without the fragment standing off the line it belongs to.
   ========================================================================= */
.arabic-inline{
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: 1.06em;
  line-height: inherit;
  direction: rtl;
  unicode-bidi: isolate;
}

/* An ayah quoted mid-sentence keeps the muṣḥaf's hand — main.js adds
   .quran-text only when the fragment says it is an ayah. The isolate
   matters more here than anywhere: a bidi run that leaks takes the
   English punctuation round it to the wrong end of the line. */
.arabic-inline.quran-text,
.arabic-inline.quran-text--inline{
  font-family: var(--font-quran) !important;
  font-size: 1.1em;
}

/* ---- v142-layer-70-menu-life.css ---- */

/* =========================================================================
   v14.2 — THE MENUS, LIT.

   "on obsidian some menus are grey and weirdly greyed out, make it shiny
    & beautiful & vibrant & lively & attractive EVERYWHERE!!!"

   Measured before changing anything, on obsidian:

     · The drawer's section labels — "Read", "Your reading" — were
       --text-muted at 0.75 opacity and 11px, which comes out at 4.24:1
       against the panel. That is below AA, and "greyed out" is exactly
       what 4.24:1 looks like.
     · Every menu row hovered to rgb(var(--accent) / 0.09). Nine per cent
       of anything on a near-black ground is almost nothing, so the menus
       had no life in them at all — the row you were pointing at looked
       the same as the twenty you were not.

   So: the labels become GOLD rather than grey, which is both legible and
   the right colour for a heading on this site; and the row you are
   pointing at is unmistakably the row you are pointing at.

   The restraint: only the hovered row lights up. A menu where every row
   glows is a menu where nothing stands out, which is the fault this is
   fixing in the other direction.
   ========================================================================= */

/* ---- the section labels ------------------------------------------------ */

/* ---- the row you are pointing at --------------------------------------- */

/* The emblem beside a row is the one thing per row that is its own, so it
   takes the metal when the row is live. */

/* ---- the panel itself --------------------------------------------------- */
/* A single soft fall of light from the top edge, so the panel reads as a
   lit surface rather than a grey slab. Painted on a pseudo-element so it
   cannot tint the text sitting on it.

   NO `position: relative` HERE. The first draft of this layer set it, to
   give the ::after something to position against — and .mega-panel is
   `position: absolute` (line ~1230), so that put every dropdown back into
   the header's flow. Each nav item then became as wide as its open panel,
   the <ul> measured 3,480px inside a 1,360px header, and "About" was
   pushed off the end of the bar. An absolutely positioned element is
   ALREADY a containing block for its own pseudo-elements; there was
   nothing to fix. Caught by measuring the header, not by looking at it. */

/* ---- v142-layer-80-qibla-step3.css ---- */

/* =========================================================================
   v14.2 — QIBLA, STEP 3: WHICH WAY TO FACE.

   "in qibla page be very clear for step 3, and very very very accurate!!
    its super confusing on what to face and what not"

   The numbers were right all along; the writing was the problem. See the
   note in page-qibla.php. This sets the three steps that replaced the one
   ambiguous sentence, and gives the instruction on each time the weight of
   an instruction — it is the thing the reader came for, so it is the thing
   that should be legible from arm's length.
   ========================================================================= */

/* The answer to "which way do I face" is the loudest thing in the list. */


/* ---- v142-layer-90-header-centre.css ---- */

/* =========================================================================
   v14.2 — THE NAV SITS ON THE CENTRE OF THE PAGE.

   "also make the header slightly towards the right for PC, so that it can
    be more centered and easily navigatable (the text header)"

   MEASURED FIRST, at 1440px: the page's centre is 715 and the nav ran
   373..963, centred on 668 — forty-seven pixels to its left. The cause is
   that the two flanks are not the same size. The mark and wordmark on the
   left are 245px; the actions on the right — six icon buttons and
   Subscribe — are 388px. The nav sits in the space between them, and the
   middle of that space is not the middle of the page.

   THE FIRST ATTEMPT AT THIS DID NOT WORK, and the reason is worth keeping:
   giving both flanks `flex: 1 1 0` should make them equal, but the actions
   cannot shrink below their own content, so they kept 388px and the logo
   took what was left. It moved the nav by nine pixels.

   The nav also could not simply be pushed right: it already ended 16px
   from the actions. There was nowhere to go. So the actions give back the
   difference — a slightly tighter cluster, 34px buttons instead of 38 and
   4px gaps instead of 8 — and the nav is then centred on the PAGE rather
   than on the gap, by taking it out of the flex flow entirely.

   Only from 1360px up. Below that the flanks and a centred nav collide
   (measured: 12px of overlap at 1280), and the row keeps its ordinary
   layout, which is correct and simply not centred.

   Measured after, at 1366/1440/1536/1600/1920/2560: the nav's centre is
   the page's centre exactly at every one, with 129-149px clear on the left
   and 21-25px on the right.
   ========================================================================= */

/* ---- v142-layer-95-writings-and-others.css ---- */

/* =========================================================================
   v14.2 — THE WRITINGS GRID, AND THE OTHER COMMENTARIES.

   "also further beautify the images in (Latest Writings) and make them
    more beautiful! (genuinely!) (same for The same ayah, in another
    commentary)"

   WHAT WAS ACTUALLY WRONG WITH THE WRITINGS CARD. The cover art itself is
   good — inc/cover-art.php draws a different illuminated panel per post,
   eight compositions, seeded so neighbours never match. The card around
   it was doing nothing for it:

     · 140px tall, so a drawn panel with a medallion in it had no room to
       be a picture;
     · no mount at all — the art ran to the card's edge and stopped;
     · and the one flourish it had, `.article-cover img { scale(1.06) }`
       on hover, addressed an IMG. pp_post_cover_art() returns an <svg>.
       The rule had never once fired.

   So the panel is now MOUNTED, the way an illuminated leaf is: a gilt
   hairline round the art, a crown rule across the head of the card — the
   same one the hadith and tafsir shelves wear, so the three read as one
   library — and the art itself lifts very slightly under the pointer.

   The other commentaries get the same mount for the same reason: they are
   a shelf of books and were drawn as a row of plain chips.
   ========================================================================= */

/* ---- Latest Writings ---------------------------------------------------- */
/* The crown rule, as on every other shelf in this theme. */

/* The panel gets a mount.

   NO HEIGHT HERE. `.article-cover.has-cover-art` sets `height: auto` with
   `aspect-ratio: 400 / 150` (see the note at that rule), so the whole
   illuminated panel is shown uncropped and the shamsa stays centred. A
   fixed height here would be dead code fighting a deliberate decision —
   it was written, measured at 130px against the 172px asked for, and
   removed. The mount is margin, edge and shadow only; the art keeps its
   own proportions. */
/* THE SVG, not an img — see the note above. */


/* ---- The same ayah, in another commentary -------------------------------- */
/* The one you are reading is named in the metal rather than merely dimmed. */


/* ---- v143-layer-00-speed.css ---- */

/* =========================================================================
   v14.3 — SPEED.

   "the website is very laggy" · "the theme switch transition is ugly and
    not very smooth & laggy"

   Measured before touching anything, at a phone's CPU speed (Chrome, 4x
   throttle, 390px): switching palette froze the page for 450-1000ms on an
   ordinary page and 1300-2000ms on al-Baqarah, before any animation could
   start. Almost none of that was selector matching. It was the browser
   restyling EVERY element on the page — 8,000 of them on a long surah —
   because a palette is a set of custom properties on the root, and a
   change on the root reaches everything below it.

   Five causes, five answers, all in this layer or in assets/main.js:

   1. OFF-SCREEN CONTENT IS NOT STYLED. `content-visibility: auto` on the
      long repeated blocks (ayat, narrations, adhkār, commentary passages,
      post cards, the footer) tells the browser to skip layout, paint AND
      style for whatever is not on screen. Al-Baqarah's switch went from
      1,547ms to 178ms with nothing else changed. `contain-intrinsic-size:
      auto` keeps the scrollbar honest: each block reserves a typical
      height until it has been drawn once, and its real height after.

   2. THE HEADER NEVER CHANGES HEIGHT, and --header-h is written only when
      it changes. Both used to happen on the first pixel of every scroll.

   3. THE BARS UNDER THE HEADER MOVE BY TRANSFORM. `--header-live` — a
      custom property swapped on the root each time the header hid — is
      gone, and with it a whole-page restyle per hide.

   4. THE PAPER GRAIN IS NO LONGER BLENDED. A fixed, full-screen layer with
      `mix-blend-mode: multiply` has to be re-composited against everything
      that scrolls under it, on every frame of every scroll. The same grain
      is now drawn as translucent specks, which the GPU simply lays on top.

   5. CHANGING APPEARANCE IS ONE CROSS-FADE. See applyTheme().

   On a phone the header and the bars welded to it are also opaque rather
   than frosted: a live blur over a scrolling commentary is re-computed
   every frame, and at 88% opacity nobody can see the difference.
   ========================================================================= */

/* ---- 1. Off-screen content is skipped ---------------------------------- */
.quran-ayah{ content-visibility: auto; contain-intrinsic-size: auto 200px; }
.hadith-card{ content-visibility: auto; contain-intrinsic-size: auto 300px; }
.adhkar-card{ content-visibility: auto; contain-intrinsic-size: auto 560px; }
.tafsir-more-ayah{ content-visibility: auto; contain-intrinsic-size: auto 1400px; }
.article-card{ content-visibility: auto; contain-intrinsic-size: auto 400px; }
.site-footer{ content-visibility: auto; contain-intrinsic-size: auto 900px; }
@media print{
  .quran-ayah, .hadith-card, .adhkar-card, .tafsir-more-ayah,
  .article-card, .site-footer{ content-visibility: visible; }
}

/* ---- 3. Bars welded under the header ----------------------------------- */
.pp-welded,
.tafsir-bar{
  --welded-top: calc(var(--header-h) - 1px);
  top: var(--welded-top);
  transition: transform 0.3s var(--ease);
}
html.pp-header-hidden .pp-welded,
html.pp-header-hidden .tafsir-bar{
  transform: translateY(calc(var(--welded-top) * -1));
}
/* The two sticky bars that stop a short distance BELOW the header. */
.book-runner,
.prayer-month-row-head{ transition: transform 0.3s var(--ease); }
html.pp-header-hidden .book-runner,
html.pp-header-hidden .prayer-month-row-head{
  transform: translateY(calc(var(--header-h) * -1));
}
@media (prefers-reduced-motion: reduce){
  .pp-welded, .tafsir-bar, .book-runner, .prayer-month-row-head{ transition: none; }
}

/* ---- 4. The grain, without blending ------------------------------------ */
/* Light palettes: black at alpha 5% x (1 - noise), which is arithmetically
   the same pixel `multiply` at 5% produced. Dark palettes: white specks,
   about 2%, in place of `soft-light` at 16%. */
.grain-overlay{
  mix-blend-mode: normal;
  opacity: 1;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.05 0 0 0 0.05'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
html[data-scheme="dark"] .grain-overlay{
  mix-blend-mode: normal;
  opacity: 1;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0.06 0 0 0 -0.01'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---- 5. Changing appearance -------------------------------------------- */
@media (prefers-reduced-motion: no-preference){
  html.pp-theme-vt::view-transition-old(root),
  html.pp-theme-vt::view-transition-new(root){
    animation-duration: 280ms;
    animation-timing-function: cubic-bezier(.4, 0, .2, 1);
  }
}

/* ---- Phones: opaque chrome --------------------------------------------- */
@media (max-width: 760px){
  .site-header::before,
  .tafsir-bar,
  .pp-welded,
  .book-runner{
    background: rgb(var(--surface));
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}


/* ---- v143-layer-10-header.css ---- */

/* =========================================================================
   v14.3 — THE HEADER, ITS MENUS AND THE DRAWER.

   The whole description, in one place. The 417 rules it replaces had
   accumulated across the base and twenty-two later layers — a hover
   background from one, a gradient and an inset ring from another, an icon
   recoloured to pale gold by a third — and they were the cause of

     "when I hover the mouse over some things like some menu items or some
      header menu items the icons and text become weirdly coloured & greyed
      out or too contrasted or saturated"

   Those rules were deleted, not overridden. What follows is one hover
   language for everything in the bar: a soft wash of the palette's own
   tint behind the thing, the text a step darker, nothing else. Icons never
   change colour on hover; nothing moves sideways; nothing turns into a
   filled dark square.

     1. the bar
     2. the nav row (desktop)
     3. the actions
     4. a menu (desktop)
     5. a menu row
     6. the drawer (≤1180px)
     7. narrower bars
   ========================================================================= */

/* ---- 1. The bar ---------------------------------------------------------- */
.site-header{
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  border-bottom: 1px solid var(--hairline);
  -webkit-user-select: none;
  user-select: none;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.site-header::before{
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
}
.site-header.scrolled{ box-shadow: var(--e2); }
.site-header.hide-on-scroll{ transform: translateY(-100%); }
@media print{ .site-header, .overlay{ display: none !important; } }

.site-header .header-inner{
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: 1360px;
  padding-top: 14px;
  padding-bottom: 14px;
}
.site-header .logo{ flex: 0 1 auto; min-width: 0; }

/* ---- 2. The nav row (desktop) ------------------------------------------- */
/* "keep the header texts a bit on the left towards the prophetic profit
    logo on top left, but not super close" — the nav follows the logo at a
    measured distance instead of floating in the middle of the bar, and the
    actions take the right-hand end. */
.site-header .main-nav{ margin-inline-start: clamp(20px, 2.8vw, 46px); }
.site-header .main-nav > ul{
  display: flex;
  align-items: center;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.site-header .main-nav > ul > li{
  position: relative;
  display: flex;
  align-items: center;
  border-radius: var(--radius-pill);
  transition: background-color var(--dur) var(--ease-soft);
}
.site-header .nav-link{
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 12px;
  border: 0;
  border-radius: var(--radius-pill);
  background: none;
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: -0.006em;
  color: rgb(var(--heading-soft));
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: color var(--dur) var(--ease-soft), background-color var(--dur) var(--ease-soft);
}
.site-header .has-dropdown > .nav-link{ padding-inline-end: 3px; }
.site-header .nav-caret-btn{
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 34px;
  margin-inline-end: 5px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: none;
  color: rgb(var(--heading-soft));
  cursor: pointer;
  transition: color var(--dur) var(--ease-soft);
}
.site-header .nav-caret{
  width: 11px;
  height: 11px;
  opacity: 0.55;
  pointer-events: none;
  transition: transform 0.25s var(--ease), opacity var(--dur) var(--ease-soft);
}
.site-header .has-dropdown.open .nav-caret{ transform: rotate(180deg); opacity: 0.9; }

/* The current section. */
.site-header .nav-link.is-current,
.site-header .nav-link[aria-current="page"],
.site-header .main-nav > ul > li.is-current-item > .nav-link{
  color: rgb(var(--accent-ui));
  font-weight: 600;
}
.site-header .main-nav > ul > li.is-current-item > .nav-caret-btn{ color: rgb(var(--accent-ui)); }

.site-header .main-nav > ul > li.nav-mobile-only,
.site-header .main-nav > ul > li.nav-phone-only{ display: none; }
.site-header .menu-toggle{ display: none; }

@media (min-width: 1181px){
  .site-header .main-nav > ul > li.is-current-item,
  .site-header .main-nav > ul > li:has(> .nav-link.is-current),
  .site-header .main-nav > ul > li:has(> .nav-link[aria-current="page"]){
    background: rgb(var(--wash) / 0.1);
  }
  .site-header .main-nav > ul > li.open{ background: rgb(var(--wash) / 0.1); }
}
@media (min-width: 1181px) and (hover: hover){
  .site-header .main-nav > ul > li:hover{ background: rgb(var(--wash) / 0.1); }
  .site-header .main-nav > ul > li:hover > .nav-link,
  .site-header .main-nav > ul > li:hover > .nav-caret-btn{ color: rgb(var(--heading)); }
  .site-header .main-nav > ul > li.is-current-item:hover > .nav-link{ color: rgb(var(--accent-ui)); }
  .site-header .has-dropdown:hover .nav-caret{ transform: rotate(180deg); opacity: 0.9; }
}
.site-header .nav-link:focus-visible,
.site-header .nav-caret-btn:focus-visible{
  outline: 2px solid rgb(var(--accent-ui));
  outline-offset: 1px;
}

/* ---- 3. The actions ------------------------------------------------------ */
.site-header .header-actions{
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 6px;
  margin-inline-start: auto;
}
.site-header .header-actions > *{ flex-shrink: 0; }
.site-header .icon-btn{
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-sm);
  background: transparent;
  color: rgb(var(--heading-soft));
  cursor: pointer;
  transition: background-color var(--dur) var(--ease-soft),
              border-color var(--dur) var(--ease-soft),
              color var(--dur) var(--ease-soft),
              transform var(--dur-fast) var(--ease-soft);
}
.site-header .icon-btn svg{ width: 17px; height: 17px; }
.site-header .icon-btn:active{ transform: scale(0.95); }
.site-header .icon-btn:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }
@media (hover: hover){
  .site-header .icon-btn:hover{
    background: rgb(var(--wash) / 0.1);
    border-color: rgb(var(--wash) / 0.42);
    color: rgb(var(--heading));
  }
}
.site-header .icon-btn[aria-current="page"],
.site-header .icon-btn[aria-expanded="true"]{
  background: rgb(var(--wash) / 0.12);
  border-color: rgb(var(--wash) / 0.42);
  color: rgb(var(--accent-ui));
}
.site-header .header-actions-sep{
  width: 1px;
  height: 20px;
  margin: 0 4px;
  border-radius: 1px;
  background: var(--hairline-strong);
}
/* "make subscribe button on header a bit more to the right as its too close
    to the icons" */
.site-header .header-subscribe{ margin-inline-start: 12px; white-space: nowrap; }
.site-header .pp-install-btn.is-ready::after{
  content: "";
  position: absolute;
  top: 6px;
  right: 6px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgb(var(--accent));
  box-shadow: 0 0 0 2px rgb(var(--bg));
}
.pp-scheme-ic{ display: block; }
[data-scheme="light"] .pp-scheme-ic.is-sun,
[data-scheme="dark"] .pp-scheme-ic.is-moon{ display: none; }
[data-scheme="light"] .pp-scheme-ic.is-moon{ transform: rotate(-18deg); }
.site-header .header-actions .pp-tool-kaaba svg{ width: 18px; height: 18px; }

/* ---- 4. A menu (desktop) -----------------------------------------------
   Opaque, one hairline, one shadow. CLOSED MEANS display:none — a closed
   menu is no work for the browser at all (the four of them are most of
   the header's six hundred elements). It fades and settles in on open
   through @starting-style; where that is not supported it simply
   appears. A strip above it bridges the gap to its item, so the pointer
   can travel down without the menu closing under it. */
@media (min-width: 1181px){
  .site-header .mega-panel{
    position: absolute;
    top: calc(100% + 10px);
    left: 50%;
    z-index: 5;
    display: none;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2px;
    width: 580px;
    max-width: calc(100vw - 32px);
    padding: 8px;
    border: 1px solid var(--menu-border);
    border-radius: var(--radius-lg);
    background-color: var(--menu-bg);
    background-image: var(--menu-sheen);
    box-shadow: var(--e-overlay);
    opacity: 0;
    translate: -50% -6px;
    transition: opacity 180ms var(--ease-soft),
                translate 240ms var(--ease-out-expo),
                display 240ms allow-discrete;
  }
  .site-header .mega-panel::before{
    content: "";
    position: absolute;
    top: -6px;
    left: 50%;
    width: 12px;
    height: 12px;
    margin-left: -6px;
    transform: rotate(45deg);
    border-left: 1px solid var(--menu-border);
    border-top: 1px solid var(--menu-border);
    border-radius: 2px 0 0 0;
    background: var(--menu-bg);
  }
  .site-header .mega-panel::after{
    content: "";
    position: absolute;
    inset: -14px 0 auto 0;
    height: 14px;
  }
  .site-header .has-dropdown.open > .mega-panel{ display: grid; opacity: 1; translate: -50% 0; }
  @starting-style{
    .site-header .has-dropdown.open > .mega-panel{ opacity: 0; translate: -50% -6px; }
  }
  .site-header .quran-panel{ width: 620px; }
  .site-header .tafsir-panel{ width: 660px; }
  .site-header .hadith-panel{ width: 600px; }
  .site-header .adhkar-menu{ width: 720px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 1181px) and (hover: hover){
  .site-header .has-dropdown:hover > .mega-panel{ display: grid; opacity: 1; translate: -50% 0; }
  @starting-style{
    .site-header .has-dropdown:hover > .mega-panel{ opacity: 0; translate: -50% -6px; }
  }
}
@media (prefers-reduced-motion: reduce){
  .site-header .mega-panel{ transition: none; }
}

.mega-panel-head{
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 38px;
  padding: 4px 10px 8px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--hairline);
}
.mega-panel-head-title{
  font-family: var(--font-ui);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
  white-space: nowrap;
}
/* "the huge long bar in tafsir menu from header showing resume is too big,
    make it small please" — it is a chip in the menu's own heading now,
    beside the title, the size of the words in it. */
.mega-resume{
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  max-width: 55%;
  height: 26px;
  padding: 0 11px 0 9px;
  border: 1px solid rgb(var(--wash) / 0.3);
  border-radius: var(--radius-pill);
  background: rgb(var(--wash) / 0.09);
  font-family: var(--font-ui);
  font-size: 0.74rem;
  font-weight: 600;
  color: rgb(var(--accent-ui));
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease-soft);
}
.mega-resume svg{ flex: none; width: 13px; height: 13px; }
.mega-resume-label{ min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.mega-panel-head-all{
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-inline-start: auto;
  margin-inline-end: -4px;
  padding: 4px 8px;
  border-radius: var(--radius-pill);
  font-family: var(--font-ui);
  font-size: 0.74rem;
  font-weight: 600;
  color: rgb(var(--accent-ui));
  white-space: nowrap;
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease-soft);
}
.mega-panel-head-all::after{
  content: "\2192";
  font-size: 0.95em;
  transition: transform var(--dur) var(--ease-out-expo);
}
@media (hover: hover){
  .mega-resume:hover{ background: rgb(var(--wash) / 0.16); }
  .mega-panel-head-all:hover{ background: rgb(var(--wash) / 0.1); }
  .mega-panel-head-all:hover::after{ transform: translateX(2px); }
}

.mega-panel-foot-link{
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 4px;
  padding: 11px 12px 5px;
  border-top: 1px solid var(--hairline);
  font-family: var(--font-ui);
  font-size: 0.8rem;
  font-weight: 600;
  color: rgb(var(--text-muted));
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-soft);
}
.mega-panel-foot-ic{ flex: none; width: 15px; height: 15px; color: rgb(var(--accent-ui)); }
.mega-panel-foot-text{ min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.mega-panel-foot-go{
  flex: none;
  width: 14px;
  height: 14px;
  margin-inline-start: auto;
  opacity: 0.5;
  transition: opacity var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){
  .mega-panel-foot-link:hover{ color: rgb(var(--heading)); }
  .mega-panel-foot-link:hover .mega-panel-foot-go{ opacity: 1; transform: translateX(2px); }
}

/* "All collections" — the rest of the Hadith menu, in the same menu. */
.mega-more{ display: contents; }
.mega-more-btn{
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  margin-top: 4px;
  padding: 10px 12px 6px;
  border: 0;
  border-top: 1px solid var(--hairline);
  background: none;
  font-family: var(--font-ui);
  font-size: 0.8rem;
  font-weight: 600;
  color: rgb(var(--accent-ui));
  cursor: pointer;
}
.mega-more-btn svg{ width: 12px; height: 12px; transition: transform 0.25s var(--ease); }
.mega-more-btn .mega-more-hide{ display: none; }
.mega-more-btn[aria-expanded="true"] .mega-more-show{ display: none; }
.mega-more-btn[aria-expanded="true"] .mega-more-hide{ display: inline; }
.mega-more-btn[aria-expanded="true"] svg{ transform: rotate(180deg); }
@media (hover: hover){
  .mega-more-btn:hover{ color: rgb(var(--heading)); }
}

/* ---- 5. A menu row ------------------------------------------------------
   English on the left, its quiet second line under it, and — where the
   thing has one — its Arabic name at the right-hand end, where Arabic
   begins: "in tafsir header menu keep arabic start from the right &
   English from left on each box". The Qur'an and the Tafsīr menus are the
   same shape, as asked; the surah names are a size larger than they were.

   NOTHING ARABIC IS CLIPPED. An Arabic label is never overflow:hidden,
   and its line box is tall enough for the deepest descender in the face
   ("the name of many tafasir in Arabic is partially missing, like some
   parts of the bottom of some characters"). The English side is the one
   that gives way if a row is short of room. */
.menu-row{
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  min-height: 54px;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  color: inherit;
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease-soft);
}
.menu-row-ic{
  flex: none;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: rgb(var(--wash) / 0.12);
  color: rgb(var(--accent-ui));
}
.menu-row-ic svg{ width: 19px; height: 19px; }
.menu-row-main{
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}
.menu-row-title{
  font-family: var(--font-ui);
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.35;
  color: rgb(var(--heading));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.menu-row-sub{
  font-family: var(--font-ui);
  font-size: 0.78rem;
  line-height: 1.4;
  color: rgb(var(--text-muted));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.menu-row-sub-ar{
  overflow: visible;
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: 0.92rem;
  line-height: 1.9;
  text-align: left;
  unicode-bidi: isolate;
}
.menu-row-ar{
  flex: none;
  margin-inline-start: auto;
  padding-block: 3px;
  font-family: var(--font-arabic-display);
  font-weight: 400;
  font-size: 1.16rem;
  line-height: 1.95;
  color: rgb(var(--heading));
  white-space: nowrap;
  direction: rtl;
  unicode-bidi: isolate;
  text-align: right;
}
.menu-row-ar.is-surah{
  font-family: var(--font-surah);
  font-size: 1.42rem;
  line-height: 1.9;
}
.quran-panel .menu-row-title{ font-size: 0.97rem; }
.quran-panel .menu-row-sub{ font-size: 0.8rem; }
.tafsir-panel .menu-row-title{ font-size: 0.95rem; }
.adhkar-menu .menu-row{ gap: 11px; min-height: 58px; padding: 8px 10px; }
.adhkar-menu .menu-row-ic{ width: 30px; height: 30px; border-radius: 9px; }
.adhkar-menu .menu-row-ic svg{ width: 17px; height: 17px; }
.topics-panel .menu-row{ align-items: flex-start; }
.topics-panel .menu-row-sub{ white-space: normal; }

.menu-row.is-now{
  background: rgb(var(--wash) / 0.08);
  box-shadow: inset 2px 0 0 rgb(var(--accent) / 0.7);
}
.menu-row-now{
  display: inline-block;
  margin-inline-start: 8px;
  padding: 1px 7px 2px;
  border-radius: var(--radius-pill);
  background: rgb(var(--accent));
  color: rgb(var(--on-accent));
  font-family: var(--font-ui);
  font-size: 0.56rem;
  font-weight: 700;
  line-height: 1.5;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  vertical-align: 2px;
}
@media (hover: hover){
  .menu-row:hover{ background: rgb(var(--wash) / 0.1); }
}
.menu-row:active{ background: rgb(var(--wash) / 0.14); }
.menu-row:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: -2px; }

/* ---- 6. The drawer (≤1180px) -------------------------------------------- */
.overlay{
  position: fixed;
  inset: var(--header-h) 0 0 0;
  z-index: 96;
  background: var(--scrim);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-slow) var(--ease-soft), visibility var(--dur-slow);
}
.overlay.show{ opacity: 1; visibility: visible; }

@media (max-width: 1180px){
  .site-header .main-nav{
    position: fixed;
    top: var(--header-h);
    right: 0;
    bottom: 0;
    left: auto;
    z-index: 97;
    display: flex;
    flex-direction: column;
    width: min(88%, 380px);
    margin: 0;
    padding: 8px 16px calc(28px + env(safe-area-inset-bottom));
    padding-right: calc(16px + env(safe-area-inset-right));
    overflow-x: clip;
    overflow-y: auto;
    overscroll-behavior: contain;
    border-left: 1px solid var(--menu-border);
    border-radius: var(--radius-xl) 0 0 0;
    background-color: var(--menu-bg);
    background-image: var(--menu-sheen);
    box-shadow: var(--e-overlay);
    transform: translateX(100%);
    visibility: hidden;
    transition: transform var(--dur-slow) var(--ease-out-expo), visibility 0s linear var(--dur-slow);
  }
  .site-header .main-nav.open{
    transform: none;
    visibility: visible;
    transition: transform var(--dur-slow) var(--ease-out-expo), visibility 0s;
  }
  .site-header .main-nav > ul{
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    width: 100%;
    padding-bottom: var(--sp-4);
  }
  .site-header .main-nav > ul > li{
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    width: 100%;
    border-bottom: 1px solid var(--hairline-faint);
    border-radius: 0;
  }
  .site-header .main-nav > ul > li.nav-mobile-only{ display: flex; }
  .site-header .main-nav > ul > li.nav-group-label.nav-group-label{
    display: block;
    padding: 18px 10px 6px;
    border-bottom: 0;
    font-family: var(--font-ui);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: rgb(var(--gilt-edge));
  }
  [data-scheme="dark"] .site-header .main-nav > ul > li.nav-group-label{ color: rgb(var(--gilt)); }
  [data-scheme="dark"] .site-header .main-nav{
    box-shadow: inset 0 1px 0 rgb(var(--gilt) / 0.16), var(--e-overlay);
  }
  .site-header .main-nav > ul > li.nav-group-label:first-child{ padding-top: 8px; }
  .site-header .main-nav .nav-link{
    position: relative;
    flex: 1;
    min-width: 0;
    min-height: 52px;
    padding: 14px 10px;
    border-radius: var(--radius-sm);
    font-size: var(--fs-base);
    font-weight: 500;
    color: rgb(var(--heading));
    text-align: start;
  }
  .site-header .main-nav .has-dropdown > .nav-link{ font-weight: 600; }
  .site-header .main-nav button.nav-link{ width: 100%; }
  .site-header .nav-link-icon{ flex: none; width: 18px; height: 18px; margin-inline-end: 8px; color: rgb(var(--accent-ui)); }
  .site-header .nav-link-badge{
    margin-inline-start: auto;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    background: rgb(var(--accent));
    color: rgb(var(--on-accent));
    font-family: var(--font-ui);
    font-size: 0.66rem;
    font-weight: 700;
    line-height: 1;
  }
  .site-header .main-nav .nav-caret-btn{
    width: 52px;
    height: auto;
    min-height: 52px;
    margin: 0;
    border-left: 1px solid var(--hairline-faint);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    color: rgb(var(--heading-soft));
  }
  .site-header .main-nav .nav-caret{ width: 14px; height: 14px; }
  .site-header .main-nav .nav-link:active,
  .site-header .main-nav .nav-caret-btn:active{ background: rgb(var(--wash) / 0.1); }
  .site-header .main-nav .nav-link.is-current,
  .site-header .main-nav .nav-link[aria-current="page"],
  .site-header .main-nav > ul > li.is-current-item > .nav-link{
    padding-left: 22px;
    background: rgb(var(--wash) / 0.09);
    color: rgb(var(--accent-ui));
  }
  .site-header .main-nav .nav-link.is-current::before,
  .site-header .main-nav .nav-link[aria-current="page"]::before,
  .site-header .main-nav > ul > li.is-current-item > .nav-link::before{
    content: "";
    position: absolute;
    left: 8px;
    top: 50%;
    width: 3px;
    height: 20px;
    border-radius: 3px;
    transform: translateY(-50%);
    background: rgb(var(--accent));
  }

  /* A menu in the drawer is an accordion under its item. */
  .site-header .main-nav .mega-panel{
    position: static;
    display: none;
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
    width: 100%;
    margin: 0 0 8px 8px;
    padding: 2px 0 8px 6px;
    border: 0;
    border-left: 2px solid rgb(var(--wash) / 0.32);
    border-radius: 0;
    background: none;
    box-shadow: none;
  }
  .site-header .main-nav .has-dropdown.open > .mega-panel{ display: grid; }
  .site-header .main-nav .mega-panel-head{ display: none; }
  .site-header .main-nav .mega-panel-head:has(.mega-resume:not([hidden])){
    display: flex;
    min-height: 0;
    margin: 0;
    padding: 6px 12px 6px;
    border: 0;
  }
  .site-header .main-nav .mega-panel-head-title,
  .site-header .main-nav .mega-panel-head-all{ display: none; }
  .site-header .main-nav .mega-resume{ max-width: 100%; }
  .site-header .main-nav .menu-row{ min-height: 48px; padding: 8px 12px; }
  .site-header .main-nav .topics-panel .menu-row-sub{ display: none; }
  .site-header .main-nav .topics-panel .menu-row{ align-items: center; }
  .site-header .main-nav .menu-row-ic{ width: 32px; height: 32px; }

  .site-header .main-nav > ul > li.nav-drawer-cta{ display: block; margin-top: 22px; border-bottom: 0; }
  .site-header .nav-drawer-cta .btn{ width: 100%; justify-content: center; padding: 14px 22px; }
  .site-header .nav-only-desktop{ display: none; }

  .site-header .menu-toggle{
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 1px solid var(--hairline-strong);
    border-radius: var(--radius-sm);
    background: none;
    color: rgb(var(--heading));
    cursor: pointer;
    transition: background-color var(--dur) var(--ease-soft), border-color var(--dur) var(--ease-soft);
  }
  .site-header .menu-toggle svg{ display: none; }
  .site-header .menu-toggle::before,
  .site-header .menu-toggle::after{
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 17px;
    height: 1.9px;
    margin-left: -8.5px;
    border-radius: 2px;
    background: currentColor;
    transition: transform var(--dur) var(--ease-out-expo);
  }
  .site-header .menu-toggle::before{ transform: translateY(-4px); }
  .site-header .menu-toggle::after{ transform: translateY(4px); }
  .site-header .menu-toggle.is-open{ background: rgb(var(--wash) / 0.12); border-color: rgb(var(--wash) / 0.42); }
  .site-header .menu-toggle.is-open::before{ transform: rotate(45deg); }
  .site-header .menu-toggle.is-open::after{ transform: rotate(-45deg); }
  .site-header .header-actions .icon-btn{ width: 44px; height: 44px; }
  .site-header .logo-text .tagline{ display: none; }
  .site-header .logo{ min-height: 44px; }
}
@media (max-width: 1180px) and (hover: hover){
  .site-header .main-nav .nav-link:hover{ background: rgb(var(--wash) / 0.08); }
  .site-header .menu-toggle:hover{ background: rgb(var(--wash) / 0.1); border-color: rgb(var(--wash) / 0.42); }
}
@media (max-width: 860px){
  .site-header .main-nav > ul > li.nav-phone-only{ display: flex; }
  .site-header .main-nav > ul > li.nav-phone-only.nav-group-label{ display: block; }
}

/* ---- 7. Narrower bars ---------------------------------------------------- */
@media (max-width: 1439px){
  .site-header .logo-text .tagline{ display: none; }
}
@media (min-width: 1181px) and (max-width: 1320px){
  .site-header .main-nav{ margin-inline-start: 14px; }
  .site-header .main-nav > ul{ gap: 0; }
  .site-header .nav-link{ padding-inline: 9px; }
  .site-header .has-dropdown > .nav-link{ padding-inline-end: 2px; }
  .site-header .nav-caret-btn{ width: 18px; margin-inline-end: 3px; }
  .site-header .header-actions{ gap: 4px; }
  .site-header .icon-btn{ width: 35px; height: 35px; }
  .site-header .header-subscribe{ margin-inline-start: 8px; }
}
@media (max-width: 620px){
  .site-header .header-inner{ gap: 8px; }
  .site-header .logo{ gap: 8px; }
  .site-header .logo-mark{ width: 32px; height: 32px; }
  .site-header .logo-text .name{
    min-width: 0;
    font-size: clamp(0.98rem, 3.4vw, 1.14rem);
    white-space: nowrap;
    overflow-x: clip;
    overflow-y: visible;
    text-overflow: ellipsis;
  }
  .site-header .header-actions{ gap: 6px; }
  .site-header .header-actions .pp-install-btn,
  .site-header .header-actions .pp-tool-btn,
  .site-header .header-actions-sep{ display: none; }
  .site-header .header-actions .icon-btn svg{ width: 18px; height: 18px; }
}
@media (max-width: 430px){
  .site-header .pp-scheme-btn{ display: none; }
  .site-header .header-actions{ gap: 5px; }
  .site-header .header-inner{ padding-top: 12px; padding-bottom: 12px; }
}
@media (max-width: 353px){
  .site-header .logo-text{ display: none; }
  .site-header .logo-mark{ width: 30px; height: 30px; }
}


/* ---- v143-layer-20-post.css ---- */

/* =========================================================================
   v14.3 — A POST.

   This layer is the whole description of a post's frame. The rules it
   replaces — spread over eleven places in the base and four later layers
   — were deleted, not overridden. See single.php for the markup.

     1. the grid: one markup, two layouts
     2. the title block: topic, title, one quiet line of meta
     3. the tools: a slim row on a phone, a column on a desktop
     4. "On this page"
     5. the reading bar and the progress line
     6. focus mode
     7. Standard size — Arabic, English and the Qur'an at one size
     8. the Aa button
     9. a card is one link
   ========================================================================= */

/* ---- 1. The grid ------------------------------------------------------- */
.article-shell{ padding-top: 34px; }
.article-grid{
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "head" "rail" "main";
}
.article-header{ grid-area: head; min-width: 0; }
.article-rail{ grid-area: rail; min-width: 0; }
.article-main{ grid-area: main; min-width: 0; max-width: 720px; }

@media (min-width: 1101px){
  .article-shell{ padding-top: 52px; }
  .article-grid{
    grid-template-columns: 200px minmax(0, 720px);
    grid-template-areas: "rail head" "rail main";
    column-gap: 64px;
  }
  /* It never moves. It used to slide down when the reading bar appeared,
     by an animated `top`, which is a layout on every frame. */
  .article-rail{
    position: sticky;
    top: calc(var(--header-h) + 28px);
    align-self: start;
    z-index: 2;
  }
}

/* A post does not need a breadcrumb trail on a phone: the topic above the
   title is the way back, and it is one tap. */
@media (max-width: 760px){
  body.single-post .breadcrumbs{ display: none; }
}

.page-links{ margin-top: 24px; }
.related-section .articles-grid{ margin-top: 16px; }
.article-comments{ margin-top: 56px; }
/* A post nobody has written under yet opened its comments with two rules
   and an empty band between them — the rule over the comments and the
   rule over the form, with nothing listed in between. With no comments
   the form is the first thing there, and it takes the one rule. */
.comments-shell > .comment-form-shell:first-child{ margin-top: 0; padding-top: 0; border-top: 0; }

/* ---- 2. The title block ------------------------------------------------ */
.article-header{ margin: 0 0 24px; }
/* "the topic name on the top of the post page like "Hadith reflections""
   was a monospace pill. It is a small line of caps in the interface face,
   led by a short gilt rule. */
.post-eyebrow{
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-ui);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.4;
  color: rgb(var(--accent-ui));
  text-decoration: none;
}
.post-eyebrow::before{
  content: "";
  width: 22px;
  height: 1px;
  background: linear-gradient(90deg, rgb(var(--gilt-deep)), rgb(var(--gilt)));
}
.article-header h1{
  margin: 12px 0 0;
  font-size: clamp(2rem, 1.35rem + 2.6vw, 2.9rem);
  line-height: 1.12;
  letter-spacing: -0.012em;
  text-wrap: balance;
}
/* "the date used and read time in the top is quite ugly!! make it minimal,
   and very clean, and dont use such ugly fonts" — one line, the reading
   face's companion sans at body colour's quieter step, and a gilt point
   between the two facts instead of a gap. The author was a username
   ("propheticprofit") and is gone from it: this is a one-author site. */
.post-meta{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  margin: 14px 0 0;
  font-family: var(--font-ui);
  font-size: 0.88rem;
  line-height: 1.5;
  color: rgb(var(--text-muted));
  font-variant-numeric: lining-nums tabular-nums;
}
.post-meta-sep{
  flex: none;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: rgb(var(--gilt-deep));
}
.post-resume{
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-weight: 600;
  color: rgb(var(--accent-ui));
  cursor: pointer;
}
.post-resume svg{ width: 14px; height: 14px; margin-inline-start: -6px; }

/* ---- 3. The tools ------------------------------------------------------ */
.rail-btn{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 0;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: rgb(var(--heading-soft));
  font-family: var(--font-ui);
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
.rail-btn svg{ flex: none; }
.rail-btn .rail-count{
  font-size: 0.78rem;
  font-weight: 600;
  color: rgb(var(--text-muted));
  font-variant-numeric: tabular-nums;
}
.rail-btn .rail-count:empty{ display: none; }
.rail-btn[aria-pressed="true"],
.rail-btn.is-active,
.rail-btn.copied{ color: rgb(var(--accent-ui)); }
.rail-btn[aria-pressed="true"] svg{ fill: rgb(var(--accent-ui) / 0.18); }
.rail-btn.pulse svg{ animation: heartPulse 0.45s var(--ease); }
.rail-btn:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }
@media (hover: hover){
  .rail-btn:hover{ background: rgb(var(--wash) / 0.1); color: rgb(var(--heading)); }
}
.rail-btn:active{ background: rgb(var(--wash) / 0.14); }

/* The words over the list, and over "Read next" at the end of a post. */
.rail-toc-label{
  display: block;
  font-family: var(--font-ui);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}

/* ---- 3a. On a phone: one slim row between the title and the text ------
   "fix the top bar on posts on phone, you have to press the ugly on this
    page and you have to scroll to the right, keep it all clean & nice!"

   It was a boxed strip, sticky under the header, above the title, whose
   buttons overflowed a 360px phone and scrolled sideways behind a fade.
   Now it is a row between two hairlines that scrolls away with the page
   (the header comes back on the smallest upward scroll, and the thin gilt
   line at the top of the window shows how far you are). Five tools fit a
   360px phone at 44px each; the sixth, comments, steps aside there when
   "On this page" needs the room — the comments are at the end of the post
   either way. */
@media (max-width: 1100px){
  .article-rail{
    position: relative;
    margin: 0 0 30px;
    border-block: 1px solid rgb(var(--heading) / 0.1);
  }
  .rail-inner{
    display: flex;
    align-items: center;
    gap: 6px;
    min-height: 54px;
  }
  .rail-actions{
    display: flex;
    align-items: center;
    gap: 0;
    flex: 1 1 auto;
    min-width: 0;
    margin-inline-start: -10px;
  }
  .rail-btn{
    min-width: 44px;
    height: 44px;
    padding: 0 10px;
  }
  .rail-btn svg{ width: 20px; height: 20px; }
  .rail-btn .rail-label{ display: none; }
  .rail-toc{ flex: none; }
  .article-rail .rail-toc-label,
  .toc-body{ display: none; }
  .rail-toggle{
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 38px;
    padding: 0 12px 0 11px;
    border: 1px solid rgb(var(--wash) / 0.32);
    border-radius: var(--radius-pill);
    background: rgb(var(--wash) / 0.07);
    color: rgb(var(--heading));
    font-family: var(--font-ui);
    font-size: 0.82rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
  }
  .rail-toggle-ic{ width: 16px; height: 16px; }
  .rail-toggle-chev{ width: 13px; height: 13px; transition: transform var(--dur) var(--ease-soft); }
  .article-rail.toc-open .rail-toggle{ background: rgb(var(--wash) / 0.14); }
  .article-rail.toc-open .rail-toggle-chev{ transform: rotate(180deg); }
  .article-rail.toc-open .toc-body{
    display: block;
    position: absolute;
    inset-inline: 0;
    top: calc(100% + 8px);
    z-index: 30;
    max-height: min(60vh, 460px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 10px 18px;
    border: 1px solid var(--hairline);
    border-radius: var(--radius);
    background: rgb(var(--surface));
    box-shadow: 0 22px 46px -22px rgb(var(--shadow) / 0.5);
  }
  .toc-track{ display: none; }
}
@media (max-width: 420px){
  .article-shell:not(.has-no-toc) .rail-btn-comments{ display: none; }
}

/* ---- 3b. On a desktop: a quiet column beside the text ------------------ */
@media (min-width: 1101px){
  .rail-inner{ display: flex; flex-direction: column; gap: 26px; }
  .rail-actions{ display: flex; flex-direction: column; gap: 2px; }
  .rail-btn{
    justify-content: flex-start;
    gap: 12px;
    width: 100%;
    padding: 9px 12px;
    border-radius: 10px;
    color: rgb(var(--text-muted));
    font-size: 0.86rem;
    font-weight: 500;
    text-align: start;
  }
  .rail-btn svg{ width: 18px; height: 18px; }
  .rail-btn .rail-count{ margin-inline-start: auto; }
  .rail-toggle{ display: none; }
  .rail-toc{ display: flex; flex-direction: column; gap: 12px; }
  .rail-toc[hidden]{ display: none; }
  .toc-body{ display: flex; gap: 14px; }
  .toc-track{
    position: relative;
    flex: none;
    width: 2px;
    border-radius: 2px;
    background: rgb(var(--heading) / 0.1);
  }
  .toc-progress{
    position: absolute;
    inset: 0;
    border-radius: 2px;
    background: rgb(var(--accent));
    transform-origin: 50% 0;
    transform: scaleY(0);
  }
}

/* ---- 4. "On this page" ------------------------------------------------- */
#tocList{
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
  flex: 1;
  min-width: 0;
}
#tocList li a{
  position: relative;
  display: block;
  padding: 7px 0;
  font-family: var(--font-ui);
  font-size: 0.86rem;
  line-height: 1.4;
  color: rgb(var(--text-muted));
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-soft);
}
#tocList li.toc-level-3 a{ padding-inline-start: 14px; font-size: 0.82rem; }
#tocList li a.active{ color: rgb(var(--accent-ui)); font-weight: 600; }
@media (hover: hover){
  #tocList li a:hover{ color: rgb(var(--heading)); }
}
@media (min-width: 1101px){
  #tocList li a.active::before{
    content: "";
    position: absolute;
    left: -16px;
    top: 50%;
    width: 2px;
    height: 16px;
    border-radius: 2px;
    transform: translateY(-50%);
    background: rgb(var(--accent));
  }
}

/* ---- 5. The reading bar and the progress line ---------------------------
   "the switch between the header to the reading bar only is very weird &
    not smooth & instant, make it perfect"

   The reading bar is shown exactly while the header is away and the title
   is behind you (assets/main.js), and it arrives by the same transform, on
   the same curve, over the same 300ms, that the header leaves by. So the
   eye sees one bar change its contents, not two bars passing each other. */
.mini-bar{ display: none; }
@media (min-width: 1101px){
  .mini-bar{
    display: block;
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 99;
    background: rgb(var(--surface) / 0.9);
    -webkit-backdrop-filter: saturate(1.6) blur(16px);
    backdrop-filter: saturate(1.6) blur(16px);
    border-bottom: 1px solid var(--hairline);
    transform: translateY(-101%);
    transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
    pointer-events: none;
  }
  .mini-bar.show{
    transform: translateY(0);
    pointer-events: auto;
    box-shadow: 0 8px 22px -18px rgb(var(--shadow) / 0.55);
  }
  .mini-bar-inner{ display: flex; align-items: center; gap: 20px; height: 50px; }
  .mini-bar-title{
    max-width: 46%;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-family: var(--font-display);
    font-size: 0.98rem;
    font-weight: 600;
    color: rgb(var(--heading));
  }
  .mini-bar-track{
    flex: 1;
    height: 3px;
    border-radius: 3px;
    overflow: hidden;
    background: rgb(var(--heading) / 0.1);
  }
  .mini-bar-fill{
    height: 100%;
    background: linear-gradient(90deg, rgb(var(--gilt-deep)), rgb(var(--accent)));
    transform-origin: 0 50%;
    transform: scaleX(0);
  }
  .mini-bar-pct{
    min-width: 4ch;
    text-align: end;
    font-family: var(--font-ui);
    font-size: 0.78rem;
    font-weight: 600;
    color: rgb(var(--text-muted));
    font-variant-numeric: tabular-nums;
  }
}
@media (prefers-reduced-motion: reduce){
  .mini-bar{ transition: none; }
}

/* The thin line along the very top of the window: a phone's only progress
   mark. A desktop has the reading bar and the rail's own track. */
.reading-progress{
  position: fixed;
  inset: 0 0 auto 0;
  height: 2px;
  z-index: 260;
  pointer-events: none;
  background: linear-gradient(90deg, rgb(var(--gilt-deep)), rgb(var(--gilt)));
  transform-origin: 0 50%;
  transform: scaleX(0);
  opacity: 0;
  transition: opacity 0.2s ease;
}
.reading-progress.show{ opacity: 1; }
@media (min-width: 1101px){
  .reading-progress{ display: none; }
}

/* ---- 6. Focus mode ------------------------------------------------------ */
.zen-exit{
  position: fixed;
  top: 16px;
  inset-inline-end: 16px;
  z-index: 120;
  display: none;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border: 0;
  border-radius: var(--radius-pill);
  background: rgb(var(--ink));
  color: rgb(var(--on-ink));
  font-family: var(--font-ui);
  font-size: 0.82rem;
  font-weight: 600;
  box-shadow: 0 12px 30px -14px rgb(var(--shadow) / 0.6);
  cursor: pointer;
}
.zen-exit svg{ width: 15px; height: 15px; }
body.pp-zen .zen-exit{ display: inline-flex; }
body.pp-zen :is(.site-header, .article-rail, .site-footer, .mini-bar, .breadcrumbs,
  .article-footer-nav, .author-card, .related-section, .article-comments,
  .reading-progress, .back-top, .pp-aa){ display: none !important; }
body.pp-zen .article-shell{ padding-top: 40px; }
body.pp-zen .article-grid{
  grid-template-columns: minmax(0, 720px);
  grid-template-areas: "head" "main";
  justify-content: center;
}

/* ---- 7. Standard size ----------------------------------------------------
   "keep all text same size, Arabic, English, and Qur'an verses with the
    specific Hafs font on all devices! and make sure it actually works and
    has all visually similar size"

   With it on (the default — header.php writes the attribute before first
   paint) three things are set aside:

     · the writer's own sizes: an inline font-size, a <font size>, and
       WordPress's has-*-font-size presets — everywhere except headings;
     · the theme's own enlargement of Arabic (1.2em) and of a quoted verse
       (1.55em in a block, ~1.1em inline);
     · nothing else. The FACES are untouched: prose Arabic stays in the
       naskh, and anything recognised as the Qur'an stays in the Ḥafṣ face
       — `--font-quran`, bundled, so it is the same on every device.

   "Visually similar" is not the same number. Arabic naskh is drawn small
   on its em, and the Ḥafṣ face smaller still; the bundled @font-face rules
   already correct that with size-adjust (118% and 135%), which is what
   makes 1em of Arabic sit at the height of 1em of Newsreader. The small
   extra step on the Qur'an below was set by eye against the English on a
   phone and a desktop, in the same paragraph. */
html[data-post-even="1"] .entry-content :is(p, li, blockquote, div, span, em, strong, b, i, u, a,
  font, small, big, mark, cite, q, sup, sub, td, th, dd, dt, figcaption)[style*="font-size"],
html[data-post-even="1"] .entry-content font[size],
html[data-post-even="1"] .entry-content :is(.has-small-font-size, .has-medium-font-size,
  .has-large-font-size, .has-x-large-font-size, .has-huge-font-size):not(h1, h2, h3, h4, h5, h6){
  font-size: inherit !important;
}
html[data-post-even="1"] .entry-content :is(p, li, blockquote, div)[style*="line-height"]{
  line-height: inherit !important;
}
html[data-post-even="1"] .entry-content :lang(ar),
html[data-post-even="1"] .entry-content .arabic-text,
html[data-post-even="1"] .entry-content .arabic-inline{
  font-size: 1em;
}
html[data-post-even="1"] .entry-content :is(p, li, blockquote, div):lang(ar){ line-height: 2; }
html[data-post-even="1"] .entry-content .quran-text,
html[data-post-even="1"] .entry-content .is-style-quran-verse,
html[data-post-even="1"] .entry-content .quran-text--inline,
html[data-post-even="1"] .entry-content .arabic-inline.quran-text{
  font-size: 1.04em;
}
html[data-post-even="1"] .entry-content :is(.quran-text, .is-style-quran-verse):not(.quran-text--inline){
  line-height: 2.1;
  padding: 20px 24px;
}
.pp-aa-glyph-even{ gap: 1px; font-size: 0.74rem; }
.pp-aa-glyph-even > span[lang="ar"]{ font-family: var(--font-arabic); font-size: 1.05em; line-height: 1; }

/* ---- 8. The Aa button ----------------------------------------------------
   "sometimes when closing Aa button menu it remains opaque, and keeping it
    opaque is ugly also choose something better"

   Two things. The "stays tinted after closing" was a phone keeping the
   :hover style of the last thing tapped — a hover rule with no
   (hover: hover) guard is a sticky rule on every touchscreen. And at rest
   the button was an opaque disc with a heavy shadow sitting over the text.
   Now it is glass: the page shows through it, a hairline of the palette's
   metal draws its edge, and only while its panel is open is it filled. */
.pp-aa-btn{
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 1px solid rgb(var(--gilt-edge) / 0.3);
  background: rgb(var(--surface) / 0.62);
  -webkit-backdrop-filter: saturate(1.5) blur(12px);
  backdrop-filter: saturate(1.5) blur(12px);
  color: rgb(var(--heading));
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0;
  box-shadow: 0 8px 22px -12px rgb(var(--shadow) / 0.42);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--dur) var(--ease-soft),
              border-color var(--dur) var(--ease-soft),
              color var(--dur) var(--ease-soft),
              transform var(--dur-fast) var(--ease-soft);
}
.pp-aa.is-open .pp-aa-btn{
  background: rgb(var(--surface) / 0.94);
  border-color: rgb(var(--gilt-edge) / 0.6);
  color: rgb(var(--accent-ui));
}
@media (hover: hover){
  .pp-aa-btn:hover{ border-color: rgb(var(--gilt-edge) / 0.55); background: rgb(var(--surface) / 0.86); }
}
.pp-aa-btn:active{ transform: scale(0.94); }
.pp-aa-btn:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }
.pp-aa.is-open .pp-aa-pop{ animation: ppAaIn 180ms var(--ease-out-expo) both; }
@keyframes ppAaIn{
  from{ opacity: 0; transform: translateY(6px) scale(0.98); }
  to{ opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce){
  .pp-aa.is-open .pp-aa-pop{ animation: none; }
}

/* ---- 9. A card is one link -----------------------------------------------
   "when pressing on the box of the topic, it doesn't open the post! I have
    to press on the title.. so keep it the entire box as previously asked"

   Only the title was a link. The title's link now stretches over the whole
   card, so a tap anywhere on it opens the post; anything else in the card
   that is its own control (the Saved page's remove button, the spotlight's
   "Read this reflection") sits above that and still does its own job. */
:is(.article-card, .featured-card, .essay-rec){ position: relative; cursor: pointer; }
:is(.article-card, .featured-card, .essay-rec) :is(.article-body, .featured-body, h3){ position: static; }
:is(.article-card, .featured-card, .essay-rec) h3 a::after{
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
}
:is(.article-card, .featured-card, .essay-rec) :is(a, button):not(h3 a, .saved-remove){ position: relative; z-index: 2; }
:is(.article-card, .featured-card, .essay-rec) h3 a:focus-visible{ outline: none; }
:is(.article-card, .featured-card, .essay-rec):has(h3 a:focus-visible){
  outline: 2px solid rgb(var(--accent-ui));
  outline-offset: 3px;
}


/* ---- 10. Aa over the arrow, on one axis ----------------------------------
   The Aa button (46px) stands over the back-to-top arrow (44px, 42px on a
   phone). Both were pinned by their right EDGES, so their centres missed
   by the difference in size — and on a phone the arrow never moved to the
   16px floor the Aa's own offset assumed: it stayed at 24px, 5px out of
   line with the Aa and touching it. The arrow is placed by its centre now,
   under the Aa, with the gap the Aa's offset counts on. */
.back-top{
  right: calc(25px + env(safe-area-inset-right));
  transition: opacity 0.25s var(--ease), transform 0.25s var(--ease), visibility 0.25s,
              background 0.2s var(--ease), bottom 0.25s var(--ease-out-expo);
}
@media (max-width: 640px){
  .back-top{ right: calc(26px + env(safe-area-inset-right)); }
}
@media (max-width: 520px){
  .back-top{
    right: calc(18px + env(safe-area-inset-right));
    bottom: calc(16px + env(safe-area-inset-bottom));
  }
}

/* ---- 11. Both of them above the recitation bar ----------------------------
   On a Qur'an page the recitation bar docks along the bottom of the window
   (z-index 140), and the two buttons stayed where they were: on a phone
   the Aa was underneath the bar — the reading options unreachable for as
   long as anything was playing — and the arrow half on it. The old side
   rail had its own lifts for this; they lifted a rail that is never shown.

   assets/quran-audio.js measures how far the bar reaches up (--qa-dock,
   one row on a desk, two on a phone, taller with its settings open) and
   the pair stands 12px above that, in the same order and with the same
   gap as on the floor. The popover that opens from the Aa is capped to
   the room left above it. */
body.qa-playing .back-top{ bottom: calc(var(--qa-dock, 104px) + 12px); }
body.qa-playing .pp-aa{ bottom: calc(var(--qa-dock, 104px) + 12px); }
body.qa-playing .pp-aa.has-arrow{ bottom: calc(var(--qa-dock, 104px) + 12px + 44px + 10px); }
body.qa-playing .pp-aa-pop{
  max-height: min(70vh, 560px, calc(100dvh - var(--header-h, 68px) - var(--qa-dock, 104px) - 134px));
}
@media (max-width: 520px){
  body.qa-playing .pp-aa.has-arrow{ bottom: calc(var(--qa-dock, 104px) + 12px + 42px + 9px); }
}

/* ---- v143-layer-30-cards.css ---- */

/* =========================================================================
   v14.3 — A POST, AS A CARD.

   "beautify the Latest Writings images … make it more clean & beautiful &
    place the images in a better way"

   The cover was a picture MOUNTED inside the card — an inset frame 10px in
   from the edge, with its own border and shadow, under a gilt crown rule —
   and under it two pills and a line of typewriter text. Three frames and
   two badges around one small drawing.

   Now the cover is the top of the card, edge to edge, finished by one
   gilt rule where it meets the page of the card; the topic is a line of
   small caps; the excerpt stops at three lines; and date and reading time
   share one quiet line. The drawing itself is the palette's: on Saffron,
   a green binding tooled in gold (see `cover_hues` in gen_palettes.py).

   The old rules for these selectors were deleted, not overridden. The
   whole card is one link — see "a card is one link" in the post layer.
   ========================================================================= */

.articles-grid{
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
}
.related-section .articles-grid{ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
@media (max-width: 960px){
  .articles-grid{ grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
}
@media (max-width: 620px){
  .articles-grid{ grid-template-columns: minmax(0, 1fr); gap: 16px; }
}

.article-card{
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  isolation: isolate;
  border: 1px solid rgb(var(--gilt-edge) / 0.18);
  border-radius: var(--radius-lg);
  background: rgb(var(--surface));
  box-shadow: 0 1px 2px rgb(var(--shadow) / 0.05),
              0 12px 28px -20px rgb(var(--shadow) / 0.4);
  -webkit-user-select: none;
  user-select: none;
  transition: transform var(--dur) var(--ease-out-expo),
              box-shadow var(--dur) var(--ease-out-expo),
              border-color var(--dur) var(--ease-soft);
}
@media (hover: hover){
  .article-card:hover{
    transform: translateY(-3px);
    border-color: rgb(var(--gilt-edge) / 0.42);
    box-shadow: 0 2px 4px rgb(var(--shadow) / 0.06),
                0 24px 44px -24px rgb(var(--shadow) / 0.55);
  }
  .article-card:hover .article-cover .cover-art{ transform: scale(1.035); }
}
@media (hover: none){
  .article-card:active{ transform: scale(0.985); transition-duration: 90ms; }
}
@media (prefers-reduced-motion: reduce){
  .article-card, .article-card:active{ transform: none; }
  @media (hover: hover){ .article-card:hover{ transform: none; } }
}
html[data-scheme="dark"] .article-card{ border-color: rgb(var(--gilt) / 0.16); }

/* The cover: edge to edge, one gilt rule at its foot. */
.article-cover{
  position: relative;
  aspect-ratio: 16 / 7;
  overflow: hidden;
  background: rgb(var(--bg-alt));
}
.article-cover .cover-art{
  position: absolute;
  inset: 0;
  transition: transform 0.9s var(--ease);
}
.article-cover img{ width: 100%; height: 100%; object-fit: cover; }
.article-cover::after{
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 2px;
  background: linear-gradient(90deg, rgb(var(--gilt-deep)), rgb(var(--gilt-hi)) 50%, rgb(var(--gilt-deep)));
}

.article-body{
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 8px;
  padding: 18px 20px 20px;
}

/* ---- the words, shared by every card that lists a post ---------------- */
.card-eyebrow{
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 18px;
}
.card-topic{
  font-family: var(--font-ui);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  line-height: 1.4;
  text-transform: uppercase;
  color: rgb(var(--accent-ui));
}
.card-new{
  display: inline-flex;
  align-items: center;
  height: 18px;
  padding: 0 7px;
  border-radius: var(--radius-pill);
  background: rgb(var(--accent));
  color: rgb(var(--on-accent));
  font-family: var(--font-ui);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.article-body h3{
  margin: 2px 0 0;
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 600;
  line-height: 1.28;
  color: rgb(var(--heading));
  text-wrap: balance;
}
.article-body h3 a{ color: inherit; text-decoration: none; }
.card-excerpt{
  display: -webkit-box;
  margin: 0;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  font-family: var(--font-ui);
  font-size: 0.9rem;
  line-height: 1.6;
  color: rgb(var(--text-muted));
}
.card-meta{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  margin-top: auto;
  padding-top: 6px;
  font-family: var(--font-ui);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0;
  color: rgb(var(--text-muted));
  font-variant-numeric: lining-nums tabular-nums;
}
/* A card narrower than its date and reading time side by side — the three
   "Read next" cards under a post are 182px inside — wrapped the reading
   time under the date and left the dot hanging at the end of the first
   line. A card that narrow sets the two one above the other, without the
   dot. (The card is already the positioning box for its link overlay, so
   making it a container moves nothing.) */
:is(.article-card, .essay-rec){ container-type: inline-size; }
@container (max-width: 230px){
  .card-meta{ flex-direction: column; align-items: flex-start; gap: 1px; }
  .card-meta .post-meta-sep{ display: none; }
}

/* ---- the spotlight on the home page ------------------------------------ */
.featured-body .card-excerpt{ -webkit-line-clamp: 4; font-size: 0.95rem; }
.featured-cta{ margin-top: 10px; }

/* ---- the Saved page draws its own cover (no server art there) ---------- */
.saved-card .article-cover{
  display: grid;
  place-items: center;
  background: radial-gradient(120% 140% at 30% 20%, rgb(var(--accent)) 0%, rgb(var(--ink)) 78%);
}
.saved-card .article-cover .cover-ornament{
  width: 24%;
  max-width: 88px;
  color: rgb(var(--gilt));
  opacity: 0.9;
}


/* ---- v143-layer-40-tafsir.css ---- */

/* =========================================================================
   v14.3 — THE COMMENTARIES.

   Items 12, 13, 14, 17, 20, 33, 34 and 35 of the v14.3 list, in one layer.
   The old rules for every selector below were DELETED, not overridden
   (187 rules and 12 selector lists): the book cards, the switch sheet,
   "the same ayah in another commentary", the rail's passage and compare
   forms, the picker's mode switch, the English under the ayah, the title
   block and the comparison columns.

     THE TITLE       the Arabic name, then — with room between them — the
                     English one, the author and one line.
     THE PICKER      one control for a verse and a passage (renderAyat()).
     THE COMPARISON  up to five books, side by side, then sideways.
     THE RAIL        where you are, and what is open beside it.
     THE SHELF       every book a title page, one surface; a row on a phone.
     THE CHOOSER     PPPicker rows with the Arabic title on the right.
   ========================================================================= */


/* ---- the title ---------------------------------------------------------
   "some text is too close, like tafsir name in Ar & En in the book itself"
   The English sat 2px under an Arabic line whose descenders already reach
   its own line box, so the two names touched. 14px now, and the author a
   line of its own under them. */
.tafsir-title{
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: var(--tafsir-measure);
  margin: 0 auto clamp(28px, 4vw, 44px);
  text-align: center;
}
.tafsir-title-ar{
  margin: 0;
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight-strong);
  font-size: clamp(1.9rem, 1.3rem + 2.6vw, 2.9rem);
  line-height: 1.6;
  color: rgb(var(--heading));
}
.tafsir-title-en{
  margin: 14px 0 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.1rem, 1rem + 0.5vw, 1.35rem);
  line-height: 1.3;
  color: rgb(var(--accent-ui));
}
.tafsir-title-author{
  margin: 6px 0 0;
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: 1.05rem;
  line-height: 1.8;
  color: rgb(var(--text-muted));
}
.tafsir-title-note{
  margin: 6px auto 0;
  max-width: 52ch;
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: rgb(var(--text-muted));
}


/* ---- the ayah, without the English under it ---------------------------- */
.tafsir-ayah-ar{ margin-bottom: 0; }


/* ---- the picker: one control for a verse and a passage ------------------ */
.tafsir-pop-hint{
  flex-shrink: 0;
  margin: 0;
  padding: 10px 16px 0;
  font-family: var(--font-ui);
  font-size: 0.76rem;
  line-height: 1.45;
  color: rgb(var(--text-muted));
}
/* The verse you are on is a ring; a verse you have chosen is filled. */
.tafsir-pop-num.is-current{
  background: transparent;
  border-color: rgb(var(--accent) / 0.55);
  box-shadow: inset 0 0 0 1px rgb(var(--accent) / 0.55);
  color: rgb(var(--accent-ui));
  font-weight: 600;
}
.tafsir-pop-num.is-in-span{
  background: rgb(var(--wash) / 0.16);
  border-color: rgb(var(--wash) / 0.34);
  color: rgb(var(--heading));
}
.tafsir-pop-num.is-preview{
  border-color: rgb(var(--accent) / 0.6);
  color: rgb(var(--accent-ui));
}
.tafsir-pop-num.is-chosen{
  background: rgb(var(--accent));
  border-color: rgb(var(--accent));
  box-shadow: none;
  color: rgb(var(--on-accent));
  font-weight: 600;
}
@media (hover: hover){
  .tafsir-pop-num.is-chosen:hover{
    background: rgb(var(--accent));
    border-color: rgb(var(--accent));
    box-shadow: none;
    color: rgb(var(--on-accent));
    font-weight: 600;
  }
}
.tafsir-pop-num{ touch-action: manipulation; }

.tafsir-pop-read{
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: 8px;
  padding: 10px;
  border-top: 1px solid var(--hairline);
}
.tafsir-pop.is-sheet .tafsir-pop-read{
  padding-bottom: calc(10px + env(safe-area-inset-bottom));
}
.tafsir-pop-go{
  display: inline-flex;
  flex: 1;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 16px;
  border: 0;
  border-radius: var(--radius-pill);
  background: rgb(var(--accent));
  color: rgb(var(--on-accent));
  font-family: var(--font-ui);
  font-size: 0.88rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
.tafsir-pop-go svg{ width: 16px; height: 16px; flex-shrink: 0; }
.tafsir-pop-go:disabled{
  background: rgb(var(--ink) / 0.06);
  color: rgb(var(--text-muted));
  cursor: default;
}
.tafsir-pop-go:disabled svg{ display: none; }
.tafsir-pop-clear{
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  background: transparent;
  color: rgb(var(--text-muted));
  font-family: var(--font-ui);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
}
@media (hover: hover){
  .tafsir-pop-go:not(:disabled):hover{ background: rgb(var(--accent-ui)); }
  .tafsir-pop-clear:hover{ border-color: rgb(var(--wash) / 0.45); color: rgb(var(--heading)); }
}
.tafsir-pop-go:focus-visible,
.tafsir-pop-clear:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }


/* ---- the comparison: up to five books ----------------------------------
   One column, two, three: a grid that fits. From the fourth (and from the
   second on a phone) the columns keep a readable width and the row scrolls
   sideways a column at a time instead of squeezing Arabic into strips.
   assets/tafsir-rail.js keeps the rows of a passage scrolled together and
   marks a row that overflows (`has-overflow`). */
.tafsir-cols{
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
}
.tafsir-col{ min-width: 0; }
.tafsir-cols:not([data-cols="1"]){ gap: clamp(18px, 2.4vw, 32px); }

.tafsir-cols:not([data-cols="1"]) .tafsir-body{
  font-size: calc(1.16rem * var(--tafsir-fs, 1));
  line-height: 2;
}

@media (min-width: 900px){
  .tafsir-cols[data-cols="2"]{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1280px){
  .tafsir-cols[data-cols="3"]{ grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* The scrolling row. */
@media (max-width: 899px){
  .tafsir-cols:not([data-cols="1"]){
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 86%;
  }
}
@media (min-width: 900px) and (max-width: 1279px){
  .tafsir-cols[data-cols="3"],
  .tafsir-cols[data-cols="4"],
  .tafsir-cols[data-cols="5"]{
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: calc((100% - clamp(18px, 2.4vw, 32px)) / 2);
  }
}
@media (min-width: 1280px){
  .tafsir-cols[data-cols="4"],
  .tafsir-cols[data-cols="5"]{
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: calc((100% - 2 * clamp(18px, 2.4vw, 32px)) / 3);
  }
}
/* Whatever overflows scrolls, a column at a time. Harmless where nothing
   does: a grid that fits has nothing to scroll. */
.tafsir-cols:not([data-cols="1"]){
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
  scrollbar-color: rgb(var(--wash) / 0.35) transparent;
}
.tafsir-cols:not([data-cols="1"]) > .tafsir-col{ scroll-snap-align: start; }
.tafsir-cols.has-overflow{ padding-bottom: 14px; }

/* The books in a row that scrolls, named above it (built by
   assets/tafsir-rail.js only when the row does scroll). */
.tafsir-cols-nav{
  display: flex;
  gap: 6px;
  margin: 0 0 16px;
  overflow-x: auto;
  scrollbar-width: none;
}
.tafsir-cols-nav::-webkit-scrollbar{ display: none; }
.tafsir-cols-tab{
  flex-shrink: 0;
  min-height: 34px;
  padding: 0 13px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  background: transparent;
  color: rgb(var(--text-muted));
  font-family: var(--font-ui);
  font-size: 0.76rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft),
              border-color var(--dur-fast) var(--ease-soft),
              color var(--dur-fast) var(--ease-soft);
}
.tafsir-cols-tab.is-shown{
  border-color: rgb(var(--wash) / 0.4);
  background: rgb(var(--wash) / 0.1);
  color: rgb(var(--heading));
}
@media (hover: hover){
  .tafsir-cols-tab:hover{ border-color: rgb(var(--wash) / 0.45); color: rgb(var(--heading)); }
}
.tafsir-cols-tab:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }

/* The head of a column: the English name on the left, the Arabic title on
   the right, as every book is laid out on this site. Only shown when there
   is more than one column. */
.tafsir-cols[data-cols="1"] .tafsir-col-head{ display: none; }
.tafsir-col-head{
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--hairline);
  direction: ltr;
}
.tafsir-col-en{
  order: 1;
  min-width: 0;
  font-family: var(--font-ui);
  font-size: 0.78rem;
  font-weight: 600;
  color: rgb(var(--heading-soft));
  white-space: nowrap;
  overflow-x: clip;
  text-overflow: ellipsis;
}
.tafsir-col-ar{
  order: 2;
  flex-shrink: 0;
  max-width: 62%;
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: 1.08rem;
  line-height: 1.8;
  color: rgb(var(--heading));
  direction: rtl;
  text-align: right;
  white-space: nowrap;
  overflow-x: clip;
  text-overflow: ellipsis;
}


/* ---- the rail: what is open --------------------------------------------- */
.tr-count{
  font-family: var(--font-ui);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: rgb(var(--text-muted));
  font-variant-numeric: tabular-nums;
}
.tr-cmp-list{
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.tr-cmp{
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 6px 7px 11px;
  border: 1px solid var(--hairline);
  border-radius: 10px;
  background: rgb(var(--surface));
}
.tr-cmp.is-reading{
  border-color: rgb(var(--wash) / 0.3);
  background: rgb(var(--wash) / 0.07);
}
.tr-cmp-text{
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
}
.tr-cmp-en{
  font-family: var(--font-ui);
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1.35;
  color: rgb(var(--heading));
  white-space: nowrap;
  overflow-x: clip;
  text-overflow: ellipsis;
}
.tr-cmp-ar{
  align-self: flex-end;
  max-width: 100%;
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: 0.98rem;
  line-height: 1.75;
  color: rgb(var(--text-muted));
  direction: rtl;
  white-space: nowrap;
  overflow-x: clip;
  text-overflow: ellipsis;
}
.tr-cmp-tag{
  align-self: flex-start;
  margin: 2px 4px 0 0;
  font-family: var(--font-ui);
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgb(var(--accent-ui));
}
.tr-cmp-x{
  display: grid;
  flex-shrink: 0;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  color: rgb(var(--text-muted));
  transition: background-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
.tr-cmp-x svg{ width: 14px; height: 14px; }
.tr-cmp-add{
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  min-height: 38px;
  margin-top: 2px;
  border: 1px dashed rgb(var(--wash) / 0.45);
  border-radius: 10px;
  background: transparent;
  color: rgb(var(--accent-ui));
  font-family: var(--font-ui);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
.tr-cmp-add svg{ width: 15px; height: 15px; }
@media (hover: hover){
  .tr-cmp-x:hover{ background: rgb(var(--wash) / 0.12); color: rgb(var(--heading)); }
  .tr-cmp-add:hover{ border-style: solid; background: rgb(var(--wash) / 0.08); }
}
.tr-cmp-x:focus-visible,
.tr-cmp-add:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }
.tr-note{
  margin: 2px 0 0;
  font-family: var(--font-ui);
  font-size: 0.74rem;
  line-height: 1.5;
  color: rgb(var(--text-muted));
}
.tr-reset{
  align-self: flex-start;
  font-family: var(--font-ui);
  font-size: 0.76rem;
  font-weight: 600;
  color: rgb(var(--accent-ui));
  text-decoration: underline;
  text-decoration-color: rgb(var(--wash) / 0.45);
  text-underline-offset: 3px;
}


/* ---- the shelf: every book a title page --------------------------------
   "the boxes for tafsir books have weird colours, vertical lines have same
    colour which doesnt make sense, choose much more beautiful designs"
   One surface for every card, no spine, no alternate fill. The book's own
   device, its Arabic title, a short gilt rule, and then its name, author
   and one line. */
.tafsir-book-grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(236px, 1fr));
  gap: 18px;
}
.tafsir-book-card{
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  padding: 22px 20px 20px;
  border: 1px solid rgb(var(--gilt-edge) / 0.18);
  border-radius: var(--radius-lg);
  background: rgb(var(--surface));
  box-shadow: 0 1px 2px rgb(var(--shadow) / 0.04),
              0 12px 26px -22px rgb(var(--shadow) / 0.4);
  color: inherit;
  text-align: center;
  text-decoration: none;
  transition: transform var(--dur) var(--ease-out-expo),
              box-shadow var(--dur) var(--ease-out-expo),
              border-color var(--dur) var(--ease-soft);
}
@media (hover: hover){
  .tafsir-book-card:hover{
    transform: translateY(-2px);
    border-color: rgb(var(--gilt-edge) / 0.4);
    box-shadow: 0 2px 4px rgb(var(--shadow) / 0.05),
                0 20px 36px -24px rgb(var(--shadow) / 0.5);
  }
}
@media (prefers-reduced-motion: reduce){
  .tafsir-book-card{ transform: none; }
  @media (hover: hover){ .tafsir-book-card:hover{ transform: none; } }
}
.tafsir-book-card:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 3px; }
html[data-scheme="dark"] .tafsir-book-card{ border-color: rgb(var(--gilt) / 0.16); }

.tafsir-book-crest{
  display: block;
  width: 30px;
  height: 30px;
  margin-bottom: 8px;
  color: rgb(var(--gilt-deep));
}
.tafsir-book-crest svg{ display: block; width: 100%; height: 100%; }

.tafsir-book-ar{
  display: -webkit-box;
  max-width: 100%;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight-strong);
  font-size: clamp(1.4rem, 1.2rem + 0.7vw, 1.7rem);
  line-height: 1.8;
  color: rgb(var(--heading));
  direction: rtl;
  unicode-bidi: isolate;
}
.tafsir-book-text{
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  width: 100%;
  min-width: 0;
}
.tafsir-book-text::before{
  content: "";
  width: 44px;
  height: 1px;
  margin: 10px auto 12px;
  background: linear-gradient(90deg, transparent, rgb(var(--gilt)), transparent);
}
.tafsir-book-en{
  font-family: var(--font-display);
  font-size: 1.06rem;
  font-weight: 600;
  line-height: 1.3;
  color: rgb(var(--heading));
}
.tafsir-book-author{
  max-width: 100%;
  margin-top: 2px;
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: 0.98rem;
  line-height: 1.8;
  color: rgb(var(--text-muted));
  direction: rtl;
  unicode-bidi: isolate;
  text-wrap: balance;
}
.tafsir-book-note{
  display: -webkit-box;
  margin-top: 6px;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  font-family: var(--font-ui);
  font-size: 0.85rem;
  line-height: 1.55;
  color: rgb(var(--text-muted));
}

/* A phone: the same card as a row — name and line on the left, the Arabic
   title on the right. */
@media (max-width: 620px){
  .tafsir-book-grid{ grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .tafsir-book-card{
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "text ar";
    align-items: center;
    gap: 14px;
    padding: 12px 16px;
    border-radius: var(--radius);
    text-align: left;
  }
  .tafsir-book-crest{ display: none; }
  .tafsir-book-ar{
    grid-area: ar;
    max-width: 44vw;
    font-size: 1.28rem;
    line-height: 1.75;
    text-align: right;
  }
  .tafsir-book-text{ grid-area: text; align-items: flex-start; }
  .tafsir-book-text::before,
  .tafsir-book-author{ display: none; }
  .tafsir-book-note{ margin-top: 2px; font-size: 0.8rem; -webkit-line-clamp: 2; line-clamp: 2; }
}


/* ---- the chooser: a commentary is its English and its Arabic ------------ */

/* Every subtitle in the chooser was set in --font-arabic (v14.1, for the
   hadith chapters, whose subtitles are Arabic). That stack has no Latin
   face in it at all — PP Naskh and Amiri are bundled for Arabic only — so
   every ENGLISH subtitle anywhere the chooser is used (a commentary's
   note, a calculation method's explanation) fell through to the system's
   Times New Roman. Inter for Latin, the Naskh for Arabic, per glyph. */
.pp-picker-row-sub{
  font-family: 'Inter', 'PP Naskh', 'Amiri', 'Noto Naskh Arabic', -apple-system, 'Segoe UI', sans-serif;
  font-size: 0.8rem;
}
.pp-picker-row-sub:lang(ar),
.pp-picker-row-sub[dir="rtl"]{ font-size: 0.9rem; }

/* The pale yellow band behind every group heading, "weird light yellow
   lines" (v14.2), was never the heading's background: v14.2 took that away
   and left the glass BLUR on, and a saturating blur over a transparent box
   turns the cream beneath it yellow. */
.pp-picker-group-label{
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.pp-picker-row-aside[lang="ar"]{
  max-width: 44%;
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: 1.12rem;
  line-height: 1.8;
  color: rgb(var(--heading-soft));
  direction: rtl;
  text-align: right;
  overflow-x: clip;
  text-overflow: ellipsis;
}
.pp-picker-row.is-selected .pp-picker-row-aside[lang="ar"]{ color: rgb(var(--accent-ui)); }


/* ---- the book pill in the bar: never cut the Arabic --------------------- */
.tafsir-bar-book-ar,
.tafsir-bar-book-en{
  overflow-x: clip;
  overflow-y: visible;
}
.tafsir-bar-book-ar{ line-height: 1.7; }


/* ---- v143-layer-50-tools.css ---- */

/* =========================================================================
   v14.3 — PRAYER TIMES AND THE QIBLA.

   Prayer times: one quiet line while Fajr is in ("Fajr time ends at
   sunrise, 6:01 AM"), from startCountdown() in assets/prayer-times.js.

   The Qibla's sun method, rebuilt (item 5: "SUPER confusing, make it SUPER
   simple, and brief, and very clear"). The old rules for .qibla-sun-* were
   deleted (34). A drawing — you, the sun ahead, the Qibla as an arrow and
   the turn between them as an arc — beside two steps; then the moments
   today when no turn is needed.
   ========================================================================= */

/* ---- prayer times ------------------------------------------------------- */
.prayer-now-note{
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 10px auto 0;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  background: rgb(var(--wash) / 0.1);
  font-family: var(--font-ui);
  font-size: 0.8rem;
  font-weight: 500;
  color: rgb(var(--heading-soft));
  font-variant-numeric: tabular-nums;
}
.prayer-now-note::before{
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgb(var(--accent));
}


/* ---- the Qibla by the sun ------------------------------------------------ */
.qibla-sun-title{
  margin: 0 0 16px;
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem);
  font-weight: 600;
  line-height: 1.25;
  color: rgb(var(--heading));
}

.qibla-sun-live{
  display: grid;
  grid-template-columns: 148px minmax(0, 1fr);
  align-items: center;
  gap: 22px;
}
.qibla-sun-live[hidden]{ display: none; }

.qibla-sun-dial{ display: block; width: 148px; height: 148px; overflow: visible; }
.qsd-ring{
  fill: rgb(var(--surface));
  stroke: rgb(var(--gilt-edge) / 0.3);
  stroke-width: 1.2;
}
.qsd-ahead{
  stroke: rgb(var(--text-muted) / 0.45);
  stroke-width: 1.4;
  stroke-dasharray: 3 4;
}
.qsd-arc{
  fill: none;
  stroke: rgb(var(--gilt));
  stroke-width: 2.4;
  stroke-linecap: round;
}
.qsd-sun circle{ fill: rgb(var(--gilt)); }
.qsd-sun path{
  fill: none;
  stroke: rgb(var(--gilt));
  stroke-width: 1.8;
  stroke-linecap: round;
}
.qsd-qibla line{
  stroke: rgb(var(--accent));
  stroke-width: 3;
  stroke-linecap: round;
}
.qsd-qibla path{ fill: rgb(var(--accent)); }
.qsd-qibla{ transition: transform 0.6s var(--ease-out-expo); }
.qsd-you{
  fill: rgb(var(--heading));
  stroke: rgb(var(--surface));
  stroke-width: 2.5;
}

.qibla-sun-say{ display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.qibla-sun-step{
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  font-family: var(--font-ui);
  font-size: clamp(1rem, 0.95rem + 0.3vw, 1.12rem);
  font-weight: 600;
  line-height: 1.35;
  color: rgb(var(--heading));
}
.qibla-sun-n{
  display: grid;
  flex-shrink: 0;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: rgb(var(--wash) / 0.14);
  color: rgb(var(--accent-ui));
  font-size: 0.78rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.qibla-sun-deg{
  margin: -2px 0 0 38px;
  font-family: var(--font-ui);
  font-size: 0.82rem;
  color: rgb(var(--text-muted));
  font-variant-numeric: tabular-nums;
}
.qibla-sun-deg:empty{ display: none; }

.qibla-sun-down{
  margin: 0;
  font-family: var(--font-ui);
  font-size: 0.95rem;
  line-height: 1.6;
  color: rgb(var(--text-muted));
}

.qibla-sun-times{
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--hairline);
}
.qibla-sun-times[hidden]{ display: none; }
.qibla-sun-subtitle{
  margin: 0 0 10px;
  font-family: var(--font-ui);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.qibla-sun-align{
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.qibla-sun-align li{
  display: grid;
  grid-template-columns: 5.6em minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 12px;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  background: rgb(var(--wash) / 0.07);
  font-family: var(--font-ui);
  font-size: 0.92rem;
  color: rgb(var(--heading));
}
.qibla-sun-align time{
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: rgb(var(--accent-ui));
}
.qibla-sun-align em{
  font-style: normal;
  font-size: 0.72rem;
  color: rgb(var(--text-muted));
}
.qibla-sun-align li.is-past{ background: transparent; color: rgb(var(--text-muted)); }
.qibla-sun-align li.is-past time{ color: rgb(var(--text-muted)); }

@media (max-width: 480px){
  .qibla-sun-live{ grid-template-columns: 1fr; justify-items: center; gap: 16px; }
  .qibla-sun-dial{ width: 136px; height: 136px; }
  .qibla-sun-say{ align-self: stretch; }
  .qibla-sun-align li{ grid-template-columns: 5.2em minmax(0, 1fr); }
  .qibla-sun-align em{ grid-column: 2; }
}
@media (prefers-reduced-motion: reduce){
  .qsd-qibla{ transition: none; }
}


/* ---- v143-layer-60-quran.css ---- */

/* =========================================================================
   v14.3 — THE AYAT, A LITTLE CLOSER.

   "make the ayat in the mushaf a bit closer to each other (but make 100%
    sure reasonable space)"

   Most of the gap was never designed. The ayah and its translation are
   <p> elements and nothing had ever set their top margins, so each carried
   the browser's own 1em — 27px above every ayah on a desktop — and the row
   of verse tools under the translation reserved 46px of empty space even
   while it was invisible. A short ayah stood in 215px; it stands in about
   160 now, with the same padding on either side of the rule between ayat,
   so the space still reads as a pause and not a crowd.
   ========================================================================= */
.quran-ayah{ padding-block: 14px; }
.quran-ayah-ar{ margin-top: 0; margin-bottom: 0; }
.quran-ayah-en{ margin-top: 4px; margin-bottom: 0; }
/* With a mouse the tools row keeps its place (it fades in on hover, and a
   row that pushed the page about as the pointer crossed it would be
   worse), so the ayah gives back the same amount underneath to keep the
   space above and below the text even. */
@media (hover: hover){
  .quran-ayah{ padding-bottom: 6px; }
  .quran-ayah-actions{ margin-top: 2px; }
  .quran-ayah-action{ min-height: 28px; }
}
@media (hover: none){
  .quran-ayah.is-open .quran-ayah-actions,
  .quran-ayah:focus-within .quran-ayah-actions{ margin-top: 10px; }
}


/* ---- v143-layer-70-hadith-book.css ---- */

/* =========================================================================
   v14.3 — A COLLECTION, READ AS A BOOK.

   "browse as a book is not very clear, make it easy to view & convenient &
    clear & minimal and beautiful page that shows all ahadith under a
    specific selected chapters, and allow for multiple chapters"

   Two pages, both in hadith-collection.php:

     THE CONTENTS   every chapter a row — a tick, its number, its name in
                    both scripts, how many narrations — and a bar at the
                    foot that says what has been chosen and reads it.
     THE READING    each chapter under a title of its own, then every
                    narration whole: its number, the Arabic, the narrator,
                    the English. No cards, no excerpts, no arrows — a page.
   ========================================================================= */

.hadith-none{ padding: 40px 20px; }
.hadith-pages{ margin-top: 12px; }

/* ---- the contents -------------------------------------------------------- */
.hbook-toc{
  position: relative;
  margin-top: 4px;
  border: 1px solid rgb(var(--gilt-edge) / 0.18);
  border-radius: var(--radius-lg);
  background: rgb(var(--surface));
  box-shadow: 0 1px 2px rgb(var(--shadow) / 0.04), 0 18px 40px -30px rgb(var(--shadow) / 0.4);
}
.hbook-toc-head{
  padding: 24px 24px 14px;
  text-align: center;
}
.hbook-toc-title{
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.2rem, 1.05rem + 0.6vw, 1.45rem);
  font-weight: 600;
  color: rgb(var(--heading));
}
.hbook-toc-lead{
  margin: 6px 0 0;
  font-family: var(--font-ui);
  font-size: 0.88rem;
  line-height: 1.55;
  color: rgb(var(--text-muted));
}
.hbook-toc-list{
  margin: 0;
  padding: 6px 12px 14px;
  list-style: none;
  columns: 2 360px;
  column-gap: 20px;
}
.hbook-toc-list li{ break-inside: avoid; }
.hbook-toc-row{
  position: relative;
  display: grid;
  grid-template-columns: 22px 2.2em minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  padding: 9px 12px 9px 10px;
  border-radius: 10px;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft);
}
.hbook-toc-check{
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.hbook-toc-box{
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border: 1.5px solid var(--hairline-strong);
  border-radius: 6px;
  background: rgb(var(--surface));
  transition: background-color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
.hbook-toc-box svg{
  width: 14px;
  height: 14px;
  color: rgb(var(--on-accent));
  opacity: 0;
  transform: scale(0.6);
  transition: opacity var(--dur-fast) var(--ease-soft), transform var(--dur) var(--spring);
}
.hbook-toc-check:checked + .hbook-toc-box{ border-color: rgb(var(--accent)); background: rgb(var(--accent)); }
.hbook-toc-check:checked + .hbook-toc-box svg{ opacity: 1; transform: none; }
.hbook-toc-row:has(.hbook-toc-check:checked){ background: rgb(var(--wash) / 0.09); }
.hbook-toc-row:has(.hbook-toc-check:focus-visible){ box-shadow: inset 0 0 0 2px rgb(var(--accent-ui)); }
@media (hover: hover){
  .hbook-toc-row:hover{ background: rgb(var(--wash) / 0.06); }
  .hbook-toc-row:hover .hbook-toc-box{ border-color: rgb(var(--wash) / 0.6); }
}
.hbook-toc-n{
  font-family: var(--font-ui);
  font-size: 0.76rem;
  font-weight: 500;
  color: rgb(var(--text-muted));
  font-variant-numeric: tabular-nums;
}
.hbook-toc-names{ display: flex; flex-direction: column; min-width: 0; }
/* The name and its count on one line, the Arabic under it on the right:
   English starts from the left, Arabic from the right. */
.hbook-toc-top{ display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.hbook-toc-en{
  font-family: var(--font-ui);
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.35;
  color: rgb(var(--heading));
}
.hbook-toc-ar{
  align-self: flex-end;
  max-width: 100%;
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: 1rem;
  line-height: 1.75;
  color: rgb(var(--text-muted));
  text-align: right;
}
.hbook-toc-c{
  font-family: var(--font-ui);
  font-size: 0.74rem;
  color: rgb(var(--text-muted));
  font-variant-numeric: tabular-nums;
}

.hbook-toc-bar{
  position: sticky;
  bottom: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--hairline);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  background: rgb(var(--surface));
  box-shadow: 0 -14px 24px -22px rgb(var(--shadow) / 0.5);
}
.hbook-toc-sum{
  flex: 1;
  min-width: 0;
  font-family: var(--font-ui);
  font-size: 0.86rem;
  font-weight: 500;
  color: rgb(var(--text-muted));
  font-variant-numeric: tabular-nums;
}
.hbook-toc.has-choice .hbook-toc-sum{ color: rgb(var(--heading)); font-weight: 600; }
.hbook-toc-clear{
  min-height: 40px;
  padding: 0 14px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  background: transparent;
  color: rgb(var(--text-muted));
  font-family: var(--font-ui);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
}
.hbook-toc-go{ display: inline-flex; align-items: center; gap: 8px; }
.hbook-toc-go svg{ width: 15px; height: 15px; }
.hbook-toc-go:disabled{ opacity: 0.45; cursor: default; box-shadow: none; }

/* ---- the reading --------------------------------------------------------- */
.hbook-bar{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  max-width: 820px;
  margin: 0 auto 8px;
  padding: 12px 16px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: rgb(var(--surface));
}
.hbook-bar-text{ display: flex; flex-direction: column; min-width: 0; }
.hbook-bar-book{
  font-family: var(--font-ui);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgb(var(--accent-ui));
}
.hbook-bar-what{
  font-family: var(--font-ui);
  font-size: 0.92rem;
  font-weight: 600;
  color: rgb(var(--heading));
  font-variant-numeric: tabular-nums;
}
.hbook-bar-change{
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  gap: 7px;
  min-height: 38px;
  padding: 0 14px;
  border: 1px solid rgb(var(--wash) / 0.35);
  border-radius: var(--radius-pill);
  color: rgb(var(--accent-ui));
  font-family: var(--font-ui);
  font-size: 0.82rem;
  font-weight: 600;
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease-soft);
}
.hbook-bar-change svg{ width: 15px; height: 15px; }
@media (hover: hover){
  .hbook-bar-change:hover{ background: rgb(var(--wash) / 0.1); }
}
.hbook-bar + .hadith-where{ max-width: 820px; margin: 14px auto 0; }

.hbook{ max-width: 820px; margin: 0 auto; }
.hbook-chapter + .hbook-chapter{ margin-top: 40px; }
.hbook-chapter-head{
  padding: 36px 0 22px;
  border-bottom: 1px solid rgb(var(--gilt-edge) / 0.3);
  text-align: center;
}
.hbook-chapter-n{
  display: block;
  font-family: var(--font-ui);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgb(var(--accent-ui));
}
.hbook-chapter-cont{ color: rgb(var(--text-muted)); letter-spacing: 0.08em; }
.hbook-chapter-ar{
  margin: 8px 0 0;
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight-strong);
  font-size: clamp(1.6rem, 1.3rem + 1.2vw, 2.1rem);
  line-height: 1.7;
  color: rgb(var(--heading));
}
.hbook-chapter-en{
  margin: 6px 0 0;
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 1rem + 0.3vw, 1.2rem);
  font-weight: 600;
  line-height: 1.35;
  color: rgb(var(--heading-soft));
}

.hbook-item{
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  column-gap: 18px;
  padding: 26px 0;
  border-bottom: 1px solid var(--hairline-faint);
  content-visibility: auto;
  contain-intrinsic-size: auto 420px;
  scroll-margin-top: calc(var(--header-h) + 16px);
}
.hbook-item > :not(.hbook-num){ grid-column: 2; }
.hbook-num{
  grid-row: 1 / span 4;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  margin-top: 4px;
  border: 1px solid rgb(var(--gilt-edge) / 0.35);
  border-radius: 50%;
  color: rgb(var(--heading-soft));
  font-family: var(--font-ui);
  font-size: 0.72rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  transition: border-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
@media (hover: hover){
  .hbook-num:hover{ border-color: rgb(var(--accent)); color: rgb(var(--accent-ui)); }
}
.hbook-ar{
  margin: 0 0 14px;
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: 1.34rem;
  line-height: 2.1;
  color: rgb(var(--heading));
  text-align: right;
}
.hbook-ar-p{ margin: 0; }
.hbook-ar-p + .hbook-ar-p{ margin-top: 0.7em; }
.hbook-narrator{
  margin: 0 0 6px;
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-style: italic;
  color: rgb(var(--text-muted));
}
.hbook-en-p{
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.04rem;
  line-height: 1.8;
  color: rgb(var(--text));
}
.hbook-en-p + .hbook-en-p{ margin-top: 0.8em; }

@media (max-width: 620px){
  .hbook-toc-head{ padding: 20px 16px 10px; }
  .hbook-toc-list{ padding: 4px 6px 10px; }
  .hbook-toc-row{ grid-template-columns: 22px 1.8em minmax(0, 1fr); gap: 8px; padding: 9px 10px 9px 8px; }
  .hbook-toc-sum{ font-size: 0.8rem; }
  .hbook-toc-clear{ padding: 0 12px; }
  .hbook-bar{ flex-wrap: wrap; }
  .hbook-item{ grid-template-columns: minmax(0, 1fr); padding: 22px 0; }
  .hbook-item > :not(.hbook-num){ grid-column: 1; }
  .hbook-num{ grid-row: auto; width: 30px; height: 30px; margin: 0 0 8px; font-size: 0.68rem; }
  .hbook-ar{ font-size: 1.2rem; line-height: 2; }
  .hbook-en-p{ font-size: 1rem; }
}
/* The floating "back to top" would sit on the Read button. */
body:has(.hbook-toc) .back-top{ bottom: calc(84px + env(safe-area-inset-bottom)); }

@media print{
  .hbook-item{ content-visibility: visible; }
  .hbook-toc-bar, .hbook-bar-change{ display: none; }
}

/* ---- v143-layer-80-adhkar.css ---- */
/* =========================================================================
   v14.3 — THE ADHKĀR PAGE: ONE LIST, AND A HEAD THAT IS ONE LINE.  (item 19)

   "dont section it weirdly, be clean & very minimal so the main focus is
    the adhkar themselves"

   The section chips and headings are gone with the groups they named
   (page-tasbih.php). What was left above the first card was the set's
   head: a bordered card holding a second bordered box, a 6px track, the
   count on its own line, the note, and a 44px outlined pill — on a phone,
   163px of chrome before a single word of dhikr, framed twice.

   It is one line now: the count, the track, and "Start again" as a quiet
   text control, with the set's one line of guidance under it. No frame,
   no fill; the picker bar above is already the frame.
   ========================================================================= */
/* The bar and the search sat inside a faint shadowed frame left over from
   v13.0's index card (its border and fill were reset in v14.0, its shadow
   was not). The two controls are the frame; nothing is drawn round them. */
.adhkar-index{ box-shadow: none; border-radius: 0; }

.adhkar-panel-head{
  display: block;
  margin: 0 0 var(--sp-5);
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
}
.adhkar-progress{
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px 14px;
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}
.adhkar-progress-row{ display: contents; }
.adhkar-progress-count{
  grid-column: 1; grid-row: 1;
  font-family: var(--font-ui);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  color: rgb(var(--text-muted));
}
.adhkar-progress-track{
  grid-column: 2; grid-row: 1;
  display: block;
  height: 4px;
  border-radius: 999px;
  background: rgb(var(--ink) / 0.08);
  overflow: hidden;
}
.adhkar-progress-fill{ border-radius: 999px; }
.adhkar-panel-head .adhkar-reset{
  grid-column: 3; grid-row: 1;
  justify-self: end;
  min-height: 32px;
  padding: 4px 8px;
  margin-right: -8px;
  border: 0;
  border-radius: 999px;
  background: none;
  font-family: var(--font-ui);
  font-size: 0.78rem;
  font-weight: 600;
  color: rgb(var(--text-muted));
}
.adhkar-panel-head .adhkar-reset svg{ width: 13px; height: 13px; }
@media (hover: hover){
  .adhkar-panel-head .adhkar-reset:hover{
    background: rgb(var(--ink) / 0.05);
    color: rgb(var(--heading));
  }
}
.adhkar-panel-head .adhkar-panel-note{
  grid-column: 1 / -1; grid-row: 2;
  margin: 0;
  max-width: 68ch;
  font-size: 0.86rem;
  line-height: 1.6;
  color: rgb(var(--text-muted));
}
/* A set with no progress keeps only its line of guidance. */
.adhkar-panel-note.is-loose{
  margin: 0 0 var(--sp-5);
  padding: 0;
  border: 0;
  max-width: 68ch;
  font-size: 0.86rem;
  line-height: 1.6;
  color: rgb(var(--text-muted));
}
/* On a touch screen the control keeps its 44px target (v12.0) without
   drawing it: the height is invisible because nothing is painted. */
@media (pointer: coarse){
  #adhkarApp .adhkar-panel-head .adhkar-reset{ min-height: 44px; }
}
@media (max-width: 620px){
  .adhkar-panel-head{ margin-bottom: var(--sp-4); }
  .adhkar-progress{ gap: 6px 12px; }
  .adhkar-panel-head .adhkar-panel-note,
  .adhkar-panel-note.is-loose{ font-size: 0.84rem; }
}

/* A card with no counter (the sets you consult rather than work through)
   had its lone copy button on a line of its own above the citation on a
   phone — the layout for a card that also carries the count. With nothing
   to count, the citation and the copy button share one line. */
@media (max-width: 560px){
  .adhkar-card-foot:not(:has(.adhkar-card-count)){ flex-wrap: nowrap; }
  .adhkar-card-foot:not(:has(.adhkar-card-count)) .adhkar-card-source{ flex: 1 1 auto; order: 1; }
  .adhkar-card-foot:not(:has(.adhkar-card-count)) .adhkar-card-actions{ flex: 0 0 auto; order: 2; }
}

/* ---- v143-layer-90-ink.css ---- */
/* =========================================================================
   v14.3 — ROOM FOR THE INK.  (item 12)

   "the name of many tafasir in Arabic is partially missing, like some parts
    of the bottom of some characters"

   A label that ends in an ellipsis, or is clamped to two lines, has to clip
   — and it clips at its PADDING box. Amiri and the muṣḥaf face draw well
   outside their own line box: the hamzah over an alif and the ḍammah over
   a kāf rise above it, rāʾ, wāw and ḥāʾ fall below it. Raising the line
   height only moves the lines apart; the glyph still overhangs its own
   line. So the audit (every page, every open menu, desk and phone) still
   found bottoms of letters shaved off at 1.75–1.85.

   The fix is room INSIDE the clip and none outside it: padding that the
   ink can use, taken back with an equal negative margin so nothing on the
   page moves by a pixel. (The two-line book titles were measured first:
   none runs to a third line, so no third line can show in the padding.)
   ========================================================================= */
.tafsir-book-ar,
.tafsir-surah-ar,
.sirah-book-toc-ar {
  --ink-room: 0.34em;
  padding-block: var(--ink-room);
  margin-block: calc(-1 * var(--ink-room));
}
/* It already had a pixel of padding, which the page is laid out around. */
.adhkar-pick-ar {
  --ink-room: 0.3em;
  padding-block: var(--ink-room);
  margin-block: calc(1px - var(--ink-room));
}
/* A row of commentaries that scrolls sideways clips vertically too (a
   scroller clips both ways), and its column heads sit on its top edge: the
   hamzah of الجامع لأحكام القرآن lost its tip. The same room, at the top. */
.tafsir-cols:not([data-cols="1"]) {
  padding-top: 6px;
  margin-top: -6px;
}

/* An excerpt that opens with a verse or a ḥadīth is Arabic (marked by
   pp_text_dir_attrs() in functions.php): it runs from the right, at a line
   height its vowel marks fit in. The family is left alone on purpose —
   --font-ui already sets Arabic in the site's naskh, and an English
   sentence that follows the verse in the same excerpt stays in Inter
   rather than falling to a serif. Three lines, as in English. */
.card-excerpt[lang="ar"] {
  font-size: 0.95rem;
  line-height: 1.95;
  text-align: right;
}
.featured-body .card-excerpt[lang="ar"] { font-size: 1rem; }
/* English that quotes Arabic further on keeps its size and direction; only
   its lines open up, to the spacing the Arabic in them needs. */
.card-excerpt[data-has-ar] { line-height: 1.95; }
