/*
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-two classical works readable a passage at a time, thirteen hadith collections (the Shama'il readable as narrations or as a book), prayer times, a Qibla compass, a tasbih counter and two hundred and thirty-four adhkar, in eight appearances, each with its own metal.
Version: 13.2.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: propheticprofit
*/

/* 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;
}

/* =========================================================================
   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;
}
@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;
}
/* 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.
   */
  --font-display:'Fraunces', 'Newsreader', Georgia, 'Times New Roman', 'Amiri', 'Noto Naskh Arabic', serif;
  --font-body:'Newsreader', Georgia, 'Times New Roman', 'Amiri', 'Noto Naskh Arabic', serif;
  --font-ui:'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Amiri', 'Noto Naskh Arabic', sans-serif;
  --font-mono:'IBM Plex Mono', 'SFMono-Regular', Menlo, 'Amiri', 'Noto Naskh Arabic', 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 48 pairs, all passing at emit time. */

/* -------- SAFFRON (slug: saffron) — Golden paper, burnt spice ink -------- */
:root,
html[data-theme="saffron"]{
  color-scheme: light;
  --bg: 255 245 222;
  --bg-alt: 252 234 197;
  --surface: 255 251 238;
  --text: 58 42 18;
  --text-muted: 117 91 46;
  --heading: 93 43 6;
  --heading-soft: 122 70 20;
  --ink: 56 31 6;
  --ink-soft: 80 48 14;
  --on-ink: 255 246 228;
  --accent: 168 74 8;
  --accent-ui: 158 68 6;
  --accent-light: 247 197 121;
  --accent-2: 16 100 86;
  --accent-3: 139 36 46;
  --shadow: 86 54 12;
  --on-accent: var(--on-ink);
  --gilt-hi: 252 224 168;
  --gilt: 230 178 96;
  --gilt-deep: 192 136 52;
  --gilt-edge: 114 70 12;
  --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);
}

/* -------- PORCELAIN (slug: porcelain) — Glazed white, cold steel ink -------- */
html[data-theme="porcelain"]{
  color-scheme: light;
  --bg: 240 247 252;
  --bg-alt: 225 238 248;
  --surface: 250 253 255;
  --text: 33 48 62;
  --text-muted: 86 103 121;
  --heading: 18 40 60;
  --heading-soft: 44 68 90;
  --ink: 14 30 46;
  --ink-soft: 27 46 66;
  --on-ink: 238 247 253;
  --accent: 19 102 148;
  --accent-ui: 17 95 138;
  --accent-light: 158 208 236;
  --accent-2: 120 76 32;
  --accent-3: 14 104 98;
  --shadow: 24 44 64;
  --on-accent: var(--on-ink);
  --gilt-hi: 250 253 255;
  --gilt: 206 222 236;
  --gilt-deep: 150 175 198;
  --gilt-edge: 58 88 116;
  --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);
}

/* -------- DAMASK (slug: damask) — Blush paper, madder crimson -------- */
html[data-theme="damask"]{
  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);
}

/* -------- 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);
}

/* -------- 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);
}

/* -------- MIDNIGHT (slug: midnight) — Blue-black night, frost light -------- */
html[data-theme="midnight"]{
  color-scheme: dark;
  --bg: 10 17 30;
  --bg-alt: 17 27 44;
  --surface: 22 34 52;
  --text: 220 232 245;
  --text-muted: 148 169 193;
  --heading: 240 248 255;
  --heading-soft: 205 220 238;
  --ink: 6 11 21;
  --ink-soft: 14 23 37;
  --on-ink: 233 243 253;
  --accent: 122 186 238;
  --accent-ui: 152 205 246;
  --accent-light: 196 226 250;
  --accent-2: 234 190 130;
  --accent-3: 128 222 212;
  --shadow: 0 0 0;
  --on-accent: var(--ink);
  --gilt-hi: 238 248 255;
  --gilt: 198 222 244;
  --gilt-deep: 142 180 216;
  --gilt-edge: 68 108 152;
  --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);
}

/* -------- 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);
}

/* -------- 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);
}

/* ==== 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-family:var(--font-mono);
  font-size:0.72rem;
  letter-spacing:0.14em;
  text-transform:uppercase;
  color:rgb(var(--accent));
  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;
}

::selection{ background:rgb(var(--accent) / 0.28); color:rgb(var(--heading)); }

.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(--accent) / 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;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode:multiply; opacity:0.05;
}
html[data-scheme="dark"] .grain-overlay{
  mix-blend-mode:soft-light; opacity:0.16;
}
@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)
   ========================================================================= */
.reading-progress{
  position:fixed; top:0; left:0; height:3px; width:0%; z-index:210;
  background:linear-gradient(90deg, rgb(var(--accent)), rgb(var(--accent-light)));
  transition:width 0.1s linear, opacity 0.2s ease;
  opacity:0;
}
.reading-progress.show{ opacity:1; }

/* =========================================================================
   3. HEADER / NAVIGATION
   ========================================================================= */
.site-header{
  position:fixed; top:0; left:0; right:0; width:100%; z-index:100;
  background:transparent;
  border-bottom:1px solid rgb(var(--heading) / 0.08);
  transition:box-shadow 0.3s var(--ease), border-color 0.35s var(--ease), transform 0.3s var(--ease);
}
/* 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-header::before{
  content:""; position:absolute; inset:0; z-index:-1;
  background:rgb(var(--bg) / 0.82);
  -webkit-backdrop-filter:blur(12px); backdrop-filter:blur(12px);
  transition:background 0.35s var(--ease);
}
.site-header.scrolled{ box-shadow:0 8px 24px -16px rgb(var(--shadow) / 0.35); }
.site-header.hide-on-scroll{ transform:translateY(-100%); }
.site-main{ display:block; padding-top:calc(var(--header-h-static) + 4px); }
/*
 * 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.
 */
.header-inner{
  /*
   * v12.1 — THE SIDE TRACKS SHARE THE SPARE SPACE, BUT NEVER BELOW
   * WHAT IS ACTUALLY IN THEM.
   *
   * This was `minmax(0,1fr) auto minmax(0,1fr)`: both outer tracks took
   * an EQUAL share of the leftover width with no regard for their
   * contents. That is only safe while the two sides are about the same
   * size, and they are not — the logo lockup is ~211px and the actions
   * row ~319px. So from roughly 1240px downwards the shared track came
   * out smaller than the actions needed, and the actions (justify-self:
   * end) spilled leftwards over the last nav item: the clock icon
   * printed on top of the word "About".
   *
   * That is why this fault kept returning. Every previous attempt
   * adjusted paddings and breakpoints; the cause was the equal share,
   * which no padding can rescue once the two sides differ.
   *
   * `max-content` as the track minimum states the missing rule: share
   * the spare space evenly, but never below the width of what you are
   * holding. Above about 1290px both sides are under their fair share,
   * the tracks come out equal, and the nav is exactly centred on the
   * page. Below that the actions keep their width, the logo side gives
   * up the difference, and the nav slides a few pixels left instead of
   * being painted over.
   *
   * Verified by measuring the nav-to-actions and logo-to-nav gaps at
   * every tested width from 1181px to 1920px: no negative gap anywhere.
   */
  /*
   * ═════════════════════════════════════════════════════════════════
   * v12.2 — THE BAR IS A FLEX ROW WITH AUTO MARGINS, NOT A GRID.
   * ═════════════════════════════════════════════════════════════════
   *
   * THE GRID COULD NOT DO THE JOB, AND THE REASON IS ARITHMETIC.
   *
   * v12.1 fixed the overlap by giving the two side tracks a max-content
   * minimum, and that fix was right. What it could not do — what no
   * three-track grid can do — is put the nav in the middle of the bar
   * when the two sides differ in width. The lockup is about 211px and
   * the actions row about 341px. `minmax(max-content,1fr)` hands each
   * track its own contents first and splits the rest evenly, so the
   * sides come out 211+n and 341+n and never match. `1fr auto 1fr`
   * splits first and clamps up, which is equal — but only while half
   * the leftover clears 341px, and inside a 1360px bar holding a 670px
   * nav it never does. Measured: the nav's midpoint was 21px left of
   * centre at 1280px and 40px left at 1600px. Small enough to read as
   * carelessness rather than as a bug, which is how it was reported.
   *
   * AND MATHEMATICAL CENTRING WAS THE WRONG TARGET ANYWAY. Put the nav
   * on the page's exact centre line with a 211px lockup on one side and
   * a 341px cluster on the other, and the gap to the left of the nav
   * comes out 130px wider than the gap to its right. It is centred, and
   * it looks lopsided, because what an eye checks in a bar like this is
   * the two gaps and not the centre line.
   *
   * So: `margin-inline: auto` on the nav. An auto margin on a flex item
   * absorbs free space, and two of them absorb it in equal halves — the
   * gap to the left of the nav and the gap to its right are the same
   * number at EVERY width, by construction, whatever the two sides
   * happen to contain. The bar is balanced at 1181px and at 2560px and
   * at every step between, and it stays balanced if a nav item or a
   * header button is ever added or removed.
   *
   * IT ALSO CANNOT OVERLAP, which is the property v12.1 bought and this
   * must not give back. When the free space reaches zero the auto
   * margins are zero and the row simply packs; nothing is overlaid,
   * because flex items are laid out one after another and never on top
   * of one another. `min-width:max-content` on the nav and on the
   * actions stops either of them being compressed below its contents;
   * the lockup is the one thing allowed to give, and it gives by
   * eliding its tagline.
   */
  display:flex;
  align-items:center; gap:16px;
  justify-content:space-between;
  /* Longhand top/bottom ONLY — not shorthand `padding`. This element
     carries both `.wrap` and `.header-inner`, both classes at the same
     specificity (0,1,0). A shorthand `padding` here would set all four
     sides and, being later in the file, would beat `.wrap{padding:0
     28px}` outright on every side. Longhand top/bottom touches only
     those two sides, so `.wrap`'s own left/right survives the cascade. */
  padding-top:16px; padding-bottom:16px;
  transition:padding 0.3s var(--ease);
}
/* The lockup is the one item allowed to give. */
.header-inner > .logo{ flex:0 1 auto; min-width:0; }
/* 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. */
.header-inner > .main-nav{ flex:0 0 auto; margin-inline:auto; }
/* Every item in the actions row is a fixed-size tap target, and none of
   them may be compressed. */
.header-inner > .header-actions{ flex:0 0 auto; min-width:max-content; }
/*
 * 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.
 */
.site-header .header-inner{ max-width:1360px; }
.site-header.scrolled .header-inner{ padding-top:10px; padding-bottom:10px; }

.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;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.logo-mark{ width:40px; height:40px; flex-shrink:0; transition:transform 0.5s var(--ease); }
.logo:hover .logo-mark{ transform:rotate(45deg); }
.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; }

.main-nav{ display:flex; align-items:center; gap:2px; }
.main-nav ul{ list-style:none; display:flex; align-items:center; gap:2px; margin:0; padding:0; }
/*
 * 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.
 */
.main-nav > ul > li{
  position:relative; display:flex; align-items:center;
  border-radius:var(--radius-pill, 999px);
  transition:background-color 0.2s var(--ease);
}
.site-header .main-nav > ul > li:hover,
.site-header .main-nav > ul > li:focus-within,
.site-header .main-nav > ul > li.open{ background:rgb(var(--accent) / 0.08); }
.nav-link{
  display:inline-flex; align-items:center; gap:4px;
  padding:9px 13px; font-size:0.9rem; font-weight:500; color:rgb(var(--heading-soft));
  border-radius:var(--radius-pill, 999px);
  transition:color 0.2s var(--ease), background 0.2s var(--ease);
  position:relative; white-space:nowrap;
  font-family:inherit; text-align:left;
}
/* --accent-ui: the hovered label is text sitting on a tint of its own
   colour. See the note on .lib-row-topic. */
.nav-link:hover, .nav-link:focus-visible{ color:rgb(var(--accent-ui)); background:transparent; }
.site-header .main-nav > ul > li:hover > .nav-link,
.site-header .main-nav > ul > li:focus-within > .nav-link,
.site-header .main-nav > ul > li.open > .nav-link{ color:rgb(var(--accent-ui)); }
.nav-link-icon{ width:14px; height:14px; margin-right:2px; vertical-align:-2px; }
/* 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. */
.nav-caret-btn{
  display:flex; align-items:center; justify-content:center;
  width:20px; height:32px; margin-left:-9px; margin-right:3px;
  padding:0; border-radius:var(--radius-pill, 999px); appearance:none; -webkit-appearance:none;
  background:transparent; border:none; cursor:pointer;
  color:rgb(var(--heading-soft)); transition:color 0.2s var(--ease);
}
.nav-caret-btn:hover, .nav-caret-btn:focus-visible{ color:rgb(var(--accent-ui)); background:transparent; }
.site-header .main-nav > ul > li:hover > .nav-caret-btn,
.site-header .main-nav > ul > li.open > .nav-caret-btn{ color:rgb(var(--accent-ui)); }
.nav-caret{
  width:11px; height:11px; opacity:0.6; pointer-events:none;
  transition:transform 0.25s var(--ease), opacity 0.2s var(--ease);
}
.has-dropdown:hover .nav-caret, .has-dropdown.open .nav-caret{ transform:rotate(180deg); opacity:0.9; }
/* 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. */
.site-header .nav-mobile-only{ display:none; }
/* 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. */
.site-header .nav-phone-only{ display:none; }

/* 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. */
.site-header button.nav-link{
  width:100%; background:transparent; border:none; appearance:none; -webkit-appearance:none;
}
/* 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. */
.nav-link-badge{
  margin-left:auto; min-width:20px; height:20px; padding:0 6px;
  display:inline-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.64rem; font-weight:700; line-height:1;
}

.mega-panel{
  position:absolute; top:calc(100% + 10px); left:50%; transform:translateX(-50%) translateY(6px);
  width:560px; max-width:calc(100vw - 32px); background:rgb(var(--surface)); border:1px solid rgb(var(--heading) / 0.08);
  border-radius:var(--radius); box-shadow:0 20px 45px -18px rgb(var(--shadow) / 0.35); padding:16px;
  display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:4px;
  opacity:0; visibility:hidden; transition:opacity 0.2s var(--ease), transform 0.2s var(--ease), visibility 0.2s;
}
.has-dropdown:hover .mega-panel, .has-dropdown.open .mega-panel{
  opacity:1; visibility:visible; transform:translateX(-50%) translateY(0);
}
.mega-item{
  display:flex; gap:11px; align-items:flex-start; padding:11px; border-radius:10px; min-width:0;
  transition:background 0.2s var(--ease), transform 0.2s var(--ease);
}
.mega-item .mega-title, .mega-item .mega-desc{ min-width:0; overflow-wrap:anywhere; }
.mega-item:hover{ background:rgb(var(--accent) / 0.09); transform:translateX(2px); }
.mega-item svg{ width:19px; height:19px; color:rgb(var(--accent)); flex-shrink:0; margin-top:2px; }
.mega-item .mega-title{ font-size:0.87rem; font-weight:600; color:rgb(var(--heading)); display:block; }
.mega-item .mega-desc{ font-size:0.76rem; color:rgb(var(--text-muted)); display:block; margin-top:2px; line-height:1.4; }
.mega-panel-foot{
  grid-column:1 / -1; border-top:1px solid rgb(var(--heading) / 0.08); margin-top:6px; padding:10px 11px 2px;
  font-size:0.76rem; color:rgb(var(--text-muted));
}
.mega-panel-foot a{ color:rgb(var(--accent)); font-weight:600; }

.header-actions{ display:flex; align-items:center; gap:8px; flex-shrink:0; }
/*
 * 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.
 */
.header-actions > *{ flex-shrink:0; }
/* 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. */
.header-actions-sep{
  width:1px; height:20px; flex-shrink:0; margin:0 3px;
  background:rgb(var(--heading) / 0.14); border-radius:1px;
}
/*
 * 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. */
.site-header .header-actions .pp-tool-kaaba svg{ width:17px; height:17px; }

/* 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. */
.site-header .header-actions .pp-tool-btn[aria-current="page"]{
  color: rgb(var(--accent-ui));
  background: rgb(var(--accent) / 0.12);
}
/* 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. */
.pp-install-btn{ position:relative; }
.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));
}
.icon-btn{
  width:38px; height:38px; display:flex; align-items:center; justify-content:center;
  background:transparent; border:1px solid rgb(var(--heading) / 0.15); border-radius:50%;
  color:rgb(var(--heading-soft)); transition:background 0.2s var(--ease), transform 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
  position:relative; flex-shrink:0;
}
.icon-btn:hover{ background:rgb(var(--ink)); color:rgb(var(--on-ink)); border-color:rgb(var(--ink)); transform:translateY(-1px); }
.icon-btn svg{ width:16px; height:16px; }
.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;
  background:rgb(var(--surface)); border:1px solid rgb(var(--heading) / 0.1);
  border-radius:var(--radius); box-shadow:0 20px 45px -18px rgb(var(--shadow) / 0.35);
  padding:14px 14px 12px;
  opacity:0; visibility:hidden; transform:translateY(-6px);
  transition:opacity 0.2s var(--ease), transform 0.2s var(--ease), visibility 0.2s;
  z-index:20;
}
.theme-panel.open{ opacity:1; visibility:visible; transform:translateY(0); }

.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; }
.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;
  transition:background 0.2s var(--ease), border-color 0.2s var(--ease);
}
.theme-option:hover{ background:rgb(var(--accent) / 0.07); }
.theme-option[aria-pressed="true"]{
  border-color:rgb(var(--accent) / 0.35); background:rgb(var(--accent) / 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(255 245 222); --sw-surface:rgb(255 251 238); --sw-head:rgb(93 43 6); --sw-text:rgb(117 91 46); --sw-accent:rgb(168 74 8); --sw-edge:rgb(93 43 6 / 0.16); }
.theme-option[data-swatch="porcelain"]{ --sw-bg:rgb(240 247 252); --sw-surface:rgb(250 253 255); --sw-head:rgb(18 40 60); --sw-text:rgb(86 103 121); --sw-accent:rgb(19 102 148); --sw-edge:rgb(18 40 60 / 0.16); }
.theme-option[data-swatch="damask"]{ --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(10 17 30); --sw-surface:rgb(22 34 52); --sw-head:rgb(240 248 255); --sw-text:rgb(148 169 193); --sw-accent:rgb(122 186 238); --sw-edge:rgb(240 248 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; transition:transform 0.25s var(--ease), box-shadow 0.25s var(--ease), background 0.25s var(--ease), color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.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-ghost{ border-color:rgb(var(--heading) / 0.25); color:rgb(var(--heading)); background:transparent; }
.btn-ghost:hover{ border-color:rgb(var(--heading) / 0.42); background:rgb(var(--heading) / 0.06); color:rgb(var(--heading)); transform:translateY(-2px); }
.btn-sm{ padding:9px 16px; font-size:0.8rem; }

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

/* =========================================================================
   4. HERO
   ========================================================================= */
.hero{ padding:76px 0 40px; position:relative; z-index:1; }
.hero-frame{
  position:relative; border:1px solid rgb(var(--accent) / 0.35); border-radius:var(--radius-lg);
  padding:64px 40px; text-align:center; overflow:hidden;
  background:
    radial-gradient(ellipse 60% 50% at 50% 0%, rgb(var(--accent) / 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{ width:340px; height:340px; top:-90px; right:-70px; transform:rotate(12deg); }
.hero-watermark-2{ width:210px; height:210px; bottom:-60px; left:-50px; transform:rotate(-18deg); }
.corner{ position:absolute; width:46px; height:46px; color:rgb(var(--accent)); opacity:0.7; }
.corner.tl{ top:14px; left:14px; }
.corner.tr{ top:14px; right:14px; transform:scaleX(-1); }
.corner.bl{ bottom:14px; left:14px; transform:scaleY(-1); }
.corner.br{ bottom:14px; right:14px; transform:scale(-1,-1); }

.hero-content{ max-width:660px; margin:0 auto; position:relative; z-index:1; }
.hero .eyebrow{ display:block; margin-bottom:18px; }
.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;
  font-size:clamp(1.05rem, 2.4vw, 1.35rem); letter-spacing:0;
  color:rgb(var(--accent)); margin-top:14px; text-transform:none;
}

.hero p.desc{ margin-top:24px; color:rgb(var(--text-muted)); font-size:1.05rem; max-width:500px; margin-left:auto; margin-right:auto; line-height:1.7; }
.hero-ctas{ display:flex; gap:14px; justify-content:center; margin-top:34px; flex-wrap:wrap; }
.hero-note{ font-size:0.8rem; color:rgb(var(--text-muted)); margin-top:16px; font-style:italic; }

.hero-stats{ display:flex; align-items:center; justify-content:center; gap:22px; margin-top:38px; 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; font-size:1.6rem; color:rgb(var(--heading)); line-height:1; }
.hero-stat-label{ font-family:var(--font-mono); font-size:0.64rem; letter-spacing:0.06em; text-transform:uppercase; color:rgb(var(--text-muted)); }
.hero-stat-divider{ width:1px; height:30px; background:rgb(var(--heading) / 0.15); }

/* =========================================================================
   5. REVEAL / SECTION SHELL
   ========================================================================= */
.reveal{ opacity:0; transform:translateY(18px); transition:opacity 0.6s var(--ease), transform 0.6s var(--ease); }
.reveal.in-view{ opacity:1; transform:translateY(0); }

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{ font-size:clamp(1.7rem, 3.4vw, 2.1rem); 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); }
.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;
}
.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; position:relative; overflow:hidden;
  background:linear-gradient(135deg, rgb(var(--ink)) 0%, rgb(var(--ink-soft)) 55%, rgb(var(--accent-3)) 100%);
}
.featured-cover img{ width:100%; height:100%; object-fit:cover; transition:transform 0.6s var(--ease); }
.featured-card:hover .featured-cover img{ transform:scale(1.045); }
.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(--accent-ui) / 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); }
.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; }
.card-meta{ font-family:var(--font-mono); font-size:0.7rem; color:rgb(var(--text-muted)); display:flex; gap:14px; margin-top:auto; padding-top:6px; }

/* 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;
  opacity:0.42; 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{
  content:'\201C'; 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; margin-top:22px; }
.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; background:linear-gradient(90deg, rgb(var(--accent-light)), rgb(var(--accent-3))); 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);
}
.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%);
}
.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);
}
.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); }
.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; }
.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)); }
.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);
}
.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(--accent) / 0.3); }
.welcome-icon{
  width:54px; height:54px; border-radius:50%; background:rgb(var(--accent) / 0.12); color:rgb(var(--accent));
  display:flex; align-items:center; justify-content:center; margin:0 auto 18px; transition:transform 0.3s var(--ease);
}
.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
   ========================================================================= */
.articles-grid{ display:grid; grid-template-columns:repeat(3, 1fr); gap:24px; }
.article-card{
  border-radius:18px; 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);
  border:1px solid rgb(var(--heading) / 0.07); transition:transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
  display:flex; flex-direction:column;
}
.article-card:hover{ transform:translateY(-6px); box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5), 0 24px 50px -18px rgb(var(--shadow) / 0.35); }
.article-cover{ height:140px; position:relative; overflow:hidden; }
.article-cover img{ width:100%; height:100%; object-fit:cover; transition:transform 0.6s var(--ease); }
.article-card:hover .article-cover img{ transform:scale(1.06); }
.article-body{ padding:20px 20px 22px; display:flex; flex-direction:column; gap:10px; flex:1; }
.article-body h3{ font-size:1.18rem; line-height:1.32; }
.article-body h3 a:hover{ color:rgb(var(--accent)); }
.article-body p{ font-size:0.86rem; color:rgb(var(--text-muted)); margin:0; line-height:1.6; }
.article-body .card-meta{ margin-top:auto; }

/* =========================================================================
   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); }
.essay-link:hover{ color:rgb(var(--accent)); padding-left:8px; }
.essay-link:hover svg{ opacity:1; transform:translateX(0); }

/* =========================================================================
   11. NEWSLETTER
   ========================================================================= */
.newsletter-band{ background:rgb(var(--ink)); color:rgb(var(--on-ink)); border-radius:24px; padding:58px 48px; text-align:center; position:relative; overflow:hidden; 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(--accent) / 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{ background:rgb(var(--ink)); 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);
}
.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; transition:color 0.2s var(--ease); }
.footer-col a:hover{ color:rgb(var(--accent-light)); }
.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);
  transition:opacity 0.25s var(--ease), transform 0.25s var(--ease), visibility 0.25s, background 0.2s var(--ease); z-index:90;
}
.back-top.show{ opacity:1; visibility:visible; transform:translateY(0); }
.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)); transition:color 0.2s var(--ease); }

/* =========================================================================
   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(--accent) / 0.4); text-underline-offset:3px; transition:color 0.2s var(--ease), text-decoration-color 0.2s var(--ease); }
.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{
  margin:1.8em 0; padding:16px 24px; border-left:3px solid rgb(var(--accent));
  background:rgb(var(--accent) / 0.06); font-family:var(--font-display); font-style:italic; font-weight:500; font-size:1.18rem; color:rgb(var(--heading-soft));
  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-mono); 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(--accent) / 0.055);
  border:1px solid rgb(var(--accent) / 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(--accent) / 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);
}
.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)); }
.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(--accent) / 0.35); border-radius:999px; transition:background 0.2s var(--ease), color 0.2s var(--ease);
}
.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); }
.related-section .articles-grid{ grid-template-columns:repeat(auto-fit, minmax(200px, 1fr)); }

/* =========================================================================
   19. SCROLL-SYNCED MINI TITLE / PROGRESS BAR (single posts)
   ========================================================================= */
.mini-bar{
  position:fixed; top:var(--header-h); left:0; right:0; z-index:95;
  background:rgb(var(--surface) / 0.96); backdrop-filter:blur(8px);
  border-bottom:1px solid rgb(var(--heading) / 0.08);
  transform:translateY(-100%); opacity:0; pointer-events:none;
  transition:transform 0.3s var(--ease), opacity 0.3s var(--ease), top 0.3s var(--ease);
}
.mini-bar.show{ transform:translateY(0); opacity:1; pointer-events:auto; }
.mini-bar.header-hidden{ top:0; }
.mini-bar-inner{ display:flex; align-items:center; gap:16px; padding:10px 28px; }
.mini-bar-title{ font-family:var(--font-display); font-weight:600; font-size:0.92rem; color:rgb(var(--heading)); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:40%; }
.mini-bar-track{ flex:1; height:4px; background:rgb(var(--heading) / 0.1); border-radius:2px; overflow:hidden; }
.mini-bar-fill{ height:100%; width:0%; background:linear-gradient(90deg, rgb(var(--accent)), rgb(var(--accent-light))); transition:width 0.1s linear; }
.mini-bar-pct{ font-family:var(--font-mono); font-size:0.7rem; color:rgb(var(--text-muted)); flex-shrink:0; }
@media (max-width:600px){ .mini-bar-title{ display:none; } .mini-bar-inner.mini-bar-inner{ padding:10px 20px; } }

/* =========================================================================
   20. SINGLE POST — reading rail (actions + table of contents)
   ========================================================================= */
.article-shell{ padding:52px 0 0; }
.article-grid{
  display:grid; grid-template-columns:224px minmax(0,1fr); gap:56px; align-items:start;
}
.article-main{ min-width:0; max-width:720px; }

.article-rail{ position:sticky; top:calc(var(--header-h) + 22px); align-self:start; }
.rail-inner{ display:flex; flex-direction:column; gap:22px; }

.rail-actions{ display:flex; flex-direction:column; gap:6px; }
.rail-btn{
  display:flex; align-items:center; gap:10px; padding:9px 10px; border-radius:10px; border:1px solid transparent;
  background:transparent; color:rgb(var(--text-muted)); font-size:0.83rem; font-weight:500; width:100%; text-align:left;
  transition:background 0.2s var(--ease), color 0.2s var(--ease), border-color 0.2s var(--ease), transform 0.2s var(--ease);
}
.rail-btn:hover{ background:rgb(var(--accent) / 0.08); color:rgb(var(--heading)); transform:translateX(2px); }
.rail-btn svg{ width:17px; height:17px; flex-shrink:0; }
.rail-btn[aria-pressed="true"]{ color:rgb(var(--accent-2)); }
.rail-btn[aria-pressed="true"] svg{ fill:rgb(var(--accent-2) / 0.18); stroke:rgb(var(--accent-2)); }
.rail-btn .rail-count{ margin-left:auto; font-family:var(--font-mono); font-size:0.72rem; color:rgb(var(--text-muted)); }
.rail-btn.copied{ color:rgb(var(--accent-3)); }

/* 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-btn.pulse svg{ animation:heartPulse 0.45s var(--ease); }

.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);
}
.rail-fontsize button:hover{ background:rgb(var(--accent) / 0.12); border-color:rgb(var(--accent) / 0.4); }

.rail-divider{ height:1px; background:rgb(var(--heading) / 0.09); }

.rail-toc{ display:flex; flex-direction:column; gap:10px; }
.rail-toc-label{ font-family:var(--font-mono); font-size:0.66rem; letter-spacing:0.1em; text-transform:uppercase; color:rgb(var(--text-muted)); }
.toc-body{ display:flex; gap:12px; }
.toc-track{ width:2px; border-radius:2px; background:rgb(var(--heading) / 0.1); flex-shrink:0; position:relative; }
.toc-progress{ position:absolute; top:0; left:0; width:100%; background:rgb(var(--accent)); border-radius:2px; height:0%; transition:height 0.15s linear; }
#tocList{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:2px; flex:1; }
#tocList li a{
  display:block; padding:5px 0; font-size:0.83rem; line-height:1.4; color:rgb(var(--text-muted));
  transition:color 0.2s var(--ease), padding-left 0.2s var(--ease); border-left:2px solid transparent;
  padding-left:10px; margin-left:-11px;
}
#tocList li.toc-level-3 a{ padding-left:22px; font-size:0.78rem; }
#tocList li a:hover{ color:rgb(var(--heading)); }
#tocList li a.active{ color:rgb(var(--accent)); font-weight:600; border-left-color:rgb(var(--accent)); }
.rail-empty{ font-size:0.78rem; color:rgb(var(--text-muted)); font-style:italic; }

.rail-toggle{ display:none; }

/* =========================================================================
   21. ARTICLE HEADER / META (single.php)
   ========================================================================= */
.article-header{ margin-bottom:32px; }
.article-header h1{ margin-top:16px; font-size:clamp(2rem,5vw,2.9rem); line-height:1.15; }
.article-meta-row{ display:flex; align-items:center; gap:16px; margin-top:16px; flex-wrap:wrap; }
.article-meta-row .card-meta{ margin-top:0; }
.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, .pagination .page-numbers:hover{
  background:rgb(var(--ink)); color:rgb(var(--on-ink)); border-color:rgb(var(--ink));
}

/* =========================================================================
   23. SAVED REFLECTIONS PAGE
   ========================================================================= */
.saved-card{ position:relative; }
.saved-remove{
  position:absolute; top:12px; right:12px; z-index:2; width:32px; height:32px; border-radius:50%;
  background:rgb(var(--surface) / 0.9); backdrop-filter:blur(4px); border:1px solid rgb(var(--heading) / 0.15);
  color:rgb(var(--accent-2)); display:flex; align-items:center; justify-content:center;
  transition:background 0.2s var(--ease), color 0.2s var(--ease), transform 0.2s var(--ease);
}
.saved-remove:hover{ background:rgb(var(--accent-2)); color:rgb(var(--on-accent)); transform:scale(1.08); }
.saved-remove svg{ width:14px; height:14px; }

/* =========================================================================
   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;
}
.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 ---- */
.hadith-panel{
  width:520px; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:2px; padding:12px;
}
.hadith-menu-row{
  display:flex; align-items:center; gap:11px; padding:9px 11px; border-radius:10px; min-width:0;
  transition:background 0.2s var(--ease), transform 0.2s var(--ease);
}
.hadith-menu-row:hover{ background:rgb(var(--accent) / 0.09); transform:translateX(2px); }
.hadith-menu-ic{
  width:32px; height:32px; flex-shrink:0; border-radius:9px;
  background:rgb(var(--accent) / 0.13); color:rgb(var(--accent));
  display:flex; align-items:center; justify-content:center;
}
.hadith-menu-ic svg{ width:16px; height:16px; }
.hadith-menu-main{ display:flex; flex-direction:column; gap:1px; min-width:0; flex:1; }
.hadith-menu-title{ font-family:var(--font-display); font-weight:600; font-size:0.9rem; color:rgb(var(--heading)); line-height:1.3; overflow-wrap:anywhere; }
/* --accent-ui: this line appears inside .quran-menu-resume, whose panel is
   a 10% accent tint. See the note on .lib-row-topic. */
.hadith-menu-count{ font-family:var(--font-mono); font-size:0.64rem; letter-spacing:0.03em; color:rgb(var(--accent-ui)); white-space:nowrap; }
/* ---- Qur'an nav dropdown additions ---- */
.quran-menu-resume{
  display:flex; align-items:center; gap:11px; padding:9px 11px; border-radius:10px; min-width:0; margin-bottom:4px;
  background:rgb(var(--accent) / 0.1); border:1px solid rgb(var(--accent) / 0.22);
  transition:background 0.2s var(--ease), transform 0.2s var(--ease);
}
.quran-menu-resume:hover{ background:rgb(var(--accent) / 0.16); transform:translateX(2px); }
.quran-menu-ic{
  width:32px; height:32px; flex-shrink:0; border-radius:9px;
  background:rgb(var(--accent) / 0.13); color:rgb(var(--accent));
  display:flex; align-items:center; justify-content:center;
}
.quran-menu-ic svg{ width:16px; height:16px; }
.quran-menu-ar{
  font-family:var(--font-arabic); font-weight: var(--ar-weight); direction:rtl; font-size:1.1rem; color:rgb(var(--heading-soft));
  min-width:56px; flex-shrink:0; text-align:center; line-height:1.3; white-space:nowrap;
}

/* ---- /hadith/ index page ---- */
.hadith-grid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(260px, 1fr)); gap:22px; }
.hadith-collection-card{
  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:30px 26px; transition:transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
}
.hadith-collection-card: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(--accent) / 0.35); }
.hadith-collection-icon{
  width:50px; height:50px; border-radius:14px; background:rgb(var(--accent) / 0.12); color:rgb(var(--accent));
  display:flex; align-items:center; justify-content:center; margin-bottom:16px;
}
.hadith-collection-icon svg{ width:24px; height:24px; }
.hadith-collection-arabic{ display:block; font-family:var(--font-arabic); font-weight: var(--ar-weight); direction:rtl; font-size:1.3rem; color:rgb(var(--heading-soft)); margin-bottom:4px; }
.hadith-collection-card h3{ font-size:1.25rem; margin-bottom:8px; }
.hadith-collection-card p{ color:rgb(var(--text-muted)); font-size:0.88rem; line-height:1.55; margin:0 0 16px; }

/* ---- /hadith/{collection}/ browse page ---- */
.hadith-book-header{
  display:flex; align-items:center; gap:20px; padding:28px; margin-bottom:32px;
  background:rgb(var(--bg-alt)); border:1px solid rgb(var(--accent) / 0.2); border-radius:var(--radius-lg); flex-wrap:wrap;
}
.hadith-book-icon{
  width:56px; height:56px; border-radius:50%; background:rgb(var(--ink)); color:rgb(var(--accent-light));
  display:flex; align-items:center; justify-content:center; flex-shrink:0;
}
.hadith-book-icon svg{ width:26px; height:26px; }.hadith-book-meta .eyebrow{ font-family:var(--font-arabic); font-weight: var(--ar-weight); direction:rtl; font-size:1rem; text-transform:none; letter-spacing:0; display:block; }.hadith-book-author{ color:rgb(var(--text-muted)); font-size:0.88rem; 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; gap:10px; }
.hadith-card{
  display:flex; align-items:flex-start; gap:16px; padding:18px 20px; background:rgb(var(--surface));
  border:1px solid rgb(var(--heading) / 0.07); border-radius:14px;
  transition:background 0.2s var(--ease), border-color 0.2s var(--ease), transform 0.2s var(--ease);
}
.hadith-card:hover{ background:rgb(var(--accent) / 0.05); border-color:rgb(var(--accent) / 0.25); transform:translateX(3px); }
.hadith-card-num{
  width:34px; height:34px; border-radius:50%; background:rgb(var(--accent) / 0.12); color:rgb(var(--accent));
  display:flex; align-items:center; justify-content:center; font-family:var(--font-mono); font-size:0.76rem; font-weight:600; flex-shrink:0;
}
.hadith-card-body{ flex:1; min-width:0; }
.hadith-card-chapter{ font-family:var(--font-mono); font-size:0.64rem; letter-spacing:0.06em; text-transform:uppercase; color:rgb(var(--accent)); }
.hadith-card-narrator{ font-size:0.78rem; font-style:italic; color:rgb(var(--text-muted)); margin:4px 0 2px; }
/* 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{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  direction: rtl; unicode-bidi: isolate; text-align: right;
  font-size: 1.12rem; line-height: 1.95;
  color: rgb(var(--heading));
  margin: 0 0 8px;
}
.hadith-card-excerpt{ font-family:var(--font-body); font-size:0.98rem; color:rgb(var(--text)); line-height:1.55; 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); }
.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.
   ========================================================================= */
.hadith-book-header{
  position: relative; overflow: hidden;
  align-items: center; gap: var(--sp-5);
  padding: var(--sp-8) var(--sp-6);
  background:
    radial-gradient(120% 100% at 50% 0%, rgb(var(--accent) / 0.10), transparent 62%),
    rgb(var(--surface));
  border: 1px solid rgb(var(--accent) / 0.28);
  box-shadow: var(--e2);
}
/* 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(--accent) / 0) 0%, rgb(var(--accent) / 0.85) 22%,
    rgb(var(--accent) / 0.85) 78%, rgb(var(--accent) / 0) 100%);
}
.hadith-book-icon{
  width: 60px; height: 60px;
  background: rgb(var(--accent) / 0.12);
  color: rgb(var(--accent-ui));
  border: 1px solid rgb(var(--accent) / 0.35);
}
.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. */
.hadith-card:hover{
  transform: none;
  border-color: rgb(var(--accent) / 0.4);
  box-shadow: var(--e2);
}
.hadith-card-num{
  width: 38px; height: 38px;
  background: transparent;
  border: 1px solid rgb(var(--accent) / 0.4);
  color: rgb(var(--accent-ui));
  font-size: 0.8rem;
}
.hadith-card:hover .hadith-card-num{ background: rgb(var(--accent) / 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-menu-count,
  .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{ font-family:var(--font-arabic); font-weight: var(--ar-weight); direction:rtl; font-size:1.1rem; color:rgb(var(--text-muted)); margin-top:6px; }

.hadith-arabic{
  font-family:var(--font-arabic); font-weight: var(--ar-weight); direction:rtl; unicode-bidi:isolate; text-align:right;
  font-size:1.4em; line-height:2.15; color:rgb(var(--heading));
  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(--accent) / 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; }
.hadith-action-btn:hover{ transform:none; border-color:rgb(var(--accent) / 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(--accent) / 0.4); background:rgb(var(--accent) / 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%;
}
.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; }
.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){
  .article-shell .article-grid{ grid-template-columns:minmax(0,1fr); gap:0; }
  .article-rail.article-rail{
    position:sticky; top:var(--header-h); z-index:40; align-self:auto;
    background:rgb(var(--bg) / 0.94); backdrop-filter:blur(8px);
    border-bottom:1px solid rgb(var(--heading) / 0.08); margin-bottom:32px;
    padding:6px 0;
    /* Without this, the rail's un-shrinkable horizontal toolbar (below)
       forced this grid item — and with it, the whole single-column grid
       including the article text — wider than the viewport, hiding the
       overflow off the left/right edge instead of showing it. */
    min-width:0;
  }
  /* 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-inner.rail-inner{
    flex-direction:row; align-items:center; gap:10px;
    padding:4px; min-width:0; overflow:visible;
  }
  .rail-actions.rail-actions{
    flex-direction:row; gap:2px;
    flex:1 1 auto; min-width:0;
    overflow-x:auto; -webkit-overflow-scrolling:touch; scrollbar-width:none;
  }
  .rail-actions::-webkit-scrollbar{ display:none; }
  .rail-btn.rail-btn{ width:auto; min-width:44px; min-height:44px; padding:10px; border-radius:10px; justify-content:center; flex-shrink:0; }
  .rail-btn .rail-label, .rail-btn .rail-count{ display:none; }
  .rail-fontsize.rail-fontsize{ margin-top:0; flex-shrink:0; }
  .rail-fontsize button{ min-width:34px; min-height:34px; }
  .rail-divider.rail-divider{ width:1px; height:26px; flex:0 0 auto; }
  /* 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. */
  .rail-toc{ flex:0 0 auto; min-width:0; position:static; }
  .rail-toc-label{ display:none; }
  .toc-body.toc-body{ display:none; }
  .rail-toggle.rail-toggle{
    display:flex; align-items:center; gap:6px; font-size:0.8rem; font-weight:600; color:rgb(var(--heading));
    background:transparent; border:none; padding:10px 4px; min-height:44px; white-space:nowrap;
  }
  .rail-toggle svg{ width:13px; height:13px; transition:transform 0.2s var(--ease); flex-shrink:0; }
  .article-rail.toc-open .rail-toggle svg{ transform:rotate(180deg); }
  .article-rail.toc-open .toc-body{
    display:flex; position:absolute; left:0; right:0; top:100%; background:rgb(var(--surface));
    border:1px solid rgb(var(--heading) / 0.1); border-radius:0 0 var(--radius) var(--radius); padding:16px 20px;
    box-shadow:0 20px 45px -18px rgb(var(--shadow) / 0.35); max-height:60vh; overflow-y:auto;
  }
  .mini-bar{ display:none; } /* 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); }
  .articles-grid.articles-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:1300px){
  /* `.site-header .main-nav .nav-link` (0,3,0), not (0,2,0): the v7.1
     elevation pass further down this file re-declares
     `.site-header .nav-link{padding:9px 14px}` at (0,2,0), and a
     same-specificity rule here would lose to it on source order — which
     is exactly what happened on the first attempt at this block, where
     the nav measured 590px at 1181px whether the query matched or not. */
  .site-header .main-nav .nav-link{ padding-left:10px; padding-right:10px; }
  .site-header .header-actions{ gap:6px; }
  .site-header .icon-btn{ width:36px; height:36px; }
  .site-header .header-inner{ gap:12px; }
}

@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. ---- */
  .menu-toggle.menu-toggle{
    display:flex; width:44px; height:44px; align-items:center; justify-content:center;
    background:transparent; border:1px solid rgb(var(--heading) / 0.15); border-radius:12px;
    color:rgb(var(--heading)); flex-shrink:0;
    transition:background 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
  }
  .menu-toggle:hover{ background:rgb(var(--accent) / 0.08); border-color:rgb(var(--accent) / 0.3); }
  .menu-toggle.is-open{ background:rgb(var(--accent) / 0.12); border-color:rgb(var(--accent) / 0.4); color:rgb(var(--accent)); }
  .menu-toggle svg{ width:18px; height:18px; }

  .main-nav.main-nav{
    position:fixed; top:var(--header-h); right:0; bottom:0; left:auto;
    width:min(88%, 380px); background:rgb(var(--bg));
    display:flex; flex-direction:column; align-items:stretch;
    padding:12px 20px calc(28px + env(safe-area-inset-bottom));
    padding-right:calc(20px + env(safe-area-inset-right));
    gap:0; transform:translateX(100%);
    transition:transform 0.34s cubic-bezier(0.4, 0, 0.2, 1);
    box-shadow:-18px 0 50px -18px rgb(var(--shadow) / 0.5);
    border-left:1px solid rgb(var(--heading) / 0.08);
    /* Inside .site-header's stacking context, so this number only
       orders it against its siblings there — it can never lift the
       drawer above the header itself. See the note on .overlay. */
    z-index:97; overflow-y:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch;
  }
  .main-nav.open{ transform:translateX(0); }
  .main-nav > ul{ display:flex; flex-direction:column; width:100%; gap:0; list-style:none; margin:0; padding:0; }
  .main-nav > ul > li{ width:100%; border-bottom:1px solid rgb(var(--heading) / 0.07); display:flex; align-items:stretch; flex-wrap:wrap; }
  .main-nav > ul > li:last-child{ border-bottom:none; }
  /* 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. */
  .site-header .main-nav > ul > li{ border-radius:0; background:transparent; }
  .site-header .main-nav > ul > li:hover,
  .site-header .main-nav > ul > li:focus-within,
  .site-header .main-nav > ul > li.open{ background:transparent; }
  .main-nav .nav-link{
    display:flex; align-items:center; justify-content:flex-start; flex:1; min-width:0;
    min-height:52px; padding:14px 6px; font-size:1.02rem; border-radius:0;
  }
  .main-nav .has-dropdown > .nav-link{ font-weight:600; }
  .main-nav .nav-caret{ display:none; }
  /* 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. */
  .main-nav .nav-caret-btn{
    width:52px; height:auto; min-height:52px; margin-left:0; margin-right:0; border-radius:0;
    border-left:1px solid rgb(var(--heading) / 0.07);
  }
  .main-nav .nav-caret-btn::before{
    content:""; width:8px; height:8px;
    border-right:2px solid currentColor; border-bottom:2px solid currentColor;
    transform:rotate(45deg) translateY(-2px); opacity:0.45;
    transition:transform 0.25s var(--ease), opacity 0.2s var(--ease);
  }
  .has-dropdown.open .nav-caret-btn::before{ transform:rotate(-135deg) translateY(2px); opacity:0.85; }
  .main-nav .nav-link:hover, .main-nav .nav-link:focus-visible{ background:transparent; color:rgb(var(--accent)); }
  /* 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. */
  .site-header .nav-mobile-only.nav-mobile-only{ display:block; }
  .nav-drawer-cta{ display:block; margin-top:20px; }
  .nav-drawer-cta .btn{ width:100%; justify-content:center; }
  /* 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. */
  .main-nav .mega-panel{
    position:static; width:100%; max-width:none; transform:none; box-shadow:none; border:none;
    background:transparent; opacity:1; visibility:visible; display:none;
    grid-template-columns:1fr; gap:0; padding:0 0 12px; margin:0 0 8px 4px;
    border-left:2px solid rgb(var(--accent) / 0.28);
  }
  .main-nav .has-dropdown.open .mega-panel{ display:grid; }
  .main-nav .has-dropdown .mega-panel{
    /* Neutralizes the desktop hover-state rule's translateX(-50%) —
       .has-dropdown:hover .mega-panel / .has-dropdown.open .mega-panel
       is 3 classes (specificity 3), which silently beat every previous
       attempt at this reset (all 2 classes or fewer) and shifted the
       whole panel and everything in it left by half its own width,
       invisibly clipped by overflow-x:clip. This is the actual,
       previously-unidentified cause of the "menu text not showing /
       huge blank space" bug. !important is deliberate here: we proved
       by testing that getting the specificity numerically higher than
       3 is easy to get subtly wrong again later, and this exact
       property (transform/left, only in the mobile drawer) has no
       legitimate reason to ever be contested further. */
    transform:none !important; left:auto !important; top:auto !important;
  }
  .main-nav .mega-item{ padding:11px 12px; gap:11px; }
  .main-nav .mega-item:hover{ transform:none; background:rgb(var(--accent) / 0.07); }
  .main-nav .mega-item .mega-desc{ display:none; }
  .main-nav .hadith-menu-row{ padding:11px 12px; }
  .main-nav .hadith-menu-row:hover{ transform:none; background:rgb(var(--accent) / 0.07); }
  .main-nav .mega-panel-foot{ display:block; grid-column:1; border-top:none; padding:6px 12px 0; margin-top:2px; font-size:0.82rem; }
  .main-nav .hadith-panel{ width:100%; grid-template-columns:1fr; }
  .nav-only-desktop{ display:none; }
  /* 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. */
  .site-header .header-actions .icon-btn{ width:44px; height:44px; }
  .site-header .header-actions{ gap:6px; }
  .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.
   ========================================================================= */
@media (max-width:860px){
  /* v11.4 — the .is-bar-overflow rule that lived here is gone: the
     class no longer appears in the markup (see header.php). Left
     un-collapsed on purpose so this block's line numbers don't shift
     against the CHANGELOG note above it. */
  .site-header .nav-phone-only.nav-phone-only{ display:block; }
}

/* =========================================================================
   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; }
  .articles-grid.articles-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){
  .site-header .header-inner{ gap:8px; }

  /* 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. */
  .site-header .logo{ min-width:0; flex-shrink:1; gap:8px; }
  .site-header .logo-text{ display:flex; min-width:0; }
  .site-header .logo-text .name{
    /* 0.98rem, not the desktop 1.28rem: measured, this is what lets the
       full name sit beside three 44px buttons at 360px — the most common
       narrow Android width — with the row still 6px inside its budget.
       ellipsis is the safety net, not the plan: if Fraunces fails to load
       and the wider Georgia fallback is used, the name shortens rather
       than pushing the row into a horizontal scroll. */
    font-size:0.98rem;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  }
  .site-header .logo-text .tagline{ display:none; }
  .site-header .logo-mark{ width:32px; height:32px; }

  /*
   * 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-install-btn,
  .site-header .header-actions .pp-tasbih-bead,
  /* v12.0 — and the two restored worship-tool icons. The drawer gives
     both a full 52px labelled row ("Prayer Times", "Qibla Direction"),
     which is strictly better than an unlabelled glyph at this width;
     this is the same trade v8.0 measured and it still holds. */
  .site-header .header-actions .pp-tool-btn{ display:none; }

  .site-header .header-actions{ gap:6px; }
  .site-header .header-actions .icon-btn{ width:44px; height:44px; }
  .site-header .header-actions .icon-btn svg{ width:18px; height:18px; }
  .site-header .header-actions-sep{ display:none; }
  .site-header .menu-toggle{ width:44px; height:44px; border-radius:13px; }
  .site-header .menu-toggle svg{ width:19px; height:19px; }

  /* 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:353px){
  /* Where the wordmark finally has to go — and the number is measured in a
     real render, not estimated. The row needs 40px of `.wrap` padding, a
     32px mark, an 8px lockup gap, ~122px of name, an 8px row gap and 144px
     of buttons: 354px of viewport. At 360px and at 375px it fits; below
     that it would start ellipsising, and a brand cut to "Prophetic Profi…"
     reads as a bug rather than as a choice.

     So the mark alone carries it here — and the buttons keep their full
     42px, which is the opposite of the trade every earlier release made. */
  .site-header .logo-text{ display:none; }
  .site-header .logo{ gap:0; }
  .site-header .logo-mark{ width:30px; height:30px; }
  .site-header .header-actions{ gap:5px; }
}

@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. */
  .site-header .header-inner{ padding-top:12px; padding-bottom:12px; }
  .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.
 */
.overlay{
  position:fixed; inset:var(--header-h) 0 0 0; background:rgb(var(--ink) / 0.5); z-index:96;
  opacity:0; visibility:hidden; transition:opacity 0.32s var(--ease), visibility 0.32s;
  -webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px);
}
.overlay.show{ opacity:1; visibility:visible; }

/* =========================================================================
   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; }
}
.reflection-band{ max-width:820px; margin:0 auto; }
.reflection-band .reflection-card{ padding:30px 34px 28px; }
.reflection-band .quote-text{ font-size:1.3rem; }

/* ---- 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(--accent) / 0.32);
  background:
    radial-gradient(circle at 88% -10%, rgb(var(--accent) / 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; border-radius:var(--radius); }
.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; color:rgb(var(--accent)); }
.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; }
.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); }
.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);
}
.hadith-home-card:hover{ transform:translateY(-4px); border-color:rgb(var(--accent) / 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(--accent) / 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); }
.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;
}
.essay-rec:hover{ transform:translateY(-4px); border-color:rgb(var(--accent) / 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; }
.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(--accent) / 0.1); border:1px solid rgb(var(--accent) / 0.24);
  transition:background 0.2s var(--ease), transform 0.2s var(--ease);
}
.shuffle-btn:hover{ background:rgb(var(--accent) / 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);
  box-shadow:0 1px 2px rgb(var(--shadow) / 0.05);
  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:hover, .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);
}
.topic-card:hover::after, .topic-card:focus-visible::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; }
.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); }
.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);
}
.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);
}
.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(--accent) / 0.22);
}
.lib-heading:first-child{ padding-top:2px; }

.lib-row{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:4px 16px; 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);
}
.lib-row:hover{ background:rgb(var(--accent) / 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(--accent-ui) / 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-card:hover .saved-remove, .saved-remove:focus-visible{ 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) ---- */
.pp-resume{
  position:sticky; top:calc(var(--header-h) + 8px); z-index:45; margin:0 auto 22px; max-width:760px;
  display:flex; align-items:center; gap:14px; padding:12px 16px; border-radius:var(--radius);
  background:rgb(var(--surface)); border:1px solid rgb(var(--accent) / 0.3);
  box-shadow:0 12px 34px -18px rgb(var(--shadow) / 0.5);
}
.pp-resume-icon{ width:34px; height:34px; border-radius:9px; display:grid; place-items:center; background:rgb(var(--accent) / 0.14); color:rgb(var(--accent)); flex-shrink:0; }
.pp-resume-icon svg{ width:18px; height:18px; }
.pp-resume-text{ flex:1; font-size:0.86rem; color:rgb(var(--text)); }
.pp-resume-text b{ color:rgb(var(--heading)); }
.pp-resume-go{ font-size:0.82rem; font-weight:700; color:rgb(var(--accent-ui)); padding:7px 14px; border-radius:999px; background:rgb(var(--accent) / 0.12); }
.pp-resume-go:hover{ background:rgb(var(--accent) / 0.2); }
.pp-resume-dismiss{ background:transparent; border:none; color:rgb(var(--text-muted)); width:30px; height:30px; display:grid; place-items:center; border-radius:8px; }
.pp-resume-dismiss:hover{ background:rgb(var(--heading) / 0.07); color:rgb(var(--heading)); }
.pp-resume-dismiss svg{ width:15px; height:15px; }

/* ---- Zen / theatre reading mode (single posts) ---- */
.zen-toggle{ position:relative; }
.zen-toggle.is-active{ color:rgb(var(--accent)); }
/* 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. */
body.pp-zen .site-header,
body.pp-zen .article-rail,
body.pp-zen .site-footer,
body.pp-zen .mini-bar,
body.pp-zen .breadcrumbs,
body.pp-zen .article-footer-nav,
body.pp-zen .author-card,
body.pp-zen .related-section,
body.pp-zen #comments,
body.pp-zen .reading-progress,
body.pp-zen .back-top{
  display:none !important;
}
body.pp-zen .article-grid{ display:block; grid-template-columns:1fr; }
body.pp-zen .article-main{ max-width:720px; margin:0 auto; }
body.pp-zen .entry-content{ font-size:1.16rem; }
body.pp-zen .article-shell{ padding-top:40px; }
body.pp-zen .article-shell,
body.pp-zen .article-grid,
body.pp-zen .article-main{ padding-bottom:0; margin-bottom:0; }
.zen-exit{
  position:fixed; top:18px; right:18px; z-index:120;
  display:none; align-items:center; gap:8px; padding:10px 16px; border-radius:999px;
  font-size:0.8rem; font-weight:600; color:rgb(var(--on-ink)); background:rgb(var(--ink));
  box-shadow:0 12px 30px -14px rgb(var(--shadow) / 0.6); border:none;
}
.zen-exit svg{ width:15px; height:15px; }
body.pp-zen .zen-exit{ display:inline-flex; }

@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; }
  .pp-resume{ margin-left:12px; margin-right:12px; }
}

/* =========================================================================
   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{
  .site-header, .article-rail, .site-footer, .back-top, .reading-progress,
  .bg-texture, .overlay, .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%);
  border:1px solid rgb(var(--heading) / 0.08); border-radius:var(--radius-lg);
  padding:28px 30px; box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5), 0 20px 50px -30px rgb(var(--shadow) / 0.3); 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:anywhere; }
.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{ position:relative; width:132px; height:132px; margin:0 auto 26px; }
.prayer-ring{ width:100%; height:100%; transform:rotate(-90deg); }
.prayer-ring-track{ fill:none; stroke:rgb(var(--heading) / 0.1); stroke-width:7; }
.prayer-ring-fill{
  fill:none; stroke:rgb(var(--accent)); stroke-width:7; stroke-linecap:round;
  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-family:var(--font-mono); font-size:1.14rem; font-weight:600; color:rgb(var(--heading)); letter-spacing:-0.01em; }

/* ---- six prayer cards ---- */
.prayer-grid{ display:grid; grid-template-columns:repeat(6, minmax(0,1fr)); gap:8px; }
.prayer-card{
  display:flex; flex-direction:column; align-items:center; gap:4px; padding:16px 6px; 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-ar{ font-family:var(--font-arabic); font-weight: var(--ar-weight); font-size:1.05rem; color:rgb(var(--text-muted)); line-height:1; }
.prayer-card-name{ font-family:var(--font-mono); font-size:0.62rem; letter-spacing:0.05em; text-transform:uppercase; color:rgb(var(--text-muted)); margin-top:2px; }
.prayer-card-time{ font-family:var(--font-ui); font-weight:700; font-size:0.86rem; color:rgb(var(--heading)); font-variant-numeric:tabular-nums; }
.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(--accent) / 0.5); background:rgb(var(--accent) / 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-card.is-next .prayer-card-time{ color:rgb(var(--heading)); }

.prayer-foot-row{
  display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; margin-top:22px; padding-top:18px;
  border-top:1px solid rgb(var(--heading) / 0.08);
}
.prayer-hijri{ font-family:var(--font-display); font-weight:600; font-size:0.95rem; color:rgb(var(--heading-soft)); }

.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(--accent) / 0.35);
}
.prayer-subrow{ margin-top:16px; }

/* ---- Extra markers (Imsak, midnight, last third) ---- */
.prayer-extras{
  grid-column:1 / -1; display:flex; gap:8px; flex-wrap:wrap;
  margin-top:10px; padding-top:12px; border-top:1px dashed rgb(var(--heading) / 0.12);
}
.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(--accent) / 0.12) 0%, rgb(var(--accent) / 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-size: clamp(1.18rem, 0.95rem + 0.85vw, 1.5rem);
  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)); opacity: 0.75; 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-app{ display:flex; flex-direction:column; gap:22px; }
.qibla-hero-panel{ display:flex; flex-direction:column; align-items:center; text-align: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);
}
/* the hero compass on the dedicated Qibla page gets much more room to
   breathe than the old half-width panel version did */
.qibla-compass-lg{ width:clamp(240px, 46vw, 320px); margin:20px 0 10px; }
/* 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(--accent) / 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{
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(2.1rem, 8vw, 2.9rem); line-height:1; letter-spacing:-0.02em;
  color:rgb(var(--heading)); margin-top:10px;
  font-variant-numeric:tabular-nums;
}
.qibla-degrees-note{
  font-family:var(--font-mono); font-size:0.66rem; letter-spacing:0.08em;
  text-transform:uppercase; color:rgb(var(--text-muted)); margin-top:4px;
}
.qibla-distance{ font-size:0.85rem; color:rgb(var(--text-muted)); margin-top:8px; }
.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) ---- */
.qibla-sun-panel{ display:flex; flex-direction:column; gap:16px; }
.qibla-sun-head{ display:flex; gap:16px; align-items:flex-start; }
.qibla-sun-icon{
  flex:0 0 auto; width:46px; height:46px; border-radius:14px; display:grid; place-items:center;
  background:linear-gradient(140deg, rgb(var(--accent) / 0.20), rgb(var(--accent) / 0.06));
  color:rgb(var(--accent));
}
.qibla-sun-icon svg{ width:25px; height:25px; }
.qibla-sun-title{ font-size:1.2rem; margin:0 0 6px; color:rgb(var(--heading)); }
.qibla-sun-lead{ margin:0; font-size:0.88rem; line-height:1.65; color:rgb(var(--text-muted)); max-width:62ch; }

.qibla-sun-now{
  margin:0; font-size:0.9rem; color:rgb(var(--heading-soft)); font-weight:500;
}
.qibla-sun-offset{
  margin:0; padding:14px 18px; border-radius:var(--radius);
  background:rgb(var(--accent) / 0.09); border:1px solid rgb(var(--accent) / 0.22);
  color:rgb(var(--heading)); font-size:1rem; font-weight:600; line-height:1.5;
}

.qibla-sun-align-block{
  padding-top:16px; border-top:1px solid rgb(var(--heading) / 0.08);
}
.qibla-sun-subtitle{
  font-family:var(--font-mono); font-size:0.68rem; letter-spacing:0.07em; text-transform:uppercase;
  color:rgb(var(--text-muted)); margin:0 0 12px; font-weight:500;
}
.qibla-sun-align{ list-style:none; margin:0 0 14px; padding:0; display:flex; flex-direction:column; gap:9px; }
.qibla-sun-align li{
  font-size:0.92rem; line-height:1.55; color:rgb(var(--text));
  padding:11px 14px; border-radius:var(--radius-sm);
  background:rgb(var(--heading) / 0.04); border-left:3px solid rgb(var(--accent));
}
.qibla-sun-align li strong{
  font-family:var(--font-ui); font-variant-numeric:tabular-nums;
  color:rgb(var(--heading)); font-weight:700;
}
.qibla-sun-align li.is-past{ opacity:0.55; border-left-color:rgb(var(--heading) / 0.2); }
.qibla-sun-past{ font-size:0.78rem; color:rgb(var(--text-muted)); }
.qibla-sun-foot{ margin:0; font-size:0.82rem; line-height:1.65; color:rgb(var(--text-muted)); max-width:64ch; }

.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-pwa-banner{
  position:fixed; left:16px; right:16px; bottom:16px; z-index:130;
  max-width:440px; margin:0 auto;
  display:flex; align-items:flex-start; gap:14px;
  background:linear-gradient(160deg, rgb(var(--surface)) 0%, rgb(var(--surface)) 62%, rgb(var(--accent) / 0.05) 130%);
  border:1px solid rgb(var(--heading) / 0.1);
  border-top:2px solid rgb(var(--accent) / 0.55);
  border-radius:var(--radius-lg);
  box-shadow:inset 0 1px 0 rgb(var(--on-ink) / 0.5), 0 26px 60px -22px rgb(var(--shadow) / 0.5);
  padding:17px 16px;
  transform:translateY(14px); opacity:0;
  transition:transform 0.45s var(--ease-out-expo), opacity 0.35s var(--ease);
  padding-bottom:calc(17px + env(safe-area-inset-bottom));
}
.pp-pwa-banner.in{ transform:translateY(0); opacity:1; }
.pp-pwa-banner-icon{
  flex-shrink:0; width:40px; height:40px; border-radius:50%; background:rgb(var(--accent) / 0.12);
  display:flex; align-items:center; justify-content:center; color:rgb(var(--accent));
}
.pp-pwa-banner-icon svg{ width:21px; height:21px; }
.pp-pwa-banner-text{ flex:1; min-width:0; display:flex; flex-direction:column; gap:3px; padding-top:2px; }
.pp-pwa-banner-text strong{ font-family:var(--font-display); font-size:0.98rem; color:rgb(var(--heading)); font-weight:600; }
.pp-pwa-banner-text span{ font-size:0.82rem; color:rgb(var(--text-muted)); line-height:1.5; }
.pp-inline-ic{ width:14px; height:14px; vertical-align:-2px; color:rgb(var(--accent)); }
.pp-pwa-banner-actions{ flex-shrink:0; display:flex; flex-direction:column; align-items:flex-end; gap:8px; }
.pp-pwa-banner-actions .btn{ white-space:nowrap; }
/* 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. */
.pp-pwa-banner-close{
  flex-shrink:0; width:40px; height:40px;
  border-radius:50%; border:none; background:transparent;
  color:rgb(var(--text-muted)); cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  transition:background 0.2s var(--ease), color 0.2s var(--ease);
}
.pp-pwa-banner-close svg{ width:17px; height:17px; }
.pp-pwa-banner-close:hover{ background:rgb(var(--heading) / 0.08); color:rgb(var(--heading)); }
.quran-resume-toast-link{ display:flex; align-items:flex-start; gap:14px; flex:1; min-width:0; }

@media (max-width:480px){
  .pp-pwa-banner{ left:12px; right:12px; bottom:12px; padding:16px 14px; }
  .pp-pwa-banner-actions{ flex-direction:row; align-items:center; }
}
@media (prefers-reduced-motion: reduce){
  .pp-pwa-banner{ transition:opacity 0.2s linear; transform:none; }
}

/* =========================================================================
   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{
  display:inline-flex; border:1px solid rgb(var(--heading) / 0.16); border-radius:999px; padding:2px; gap:2px;
}
.prayer-format-btn{
  padding:6px 14px; border-radius:999px; border:none; background:transparent; font-size:0.8rem; font-weight:600;
  color:rgb(var(--text-muted)); transition:background 0.2s var(--ease), color 0.2s var(--ease);
}
.prayer-format-btn.is-active{ background:rgb(var(--accent)); color:rgb(var(--on-accent)); }
.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(--accent) / 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; }
.quran-search-result:hover{ background:rgb(var(--accent) / 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(--accent) / 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; }
.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);
}
.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(--accent) / 0.3); }
.quran-surah-num{
  width:34px; height:34px; flex-shrink:0; border-radius:50%; border:1.5px solid rgb(var(--accent) / 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; font-size:1.02rem; color:rgb(var(--heading)); overflow-wrap:anywhere; }
.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; font-size:1.3rem; color:rgb(var(--heading-soft)); 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);
}
.quran-unit-card:hover{ transform:translateY(-3px); box-shadow:0 16px 34px -22px rgb(var(--shadow) / 0.4); border-color:rgb(var(--accent) / 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; }
.quran-surah-nav-btn:hover{ color:rgb(var(--heading-soft)); background:rgb(var(--accent) / 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(--accent) / 0.4); color:rgb(var(--heading-soft)); font-family:var(--font-mono); font-size:0.85rem; margin-bottom:16px;
}
.quran-surah-header-ar{ font-family:var(--font-arabic); font-weight: var(--ar-weight); direction:rtl; font-size:clamp(2.4rem, 6vw, 3.4rem); color:rgb(var(--heading)); line-height:1.3; margin-bottom:6px; }
.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 side rail ----
   REBUILT IN v10.1. What was wrong with it is worth writing down, because
   every fault had the same single cause.

   The rail was a fixed COLUMN, vertically centred with
   `top:50%; transform:translateY(-50%)`, holding a toggle with the panel
   stacked above it. Three consequences, all reported:

    · IT MOVED. Centring is applied to the CONTAINER, so the toggle only
      sits at the middle of the screen when it is the only thing in the
      column. Open the panel and the container grows by ~260px and the
      toggle drops by half of that — the control jumps out from under
      the finger that just pressed it. v6.5 and v10.0 each patched this
      by taking the panel out of flow in one breakpoint or the other,
      which fixed the jump and created the next fault.

    · IT DISAPPEARED. Out of flow, the panel was pinned `bottom:100%` of
      a container sitting at the vertical middle — so it opened UPWARDS
      from the centre line, and on any viewport shorter than about
      620px its top ran off the top of the screen. Nothing scrolled and
      nothing clamped it: the controls were simply not there. That is
      the "it disappears sometimes", and it depended on window height,
      which is why it came and went.

    · IT SAT ON THE TEXT. Below 1060px the panel opened over the middle
      of the reading column, which is the worst place on the page for it.

   The rail is now anchored to the BOTTOM RIGHT corner and grows upward
   from it. The toggle is at a fixed point that nothing can move, the
   panel opens above it with a hard height cap and its own scrollbar so
   it can never be clipped, and neither ever crosses the reading column.
   One behaviour at every width — there is no longer a breakpoint at
   which this component works differently, which is what made it feel
   unpredictable.

   z-index sits under the header (100) and the recitation bar (110),
   above body content. */
.quran-siderail{
  position:fixed; z-index:70;
  right:calc(20px + env(safe-area-inset-right));
  bottom:calc(20px + env(safe-area-inset-bottom));
  pointer-events:none;
}
.quran-siderail > *{ pointer-events:auto; }

/* Out of the recitation bar's way while it is docked. */
body.qa-playing .quran-siderail{
  bottom:calc(104px + env(safe-area-inset-bottom));
}
/* And the "back to top" button out of the rail's. */
body:has(.quran-siderail) .back-top{
  bottom:calc(80px + env(safe-area-inset-bottom));
}
body.qa-playing:has(.quran-siderail) .back-top{
  bottom:calc(164px + env(safe-area-inset-bottom));
}

.quran-rail-toggle{
  width:52px; height:52px; border-radius:50%;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1px;
  background:rgb(var(--surface)); color:rgb(var(--heading-soft));
  border:1px solid rgb(var(--heading) / 0.14);
  box-shadow:0 14px 34px -14px rgb(var(--shadow) / 0.5);
  transition:background 0.2s var(--ease), color 0.2s var(--ease),
             border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.quran-rail-toggle:hover{ background:rgb(var(--accent)); color:rgb(var(--on-accent)); border-color:rgb(var(--accent)); }
.quran-rail-toggle[aria-expanded="true"]{
  background:rgb(var(--accent)); color:rgb(var(--on-accent)); border-color:rgb(var(--accent));
  box-shadow:0 14px 34px -14px rgb(var(--accent) / 0.6);
}
.quran-rail-toggle-text{ font-family:var(--font-display); font-size:1.05rem; font-weight:600; line-height:1; }
/* A chevron under the Aa, so the button plainly says "this opens and
   closes" rather than only "text options". */
.quran-rail-toggle-chev{
  width:8px; height:8px; display:block;
  border-right:1.6px solid currentColor; border-bottom:1.6px solid currentColor;
  transform:rotate(45deg) translate(-1px,-1px); opacity:0.6;
  transition:transform 0.25s var(--ease);
}
.quran-rail-toggle[aria-expanded="true"] .quran-rail-toggle-chev{
  transform:rotate(-135deg) translate(-1px,-1px); opacity:0.9;
}

.quran-rail-panel{
  position:absolute; right:0; bottom:calc(100% + 12px);
  display:flex; flex-direction:column; align-items:center; gap:8px;
  padding:14px 11px 12px; border-radius:22px;
  background:rgb(var(--surface) / 0.98);
  -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-siderail.is-open .quran-rail-panel{
  opacity:1; visibility:visible; transform:none;
}
.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); font-size:0.55rem; letter-spacing:0.11em; text-transform:uppercase;
  color:rgb(var(--text-muted)); line-height:1;
}
.quran-rail-sep{ width:26px; height:1px; background:rgb(var(--heading) / 0.12); margin:2px 0; }

/* 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{
  width:38px; height:32px; border-radius:11px; border:1px solid rgb(var(--heading) / 0.12);
  background:transparent; 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);
}
.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-rail-toggle-chev{ transition:none; }
}

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

/* ---- Bismillah ---- */
.quran-bismillah{
  text-align:center; font-family:var(--font-arabic); font-weight: var(--ar-weight); direction:rtl;
  font-size:clamp(1.8rem, 4.5vw, 2.5rem); color:rgb(var(--heading-soft)); margin:40px 0 36px; line-height:1.4;
  position:relative; padding-bottom:24px;
}
.quran-bismillah::after{
  content:''; position:absolute; bottom:0; left:50%; transform:translateX(-50%);
  width:64px; height:1px; background:linear-gradient(90deg, transparent, rgb(var(--accent) / 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); transition:background 1.2s var(--ease);
}
.quran-ayah:last-child{ border-bottom:none; }
.quran-ayah.is-target-flash{ background:rgb(var(--accent) / 0.1); }
.quran-ayah-ar{
  font-family:var(--font-quran-glyphs); direction:rtl; text-align:right;
  font-size:var(--quran-font-size, 2rem); line-height:2.15; color:rgb(var(--heading)); margin-bottom:10px;
}
.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:hover .quran-ayah-actions, .quran-ayah:focus-within .quran-ayah-actions,
.quran-ayah:has(.quran-ayah-save[aria-pressed="true"]) .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);
}
.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(--accent) / 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(--accent) / 0.22); }
.quran-section-marker span{
  flex:0 0 auto;
  padding:5px 14px;
  border-radius:999px;
  border:1px solid rgb(var(--accent) / 0.3);
  background:rgb(var(--accent) / 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; }
  /* The rail tightens up a little on the smallest screens so it never
     crowds the text it's meant to stay out of the way of. */
  .quran-siderail{
    right:calc(12px + env(safe-area-inset-right));
    bottom:calc(14px + env(safe-area-inset-bottom));
  }
  .quran-rail-toggle{ width:46px; height:46px; }
  
  .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.
   ========================================================================= */
body.qibla-camera-lock{ overflow:hidden; }

.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%); }
}
.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;
  background:rgb(255 255 255 / 0.16); backdrop-filter:blur(4px);
}
.qibla-camera-cta-badge svg{ width:24px; height:24px; color:#fff; 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; color:rgb(255 255 255 / 0.88); }
.qibla-camera-cta-arrow{
  position:relative; z-index:1; flex-shrink:0; width:18px; height:18px; color:rgb(255 255 255 / 0.82);
  transform:rotate(90deg); transition:transform 0.25s var(--ease);
}
.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; }
.qibla-compass-link:hover{ color:rgb(var(--accent)); }
.qibla-compass-link[hidden]{ display:none; }

.qibla-camera-view{
  position:fixed; inset:0; z-index:500; background:#000;
  display:flex; align-items:center; justify-content:center;
  animation:qiblaCamFadeIn 0.3s var(--ease);
}
@keyframes qiblaCamFadeIn{ from{ opacity:0; } to{ opacity:1; } }
#qiblaCameraVideo{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
}
.qibla-camera-scrim{
  position:absolute; inset:0;
  background:linear-gradient(180deg, rgb(0 0 0 / 0.55) 0%, transparent 22%, transparent 68%, rgb(0 0 0 / 0.7) 100%);
  pointer-events:none;
}

.qibla-camera-close{
  position:absolute; top:calc(20px + env(safe-area-inset-top)); right:20px; z-index:2;
  width:42px; height:42px; border-radius:50%; border:1px solid rgb(255 255 255 / 0.25);
  background:rgb(0 0 0 / 0.35); backdrop-filter:blur(10px); color:#fff;
  display:flex; align-items:center; justify-content:center; transition:background 0.2s var(--ease);
}
.qibla-camera-close:hover{ background:rgb(0 0 0 / 0.55); }

/* =========================================================================
   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{
  position:relative; z-index:1; display:flex; flex-direction:column; align-items:center; gap:22px;
  padding-bottom:calc(40px + env(safe-area-inset-bottom));
}

.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.4);
  display:flex; align-items:center; justify-content:center;
  transition:border-color 0.35s var(--ease), box-shadow 0.35s var(--ease), transform 0.35s var(--ease);
  box-shadow:0 0 0 1px rgb(0 0 0 / 0.15), inset 0 0 40px rgb(0 0 0 / 0.25);
}
.qibla-camera-reticle::before{
  content:''; position:absolute; inset:-1.5px; border-radius:50%;
  border:1.5px dashed rgb(255 255 255 / 0.2);
}
.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{
  position:absolute; inset:0; display:flex; align-items:flex-start; justify-content:center;
  /* Rotation smoothing lives in JS (see assets/qibla.js) — no
     transform transition here for the same reason as .qibla-rose. */
}
.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{
  border-color:rgb(var(--accent) / 0.9);
  box-shadow:0 0 0 1px rgb(var(--accent) / 0.3), 0 0 42px 6px rgb(var(--accent) / 0.45);
  transform:scale(1.04);
}
.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)); }
.qibla-camera-reticle.is-aligned::before{ animation:qiblaCamPulse 1.6s ease-in-out infinite; }
@keyframes qiblaCamPulse{
  0%, 100%{ opacity:0.5; transform:scale(1); }
  50%{ opacity:0.9; transform:scale(1.05); }
}

.qibla-camera-hint{
  color:#fff; font-family:var(--font-display); font-size:1rem; font-weight:600; text-align:center;
  text-shadow:0 2px 10px rgb(0 0 0 / 0.5); margin:0; padding:0 24px;
}
.qibla-camera-degrees{
  color:rgb(255 255 255 / 0.75); font-family:var(--font-mono); font-size:0.8rem; margin:0;
  padding:8px 16px; border-radius:999px; background:rgb(0 0 0 / 0.3); backdrop-filter:blur(8px);
}

.qibla-camera-error{
  position:relative; z-index:2; display:flex; flex-direction:column; align-items:center; gap:14px;
  max-width:320px; text-align:center; color:#fff; padding:32px; border-radius:var(--radius-lg);
  background:rgb(0 0 0 / 0.5); 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; }
.qibla-camera-error p{ margin:0; font-size:0.9rem; line-height:1.6; color:rgb(255 255 255 / 0.85); }

@media (prefers-reduced-motion: reduce){
  .qibla-camera-reticle.is-aligned::before{ animation:none; }
  .qibla-camera-view{ animation:none; }
}

/* =========================================================================
   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);
}
.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(--accent) / 0.045); }
.prayer-month-row.is-today{
  background:rgb(var(--accent) / 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(--accent) / 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{
  display:inline-block; margin-bottom:16px; padding:5px 12px; border-radius:999px;
  /* 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. */
  background:rgb(var(--accent) / 0.14); color:rgb(var(--heading));
  border:1px solid rgb(var(--accent) / 0.28);
  font-family:var(--font-mono); font-size:0.68rem; letter-spacing:0.06em; text-transform:uppercase;
}

/* ---- accuracy indicator ---- */
.qibla-status-bar{
  display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;
  width:100%; margin-bottom:18px; padding:9px 13px; border-radius:999px;
  background:rgb(var(--heading) / 0.04); border:1px solid rgb(var(--heading) / 0.08);
}
.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{
  border:none; background:transparent; padding:4px 2px; cursor:pointer;
  font-family:inherit; font-size:0.78rem; color:rgb(var(--accent));
  text-decoration:underline; text-underline-offset:3px; text-decoration-thickness:1px;
}
.qibla-recalibrate-btn:hover{ color:rgb(var(--heading)); }

.qibla-aligned-msg{
  margin:10px 0 0; font-family:var(--font-display); font-size:1rem; font-weight:600;
  color:#2f9e6b; display:flex; align-items:center; justify-content:center; gap:7px;
}
.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-grid{ display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:22px; }
.qibla-howto-item{ display:flex; flex-direction:column; gap:12px; 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; z-index:210; 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);
}
.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(--accent) / 0.4);
}
.q8-phone-screen{
  width:28px; height:46px; border-radius:5px;
  background:rgb(var(--accent) / 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{ display:flex; align-items:flex-start; gap:11px; 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{
  position:absolute; top:calc(16px + env(safe-area-inset-top)); left:16px; z-index:3;
  display:flex; align-items:center; gap:10px;
}
.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); }
.qibla-cam-calibrate{
  padding:7px 13px; border-radius:999px; border:1px solid rgb(255 255 255 / 0.35);
  background:rgb(0 0 0 / 0.55); backdrop-filter:blur(8px); color:#fff;
  font-family:inherit; font-size:0.76rem; cursor:pointer;
}
.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{
  position:absolute; top:50%; left:50%; transform:translate(-50%, -50%) translateY(-132px); z-index:3;
  display:flex; align-items:center; gap:10px; padding:11px 20px; border-radius:999px;
  background:rgb(0 0 0 / 0.6); backdrop-filter:blur(8px); color:#fff;
  font-size:0.95rem; font-weight:600; white-space:nowrap;
  animation:qiblaTurnNudge 1.8s var(--ease) infinite;
}
.qibla-turn-icon{ width:20px; height:20px; }
.qibla-camera-turn.is-left .qibla-turn-icon{ transform:scaleX(-1); }
@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. This contains the damage to
     the element that caused it. */
  html, body { overflow-x: hidden; }
  .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. */
  .article-body,
  .entry-content,
  .page-content {
    font-size: 1.06rem;
    line-height: 1.78;
  }
  .article-body p,
  .entry-content p { margin-bottom: 1.3em; }
  .article-body h2,
  .entry-content h2 { font-size: 1.5rem; line-height: 1.25; margin-top: 1.9em; }
  .article-body h3,
  .entry-content h3 { font-size: 1.24rem; line-height: 1.3; margin-top: 1.6em; }
  .article-body blockquote,
  .entry-content blockquote { padding-left: 16px; margin-left: 0; margin-right: 0; }

  /* Long words and pasted URLs break instead of forcing the page wide. */
  .article-body, .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;
  }
  .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; }
  .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; }
  .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; }
  .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-sun-head { gap: 12px; }
  .qibla-sun-icon { width: 40px; height: 40px; border-radius: 12px; }
  .qibla-sun-icon svg { width: 21px; height: 21px; }
  .qibla-sun-title { font-size: 1.08rem; }
  .qibla-sun-offset { font-size: 0.94rem; padding: 12px 14px; }
  .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-frame.hero-frame { padding: 30px 20px 34px; }
  .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(--accent) / 0.18), rgb(var(--accent) / 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(--accent) / 0.10); border-color:rgb(var(--accent) / 0.32);
  color:rgb(var(--accent)); font-weight:600;
}
.lib-chip-all svg{ width:13px; height:13px; }
.lib-chip-all:hover{ background:rgb(var(--accent) / 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. */
  --glow-accent: 0 10px 30px -10px rgb(var(--accent) / 0.45);

  /* ---- 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(--accent) / 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;
}
::-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. */
.btn-ghost:hover{ transform: translateY(-1px); box-shadow: var(--e2); }
.btn-ghost:active{ transform: translateY(0) scale(0.985); box-shadow: none; }

/* ---- 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,
.article-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);
}
.card:hover,
.article-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);
}
.prayer-select:hover,
.prayer-input:hover,
input[type="text"]:hover,
input[type="search"]:hover,
select:hover{ border-color: rgb(var(--accent) / 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;
  }
  .card:hover, .article-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. */
.site-header::before{
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
}
.site-header.scrolled{
  box-shadow: var(--e2);
  border-bottom-color: var(--hairline);
}

/* ---- 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. */
.site-header .nav-link{
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  letter-spacing: -0.006em;
  border-radius: var(--radius-pill);
  padding: 9px 14px;
  transition:
    color var(--dur) var(--ease-soft),
    background-color var(--dur) var(--ease-soft);
}
/*
 * 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.
 */
.site-header .nav-link[aria-current="page"],
.site-header .nav-link.is-current{
  color: rgb(var(--accent-ui));
  background: rgb(var(--accent) / 0.10);
  font-weight: 600;
}

/*
 * 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.
 */
.site-header .main-nav > ul > li.is-current-item{
  background: rgb(var(--accent) / 0.10);
}
.site-header .main-nav > ul > li.is-current-item > .nav-link,
.site-header .main-nav > ul > li.is-current-item > .nav-caret-btn{
  color: rgb(var(--accent-ui));
}
.site-header .main-nav > ul > li.is-current-item > .nav-link{
  background: transparent;
  font-weight: 600;
}
/* 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. */
.site-header .main-nav > ul > li.is-current-item > .nav-caret-btn .nav-caret{ opacity: 0.85; }

/* ---- Dropdown panels ----------------------------------------------------
   The frost + overlay shadow is what turns these from "a white box" into
   "a surface floating above the page". */
.site-header .mega-panel{
  top: calc(100% + 8px);
  padding: 10px;
  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: translateX(-50%) translateY(-8px) scale(0.97);
  transform-origin: top center;
  transition:
    opacity var(--dur) var(--ease-out-expo),
    transform var(--dur) var(--spring),
    visibility var(--dur);
}
.site-header .has-dropdown:hover .mega-panel,
.site-header .has-dropdown.open .mega-panel{
  transform: translateX(-50%) translateY(0) scale(1);
}

/* 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. */
.site-header .mega-panel::before{
  content: '';
  position: absolute; top: -6px; left: 50%; width: 12px; height: 12px;
  margin-left: -6px; transform: rotate(45deg);
  background: var(--glass-bg-strong);
  border-left: 1px solid var(--glass-border);
  border-top: 1px solid var(--glass-border);
  border-radius: 2px 0 0 0;
}

/* 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. */
.site-header .mega-item,
.site-header .hadith-menu-row{
  position: relative;
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  transition:
    background-color var(--dur-fast) var(--ease-soft),
    transform var(--dur) var(--ease-out-expo);
}
.site-header .mega-item:hover,
.site-header .hadith-menu-row:hover{
  background: rgb(var(--accent) / 0.10);
  transform: translateX(3px);
}
.site-header .mega-item svg{
  width: 18px; height: 18px;
  padding: 0; margin-top: 1px;
  transition: transform var(--dur) var(--spring);
}
.site-header .mega-item:hover svg{ transform: scale(1.12); }

.site-header .mega-item .mega-title{
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  letter-spacing: -0.006em;
}
.site-header .mega-item .mega-desc{ font-size: var(--fs-2xs); }

/* 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. */
.mega-panel-head{
  grid-column: 1 / -1;
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 4px 12px 10px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--hairline);
}
.mega-panel-head-title{
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.mega-panel-head-all{
  font-family: var(--font-ui);
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: rgb(var(--accent-ui));
  white-space: nowrap;
  transition: opacity var(--dur-fast) var(--ease-soft);
}
.mega-panel-head-all:hover{ opacity: 0.7; }

.site-header .mega-panel-foot{
  border-top: 1px solid var(--hairline);
  font-size: var(--fs-2xs);
  padding: 10px 12px 2px;
}

/* 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. */
.site-header .has-dropdown.open .mega-item,
.site-header .has-dropdown:hover .mega-item,
.site-header .has-dropdown.open .hadith-menu-row,
.site-header .has-dropdown:hover .hadith-menu-row{
  animation: navRowIn var(--dur) var(--ease-out-expo) backwards;
}
.site-header .mega-item:nth-child(1),
.site-header .hadith-menu-row:nth-child(1){ animation-delay: 20ms; }
.site-header .mega-item:nth-child(2),
.site-header .hadith-menu-row:nth-child(2){ animation-delay: 40ms; }
.site-header .mega-item:nth-child(3),
.site-header .hadith-menu-row:nth-child(3){ animation-delay: 60ms; }
.site-header .mega-item:nth-child(4),
.site-header .hadith-menu-row:nth-child(4){ animation-delay: 80ms; }
.site-header .mega-item:nth-child(5),
.site-header .hadith-menu-row:nth-child(5){ animation-delay: 100ms; }
.site-header .mega-item:nth-child(n+6),
.site-header .hadith-menu-row:nth-child(n+6){ animation-delay: 120ms; }
@keyframes navRowIn{
  from{ opacity: 0; transform: translateY(6px); }
  to{ opacity: 1; transform: translateY(0); }
}

/* ---- Header icon buttons ------------------------------------------------ */
.site-header .icon-btn{
  border-color: var(--hairline-strong);
  border-radius: var(--radius-sm);
  transition:
    background-color var(--dur) var(--ease-soft),
    color var(--dur) var(--ease-soft),
    border-color var(--dur) var(--ease-soft),
    transform var(--dur-fast) var(--ease-soft),
    box-shadow var(--dur) var(--ease-soft);
}
.site-header .icon-btn:hover{
  transform: translateY(-1.5px);
  box-shadow: var(--e2);
}
.site-header .icon-btn:active{ transform: translateY(0) scale(0.94); }
.site-header .header-actions-sep{ background: var(--hairline-strong); }

/* ---- 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); }
.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. */
  .overlay{
    background: var(--scrim);
    -webkit-backdrop-filter: blur(6px) saturate(120%);
    backdrop-filter: blur(6px) saturate(120%);
    transition:
      opacity var(--dur-slow) var(--ease-soft),
      visibility var(--dur-slow);
  }

  /* ---- 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. */
  .site-header .main-nav.main-nav{
    background: var(--glass-bg-strong);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    border-left: 1px solid var(--glass-border);
    border-radius: var(--radius-xl) 0 0 0;
    box-shadow: var(--e-overlay);
    padding: 8px 16px calc(28px + env(safe-area-inset-bottom));
    padding-right: calc(16px + env(safe-area-inset-right));
    transition: transform var(--dur-slow) var(--ease-out-expo);
  }

  /* ---- 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. */
  .site-header .nav-group-label{
    display: block; width: 100%;
    padding: 18px 8px 7px;
    border-bottom: none;
    font-family: var(--font-mono);
    font-size: var(--fs-2xs);
    letter-spacing: var(--track-caps);
    text-transform: uppercase;
    color: rgb(var(--text-muted));
    opacity: 0.75;
  }
  .site-header .nav-group-label:first-child{ padding-top: 8px; }

  /* ---- 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. */
  .site-header .main-nav > ul > li{
    border-bottom: 1px solid var(--hairline-faint);
    border-radius: var(--radius-sm);
  }
  .site-header .main-nav > ul > li.nav-group-label{ border-bottom: none; }
  .site-header .main-nav .nav-link{
    font-family: var(--font-ui);
    font-size: var(--fs-base);
    font-weight: 500;
    padding: 14px 10px;
    border-radius: var(--radius-sm);
    transition: background-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
  }
  .site-header .main-nav .nav-link:active{ background: rgb(var(--accent) / 0.1); }
  .site-header .main-nav .nav-link[aria-current="page"],
  .site-header .main-nav .nav-link.is-current{
    background: rgb(var(--accent) / 0.10);
    box-shadow: inset 3px 0 0 rgb(var(--accent));
  }
  .site-header .main-nav .nav-caret-btn{
    border-left: 1px solid var(--hairline-faint);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  }
  /* 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. */
  .site-header .main-nav > ul > li.is-current-item{ background: transparent; }
  .site-header .main-nav > ul > li.is-current-item > .nav-link{
    background: rgb(var(--accent) / 0.10);
    box-shadow: inset 3px 0 0 rgb(var(--accent));
  }

  /* ---- Accordion contents ----------------------------------------------- */
  .site-header .main-nav .mega-panel{
    background: transparent;
    -webkit-backdrop-filter: none; backdrop-filter: none;
    border: none;
    border-left: 2px solid rgb(var(--accent) / 0.3);
    border-radius: 0;
    box-shadow: none;
    padding: 2px 0 10px;
    margin: 0 0 6px 6px;
  }
  /* The desktop panel's pointer must not survive into the accordion, where
     there is no trigger for it to point at. */
  .site-header .main-nav .mega-panel::before{ display: none; }
  .site-header .main-nav .mega-item,
  .site-header .main-nav .hadith-menu-row{
    min-height: 46px;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
  }
  .site-header .main-nav .mega-item:hover,
  .site-header .main-nav .hadith-menu-row:hover{ transform: none; }
  .site-header .main-nav .mega-item:active,
  .site-header .main-nav .hadith-menu-row:active{ background: rgb(var(--accent) / 0.12); }
  /* 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. */
  .site-header .main-nav .mega-item,
  .site-header .main-nav .hadith-menu-row{ animation: none; }
  .site-header .main-nav .mega-panel-head{ display: none; }

  /* ---- 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. */
  .site-header .main-nav.open > ul > li{
    animation: drawerRowIn var(--dur-slow) var(--ease-out-expo) backwards;
  }
  .site-header .main-nav.open > ul > li:nth-child(1){ animation-delay: 60ms; }
  .site-header .main-nav.open > ul > li:nth-child(2){ animation-delay: 90ms; }
  .site-header .main-nav.open > ul > li:nth-child(3){ animation-delay: 120ms; }
  .site-header .main-nav.open > ul > li:nth-child(4){ animation-delay: 150ms; }
  .site-header .main-nav.open > ul > li:nth-child(5){ animation-delay: 180ms; }
  .site-header .main-nav.open > ul > li:nth-child(6){ animation-delay: 210ms; }
  .site-header .main-nav.open > ul > li:nth-child(n+7){ animation-delay: 240ms; }
  @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. */
  .site-header .menu-toggle.menu-toggle{
    position: relative;
    border-color: var(--hairline-strong);
    border-radius: var(--radius-sm);
    transition:
      background-color var(--dur) var(--ease-soft),
      border-color var(--dur) var(--ease-soft),
      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(--spring);
  }
  .site-header .menu-toggle::before{ transform: translateY(-4px); }
  .site-header .menu-toggle::after{ transform: translateY(4px); }
  .site-header .menu-toggle.is-open::before{ transform: translateY(0) rotate(45deg); }
  .site-header .menu-toggle.is-open::after{ transform: translateY(0) rotate(-45deg); }

  .nav-drawer-cta{ margin-top: 22px; }
  .nav-drawer-cta .btn{ padding: 14px 22px; }
}


/* =========================================================================
   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; }
.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:focus-within{
  border-color: rgb(var(--accent-ui));
  box-shadow: 0 0 0 3px rgb(var(--accent) / 0.16);
}
.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; }
.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; }
.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(--accent) / 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 + .pp-picker-group{ margin-top: var(--sp-3); }
.pp-picker-group-label{
  position: sticky; top: 0; z-index: 1;
  padding: var(--sp-3) var(--sp-3) var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: rgb(var(--text-muted));
  /* Sticky headings need an opaque backing or the rows scroll visibly
     through the text. The blur keeps it consistent with the sheet. */
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
}

.pp-picker-row{
  position: relative;
  display: flex; align-items: center; gap: var(--sp-3);
  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;
  padding: var(--sp-3);
  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:hover,
.pp-picker-row.is-active{ background: rgb(var(--accent) / 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(--accent) / 0.16); }
.pp-picker-row:focus-visible{ box-shadow: var(--ring); }

.pp-picker-row-main{ flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pp-picker-row-title-line{ display: flex; align-items: center; gap: var(--sp-2); 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-sub{
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  color: rgb(var(--text-muted));
  line-height: 1.4;
}
.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;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: rgb(var(--text-muted));
  white-space: nowrap;
}
.pp-picker-row-badge{
  flex-shrink: 0;
  padding: 3px 8px;
  border-radius: var(--radius-pill);
  background: rgb(var(--accent) / 0.14);
  color: rgb(var(--accent-ui));
  font-family: var(--font-ui);
  font-size: var(--fs-2xs);
  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(--accent) / 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(--accent) / 0.06);
  box-shadow: inset 3px 0 0 rgb(var(--accent) / 0.8);
}
.pp-picker-row.is-featured:hover,
.pp-picker-row.is-featured.is-active{ background: rgb(var(--accent) / 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);
}
.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(--accent) / 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);
}
.pp-choice:hover{
  border-color: rgb(var(--accent) / 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(--accent) / 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);
}
.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(--accent) / 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(--accent) / 0.11) 0%,
    rgb(var(--accent) / 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(--accent) / 0.13);
  border: 1px solid rgb(var(--accent) / 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);
}
.qibla-recalibrate-btn:hover{ border-color: rgb(var(--accent) / 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. */
.qibla-sun-panel{
  border-color: rgb(var(--accent) / 0.28);
  background:
    linear-gradient(160deg, rgb(var(--accent) / 0.05) 0%, transparent 45%),
    rgb(var(--surface));
}
.qibla-sun-icon{
  flex-shrink: 0;
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm);
  background: rgb(var(--accent) / 0.13);
  color: rgb(var(--accent-ui));
}
.qibla-sun-icon svg{ width: 23px; height: 23px; }
.qibla-sun-head{ display: flex; gap: var(--sp-4); align-items: flex-start; }
.qibla-sun-title{
  margin: 0 0 5px;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 600;
  letter-spacing: var(--track-tight);
  color: rgb(var(--heading));
}

/* ---- "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 -------------------------------------------------------------- */
.article-card,
.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);
}
.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-grid > *{
  border-radius: var(--radius-sm);
  transition: background-color var(--dur) var(--ease-soft), box-shadow var(--dur) var(--ease-soft);
}
.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(--accent) / 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(--accent) / 0.28);
  --ornament-soft: rgb(var(--accent) / 0.14);
  --ornament-faint: rgb(var(--accent) / 0.07);

  /* Prayer grid */
  --prayer-row-bg: transparent;
  --prayer-row-bg-next: rgb(var(--accent) / 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{
  display: inline-flex; align-items: center; gap: 10px;
}
.section-header .eyebrow::before{
  content: ''; width: 22px; height: var(--rule-weight);
  background: rgb(var(--accent-ui));
  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(--accent) / 0) 0%, rgb(var(--accent) / 0.85) 20%,
    rgb(var(--accent) / 0.85) 80%, rgb(var(--accent) / 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;
  width: 108px; height: 1px; margin: var(--sp-5) auto;
  background: linear-gradient(90deg, transparent, rgb(var(--accent) / 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(--accent) / 0.75);
}
.hero-ayah{
  margin: 0 auto var(--sp-3); max-width: 30ch;
  font-family: var(--font-quran-glyphs), var(--font-quran), var(--font-arabic);
  direction: rtl; unicode-bidi: isolate;
  font-size: clamp(1.3rem, 1rem + 1.5vw, 1.85rem);
  line-height: 2.15; color: rgb(var(--heading));
}
.hero-ayah-en{
  margin: 0 auto 5px; max-width: 46ch;
  font-family: var(--font-body); font-style: italic;
  font-size: var(--fs-sm); line-height: 1.7;
  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. */
.hero-stats{ opacity: 0.9; }
.hero-stat-num{ font-size: clamp(1.2rem, 1rem + 0.7vw, 1.5rem); }

@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; }
  .qibla-sun-head{ flex-direction: column; gap: var(--sp-3); }

  /* 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. */
.article-card,
.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. */
.article-card::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;
}
.article-card:hover::before,
.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);
}
.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);
}

.article-card: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); }
.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. */
.article-cover,
.featured-cover{
  position: relative;
  background: rgb(var(--bg-alt));
}
.article-cover img,
.featured-cover img{
  transition: transform var(--dur-slow) var(--ease-out-expo);
}
.article-card:hover .article-cover img{ transform: scale(1.05); }
.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. */
.article-cover:has(img)::after,
.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);
}
.article-card:hover .cover-ornament,
.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. */
  opacity: 0.70;
}

.prayer-grid > .is-next{
  background: var(--prayer-row-bg-next);
  box-shadow: var(--e2), inset 3px 0 0 rgb(var(--accent));
  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;
}
.prayer-grid > .is-next .prayer-card-time{
  color: rgb(var(--heading));
  font-weight: 600;
}
/* 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(--accent) / 0.45);
  transition: text-decoration-color var(--dur) var(--ease-soft), text-decoration-thickness var(--dur) var(--ease-soft);
}
.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(--accent) / 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. */
.articles-grid .reveal:nth-child(2),
.topics-grid .reveal:nth-child(2){ transition-delay: 70ms; }
.articles-grid .reveal:nth-child(3),
.topics-grid .reveal:nth-child(3){ transition-delay: 140ms; }
.articles-grid .reveal:nth-child(n+4),
.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. */
.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,
.icon-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.
   ------------------------------------------------------------------------- */
:root{ --header-live: var(--header-h); }
html.pp-header-hidden{ --header-live: 0px; }

@media (max-width:1100px){
  .article-rail.article-rail{
    top: var(--header-live);
    transition: top 0.3s var(--ease);
    /* One height for every post. The rail holds a different number of
       buttons depending on whether the post has comments and whether
       listening is available, so its height changed from post to post —
       and a strip pinned directly under the header that changes height
       from post to post reads, at a glance, as the HEADER changing from
       post to post. A floor fixes it without capping anything. */
    min-height: 56px;
    display: flex;
    align-items: center;
  }
  .rail-inner.rail-inner{ width:100%; }
}

/* -------------------------------------------------------------------------
   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); }
.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; }
}

@media (max-width:620px){
  .site-header .header-actions{ gap:5px; }
  .site-header .header-actions .icon-btn{ width:42px; height:42px; }
  .site-header .menu-toggle{ width:42px; height:42px; }
}
/* 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;
}
.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);
}
.pp-tasbih-mini:hover{ color: rgb(var(--accent-ui)); border-color: rgb(var(--accent) / 0.45); }
.pp-tasbih-more{ color: rgb(var(--accent-ui)); border-color: rgb(var(--accent) / 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;
  font-size: clamp(3rem, 2rem + 6vw, 4.6rem); line-height:1;
  color: rgb(var(--heading)); transform: translateY(-4%);
  font-variant-numeric: tabular-nums;
}
.tasbih-of{
  position:absolute; left:0; right:0; bottom:19%; 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(--accent) / 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(--accent) / 0.12), rgb(var(--accent-light) / 0.16));
  border:1px solid rgb(var(--accent) / 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);
}
.tasbih-row:hover{ border-color: rgb(var(--accent) / 0.4); transform: translateX(2px); }
.tasbih-row.is-on{ border-color: rgb(var(--accent) / 0.7); background: rgb(var(--accent) / 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; max-width:9ch;
}
.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(--accent) / 0.055);
  box-shadow: inset 3px 0 0 rgb(var(--accent) / 0.75);
  border-radius: var(--radius-sm);
}

.quran-rail-play{
  width:34px; height:34px; display:grid; place-items:center;
  border-radius:50%; cursor:pointer;
  border:1px solid rgb(var(--accent) / 0.35);
  background: rgb(var(--accent) / 0.1);
  color: rgb(var(--accent-ui));
  transition: background var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--spring);
}
.quran-rail-play:hover{ background: rgb(var(--accent) / 0.2); 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-card-wrap:hover .quran-unit-play,
.quran-unit-play:focus-visible{ 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;
  width:min(760px, calc(100vw - 24px));
  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-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);
  overflow:hidden;
}
.qa-bar-main{ display:flex; align-items:center; gap:4px; padding:8px 10px; }
.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);
}
.qa-btn:hover{ background: rgb(var(--ink) / 0.07); color: rgb(var(--heading)); }
.qa-btn svg{ width:17px; height:17px; }
.qa-btn-play{
  width:44px; height:44px;
  background: rgb(var(--accent)); color: rgb(var(--on-ink));
}
.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-size: var(--fs-sm); font-weight:600;
  color: rgb(var(--heading)); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.qa-bar-status{
  font-family: var(--font-mono); font-size:0.62rem; color: rgb(var(--text-muted));
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.qa-bar-track{
  height:3px; border-radius:2px; background: rgb(var(--ink) / 0.1);
  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; padding:8px 10px; 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; }
  .qa-btn-play{ width:46px; height:46px; }
}

/* -------------------------------------------------------------------------
   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;
  width:min(560px, 100vw);
  display:flex; flex-direction:column;
  background: rgb(var(--surface));
  border-left:1px solid var(--hairline);
  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{
  display:flex; align-items:flex-start; justify-content:space-between;
  gap: var(--sp-3); padding: var(--sp-5) var(--sp-6) var(--sp-3);
  border-bottom:1px solid var(--hairline-faint);
}
.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));
}
.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;
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size:0.95rem;
  color: rgb(var(--text-muted)); text-align:right; direction:rtl;
}
.qa-tafsir-body{
  flex:1; min-height:0; 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);
  font-size:1.18rem; line-height:2.15;
  color: rgb(var(--text));
  text-align:justify;
}
.qa-tafsir-body p{ margin:0 0 1.1em; }
/* 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{
  display:block; margin:0.5em 0; padding-right:0.9em;
  border-right:2px solid rgb(var(--accent) / 0.3);
  font-size:0.82em; line-height:1.9; color: rgb(var(--text-muted));
}
.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;
    width:100%; border-left:none; 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); }
  .qa-tafsir-body{ padding-left: var(--sp-5); padding-right: var(--sp-5); font-size:1.1rem; }
}

/* -------------------------------------------------------------------------
   8. WARD AND MEMORISATION CARDS
   ------------------------------------------------------------------------- */
.quran-practice-grid{
  display:grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: var(--sp-5);
}
.quran-practice-card{
  padding: var(--sp-6);
  border-radius: var(--radius-lg);
  border:1px solid var(--hairline);
  background: rgb(var(--surface));
  box-shadow: var(--e1);
}.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.
   ------------------------------------------------------------------------- */
.cover-art{ display:block; width:100%; height:100%; }
/* =========================================================================
   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.
   ========================================================================= */
.article-cover.has-cover-art{
  height: auto;
  aspect-ratio: 400 / 150;
}
.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;
  }
}

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

/* The newest piece, marked so that its appearance in the grid reads as
   emphasis rather than as the same post twice. */
.article-card-chips{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.tag-chip.tag-newest{
  background: rgb(var(--accent)); color: rgb(var(--on-ink));
  border-color: transparent;
}
.article-card.is-newest{ border-color: rgb(var(--accent) / 0.4); }

/* -------------------------------------------------------------------------
   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. */
  .articles-grid.articles-grid,
  .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,
  .articles-grid.articles-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(--accent) / 0.22);
  background: linear-gradient(120deg, rgb(var(--accent) / 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);
}
.quran-unit-surah-link:hover{ border-color: rgb(var(--accent) / 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(--accent) / 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); font-size:1.42rem; line-height:1.6;
  color: rgb(var(--heading));
}
.quran-unit-surah-en{
  font-family: var(--font-ui); font-size: var(--fs-2xs);
  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); }
button.qa-strip:hover{ border-color: rgb(var(--accent) / 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(--accent) / 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)); }
.qa-strip-play:hover{ background: rgb(var(--accent-ui)); }
.qa-strip-edit{ background:transparent; color: rgb(var(--text-muted)); border-color: var(--hairline-strong); }
.qa-strip-edit:hover{ color: rgb(var(--accent-ui)); border-color: rgb(var(--accent) / 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{
  width:min(620px, 100vw);
  background:
    linear-gradient(rgb(var(--surface)), rgb(var(--surface))) padding-box,
    linear-gradient(160deg, rgb(var(--accent) / 0.35), rgb(var(--accent) / 0)) border-box;
  border-left:1px solid transparent;
}
.qa-tafsir-grab{ display:none; }

.qa-tafsir-head{
  display:block;
  padding: var(--sp-5) var(--sp-6) var(--sp-4);
  border-bottom:1px solid var(--hairline-faint);
  background: linear-gradient(180deg, rgb(var(--accent) / 0.06), rgb(var(--accent) / 0));
}
.qa-tafsir-head-row{
  display:flex; align-items:center; justify-content:space-between;
  gap: var(--sp-3); margin-bottom: var(--sp-3);
}
.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);
}
.qa-tafsir-tool:hover{ color: rgb(var(--accent-ui)); border-color: rgb(var(--accent) / 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; padding: var(--sp-4) var(--sp-5);
  border-radius: var(--radius);
  border:1px solid rgb(var(--accent) / 0.2);
  background: rgb(var(--accent) / 0.055);
  font-family: var(--font-quran-glyphs), var(--font-quran);
  font-size:1.5rem; line-height:2.35; 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); font-size: var(--fs-2xs); line-height:1.5;
  color: rgb(var(--text-muted));
}

.qa-tafsir-body{
  padding: var(--sp-4) var(--sp-6) var(--sp-8);
  font-size:1.12rem;             /* overridden live by the A+/A− control */
  line-height:2.25;
}
.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(--accent) / 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-head{ padding: var(--sp-3) var(--sp-5) var(--sp-3); }
  .qa-tafsir-verse{ font-size:1.28rem; line-height:2.1; padding: var(--sp-3) var(--sp-4); }
  .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(--accent) / 0.3);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(120% 90% at 50% 0%, rgb(var(--accent) / 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(--accent) / 0) 0%,
    rgb(var(--accent) / 0.85) 22%,
    rgb(var(--accent) / 0.85) 78%,
    rgb(var(--accent) / 0) 100%);
}
.adhkar-unwan-mark{
  position: absolute; top: 0; left: 50%;
  transform: translate(-50%, -50%);
  width: 52px; height: 52px; display: grid; place-items: center;
  border-radius: 50%;
  background: rgb(var(--surface));
  border: 1px solid rgb(var(--accent) / 0.4);
  color: rgb(var(--accent-ui));
  box-shadow: var(--e1);
}
.adhkar-unwan-mark svg{ width: 26px; height: 26px; }
.adhkar-unwan .eyebrow{ display: inline-block; margin-bottom: var(--sp-2); }

.adhkar-title{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: clamp(2.6rem, 1.9rem + 4.2vw, 4rem);
  line-height: 1.45; margin: 0;
  color: rgb(var(--heading));
}
.adhkar-unwan-sub{
  margin: 2px 0 0;
  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(--accent) / 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(--accent) / 0.7);
}
.adhkar-hero-ayah{
  margin: 0 0 var(--sp-3);
  /* The Qur'anic face, like every other ayah on the site. */
  font-family: var(--font-quran-glyphs), var(--font-quran), var(--font-arabic);
  font-size: clamp(1.35rem, 1rem + 1.7vw, 1.95rem);
  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{
  margin: var(--sp-5) auto 0; max-width: 62ch;
  font-size: var(--fs-sm); line-height: 1.75;
  color: rgb(var(--text-muted));
}
@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-tabs{
  display: flex; gap: 6px; 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; flex: 0 0 auto; scroll-snap-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  min-width: 104px; padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--hairline-strong); 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);
}
.adhkar-tab:hover{ border-color: rgb(var(--accent) / 0.45); transform: translateY(-1px); }
.adhkar-tab.is-on{
  border-color: rgb(var(--accent) / 0.75);
  background: rgb(var(--accent) / 0.09);
}
.adhkar-tab svg{ width: 19px; height: 19px; color: rgb(var(--accent-ui)); }
.adhkar-tab-en{
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight: 600;
  color: rgb(var(--heading)); white-space: nowrap;
}
.adhkar-tab-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 0.82rem; line-height: 1.6;
  color: rgb(var(--text-muted)); white-space: nowrap;
}
.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.8;
}
.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;
}

/* ---- a set ---- */
.adhkar-panel-head{
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--sp-5); flex-wrap: wrap;
  padding-bottom: var(--sp-4); margin-bottom: var(--sp-5);
  border-bottom: 1px solid var(--hairline);
}
.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-progress{ display: flex; flex-direction: column; gap: 5px; min-width: 168px; }
.adhkar-progress-count{
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: rgb(var(--accent-ui)); font-variant-numeric: tabular-nums;
}
.adhkar-progress-track{
  height: 4px; border-radius: 2px; background: rgb(var(--ink) / 0.1); overflow: hidden;
}
.adhkar-progress-fill{
  display: block; height: 100%; width: 0%;
  background: linear-gradient(90deg, rgb(var(--accent)), rgb(var(--accent-light)));
  transition: width 420ms var(--ease-out-expo);
}
.adhkar-reset{
  align-self: flex-start; padding: 0; border: none; background: none; cursor: pointer;
  font-family: var(--font-ui); font-size: var(--fs-2xs);
  color: rgb(var(--text-muted)); text-decoration: underline;
  text-underline-offset: 3px;
}
.adhkar-reset:hover{ color: rgb(var(--accent-ui)); }

/* ---- 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(--accent) / 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)); background: rgb(var(--accent) / 0.1);
  padding: 3px 9px; border-radius: var(--radius-pill);
}

.adhkar-card-ar{
  margin: 0 0 var(--sp-4);
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: clamp(1.35rem, 1.05rem + 1.3vw, 1.85rem);
  line-height: 2.35; 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;
  font-size: var(--fs-sm); color: rgb(var(--accent-ui)); line-height: 1.7;
}
.adhkar-card-en{
  margin: 0 0 var(--sp-4); font-size: var(--fs-sm);
  color: rgb(var(--text)); line-height: 1.7;
}
.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(--accent) / 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:hover,
.adhkar-card-ref:focus-visible{
  color: rgb(var(--accent-ui)); background: rgb(var(--accent) / 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;
}
.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);
}
.adhkar-card-copy:hover{ color: rgb(var(--accent-ui)); border-color: rgb(var(--accent) / 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(--accent) / 0.34);
  background: rgb(var(--accent) / 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);
}
.adhkar-card-count:hover{
  border-color: rgb(var(--accent) / 0.55);
  background: rgb(var(--accent) / 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(--accent) / 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(--accent) / 0.75);
  background: rgb(var(--accent) / 0.14);
}
.adhkar-card.is-done .adhkar-count-fill{ background: rgb(var(--accent) / 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(--accent) / 0.3);
  background:
    radial-gradient(120% 100% at 50% 0%, rgb(var(--accent) / 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(--accent) / 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;
}
.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-sheet{
  width: min(980px, 100vw);
  display: grid;
  grid-template-rows: auto auto auto 1fr auto;
}
.qa-tafsir-nav{
  display: flex; align-items: center; justify-content: center;
  gap: var(--sp-4); margin-top: var(--sp-3);
}
.qa-tafsir-step{
  width: 34px; height: 34px; 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);
}
.qa-tafsir-step:hover{ color: rgb(var(--accent-ui)); border-color: rgb(var(--accent) / 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. */

.qa-tafsir-body{
  /* A measure, not a column the width of the screen. Arabic at 1.2rem
     across 900px is about 120 characters a line, which is roughly twice
     what anybody can read without losing their place. */
  max-width: 74ch; margin-inline: auto; width: 100%;
}
.qa-tafsir-verse{ max-width: 40ch; margin-inline: auto; }

@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);
    font-size: 1.2rem; line-height: 1.9;
    max-height: 24vh; overflow-y: auto;
  }
  .qa-tafsir-body{ padding-left: var(--sp-4); padding-right: var(--sp-4); font-size: 1.05rem; line-height: 2.05; }
}

/* =========================================================================
   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);
}
.qa-tafsir-head{ padding: var(--sp-4) var(--sp-6) var(--sp-3); }
.qa-tafsir-head-row{ margin-bottom: var(--sp-2); }

/* The ayah: present, quotable, but never more than a glance. */
.qa-tafsir-verse{
  padding: var(--sp-3) var(--sp-5);
  font-size: 1.32rem; line-height: 2.05;
  max-height: 20vh; overflow-y: auto;
  max-width: 46ch;
}
.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);
  font-size: 1.22rem;            /* overridden live by the A+/A− control */
  line-height: 2.2;
  max-width: 68ch;
}

.qa-tafsir-foot{
  padding: 10px var(--sp-6) calc(10px + env(safe-area-inset-bottom));
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); flex-wrap: wrap;
}

@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(--accent) / 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(--accent) / 0.16);
  background:
    linear-gradient(150deg, rgb(var(--accent) / 0.05), rgb(var(--accent) / 0)) ,
    rgb(var(--surface));
  transition: border-color var(--dur) var(--ease-soft), transform var(--dur) var(--ease-soft);
}
.hadith-day.is-compact:hover{ border-color: rgb(var(--accent) / 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. */
.article-cover.has-cover-art::after,
.featured-cover.has-cover-art::after{
  content: ''; position: absolute; inset: 0;
  box-shadow: inset 0 0 0 1px rgb(var(--accent) / 0.16);
  border-radius: inherit; pointer-events: none;
}

.topic-tile-inner{ transition: transform var(--dur) var(--ease-soft); }
.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.
   ------------------------------------------------------------------------- */
.site-header .mega-panel{ padding-bottom: 10px; }
.site-header .mega-panel-head{ margin-bottom: 4px; }

@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, .adhkar-jump{ 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){
  .quran-ayah .quran-ayah-actions{ opacity:1; }
  /* 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(--accent) / 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{
  display:flex; align-items:center; justify-content:space-between;
  gap: var(--sp-4); 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(--accent) / 0.35);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.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(--accent) / 0.24);
  background:
    radial-gradient(110% 160% at 12% 0%, rgb(var(--accent) / 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(--accent) / 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(--accent) / 0.3);
  background: rgb(var(--accent) / 0.06);
  color: rgb(var(--heading));
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.qibla-compass-cta:hover{ background: rgb(var(--accent) / 0.12); border-color: rgb(var(--accent) / 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(--accent) / 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{
  position: absolute; top: 6px; left: 8px;
  font-family: var(--font-mono); font-size: 0.55rem;
  color: rgb(var(--text-muted)); opacity: 0.75;
}
.adhkar-tab.is-on .adhkar-tab-n{ color: rgb(var(--accent-ui)); opacity: 1; }

/* ---- 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; }


@media (max-width: 520px){
  
}

/* 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-id{ min-width: 0; }
.adhkar-panel-when{
  display: inline-flex; align-items: center; gap: 6px;
  margin-bottom: 8px;
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: 0.03em; color: rgb(var(--accent-ui));
}
.adhkar-panel-when svg{ width: 13px; height: 13px; }

/* 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 group rail ----------------------------------------------------
   A contents list for the set. Horizontal and scrollable, because these
   are four or five short labels and a vertical list of them would take
   more room than the first card. */
.adhkar-jump{
  display: flex; gap: 6px; margin-bottom: var(--sp-6);
  overflow-x: auto; scrollbar-width: none; padding-bottom: 3px;
}
.adhkar-jump::-webkit-scrollbar{ display: none; }
.adhkar-jump-link{
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 13px; border-radius: var(--radius-pill);
  border: 1px solid var(--hairline); background: rgb(var(--ink) / 0.03);
  font-size: var(--fs-2xs); color: rgb(var(--text-muted)); white-space: nowrap;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.adhkar-jump-link:hover{
  background: rgb(var(--accent) / 0.1);
  border-color: rgb(var(--accent) / 0.4);
  color: rgb(var(--accent-ui));
}
.adhkar-jump-link span{
  font-family: var(--font-mono); font-size: 0.58rem;
  padding: 1px 6px; border-radius: var(--radius-pill);
  background: rgb(var(--ink) / 0.07);
}

/* ---- A group ----------------------------------------------------------- */
.adhkar-group{ scroll-margin-top: calc(var(--header-h) + 20px); }
.adhkar-group + .adhkar-group{ margin-top: var(--sp-10); }
.adhkar-group-head{
  display: flex; flex-direction: column; gap: 4px;
  margin-bottom: var(--sp-4);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--hairline-faint);
}
.adhkar-group-head h3{
  margin: 0; font-family: var(--font-display);
  font-size: var(--fs-md); font-weight: 600; color: rgb(var(--heading));
  display: flex; align-items: center; gap: var(--sp-3);
}
/* A short rule after the heading, so a group reads as a section of the
   set rather than as another card with bigger text. */
.adhkar-group-head h3::after{
  content: ''; flex: 1 1 auto; height: 1px;
  background: linear-gradient(90deg, rgb(var(--accent) / 0.35), transparent);
}
.adhkar-group-head p{
  margin: 0; max-width: 62ch;
  font-size: var(--fs-2xs); color: rgb(var(--text-muted)); line-height: 1.6;
}

/* ---- 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(--accent) / 0.12);
  padding: 3px 8px; border-radius: var(--radius-pill);
}
.adhkar-card.is-quran{
  border-color: rgb(var(--accent) / 0.28);
  background:
    radial-gradient(120% 150% at 90% -10%, rgb(var(--accent) / 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(--accent) / 0.05);
  border: 1px solid rgb(var(--accent) / 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;
  font-size: clamp(1.4rem, 1.05rem + 1.4vw, 1.95rem);
  line-height: 2.3; color: rgb(var(--heading));
  transition: opacity var(--dur) var(--ease-soft);
}
.adhkar-ayah-en{
  margin: 0; font-size: var(--fs-sm); line-height: 1.7; 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(--accent) / 0.1);
  margin-inline-start: 4px;
}
.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-jump-link    varies x 34   (five of them, the section rail)
     .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){
  .adhkar-jump-link{ min-height: 44px; padding-block: 0; }
  /* 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); }
  .adhkar-group + .adhkar-group{ margin-top: var(--sp-8); }
}

@media print{
  .adhkar-jump, .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(--accent) / 0.055) 0%,
    rgb(var(--accent) / 0.012) 42%,
    rgb(var(--accent) / 0) 100%
  );
  --menu-border: var(--glass-border);
}

/* The dropdown panels. */
.site-header .mega-panel{
  background-color: var(--menu-bg);
  background-image: var(--menu-sheen);
  border-color: var(--menu-border);
}
/* 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. */
.site-header .mega-panel::before{
  background: var(--menu-bg);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* 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.
 */
@media (max-width:1180px){
  .site-header .main-nav.main-nav{
    background-color: var(--menu-bg);
    background-image: var(--menu-sheen);
  }
}
.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.
   ========================================================================= */
@media (hover: none), (pointer: coarse){
  .has-dropdown:hover .mega-panel{
    opacity: 0;
    visibility: hidden;
  }
  .has-dropdown.open .mega-panel{
    opacity: 1 !important;
    visibility: visible !important;
  }
  /* The row-entrance cascade is keyed on :hover too; without this the
     rows animate in on a touch device while the panel stays hidden, and
     then replay when it really opens. */
  .site-header .has-dropdown:hover .mega-item,
  .site-header .has-dropdown:hover .hadith-menu-row{ animation: none; }
}

/* =========================================================================
   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. */
.hadith-menu-now{
  display: inline-block;
  margin-inline-start: 7px;
  padding: 1px 7px;
  border-radius: 999px;
  background: rgb(var(--accent) / 0.14);
  color: rgb(var(--accent-ui));
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  vertical-align: 1px;
}
.site-header .hadith-menu-row.is-now{
  background: rgb(var(--accent) / 0.07);
  box-shadow: inset 2px 0 0 rgb(var(--accent) / 0.55);
}

/* ---- 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. */
.mega-panel-strip{
  grid-column: 1 / -1;
  margin-top: 6px;
  padding-top: 10px;
  border-top: 1px solid var(--hairline);
}
.mega-panel-strip-label{
  display: block;
  padding: 0 12px 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}/* 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. */
.site-header .tafsir-panel,
.site-header .adhkar-panel{ width: 580px; }

/* In the drawer everything is one column and the chips wrap freely. */
@media (max-width: 1180px){
  .main-nav .mega-panel-strip{ border-top-color: transparent; padding-top: 4px; margin-top: 2px; }
  .main-nav .mega-chips{ padding: 0 12px 4px; }
  .site-header .tafsir-panel,
  .site-header .adhkar-panel{ width: 100%; }
}

/* =========================================================================
   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; flex-direction: column; align-items: center; gap: 2px;
  margin-bottom: var(--sp-5);
}
.prayer-clock-label{
  font-family: var(--font-mono);
  font-size: 0.62rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.prayer-clock-time{
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.6rem, 1.6rem + 4.4vw, 4rem);
  line-height: 1.05;
  letter-spacing: -0.03em;
  color: rgb(var(--heading));
  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));
  max-width: 34ch;
  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{
  display: block; width: 96px; height: 1px;
  margin: 0 auto var(--sp-5);
  background: linear-gradient(90deg, transparent, rgb(var(--accent) / 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;
  letter-spacing: 0.18em;
  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);
  font-size: clamp(1.7rem, 1.2rem + 2vw, 2.3rem);
  line-height: 1.75;
  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;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.4rem, 1.4rem + 4vw, 3.4rem);
  line-height: 1;
  letter-spacing: -0.03em;
  color: rgb(var(--accent-ui));
  font-variant-numeric: tabular-nums;
}
.prayer-now-countdown .pc-num{ font-variant-numeric: tabular-nums; }
.prayer-now-countdown .pc-unit{
  font-family: var(--font-ui);
  font-size: 0.34em; font-weight: 600;
  color: rgb(var(--text-muted));
  margin-inline-end: 0.32em;
  transform: translateY(-0.1em);
}
.prayer-now-countdown .pc-sec{
  font-family: var(--font-mono);
  font-size: 0.3em; font-weight: 400;
  color: rgb(var(--text-muted));
  margin-inline-start: 0.2em;
  transform: translateY(-0.15em);
}
.prayer-now-at{
  margin: var(--sp-3) 0 0;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps);
  color: rgb(var(--text-muted));
}

@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{ padding: 40px 0 26px; }
.hero-frame.hero-frame{ padding: 40px 36px 34px; }

.hero .eyebrow{ margin-bottom: 12px; }
.hero.hero h1{ font-size: clamp(2rem, 1.4rem + 2.6vw, 3rem); }
.hero .sub{ margin-top: 9px; font-size: clamp(0.98rem, 0.9rem + 0.5vw, 1.18rem); }

/* 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{ margin: var(--sp-4) auto; width: 84px; }
.hero-ayah{
  margin-bottom: var(--sp-2);
  font-size: clamp(1.2rem, 0.95rem + 1.15vw, 1.6rem);
  line-height: 2.05;
}
.hero-ayah-en{ font-size: 0.86rem; line-height: 1.6; max-width: 44ch; }

.hero p.desc{
  margin-top: 16px;
  font-size: 0.97rem;
  line-height: 1.65;
  max-width: 46ch;
}
.hero-ctas{ margin-top: 22px; }
.hero-note{ margin-top: 11px; font-size: 0.76rem; }

/* 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{
  margin-top: 26px;
  padding-top: 18px;
  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-watermark-1{ width: 250px; height: 250px; top: -70px; right: -55px; }
.hero-watermark-2{ width: 160px; height: 160px; bottom: -46px; left: -40px; }
.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. */
@media (max-width: 400px) and (min-width: 354px){
  .site-header .logo-text{ display: flex; }
  .site-header .logo{ gap: 8px; }
  .site-header .logo-mark{ width: 32px; height: 32px; }
}

/* ---- 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. */
@media (max-width: 1180px){
  .site-header .logo{
    min-height: 44px;
    padding-block: 4px;
    align-items: center;
  }
}

/* ---- 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,
  .adhkar-jump-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,
  .adhkar-jump-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. */
@media (max-width: 1180px){
  .main-nav .mega-chip{ padding: 8px 12px; }
  .main-nav .hadith-menu-row.is-now{ box-shadow: inset 2px 0 0 rgb(var(--accent) / 0.55); }
}


/* 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);
}
.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-rule{ margin: 13px auto; }
.hero-ayah{
  max-width: 36ch;
  line-height: 1.9;
  margin-bottom: 7px;
}
.hero-ayah-en{ max-width: 52ch; }
.hero p.desc{ max-width: 58ch; margin-top: 14px; }
.hero-ctas{ margin-top: 20px; }
.hero-note{ margin-top: 10px; }
.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.
   ========================================================================= */

.site-header .hadith-menu-row,
.site-header .mega-item,
.site-header .quran-menu-resume{ min-width: 0; overflow: hidden; }

.site-header .hadith-menu-main,
.site-header .mega-item > span{ min-width: 0; max-width: 100%; }

.site-header .hadith-menu-title,
.site-header .hadith-menu-count,
.site-header .mega-title,
.site-header .mega-desc{
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 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. */
.site-header .hadith-menu-count{ white-space: nowrap; }
/* Titles may wrap to two, which is what stops a long book name being
   truncated when there is room for it below. */
.site-header .hadith-menu-title{ white-space: normal; overflow-wrap: anywhere; }

/* =========================================================================
   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.
 */
.site-header .quran-menu-ar{
  width: 64px; min-width: 64px; max-width: 64px;
  text-align: right;
  overflow: hidden; white-space: nowrap;
}

.site-header .mega-panel-foot-link{
  grid-column: 1 / -1;
  display: flex; align-items: center; gap: 8px;
  margin-top: 6px;
  padding: 9px 12px 2px;
  border-top: 1px solid var(--hairline);
  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);
}
.site-header .mega-panel-foot-link:hover{ color: rgb(var(--accent-ui)); }
.site-header .mega-panel-foot-ic{
  width: 14px; height: 14px; flex-shrink: 0;
  fill: none; stroke: currentColor;
  color: rgb(var(--accent)); opacity: 0.8;
}
.site-header .mega-panel-foot-text{
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.site-header .mega-panel-foot-go{
  width: 13px; height: 13px; flex-shrink: 0;
  margin-inline-start: auto;
  fill: none; stroke: currentColor;
  opacity: 0; transform: translateX(-4px);
  transition: opacity var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--ease-soft);
}
.site-header .mega-panel-foot-link:hover .mega-panel-foot-go{ opacity: 1; transform: translateX(0); }

/*
 * 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.
 */
.site-header .quran-panel .hadith-menu-row .hadith-menu-count{
  font-family: var(--font-ui);
  font-size: 0.87em;
  letter-spacing: 0;
  color: rgb(var(--text-muted));
}

/* =========================================================================
   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.
 */
@media (min-width: 1140px) and (max-width: 1300px){
  .site-header .main-nav > ul{ gap: 0; }
  .site-header .main-nav .nav-link{ padding-inline: 9px; }
  .site-header .header-inner{ gap: 12px; }
}
/* One step tighter again over the band nearest the drawer. */
@media (min-width: 1140px) and (max-width: 1240px){
  .site-header .main-nav .nav-link{ padding-inline: 7px; font-size: 0.86rem; }
  .site-header .main-nav .nav-caret-btn{ width: 16px; margin-left: -7px; margin-right: 1px; }
  .site-header .header-inner{ gap: 8px; }
  .site-header .header-actions{ gap: 6px; }
}

@media (min-width: 1181px){
  /*
   * v12.1 — THIS BLOCK IS WHY THE HEADER FAULT KEPT COMING BACK.
   *
   * It is a SECOND declaration of the same row, later in the file and at
   * higher specificity (0,2,0 vs 0,1,0) than the one on `.header-inner`
   * itself. Every previous attempt to fix the overlap
   * was made on that first rule, and this one quietly overrode it — with
   * `1fr auto 1fr` (equal side tracks, no content minimum) plus, fatally,
   * `min-width: 0` on the actions, which is an explicit instruction that
   * the actions row MAY be squeezed narrower than its own buttons.
   *
   * Measured at 1200px: the actions need 319px, this rule handed them a
   * 300px track, and the 19px difference was painted over the last nav
   * item. That is the clock icon sitting on the word "About".
   *
   * Both declarations now say the same thing — see the long v12.2 note
   * on `.header-inner` — so there is nothing left to contradict. If you
   * change one of them, change the other.
   */
  .site-header .header-inner{
    display: flex;
    align-items: center;
    gap: 16px;
    justify-content: space-between;
  }
  .site-header .header-inner > .logo{ flex: 0 1 auto; min-width: 0; }
  .site-header .header-inner > .main-nav{
    flex: 0 0 auto;
    /* The equal gaps. See the v12.2 note on `.header-inner`. */
    margin-inline: auto;
    min-width: max-content;
  }
  /* NOT shrinkable — the actions row is the one thing in the bar that
     must never be compressed, because every item in it is a fixed-size
     tap target. */
  .site-header .header-inner > .header-actions{ flex: 0 0 auto; min-width: max-content; }

  /* Nothing in the bar may push the bar wider than the bar. */
  .site-header .main-nav > ul{ flex-wrap: nowrap; }
  .site-header .header-actions{ flex-wrap: nowrap; }
}

/* 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. */
@media (max-width: 1439px){
  .site-header .logo-text .tagline{ display: none; }
}

/* Subscribe is the one call to action in the bar; it must never be the
   thing that gets cut. */
.site-header .header-actions .btn-primary{
  flex: 0 0 auto;
  white-space: nowrap;
}

/* =========================================================================
   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(--accent) / 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);
}
.tafsir-hit:hover{ background: rgb(var(--accent) / 0.08); transform: translateX(2px); }
.tafsir-hit-ref{ border-color: rgb(var(--accent) / 0.4); background: rgb(var(--accent) / 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(--accent) / 0.3);
  background: rgb(var(--accent) / 0.08);
  text-align: start;
  transition: background-color var(--dur) var(--ease-soft);
}
.tafsir-lib-resume:hover{ background: rgb(var(--accent) / 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(--accent) / 0.04);
}
.tafsir-browse-tabs{
  position: relative;
  display: inline-flex; 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; align-items: baseline; gap: 7px;
  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-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 0.92rem;
  opacity: 0.75;
}

.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(--accent) / 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));
}
.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);
}
.tafsir-surah-chip:hover{
  background: rgb(var(--accent) / 0.07);
  border-color: rgb(var(--accent) / 0.22);
}
.tafsir-surah-cell.is-open .tafsir-surah-chip{
  background: rgb(var(--accent) / 0.1);
  border-color: rgb(var(--accent) / 0.3);
}
.tafsir-surah-cell.is-current .tafsir-surah-chip{ border-color: rgb(var(--accent) / 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(--accent) / 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);
}
.tafsir-ayah-btn:hover{
  background: rgb(var(--accent) / 0.14);
  border-color: rgb(var(--accent) / 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);
}
.tafsir-juz-cell:hover{
  background: rgb(var(--accent) / 0.07);
  border-color: rgb(var(--accent) / 0.22);
}
.tafsir-juz-n{
  display: grid; place-items: center;
  width: 34px; height: 34px; flex-shrink: 0;
  border-radius: 50%;
  background: rgb(var(--accent) / 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(--accent) / 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{
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 var(--sp-4);
  padding: 10px 12px;
  border: 1px dashed rgb(var(--accent) / 0.32);
  border-radius: var(--radius);
  background: rgb(var(--accent) / 0.05);
  direction: ltr; text-align: left;
}
.tafsir-notesbar.is-on{
  border-style: solid;
  border-color: rgb(var(--accent) / 0.4);
  background: rgb(var(--accent) / 0.09);
}
.tafsir-notesbar-ic{
  width: 17px; height: 17px; flex-shrink: 0;
  color: rgb(var(--accent-ui));
}
.tafsir-notesbar-text{
  flex: 1; min-width: 0;
  font-family: var(--font-ui);
  font-size: var(--fs-2xs);
  line-height: 1.5;
  color: rgb(var(--text-muted));
}
.tafsir-notesbar-btn{
  flex-shrink: 0;
  min-height: 34px; padding: 0 15px;
  border: 1px solid rgb(var(--accent) / 0.4);
  border-radius: var(--radius-pill);
  background: rgb(var(--surface));
  cursor: pointer;
  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));
  transition: background-color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
.tafsir-notesbar-btn:hover{
  background: rgb(var(--accent) / 0.12);
  border-color: rgb(var(--accent) / 0.6);
}
@media (max-width: 520px){
  .tafsir-notesbar{ flex-wrap: wrap; }
  .tafsir-notesbar-text{ flex: 1 1 100%; order: 2; }
  .tafsir-notesbar-btn{ order: 3; margin-left: auto; }
}

/* ---- a shelf ---- */
.tafsir-shelf{ margin-bottom: var(--sp-10); scroll-margin-top: calc(var(--header-h) + 20px); }
.tafsir-shelf-head{
  display: flex; align-items: center; 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(--accent) / 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; display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.tafsir-shelf-titles h2{
  margin: 0;
  font-size: clamp(1.05rem, 0.95rem + 0.5vw, 1.3rem);
  line-height: 1.2;
}
.tafsir-shelf-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 1.02rem;
  color: rgb(var(--accent-ui));
  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-book-grid{ grid-template-columns: 1fr; }
  .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; }
.tafsir-page{ padding-block: var(--sp-6) var(--sp-10); }

/* ---- the bar ---------------------------------------------------------- */
.tafsir-bar{
  position: sticky;
  top: var(--header-h);
  z-index: 40;
  background: rgb(var(--surface));
  border-bottom: 1px solid var(--hairline);
  box-shadow: 0 1px 0 rgb(var(--ink) / 0.03);
}
.tafsir-bar-inner{
  display: flex; align-items: center; gap: 10px;
  min-height: 52px;
  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);
}
.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;
  min-width: 0; flex: 0 1 auto;
  margin-inline-start: auto;
  padding: 7px 12px;
  border-radius: 999px;
  border: 1px solid rgb(var(--accent) / 0.3);
  background: rgb(var(--accent) / 0.08);
  transition: background-color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
.tafsir-bar-book:hover{ background: rgb(var(--accent) / 0.16); border-color: rgb(var(--accent) / 0.5); }
.tafsir-bar-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;
}
.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; gap: 7px;
  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);
}
.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);
}
.tafsir-bar-step:hover{ background: rgb(var(--accent) / 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; }

/*
 * v11.4 — ONE MEASURE FOR THE WHOLE COLUMN.
 *
 * "tafsir isnt centered... and isnt taking enough space of the page."
 * Both complaints were the same fault, found by measuring: the title
 * and the ayah card were capped at 46rem while the commentary, the
 * prev/next nav and the "other commentaries" strip below them were
 * capped at 52rem. Each piece WAS individually centred — margin:auto
 * on every one of them — but with different widths their left and
 * right edges landed in different places, so the column visibly
 * jogged sideways as you scrolled past the ayah into the commentary.
 * That reads as "not centered" even though, block by block, it
 * technically was.
 *
 * One variable, used everywhere a width was hand-typed before, fixes
 * the misalignment and — widened from the old 46/52rem to 60rem —
 * answers "doesn't take enough space" at the same time: this is the
 * measure a reader's eye actually tracks down the page, and it is now
 * the same measure from the title to the last "other commentary" chip.
 */
.tafsir-page{ --tafsir-measure: 60rem; }

/* ---- the book, named once --------------------------------------------- */
.tafsir-title{
  max-width: var(--tafsir-measure);
  margin: 0 auto var(--sp-8);
  text-align: center;
}
.tafsir-title-ar{
  margin: 0;
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: clamp(2rem, 1.4rem + 2.8vw, 3.1rem);
  line-height: 1.5;
  color: rgb(var(--heading));
}
.tafsir-title-en{
  margin: 2px 0 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.05rem, 0.95rem + 0.6vw, 1.35rem);
  color: rgb(var(--accent-ui));
}
.tafsir-title-author{
  margin: 6px 0 0;
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 0.95rem;
  color: rgb(var(--text-muted));
}
.tafsir-title-note{
  margin: var(--sp-3) auto 0;
  max-width: 52ch;
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: rgb(var(--text-muted));
}

/* ---- 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(--accent) / 0.22);
  background:
    radial-gradient(ellipse 70% 60% at 50% 0%, rgb(var(--accent) / 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(--accent) / 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);
  max-width: 34ch;
  font-family: var(--font-quran-glyphs), var(--font-quran), var(--font-arabic);
  direction: rtl; unicode-bidi: isolate;
  font-size: clamp(1.45rem, 1.1rem + 1.7vw, 2.05rem);
  line-height: 2.15;
  text-align: center;
  color: rgb(var(--heading));
}
.tafsir-ayah-en{
  margin: 0 auto;
  max-width: 56ch;
  font-family: var(--font-body); font-style: italic;
  font-size: var(--fs-sm); line-height: 1.7;
  text-align: center;
  color: rgb(var(--text-muted));
}

.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);
}
.tafsir-tool:hover{ background: rgb(var(--accent) / 0.1); border-color: rgb(var(--accent) / 0.35); }
.tafsir-tool svg{ width: 15px; height: 15px; fill: none; stroke: currentColor; }
.tafsir-tool.is-done{ background: rgb(var(--accent) / 0.16); border-color: rgb(var(--accent) / 0.5); color: rgb(var(--accent-ui)); }
.tafsir-tool-read{ background: rgb(var(--accent) / 0.09); border-color: rgb(var(--accent) / 0.32); color: rgb(var(--accent-ui)); }
.tafsir-tool-read:hover{ background: rgb(var(--accent) / 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(--accent) / 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); font-weight: var(--ar-weight);
  direction: rtl; unicode-bidi: isolate;
  font-size: 1.26rem;
  line-height: 2.15;
  color: rgb(var(--text));
  text-align: justify;
  text-align-last: right;
}
.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));
  font-weight: 500;
}
.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(--accent) / 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; justify-content: 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);
}
.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(--accent) / 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);
}
.tafsir-onward-link:hover{ border-color: rgb(var(--accent) / 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 ------------------------------------------------ */
.tafsir-others{
  max-width: var(--tafsir-measure);
  margin: var(--sp-10) auto 0;
  padding-top: var(--sp-8);
  border-top: 1px solid var(--hairline);
}
.tafsir-others-title{
  margin: 0;
  font-size: clamp(1.05rem, 0.95rem + 0.5vw, 1.3rem);
  text-align: center;
}
.tafsir-others-sub{
  margin: 4px 0 var(--sp-6);
  text-align: center;
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps);
  color: rgb(var(--accent-ui));
}
.tafsir-others-shelf{ margin-bottom: var(--sp-5); }
.tafsir-others-shelf-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-others-row{ display: flex; flex-wrap: wrap; gap: 7px; }
.tafsir-other{
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--hairline-strong);
  background: rgb(var(--surface));
  text-align: center;
  transition: background-color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft), transform var(--dur) var(--spring);
}
.tafsir-other:hover{ background: rgb(var(--accent) / 0.1); border-color: rgb(var(--accent) / 0.4); transform: translateY(-1px); }
.tafsir-other.is-current{
  background: rgb(var(--accent) / 0.16);
  border-color: rgb(var(--accent) / 0.55);
  pointer-events: none;
}
.tafsir-other-ar{ font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 0.95rem; line-height: 1.4; color: rgb(var(--heading)); white-space: nowrap; }
.tafsir-other-en{ font-family: var(--font-ui); font-size: 0.66rem; font-weight: 600; color: rgb(var(--accent-ui)); white-space: nowrap; }

/* ---- the two sheets ---------------------------------------------------- */
.tafsir-jump,
.tafsir-switch{
  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,
.tafsir-switch.is-open{ opacity: 1; }
.tafsir-jump-inner,
.tafsir-switch-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,
.tafsir-switch.is-open .tafsir-switch-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,
.tafsir-switch-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,
.tafsir-switch-close svg{ width: 16px; height: 16px; fill: none; stroke: currentColor; }

.tafsir-switch-head{
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  padding-bottom: var(--sp-3);
  margin-bottom: var(--sp-3);
  border-bottom: 1px solid var(--hairline);
}
.tafsir-switch-eyebrow{
  display: block;
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.tafsir-switch-ref{
  display: block; margin-top: 2px;
  font-family: var(--font-display); font-size: 1.05rem;
  color: rgb(var(--heading));
}
.tafsir-switch-body{ max-height: 60vh; overflow-y: auto; margin: 0 calc(var(--sp-2) * -1); padding: 0 var(--sp-2); }
.tafsir-switch-shelf{ margin-bottom: var(--sp-4); }
.tafsir-switch-shelf-label{
  display: flex; align-items: center; gap: 7px;
  margin-bottom: 6px;
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: rgb(var(--text-muted));
  position: sticky; top: 0;
  background: rgb(var(--surface));
  padding-block: 5px;
}
.tafsir-switch-shelf-label svg{ width: 14px; height: 14px; fill: none; stroke: currentColor; color: rgb(var(--accent-ui)); }
.tafsir-switch-book{
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  min-width: 0;
  transition: background-color var(--dur-fast) var(--ease-soft);
}
.tafsir-switch-book:hover{ background: rgb(var(--accent) / 0.09); }
.tafsir-switch-book.is-current{ background: rgb(var(--accent) / 0.14); }
.tafsir-switch-book-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 1.05rem; line-height: 1.4;
  color: rgb(var(--heading)); white-space: nowrap; flex-shrink: 0;
  min-width: 8.5rem;
}
.tafsir-switch-book-main{ flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.tafsir-switch-book-en{ font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 600; color: rgb(var(--accent-ui)); }
.tafsir-switch-book-note{
  font-size: var(--fs-2xs); line-height: 1.5; color: rgb(var(--text-muted));
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.tafsir-switch-tick{ width: 16px; height: 16px; flex-shrink: 0; fill: none; stroke: currentColor; color: rgb(var(--accent-ui)); }

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-switch-book-ar{ min-width: 0; }
  .tafsir-jump, .tafsir-switch{ 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{
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-3) var(--sp-4);
  align-items: start;
  padding: var(--sp-5) var(--sp-6);
  margin-bottom: var(--sp-6);
  border-radius: var(--radius-lg);
  border: 1px solid var(--hairline);
  background:
    radial-gradient(ellipse 60% 100% at 0% 0%, rgb(var(--accent) / 0.09), transparent 70%),
    rgb(var(--surface));
}
.adhkar-panel-mark{
  display: grid; place-items: center;
  width: 46px; height: 46px;
  border-radius: 50%;
  background: rgb(var(--accent) / 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{
  margin: 0;
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: clamp(1.5rem, 1.1rem + 1.7vw, 2.05rem);
  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(--accent) / 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; }
.adhkar-panel-note{
  margin: var(--sp-3) 0 0;
  max-width: 68ch;
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: rgb(var(--text-muted));
}

/* The progress, as one line along the foot of the panel. */
.adhkar-progress{
  grid-column: 1 / -1;
  display: flex; flex-direction: column; gap: 8px;
  margin-top: var(--sp-2);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--hairline);
}
.adhkar-progress-track{
  display: block;
  height: 6px;
  border-radius: 999px;
  background: rgb(var(--ink) / 0.08);
  overflow: hidden;
}
.adhkar-progress-fill{
  display: block; height: 100%; width: 0;
  border-radius: 999px;
  background: linear-gradient(90deg, rgb(var(--accent) / 0.6), rgb(var(--accent)));
  transition: width var(--dur-slow, 420ms) var(--ease-out-expo);
}
.adhkar-progress-row{
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.adhkar-progress-count{
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-caps);
  color: rgb(var(--text-muted));
}
.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);
}
.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
   ========================================================================= */

.mega-chip-flat{
  flex-direction: row;
  align-items: center;
  gap: 7px;
  padding: 7px 13px;
}.tafsir-menu-book .quran-menu-ar{
  min-width: 6.5rem;
  text-align: right;
  font-size: 0.95rem;
}

/* =========================================================================
   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. */
@media (max-width: 640px){
  .site-header .logo{ min-width: 0; flex: 0 1 auto; }
  .site-header .logo-text{ min-width: 0; }
  .site-header .logo-text .name{
    min-width: 0;
    font-size: clamp(0.94rem, 3.3vw, 1.14rem);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* 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. */
  font-size: 1.12em;
  line-height: 1;
}
.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(--accent) / 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. Two changes: it tracks the header
   instead of hanging below where the header used to be, and it is a
   three-track grid instead of one item pinned left and a clump pinned
   right.
   ------------------------------------------------------------------------- */
.tafsir-bar{
  top: var(--header-live);
  transition: top var(--dur) var(--ease);
  /* Opaque. A bar you scroll a commentary underneath cannot be
     translucent — see "MENUS ARE OPAQUE" earlier in this file. */
  background: rgb(var(--surface));
}
.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:hover,
.tafsir-bar-aa[aria-expanded="true"]{
  background: rgb(var(--accent) / 0.12);
  border-color: rgb(var(--accent) / 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-ayah-en{ max-width: min(46rem, 100%); }
.tafsir-body{
  max-width: 100%;
  margin-inline: auto;
  font-size: 1.38rem;
  line-height: 2.2;
  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-title{ margin-bottom: var(--sp-6); }
.tafsir-title-ar{ font-size: clamp(1.75rem, 1.2rem + 2.2vw, 2.5rem); line-height: 1.4; }
.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{ font-size: 1.2rem; 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(--accent) / 0.3);
  background: rgb(var(--accent) / 0.08);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
.qa-tafsir-book:hover,
.qa-tafsir-book[aria-expanded="true"]{ background: rgb(var(--accent) / 0.16); border-color: rgb(var(--accent) / 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);
}
.qa-tafsir-pick:hover{ background: rgb(var(--accent) / 0.09); }
.qa-tafsir-pick.is-on{ background: rgb(var(--accent) / 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;
  margin: 0 0 var(--sp-2);
  padding-block: 14px 2px;
  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);
}
.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:hover,
.tafsir-jump-form input:hover,
.tafsir-lib-search input:hover,
.hadith-search input:hover,
.pp-cmd-field input:hover,
.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;
}
/* …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(--accent) / 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; }
.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));
}
.pp-cmd-esc:hover{ color: rgb(var(--heading)); border-color: rgb(var(--accent) / 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(--accent) / 0.13); }
.pp-cmd-row-ic{
  width: 30px; height: 30px; flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: 9px;
  background: rgb(var(--accent) / 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(--accent) / 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-mono); 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(--accent) / 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,
.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; }
.pp-filter:hover{ border-color: rgb(var(--accent) / 0.45); color: rgb(var(--accent-ui)); }
.pp-filter.is-on{
  background: rgb(var(--accent) / 0.13);
  border-color: rgb(var(--accent) / 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(--accent) / 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);
}
.pp-res-row:hover{ background: rgb(var(--accent) / 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(--accent) / 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);
}
.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(--accent) / 0);
  transition: border-color var(--dur-fast) var(--ease-soft);
}
.hero-ayah-ref a:hover{ border-bottom-color: rgb(var(--accent) / 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(--accent) / 0.34);
  border-radius: var(--radius-pill);
  background: rgb(var(--accent) / 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(--accent) / 0.16);
  color: rgb(var(--accent-ui));
  transition: background var(--dur-fast) var(--ease-soft);
}
.tasbih-chip-clear:hover{ background: rgb(var(--accent) / 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(--accent) / 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{
  display: flex; 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; flex: 1 1 0; 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. */
  min-width: 108px;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: var(--sp-4) var(--sp-3) var(--sp-3);
  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);
}
.adhkar-tab:hover{ border-color: rgb(var(--accent) / 0.45); transform: translateY(-1px); }
.adhkar-tab.is-on{
  border-color: rgb(var(--accent) / 0.75);
  background: rgb(var(--accent) / 0.09);
}
.adhkar-tab-ic{
  display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: rgb(var(--accent) / 0.1);
  color: rgb(var(--accent-ui));
}
.adhkar-tab.is-on .adhkar-tab-ic{ background: rgb(var(--accent) / 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{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 1.05rem; line-height: 1.75;
  color: rgb(var(--heading)); white-space: nowrap;
}
.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. --------------- */
/* v12.5 — UNWRAPPED. This was `@media (max-width: 900px)`; the picker is
   now the control at every width and the thirteen-box rail above it is
   gone. See the note in the v12.5 layer at the foot of this file. */
.adhkar-tabs{ display: none; }


/* ---- 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){
  
  
  .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{
  position: relative;
  text-align: center;
  padding: calc(var(--sp-9) + 6px) var(--sp-7) var(--sp-8);
  border: 1px solid rgb(var(--accent) / 0.3);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(130% 105% at 50% 0%, rgb(var(--accent) / 0.12), transparent 62%),
    rgb(var(--surface));
  box-shadow: var(--e2);
  overflow: hidden;
}
.book-unwan-rule{
  position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg,
    rgb(var(--accent) / 0) 0%, rgb(var(--accent) / 0.85) 22%,
    rgb(var(--accent) / 0.85) 78%, rgb(var(--accent) / 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(--accent) / 0.12);
  border: 1px solid rgb(var(--accent) / 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(--accent) / 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));
}
.book-unwan-ctas{ margin-top: var(--sp-6); }

@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{
  display: block;
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  direction: rtl; unicode-bidi: isolate; text-align: start;
  font-size: clamp(1.45rem, 1.15rem + 1.3vw, 1.95rem);
  line-height: 1.85;
  color: rgb(var(--heading));
  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{
  display: block;
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  direction: rtl; unicode-bidi: isolate; text-align: start;
  font-size: 1.32rem; line-height: 1.85;
  color: rgb(var(--heading));
  margin-bottom: 2px;
}
.hadith-collection-card h3{
  font-family: var(--font-display); font-weight: 600;
  font-size: 1.06rem; line-height: 1.3;
  color: rgb(var(--heading-soft));
}

/* ---- 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(--accent) / 0.22);
}
.hadith-single-chapter-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 1.25rem; line-height: 1.9;
  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(--accent) / 0.15), rgb(var(--accent) / 0.8), rgb(var(--accent) / 0.15));
  opacity: 0.55;
  transition: opacity var(--dur) var(--ease-soft);
}
.hadith-shelf-card:hover{
  border-color: rgb(var(--accent) / 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(--accent) / 0.09), transparent 62%),
    rgb(var(--surface));
  border-color: rgb(var(--accent) / 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(--accent) / 0.11);
  border: 1px solid rgb(var(--accent) / 0.26);
  color: rgb(var(--accent-ui));
}
.hadith-shelf-ic svg{ width: 18px; height: 18px; fill: none; stroke: currentColor; }
.hadith-shelf-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  direction: rtl; unicode-bidi: isolate; text-align: start;
  font-size: 1.5rem; line-height: 1.8;
  color: rgb(var(--heading));
}
.hadith-shelf-title{
  font-family: var(--font-display); font-weight: 600;
  font-size: 1.02rem; line-height: 1.3;
  color: rgb(var(--heading-soft));
}
.hadith-shelf-blurb{
  font-size: var(--fs-2xs); 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); }
.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){
  .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) .pp-pwa-banner,
body:has(.main-nav.open) .qa-bar,
body:has(.main-nav.open) .back-top,
body:has(.main-nav.open) .quran-siderail,
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.pp-cmd-open .quran-siderail,
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.theme-sheet-open .quran-siderail,
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,
body.pp-sheet-open .quran-siderail{
  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;
    margin-top: 14px;
    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(--accent) / 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 Aa and the back-to-top, in one column ---------------------
   Reported as "the Aa on the bottom right contradicts with arrow, make
   sure the placement is suitable and no overlapping happens".

   They were two independent fixed elements, each given its own offsets:
   the rail at right 12px / bottom 14px, back-to-top at right 24px /
   bottom 80px. Two different right edges, so they read as two accidents
   rather than as one stack — and the rail's PANEL opens upward from its
   toggle, straight through the 44px circle sitting 66px above it.

   One right edge, one gap, stated once; and the arrow leaves entirely
   while the panel is open, because a panel is a menu and nothing sits on
   top of a menu. */
.quran-siderail{
  --rail-right: calc(20px + env(safe-area-inset-right));
  --rail-bottom: calc(20px + env(safe-area-inset-bottom));
  --rail-size: 52px;
  right: var(--rail-right);
  bottom: var(--rail-bottom);
}
body.qa-playing .quran-siderail{
  --rail-bottom: calc(104px + env(safe-area-inset-bottom));
}
/* The arrow stacks directly above the rail toggle, on the same right
   edge, with a 12px gap. */
body:has(.quran-siderail) .back-top{
  right: calc(20px + env(safe-area-inset-right));
  bottom: calc(20px + 52px + 12px + env(safe-area-inset-bottom));
}
body.qa-playing:has(.quran-siderail) .back-top{
  bottom: calc(104px + 52px + 12px + env(safe-area-inset-bottom));
}
body:has(.quran-siderail.is-open) .back-top{
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
}

@media (max-width: 640px){
  .quran-siderail{
    --rail-right: calc(14px + env(safe-area-inset-right));
    --rail-bottom: calc(14px + env(safe-area-inset-bottom));
    --rail-size: 46px;
  }
  body.qa-playing .quran-siderail{
    --rail-bottom: calc(98px + env(safe-area-inset-bottom));
  }
  body:has(.quran-siderail) .back-top{
    right: calc(14px + env(safe-area-inset-right));
    /* 46px toggle at this breakpoint. */
    bottom: calc(14px + 46px + 12px + env(safe-area-inset-bottom));
  }
  body.qa-playing:has(.quran-siderail) .back-top{
    bottom: calc(98px + 46px + 12px + env(safe-area-inset-bottom));
  }
  .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".

   The height clamp was `100dvh - header - 130px` — a constant that had to
   be right for a bottom offset it did not know about. It is computed from
   the rail's own offset now, so the panel can never be sized for a
   position it is not in. That is what "missing parts" was: with the
   recitation bar docked the rail sits 104px up, and 130px of allowance
   was not enough for it. */
.quran-rail-panel{
  max-height: calc(100dvh - var(--header-h, 68px) - var(--rail-bottom, 20px) - var(--rail-size, 52px) - 12px - 16px);
  padding: var(--sp-4) var(--sp-3) var(--sp-3);
  border-radius: 20px;
  gap: 10px;
  border-color: rgb(var(--accent) / 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(--accent) / 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(--accent) / 0.12);
  border: 1px solid rgb(var(--accent) / 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);
}
.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(--accent) / 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{ transform: translateY(0) scale(0.985); 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);
}
.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,
.tag-chip.tag-newest,
.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. */
.site-header .adhkar-panel{ width: 660px; }
.site-header .adhkar-menu-unit{ display: none; }


/* =========================================================================
   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)); }
.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{
  position: relative;
  max-width: 760px; margin: 0 auto var(--sp-8);
  padding: var(--sp-9) var(--sp-6) var(--sp-7);
  text-align: center;
  border: 1px solid rgb(var(--accent) / 0.28);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background:
    radial-gradient(130% 120% at 50% 0%, rgb(var(--accent) / 0.09), transparent 62%),
    rgb(var(--bg-alt));
}
.sirah-book-unwan-rule{
  position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg,
    rgb(var(--accent) / 0) 0%, rgb(var(--accent) / 0.85) 22%,
    rgb(var(--accent) / 0.85) 78%, rgb(var(--accent) / 0) 100%);
}
.sirah-book-unwan-mark{
  display: grid; place-items: center;
  width: 64px; height: 64px; margin: 0 auto var(--sp-5);
  border-radius: 50%;
  background: rgb(var(--accent) / 0.1);
  border: 1px solid rgb(var(--accent) / 0.34);
}
.sirah-book-unwan-mark svg{ width: 40px; height: 40px; }

.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);
  letter-spacing: 0.18em; 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(--accent) / 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);
  font-style: italic;
  line-height: 1.5;
  color: rgb(var(--heading));
}
.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(--accent) / 0.35); }
.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(--accent) / 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));
}
.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(--accent) / 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(--accent) / 0.5); }

.sirah-book-toc{
  list-style: none; margin: 0; padding: 0;
  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;
}
.sirah-book-toc-link{
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-3);
  padding: 9px 10px 9px 4px;
  border-radius: var(--radius-sm);
  transition: background-color var(--dur-fast) var(--ease-soft);
}
.sirah-book-toc-link:hover{ background: rgb(var(--accent) / 0.08); }

/* 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{
  display: grid; place-items: center;
  width: 30px; height: 30px;
  border-radius: 50%;
  border: 1px solid rgb(var(--accent) / 0.35);
  background: rgb(var(--accent) / 0.08);
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 0.9rem; line-height: 1;
  color: rgb(var(--accent-ui));
}
.sirah-book-toc-names{
  min-width: 0;
  display: flex; flex-direction: column; gap: 0;
  position: relative;
}
.sirah-book-toc-ar{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 1.08rem;
  /* 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. */
  line-height: 1.85;
  color: rgb(var(--heading));
  text-align: left;         /* second line of an LTR label — see the
                               adhkār menu note for the same reasoning */
  unicode-bidi: isolate;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sirah-book-toc-en{
  font-family: var(--font-ui);
  font-size: var(--fs-2xs);
  letter-spacing: 0.02em;
  color: rgb(var(--text-muted));
  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;
  flex: 0 0 auto;
  padding-left: var(--sp-6);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: rgb(var(--text-muted));
  letter-spacing: 0;
}
.sirah-book-toc-count::before{
  content: '';
  position: absolute; right: calc(100% + 6px); left: -100vw;
  bottom: 0.42em; height: 3px;
  background-image: radial-gradient(circle, rgb(var(--accent) / 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-link{ overflow: hidden; }

.sirah-book-toc-read{
  margin-left: 8px;
  font-size: 0.8rem;
  color: rgb(var(--accent-ui));
}
.sirah-book-toc-item.is-read .sirah-book-toc-en{ opacity: 0.62; }
.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));
}
.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(--accent) / 0.24);
  background:
    radial-gradient(120% 130% at 50% 0%, rgb(var(--accent) / 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(--accent) / 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);
}
.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(--accent) / 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(--accent) / 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);
}
.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(--accent) / 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);
}
a.sirah-book-turn-link:hover{
  border-color: rgb(var(--accent) / 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);
}
.sirah-book-turn-toc:hover{ color: rgb(var(--accent-ui)); background: rgb(var(--accent) / 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){
  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);
}
.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.
   ========================================================================= */
.site-header .adhkar-menu-ar,
.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-size: 0.9rem;
  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);
}

@media (max-width: 1100px){
  .article-shell .article-rail.article-rail{
    top: calc(var(--header-h) - 1px);
    border-top: 1px solid transparent;
    background: rgb(var(--bg) / 0.9);
    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. .mini-bar already had this rule; nothing else did.

   The transition matches the header's own so the pair move as one. */
html.pp-header-hidden .tafsir-bar,
html.pp-header-hidden .pp-welded{
  top: 0;
}
/* v12.5 — THE RAIL ONLY GOES TO ZERO WHERE IT IS WELDED, AND IT IS ONLY
   WELDED ON A PHONE.

   Above 1100px `.article-rail` is not a bar under the header at all: it
   is a narrow sticky column beside the article, pinned 22px below the
   header. This rule was written without a media query, so on a desktop
   the whole column jumped to top:0 the moment the header hid itself —
   straight underneath the mini reading bar, which is 45px tall and
   z-index 95. The first two rail buttons, Like and Save, were simply
   behind it. That is the "left side of the page is weirdly overlapping"
   in the report. */
@media (max-width: 1100px){
  html.pp-header-hidden .article-shell .article-rail.article-rail{ top: 0; }
}
.tafsir-bar,
.pp-welded,
.article-shell .article-rail.article-rail{
  transition: top 0.3s var(--ease);
}
@media (prefers-reduced-motion: reduce){
  .tafsir-bar, .pp-welded, .article-shell .article-rail.article-rail{ transition: none; }
}


/* =========================================================================
   THE READER STACK — v12.4. Aa ON TOP, THE ARROW UNDER IT.

   Reported as: "the Aa should be above the arrow in the qur'an page (and
   wherever applicable) as you can see! as thats a logical issue.. and it
   causes overlapping."

   Both halves of that are right, and the second explains the first.

   v12.3 put the arrow above the Aa. But the Aa is a TOGGLE FOR A PANEL,
   and that panel opens UPWARD — so it opened straight through the 44px
   circle parked 12px above it. v12.3 dealt with that by hiding the arrow
   whenever the panel was open, which is a workaround for a stacking order
   that was simply the wrong way round: you do not put anything in the
   space a menu is going to occupy.

   Inverted, the geometry resolves itself. The panel opens above the Aa,
   into empty page; the arrow sits below the Aa, out of its path; nothing
   has to be hidden, and no two controls ever occupy the same pixels.

   It is also the better ergonomics, which is presumably why it was
   noticed. The arrow is the one-tap, no-thought control and it now has
   the bottom-right corner — the easiest place on a phone to reach with a
   thumb. The Aa, which is a considered choice you make once a session,
   sits above it.

   ONE RIGHT EDGE, ONE GAP, and both offsets derive from the same three
   numbers so the stack cannot drift apart again:

     --stack-right   the shared right edge
     --stack-bottom  the floor (raised when the recitation bar is docked)
     --stack-gap     the single space between the two controls
   ========================================================================= */

:root{
  --stack-right: calc(20px + env(safe-area-inset-right));
  --stack-bottom: calc(20px + env(safe-area-inset-bottom));
  --stack-gap: 12px;
  --stack-arrow: 44px;   /* .back-top */
}

/* The arrow takes the floor. */
body:has(.quran-siderail) .back-top{
  right: var(--stack-right);
  bottom: var(--stack-bottom);
}
/* The Aa sits one arrow plus one gap above it. */
.quran-siderail{
  --rail-right: var(--stack-right);
  --rail-bottom: calc(var(--stack-bottom) + var(--stack-arrow) + var(--stack-gap));
  right: var(--rail-right);
  bottom: var(--rail-bottom);
}
/* Docked recitation bar raises the floor; the stack rides up together. */
body.qa-playing{
  --stack-bottom: calc(104px + env(safe-area-inset-bottom));
}
body.qa-playing .quran-siderail{
  --rail-bottom: calc(var(--stack-bottom) + var(--stack-arrow) + var(--stack-gap));
}
body.qa-playing:has(.quran-siderail) .back-top{
  bottom: var(--stack-bottom);
}

/* The arrow no longer has to disappear for the panel: it is not in its
   way any more. Overriding v12.3's !important escape hatch rather than
   deleting it, so the reason stays readable next to the fix. */
body:has(.quran-siderail.is-open) .back-top{
  opacity: 1 !important;
  visibility: visible !important;
  pointer-events: auto !important;
}
/* Except when the panel actually reaches down over it on a short screen,
   where a control under a menu would be unreachable anyway. */
@media (max-height: 620px){
  body:has(.quran-siderail.is-open) .back-top{
    opacity: 0 !important; visibility: hidden !important; pointer-events: none !important;
  }
}

@media (max-width: 640px){
  :root{
    --stack-right: calc(14px + env(safe-area-inset-right));
    --stack-bottom: calc(14px + env(safe-area-inset-bottom));
    --stack-arrow: 42px;   /* .back-top shrinks at this breakpoint */
  }
  body.qa-playing{
    --stack-bottom: calc(98px + env(safe-area-inset-bottom));
  }
  .quran-siderail{ --rail-size: 46px; }
}


/* =========================================================================
   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-link{
  grid-template-columns: 30px minmax(0, 1fr) auto 16px;
}
.sirah-book-toc-read{
  margin-left: 0;
  justify-self: center;
  font-size: 0.72rem;
  line-height: 1;
  color: rgb(var(--accent-ui));
  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(--accent) / 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(--accent) / 0.32) 12%,
    rgb(var(--accent) / 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(--accent) / 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(--accent) / 0.5);
  border-color: rgb(var(--accent) / 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);
}
.maghazi-find-link:hover{ background: rgb(var(--accent) / 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; }
.maghazi-part-link:hover{ background: rgb(var(--accent) / 0.07); }
.maghazi-part-n{
  display: grid; place-items: center;
  width: 34px; height: 34px;
  border-radius: 50%;
  border: 1px solid rgb(var(--accent) / 0.32);
  background: rgb(var(--accent) / 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.
   ========================================================================= */

.pp-welded,
.mini-bar,
.tafsir-bar,
.article-shell .article-rail.article-rail{
  --welded-top: calc(var(--header-h) - 1px);
}

/* (1) and the retreat. `top` is written once, here, for all of them. */
.mini-bar{
  top: var(--welded-top);
  border-top: 1px solid transparent;
}
html.pp-header-hidden .mini-bar,
.mini-bar.header-hidden{ top: 0; }

/* (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. */
body:has(.tafsir-bar) .site-header,
body:has(.pp-welded) .site-header,
body:has(.mini-bar.show) .site-header{
  box-shadow: none;
  border-bottom-color: transparent;
}

/* (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. */
.mini-bar{
  background: rgb(var(--surface) / 0.88);
  -webkit-backdrop-filter: saturate(1.8) blur(20px);
  backdrop-filter: saturate(1.8) blur(20px);
  border-bottom: 1px solid var(--hairline);
  box-shadow: 0 2px 4px -1px rgb(var(--shadow) / 0.06),
              0 4px 10px -2px rgb(var(--shadow) / 0.07);
}

/* 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. */
.pp-resume{ top: calc(var(--header-live) + 10px); transition: top 0.3s var(--ease); }
.prayer-month-row-head{ top: calc(var(--header-live) + 6px); transition: top 0.3s var(--ease); }
@media (prefers-reduced-motion: reduce){
  .pp-resume, .prayer-month-row-head{ transition: none; }
}

/* 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. */
.reading-progress{ z-index: 260; }


/* =========================================================================
   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.
   ========================================================================= */

@media (min-width: 1101px){
  .article-rail{
    top: calc(var(--header-live) + 22px);
    transition: top 0.3s var(--ease);
    /* Above the article, below the bars. Without a stacking context of
       its own a sticky element is painted in source order, and the rail
       comes before the mini bar in the markup. */
    z-index: 2;
  }
  /* When the mini bar is showing it owns the top of the screen, and the
     rail starts under it. 45px is the bar's measured height; the extra
     14 is the same breathing space the rail has under the header. */
  body:has(.mini-bar.show) .article-rail{
    top: calc(var(--header-live) + 45px + 14px);
  }
  @media (prefers-reduced-motion: reduce){
    .article-rail{ transition: none; }
  }
}

/* ---- one line, not two -------------------------------------------------- */
.rail-toc{ gap: 12px; }
.toc-body{ gap: 14px; }
.toc-track{
  width: 2px;
  background: rgb(var(--heading) / 0.12);
}
.toc-progress{ background: rgb(var(--accent)); }

#tocList{ gap: 1px; }
#tocList li a{
  position: relative;
  border-left: none;
  margin-left: 0;
  padding: 6px 0 6px 2px;
  transition: color var(--dur-fast) var(--ease-soft);
}
#tocList li.toc-level-3 a{ padding-left: 14px; }
#tocList li a.active{
  color: rgb(var(--accent-ui));
  font-weight: 600;
}
/* 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. */
#tocList li a.active::before{
  content: "";
  position: absolute;
  left: calc((14px + 2px) * -1);
  top: 50%;
  transform: translateY(-50%);
  width: 2px; height: 16px;
  border-radius: 2px;
  background: rgb(var(--accent));
}

/* ---- 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-btn{ padding-inline: 10px; }
.rail-fontsize{ padding-inline: 10px; }
.rail-toc-label{ padding-inline: 2px; }
.rail-divider{ background: rgb(var(--heading) / 0.1); }


/* =========================================================================
   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.
   ========================================================================= */
@media (max-width:1180px){
  .site-header .main-nav .nav-link[aria-current="page"],
  .site-header .main-nav .nav-link.is-current,
  .site-header .main-nav > ul > li.is-current-item > .nav-link{
    position: relative;
    background: rgb(var(--accent) / 0.09);
    box-shadow: none;
    padding-left: 22px;
  }
  .site-header .main-nav .nav-link[aria-current="page"]::before,
  .site-header .main-nav .nav-link.is-current::before,
  .site-header .main-nav > ul > li.is-current-item > .nav-link::before{
    content: "";
    position: absolute;
    left: 8px; top: 50%;
    transform: translateY(-50%);
    width: 3px; height: 20px;
    border-radius: 3px;
    background: rgb(var(--accent));
  }
}


/* =========================================================================
   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.
   ========================================================================= */

.tafsir-book-grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: var(--sp-4);
}

.tafsir-book-card{
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-5) var(--sp-4);
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  background:
    linear-gradient(180deg, rgb(var(--surface)) 0%, rgb(var(--surface) / 0.55) 100%);
  color: inherit;
  transition:
    border-color var(--dur) var(--ease-soft),
    box-shadow var(--dur) var(--ease-soft),
    transform var(--dur) var(--ease-soft);
}
.tafsir-book-card:hover{
  border-color: rgb(var(--accent) / 0.4);
  box-shadow: var(--e2);
  transform: translateY(-2px);
}
.tafsir-book-card:focus-visible{
  outline: 2px solid rgb(var(--accent-ui));
  outline-offset: 2px;
}

/* ---- the title, over the site's own double rule -------------------------- */
.tafsir-book-head{
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  min-height: 74px;
  justify-content: flex-end;
}
.tafsir-book-ar{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: clamp(1.5rem, 1.2rem + 1vw, 1.85rem);
  line-height: 1.5;
  text-align: center;
  color: rgb(var(--heading));
  direction: rtl; unicode-bidi: isolate;
  /* Two lines, then it is trimmed — an eleven-word title must not make one
     card twice the height of the thirty-one beside it. */
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 2; line-clamp: 2;
  overflow: hidden;
}
/* The double rule this site draws under every ʿunwān: a hairline, a gap,
   a thicker one, tapered at both ends. */
.tafsir-book-rule{
  width: min(132px, 66%); height: 5px;
  background:
    linear-gradient(to right, transparent, rgb(var(--accent) / 0.75) 18%, rgb(var(--accent) / 0.75) 82%, transparent) top / 100% 1px no-repeat,
    linear-gradient(to right, transparent, rgb(var(--accent) / 0.4) 28%, rgb(var(--accent) / 0.4) 72%, transparent) bottom / 100% 1px no-repeat;
  transition: width var(--dur) var(--ease-soft);
}
.tafsir-book-card:hover .tafsir-book-rule{ width: min(160px, 78%); }

/* ---- the name, the author, the line -------------------------------------- */
.tafsir-book-body{
  display: flex; flex-direction: column; gap: 3px;
  text-align: center;
  flex: 1;
}
.tafsir-book-en{
  font-family: var(--font-display);
  font-size: 1.02rem; font-weight: 600;
  color: rgb(var(--heading));
  line-height: 1.3;
}
.tafsir-book-author{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 0.82rem; line-height: 1.7;
  color: rgb(var(--text-muted));
  direction: rtl; unicode-bidi: isolate;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tafsir-book-note{
  margin-top: 6px;
  font-size: var(--fs-sm); line-height: 1.55;
  color: rgb(var(--text-muted));
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 3; line-clamp: 3;
  overflow: hidden;
}

/* ---- the century, and the way in ----------------------------------------- */
.tafsir-book-foot{
  display: flex; align-items: center; justify-content: space-between;
  padding-top: var(--sp-3);
  border-top: 1px solid var(--hairline-faint);
  min-height: 26px;
}
.tafsir-book-died{
  font-family: var(--font-arabic); font-weight: var(--ar-weight);
  font-size: 0.78rem;
  color: rgb(var(--text-muted));
  opacity: 0.8;
  direction: rtl; unicode-bidi: isolate;
}
.tafsir-book-chev{
  width: 16px; height: 16px;
  color: rgb(var(--accent-ui));
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity var(--dur) var(--ease-soft), transform var(--dur) var(--ease-soft);
}
.tafsir-book-card:hover .tafsir-book-chev,
.tafsir-book-card:focus-visible .tafsir-book-chev{ opacity: 1; transform: none; }
@media (hover: none){
  .tafsir-book-chev{ opacity: 0.55; transform: none; }
}

@media (max-width: 600px){
  .tafsir-book-grid{ grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: var(--sp-3); }
  .tafsir-book-card{ padding: var(--sp-4); }
  .tafsir-book-head{ min-height: 60px; }
  .tafsir-book-note{ -webkit-line-clamp: 2; line-clamp: 2; }
}


/* =========================================================================
   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:hover,
.tafsir-pick-btn[aria-expanded="true"]{
  border-color: rgb(var(--accent) / 0.5);
  background: rgb(var(--accent) / 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;
}
.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);
}
.tafsir-pop-num:hover{ background: rgb(var(--accent) / 0.12); border-color: rgb(var(--accent) / 0.4); color: rgb(var(--accent-ui)); }
.tafsir-pop-num.is-current{
  background: rgb(var(--accent)); border-color: rgb(var(--accent));
  color: rgb(var(--on-accent)); font-weight: 600;
}

/* 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);
}
.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(--accent) / 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; }
.tafsir-pop-row:hover{ background: rgb(var(--accent) / 0.09); }
.tafsir-pop-row.is-current{ background: rgb(var(--accent) / 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; align-items: center; 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);
}
.tafsir-notesbar:hover{ border-color: rgb(var(--accent) / 0.45); background: rgb(var(--accent) / 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; padding: 0 9px;
  border: none; border-radius: var(--radius-pill);
  background: rgb(var(--ink) / 0.08);
  font-family: var(--font-mono); font-size: 0.6rem;
  letter-spacing: var(--track-caps); 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(--accent) / 0.5); background: rgb(var(--accent) / 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-menu-ar,
.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;
}

.site-header .quran-menu-ar{
  min-width: 0;
  text-align: right;
  font-size: 1.18rem;
  color: rgb(var(--heading));
  white-space: nowrap;
  align-self: center;
}
/* 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. */
.site-header .quran-panel .hadith-menu-row{
  display: grid;
  grid-template-columns: 6.6em minmax(0, 1fr);
  align-items: center;
  column-gap: 18px;
  padding: 10px 14px;
}
.site-header .quran-panel .quran-menu-resume{
  grid-template-columns: auto minmax(0, 1fr);
}
.site-header .quran-panel .hadith-menu-title{ line-height: 1.35; }
.site-header .quran-panel .hadith-menu-count{
  font-family: var(--font-ui);
  letter-spacing: 0;
  font-size: 0.72rem;
  color: rgb(var(--text-muted));
}


/* =========================================================================
   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);
  font-size: 1.05rem;
  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(--accent) / 0.28);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(120% 70% at 50% 0%, rgb(var(--accent) / 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(--accent) / 0.3);
  background: rgb(var(--accent) / 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(--accent) / 0.8) 18%, rgb(var(--accent) / 0.8) 82%, transparent) top / 100% 1px no-repeat,
    linear-gradient(to right, transparent, rgb(var(--accent) / 0.4) 28%, rgb(var(--accent) / 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(--accent) / 0.2) 0%, rgb(var(--accent) / 0.85) 20%,
    rgb(var(--accent) / 0.85) 80%, rgb(var(--accent) / 0.2) 100%);
  transition: width var(--dur) var(--ease-soft);
}
.seerah-bookcard:hover{
  border-color: rgb(var(--accent) / 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(--accent) / 0.28);
  background: rgb(var(--accent) / 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(--accent) / 0.7), transparent) top / 100% 1px no-repeat,
    linear-gradient(to right, rgb(var(--accent) / 0.35) 60%, transparent) bottom / 100% 1px no-repeat;
  transition: width var(--dur) var(--ease-soft);
}
.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);
}
.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 ---------------------------------------- */
.site-header .seerah-panel .seerah-menu-row{
  display: grid;
  grid-template-columns: 7.4em minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 16px;
  padding: 10px 14px;
}
.site-header .seerah-menu-ar{
  font-family: var(--font-arabic-display);
  font-weight: var(--ar-weight);
  font-size: 1.14rem; line-height: 1.8;
  color: rgb(var(--heading));
  direction: rtl; unicode-bidi: isolate;
  text-align: right;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.site-header .seerah-menu-n{
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: rgb(var(--text-muted));
  flex-shrink: 0;
}

@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, .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 ---------------------------- */


@media (max-width: 900px){
  
}

/* The picker itself. Its rules were written for a phone; on a wide screen
   it is the same object at a calmer size. */


@media (min-width: 901px){


}

/* ---- the sheet: a bottom sheet on a phone, a card on a desktop ------- */
@media (min-width: 901px){


  /* Two columns: thirteen rows in one column is a scroll, and the whole
     point of this control is that everything is on screen at once. */


}

/* 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;
}
.adhkar-panel-note{
  max-width: 64ch;
  font-size: var(--fs-sm);
  line-height: 1.6;
}
.adhkar-progress-count{
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.74rem;
  color: rgb(var(--text-muted));
}

/* ---- the section chips ------------------------------------------------ */
.adhkar-jump{ margin-block: var(--sp-4) var(--sp-5); }
/* 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. */
@media (min-width: 761px){
  .adhkar-jump{ flex-wrap: wrap; overflow-x: visible; }
}
.adhkar-jump-link span{
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}


/* =========================================================================
   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);
}
.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);
}
.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);
}
.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{
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
  pointer-events: none;
}
.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:hover,
.pp-select[aria-expanded="true"]{
  border-color: rgb(var(--accent) / 0.5);
  background: rgb(var(--accent) / 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);
}
.pp-menu-item:hover{ background: rgb(var(--accent) / 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(--accent) / 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(--accent) / 0.35);
  border-radius: var(--radius);
  background: rgb(var(--accent) / 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. */
.toc-body.is-empty .toc-track{ display: none; }
.toc-body.is-empty{ gap: 0; }

/* ---- "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(--accent) / 0.28);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(120% 200% at 0% 50%, rgb(var(--accent) / 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);
}
.hadith-in-book:hover{ border-color: rgb(var(--accent) / 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(--accent) / 0.12);
  border: 1px solid rgb(var(--accent) / 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);
}
.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:101 56 24; --cv-b:178 102 49; --cv-ink:39 22 11; --cv-foil:51 132 120; }
[data-theme="saffron"] .cv-1{ --cv-a:81 70 24; --cv-b:154 135 53; --cv-ink:31 27 11; --cv-foil:51 112 132; }
[data-theme="saffron"] .cv-2{ --cv-a:123 26 25; --cv-b:201 51 49; --cv-ink:48 12 12; --cv-foil:51 132 87; }
[data-theme="saffron"] .cv-3{ --cv-a:29 101 89; --cv-b:57 175 155; --cv-ink:13 39 35; --cv-foil:132 51 111; }
[data-theme="saffron"] .cv-4{ --cv-a:74 86 29; --cv-b:136 157 60; --cv-ink:29 33 13; --cv-foil:51 80 132; }
[data-theme="saffron"] .cv-5{ --cv-a:108 27 35; --cv-b:184 53 66; --cv-ink:42 12 15; --cv-foil:51 132 79; }
[data-theme="saffron"] .cv-6{ --cv-a:121 32 67; --cv-b:195 60 112; --cv-ink:47 14 27; --cv-foil:51 132 55; }
[data-theme="saffron"] .cv-7{ --cv-a:26 76 83; --cv-b:56 142 156; --cv-ink:12 29 32; --cv-foil:132 51 86; }
[data-theme="porcelain"] .cv-0{ --cv-a:24 74 101; --cv-b:49 132 178; --cv-ink:11 29 39; --cv-foil:132 51 68; }
[data-theme="porcelain"] .cv-1{ --cv-a:24 38 81; --cv-b:53 77 154; --cv-ink:11 16 31; --cv-foil:132 67 51; }
[data-theme="porcelain"] .cv-2{ --cv-a:25 123 119; --cv-b:49 201 195; --cv-ink:12 48 46; --cv-foil:132 51 101; }
[data-theme="porcelain"] .cv-3{ --cv-a:101 65 29; --cv-b:175 116 57; --cv-ink:39 26 13; --cv-foil:51 132 127; }
[data-theme="porcelain"] .cv-4{ --cv-a:38 29 86; --cv-b:75 60 157; --cv-ink:16 13 33; --cv-foil:132 99 51; }
[data-theme="porcelain"] .cv-5{ --cv-a:27 108 103; --cv-b:53 184 175; --cv-ink:12 42 40; --cv-foil:132 51 103; }
[data-theme="porcelain"] .cv-6{ --cv-a:32 121 82; --cv-b:60 195 135; --cv-ink:14 47 32; --cv-foil:131 51 132; }
[data-theme="porcelain"] .cv-7{ --cv-a:83 72 26; --cv-b:156 136 56; --cv-ink:32 28 12; --cv-foil:51 113 132; }
[data-theme="damask"] .cv-0{ --cv-a:101 24 55; --cv-b:178 49 101; --cv-ink:39 11 22; --cv-foil:51 132 54; }
[data-theme="damask"] .cv-1{ --cv-a:81 24 24; --cv-b:154 53 53; --cv-ink:31 11 11; --cv-foil:51 132 86; }
[data-theme="damask"] .cv-2{ --cv-a:123 25 104; --cv-b:201 49 172; --cv-ink:48 12 41; --cv-foil:82 132 51; }
[data-theme="damask"] .cv-3{ --cv-a:101 66 29; --cv-b:175 117 57; --cv-ink:39 26 13; --cv-foil:51 132 127; }
[data-theme="damask"] .cv-4{ --cv-a:86 51 29; --cv-b:157 98 60; --cv-ink:33 21 13; --cv-foil:51 132 118; }
[data-theme="damask"] .cv-5{ --cv-a:51 27 108; --cv-b:92 53 184; --cv-ink:21 12 42; --cv-foil:132 110 51; }
[data-theme="damask"] .cv-6{ --cv-a:103 32 121; --cv-b:167 60 195; --cv-ink:40 14 47; --cv-foil:114 132 51; }
[data-theme="damask"] .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 77 118; --cv-b:53 131 194; --cv-ink:13 31 46; --cv-foil:147 57 68; }
[data-theme="midnight"] .cv-1{ --cv-a:29 39 96; --cv-b:58 75 169; --cv-ink:13 16 37; --cv-foil:147 82 57; }
[data-theme="midnight"] .cv-2{ --cv-a:29 134 140; --cv-b:62 201 208; --cv-ink:13 52 54; --cv-foil:147 57 104; }
[data-theme="midnight"] .cv-3{ --cv-a:117 82 33; --cv-b:191 136 62; --cv-ink:45 32 15; --cv-foil:57 146 147; }
[data-theme="midnight"] .cv-4{ --cv-a:51 34 101; --cv-b:92 65 172; --cv-ink:21 15 39; --cv-foil:147 118 57; }
[data-theme="midnight"] .cv-5{ --cv-a:31 124 115; --cv-b:59 198 183; --cv-ink:14 48 45; --cv-foil:147 57 118; }
[data-theme="midnight"] .cv-6{ --cv-a:36 137 102; --cv-b:76 200 156; --cv-ink:16 53 40; --cv-foil:147 57 140; }
[data-theme="midnight"] .cv-7{ --cv-a:99 91 31; --cv-b:171 157 61; --cv-ink:38 35 14; --cv-foil:57 119 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:101 56 24; --cv-b:178 102 49; --cv-ink:39 22 11; --cv-foil:51 132 120; }
/* ==== 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);
  padding: 22px 22px 20px;
  border-radius: var(--radius-lg);
  background: rgb(var(--surface) / 0.72);
  border: 1px solid rgb(var(--heading) / 0.09);
  box-shadow: var(--e1);
}

.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;
  max-width: 340px;
  display: flex;
  align-items: center;
}
.adhkar-find-ic{
  position: absolute; left: 13px;
  width: 16px; height: 16px;
  color: rgb(var(--text-muted));
  pointer-events: none;
}
.adhkar-find input{
  width: 100%;
  padding: 10px 38px 10px 38px;
  border-radius: 999px;
  border: 1px solid rgb(var(--heading) / 0.14);
  background: rgb(var(--bg) / 0.85);
  color: rgb(var(--text));
  font-family: var(--font-ui);
  font-size: 0.87rem;
  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{
  outline: none;
  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);
}
.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;
  align-items: center;
  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);
}
.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{
  position: relative;
  text-align: center;
  margin-bottom: var(--sp-5);
}
.tafsir-more-rule::before{
  content: "";
  position: absolute;
  left: 0; right: 0; top: 50%;
  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; }
.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.
   ========================================================================= */

.rail-reading{
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 9px;
  margin-top: 6px;
}
.rail-reading-label{
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}

/* "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(--accent-ui) / 0.45);
}
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){
  .rail-reading{
    flex-direction: row;
    align-items: center;
    gap: 8px;
    margin-top: 0;
    flex: 0 0 auto;
  }
  .rail-reading-label{ display: none; }
  .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. */
@media (max-width: 520px){
  .rail-reading .pp-typesize-track{ display: none; }
}

/* 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. */
@media (max-width: 1100px){
  .rail-actions.rail-actions{
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent 100%);
    mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent 100%);
  }
  /* At the end of the scroll the fade would hide the last control, so it
     is lifted the moment the reader has scrolled at all. `animation-timeline`
     is not available everywhere; :hover and :focus-within are, and both
     are true exactly when somebody is using it. */
  .rail-actions.rail-actions:hover,
  .rail-actions.rail-actions:focus-within{
    -webkit-mask-image: none;
    mask-image: none;
  }
}

/* ---- 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);
}
.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(--accent) / 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(--header-live, 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);
}
.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);
}
.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);
}
.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);
}
.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);
}
.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. */

.qibla-camera-cta-badge{
  background: rgb(var(--on-gilt) / 0.14) !important;
  border-color: rgb(var(--on-gilt) / 0.2) !important;
}
.qibla-camera-cta-badge svg{ color: rgb(var(--on-gilt)) !important; }
.qibla-camera-cta-ring{ border-color: rgb(var(--on-gilt) / 0.25) !important; }
.qibla-camera-cta-sub{ color: rgb(var(--on-gilt) / 0.78); }
.qibla-camera-cta-arrow{ color: rgb(var(--on-gilt) / 0.7); }

/* ---- 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. */
.tafsir-book-author{
  font-size: 1.02rem;
  line-height: 1.75;
}

/* ---- 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.
   ========================================================================= */

.hadith-menu-ic{ width: 34px; height: 34px; }
.hadith-menu-ic svg{ width: 20px; height: 20px; }

/* 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.
   ========================================================================= */
.pp-scheme-btn{ position: relative; }
.pp-scheme-ic{ display: block; }
[data-scheme="light"] .pp-scheme-ic.is-sun,
[data-scheme="dark"]  .pp-scheme-ic.is-moon{ display: none; }

/* 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. */
[data-scheme="light"] .pp-scheme-ic.is-moon{ transform: rotate(-18deg); }

/* ---- 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.
   ========================================================================= */
.tafsir-book-card{
  position: relative;
  overflow: hidden;
  /* Squared on the spine side, rounded on the fore-edge — the profile of
     a bound volume seen face-on, and the reason the card reads as an
     object rather than as a panel. */
  border-radius: 4px var(--radius) var(--radius) 4px;
  /* Symmetric, so the centred title stays on the card's optical centre —
     padding on the spine side alone pushed every line 10px right. */
  padding-inline: calc(var(--sp-5) + 12px);
}

/* ---- the spine ---------------------------------------------------------- */
.tafsir-book-spine{
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: 14px;
  background:
    linear-gradient(90deg,
      rgb(var(--gilt-deep) / 0.55) 0%,
      rgb(var(--gilt) / 0.42) 42%,
      rgb(var(--gilt-hi) / 0.30) 62%,
      rgb(var(--gilt-deep) / 0.20) 100%);
  border-inline-end: 1px solid rgb(var(--gilt-edge) / 0.28);
}
/* 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. */
.tafsir-book-century{ display: none; }

/* ---- the device --------------------------------------------------------- */
.tafsir-book-crest{
  display: block;
  margin: 0 auto calc(var(--sp-2) * -1);
  width: 34px; height: 34px;
  /* --gilt, not --gilt-deep: the deep stop is the SHADED face of the
     metal, and on a dark appearance a device drawn entirely in it sinks
     into the card. The body colour reads on both. */
  color: rgb(var(--gilt));
  opacity: 0.9;
  transition: transform var(--dur) var(--spring), opacity var(--dur) var(--ease-soft);
}
.tafsir-book-crest-svg{ width: 100%; height: 100%; display: block; }
.tafsir-book-card:hover .tafsir-book-crest{ transform: scale(1.08) rotate(6deg); opacity: 1; }

/* ---- 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. */
.tafsir-book-card:nth-child(4n + 1),
.tafsir-book-card:nth-child(4n + 4){
  background:
    linear-gradient(180deg, rgb(var(--bg-alt) / 0.85) 0%, rgb(var(--bg-alt) / 0.45) 100%);
}



@media (max-width: 640px){
  .tafsir-book-card{ padding-inline: calc(var(--sp-4) + 10px); }
  .tafsir-book-spine{ width: 12px; }
  .tafsir-book-crest{ width: 28px; height: 28px; }
}

/* ---- 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 ----------------------------------------------------- */
.tafsir-cols{ display: grid; grid-template-columns: 1fr; gap: 0; }
.tafsir-cols[data-cols="2"],
.tafsir-cols[data-cols="3"]{
  gap: clamp(16px, 2.4vw, 34px);
}
@media (min-width: 900px){
  .tafsir-cols[data-cols="2"]{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1180px){
  .tafsir-cols[data-cols="3"]{ grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 900px) and (max-width: 1179px){
  .tafsir-cols[data-cols="3"]{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.tafsir-col{ min-width: 0; }
/* 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. */
.tafsir-cols[data-cols="1"] .tafsir-col-head{ display: none; }
.tafsir-col-head{
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding-bottom: 8px; margin-bottom: 12px;
  border-bottom: 1px solid var(--hairline);
}
.tafsir-col-ar{
  font-family: var(--font-arabic-display); font-weight: var(--ar-weight);
  font-size: 1.02rem; color: rgb(var(--heading));
}
.tafsir-col-en{
  font-family: var(--font-ui); font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.02em; color: rgb(var(--text-muted));
}
/* Two or three commentaries side by side need a smaller measure or the
   lines run to 90 characters. */
.tafsir-cols[data-cols="2"] .tafsir-body,
.tafsir-cols[data-cols="3"] .tafsir-body{
  font-size: calc(1.16rem * var(--tafsir-fs, 1));
  line-height: 2.0;
}

.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);
}
.tafsir-bar-rail:hover{ border-color: rgb(var(--accent) / 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; }
.hadith-random-btn:hover{
  border-color: rgb(var(--accent) / 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){
  .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);
}
.sirah-book-toc-link:hover{
  background: rgb(var(--accent) / 0.07);
  border-color: rgb(var(--accent) / 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: anywhere;
}
.sirah-book-toc-en{
  font-family: var(--font-ui);
  font-size: 0.76rem;
  line-height: 1.4;
  color: rgb(var(--text-muted));
  overflow-wrap: anywhere;
}
.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; }
.sirah-book-toc-item.is-read .sirah-book-toc-link{ background: rgb(var(--accent) / 0.045); }

/* ---- 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);
}
.book-runner-aa:hover{ border-color: rgb(var(--accent) / 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 ==== */

/* ---- v132-layer-00-button.css ---- */

/* =========================================================================
   v13.2 — THE PRIMARY BUTTON, DRAWN AGAIN FROM NOTHING.

   "the button colours in different themes is nice but the button is very
    ugly and this specific yellow colour is super ugly (on saffron and
    some others now) … please change this weird button emboss and weird
    feeling & texture, ditch the current button design completely and
    generate a new SUPER SUPER beautiful one … and make sure it actually
    works (not working properly now!!)"

   FOUR THINGS WERE WRONG. Every one of them is gone rather than tuned.

   1. THE EMBOSS. v13.0 and v13.1 both painted `inset 0 1px 0 white` along
      the top and `inset 0 -1px 0 dark` along the bottom. That pair is the
      2007 web-button bevel; it says "chrome widget", and no amount of
      good colour survives it. THERE IS NO INSET SHADOW ON THIS BUTTON.

   2. THE BAND. The face was a five-stop linear gradient with a hard
      specular strip held flat across the top 7-14%. A stripe of lighter
      colour is not a highlight — a highlight is a POOL, brightest where
      the light lands and falling off in every direction. The face is now
      one soft radial pool up and to the left, over a very shallow body
      ramp. Nothing on it has an edge except the rim.

   3. THE SHEEN, which is the "weird texture", AND WHICH NEVER RAN. It was
      a white diagonal band on ::before at `z-index:-1` inside a parent
      carrying `isolation:isolate` — and isolation is precisely what stops
      a negative z-index child from escaping behind its parent's own
      background. So the element was painted, then covered by the button
      it was supposed to sweep across, on every hover, in every browser,
      for two releases. That is the "not working properly". Deleted, not
      repaired: light does not slide across a struck object anyway.

   4. THE YELLOW. Saffron's metal was 236/190/98 on a 255/245/222 page —
      a lemon on cream, which is mustard, which is the exact word he used
      about it two releases ago. The METAL table in tools/gen_palettes.py
      now runs every gold deeper and redder (Saffron 230/178/96 over
      192/136/52), so it reads as gold rather than as yellow, and the two
      olive "green golds" on Emerald and Juniper are ordinary warm gold —
      a green metal on a green page was the same mistake as gold on gold.

   WHAT IT IS NOW. A struck coin, lit once, from up and to the left:

     · a radial pool of --gilt-hi at 28% -46%, wide and soft;
     · a body of --gilt that turns to --gilt-deep only in the last third;
     · ONE hairline rim of --gilt-edge, which is also the control's
       visual boundary (WCAG 2.2 SC 1.4.11, proved at 3:1 per palette);
     · a shadow tinted with the metal's own foot, not with grey — this is
       what gives depth now that the bevel is gone;
     · and on press the ramp INVERTS, so the object is lit from further
       away instead of being repainted a different colour.

   The label stays --on-gilt, which the generator proves at 4.5:1 against
   all three stops of the face, on all eight palettes.
   ========================================================================= */

.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.38);
  color: rgb(var(--on-gilt));
  font-weight: 600;
  letter-spacing: 0.005em;
  text-shadow: none;
  background-color: rgb(var(--gilt));
  background-image:
    radial-gradient(120% 165% at 28% -46%,
      rgb(var(--gilt-hi))        0%,
      rgb(var(--gilt-hi) / 0.52) 34%,
      rgb(var(--gilt-hi) / 0)    70%),
    linear-gradient(180deg,
      rgb(var(--gilt))      0%,
      rgb(var(--gilt))      58%,
      rgb(var(--gilt-deep)) 100%);
  box-shadow:
    0 1px 1px rgb(var(--shadow) / 0.10),
    0 6px 15px -8px rgb(var(--gilt-deep) / 0.62);
  transition:
    transform 180ms var(--ease-out-expo),
    box-shadow 220ms var(--ease-out-expo),
    border-color 220ms linear,
    background-color 220ms linear;
}

/* The sheen element is gone. This kills it wherever an older rule in this
   file still declares one, without having to find every such rule. */
.btn-primary::before,
.subscribe-form button[type="submit"]::before,
.pp-gold::before,
.qibla-camera-cta::before{ content: none !important; }

.btn-primary:hover,
.subscribe-form button[type="submit"]:hover,
.pp-gold:hover,
.qibla-camera-cta:hover{
  /* The object is not repainted; it is turned a degree towards the light.
     The pool widens, the rim firms up, the shadow lengthens. */
  transform: translateY(-1px);
  color: rgb(var(--on-gilt));
  border-color: rgb(var(--gilt-edge) / 0.58);
  background-image:
    radial-gradient(124% 172% at 28% -42%,
      rgb(var(--gilt-hi))        0%,
      rgb(var(--gilt-hi) / 0.62) 38%,
      rgb(var(--gilt-hi) / 0)    74%),
    linear-gradient(180deg,
      rgb(var(--gilt))      0%,
      rgb(var(--gilt))      64%,
      rgb(var(--gilt-deep)) 100%);
  box-shadow:
    0 2px 3px rgb(var(--shadow) / 0.10),
    0 12px 26px -12px rgb(var(--gilt-deep) / 0.72);
}

.btn-primary:active,
.subscribe-form button[type="submit"]:active,
.pp-gold:active,
.qibla-camera-cta:active{
  /* Pressed: the ramp inverts and the pool dims. Same metal, light
     further off. No inset, no scale — a coin does not shrink. */
  transform: translateY(1px);
  background-image:
    radial-gradient(120% 150% at 28% -54%,
      rgb(var(--gilt-hi) / 0.45) 0%,
      rgb(var(--gilt-hi) / 0)    58%),
    linear-gradient(180deg,
      rgb(var(--gilt-deep)) 0%,
      rgb(var(--gilt))      92%);
  box-shadow: 0 1px 1px rgb(var(--shadow) / 0.14);
}

.btn-primary:focus-visible,
.subscribe-form button[type="submit"]:focus-visible,
.pp-gold:focus-visible,
.qibla-camera-cta:focus-visible{
  /* Outside the button, on the page, so it is legible whatever the face
     is doing — and drawn twice, a firm thread and a soft halo. */
  outline: 2px solid rgb(var(--gilt-edge));
  outline-offset: 3px;
  box-shadow:
    0 0 0 5px rgb(var(--gilt) / 0.26),
    0 6px 15px -8px rgb(var(--gilt-deep) / 0.62);
}

.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(--gilt) / 0.42);
  border-color: rgb(var(--gilt-edge) / 0.20);
  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 that the button goes somewhere. */
.btn-primary svg,
.pp-gold svg{ transition: transform var(--dur) var(--ease-out-expo); }
.btn-primary:hover svg,
.pp-gold:hover svg{ transform: translateX(3px); }

@media (prefers-reduced-motion: reduce){
  .btn-primary,
  .subscribe-form button[type="submit"],
  .pp-gold{ transition: box-shadow 220ms linear, border-color 220ms linear; }
  .btn-primary:hover,
  .subscribe-form button[type="submit"]:hover,
  .pp-gold:hover,
  .btn-primary:active,
  .pp-gold:active{ transform: none; }
  .btn-primary:hover svg,
  .pp-gold:hover svg{ transform: none; }
}

/* ---- THE SECOND BUTTON, kept quiet ---------------------------------- */
/* A secondary action gets steadier as you approach it, not louder: the
   hairline firms up, the ground warms a few per cent, nothing lifts as
   far as the gold does. It must never impersonate the primary. */
.btn-ghost{
  border-color: rgb(var(--heading) / 0.20);
  color: rgb(var(--heading));
  background: rgb(var(--surface) / 0.55);
  box-shadow: none;
}
.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); }
/* ---- 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 */
  font-size: clamp(1.45rem, 3.4vw, 1.95rem);
  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{
    font-size: clamp(1.3rem, 6.4vw, 1.7rem);
    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,
.adhkar-menu-ar,
.tafsir-menu-ar,
.tafsir-book-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(--accent) / 0.09), transparent 64%),
    rgb(var(--surface));
  border: 1px solid rgb(var(--accent) / 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(--accent) / 0.10);
  border: 1px solid rgb(var(--accent) / 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(--accent) / 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);
  background: rgb(var(--gilt) / 0.16);
  color: rgb(var(--heading));
  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:hover{
  background: rgb(var(--gilt) / 0.34);
  border-color: rgb(var(--gilt-edge) / 0.60);
}
.hadith-field-go:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }

/* ---- the chapter index ------------------------------------------------ */
.hadith-chapters{
  margin-bottom: var(--sp-5);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: rgb(var(--surface) / 0.55);
  overflow: hidden;
}
.hadith-chapters[open]{ background: rgb(var(--surface)); }

.hadith-chapters-summary{
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  cursor: pointer;
  list-style: none;
  user-select: none;
  transition: background var(--dur) var(--ease-soft);
}
.hadith-chapters-summary::-webkit-details-marker{ display: none; }
.hadith-chapters-summary:hover{ background: rgb(var(--accent) / 0.05); }
.hadith-chapters-summary: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(--accent) / 0.10);
  color: rgb(var(--accent-ui));
}
.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.65rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: rgb(var(--text-muted));
}
.hadith-chapters-current{
  font-family: var(--font-ui);
  font-size: 0.92rem; font-weight: 600;
  color: rgb(var(--heading));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hadith-chapters-chev{
  width: 16px; height: 16px; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 2;
  color: rgb(var(--text-muted));
  transition: transform var(--dur) var(--ease-soft);
}
.hadith-chapters[open] .hadith-chapters-chev{ transform: rotate(180deg); }

.hadith-chapters-body{
  padding: 4px 10px 12px;
  border-top: 1px solid var(--hairline);
}
.hadith-chapter-filter{
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  margin: 10px 4px 8px;
  padding: 0 12px;
  height: 38px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: rgb(var(--bg-alt) / 0.6);
}
.hadith-chapter-filter:focus-within{ border-color: rgb(var(--accent) / 0.5); }
.hadith-chapter-filter svg{ width: 14px; height: 14px; color: rgb(var(--text-muted)); }
.hadith-chapter-filter input{
  width: 100%; min-width: 0; height: 100%;
  border: 0; background: transparent; color: rgb(var(--heading));
  font-family: var(--font-ui); font-size: 0.85rem;
}
.hadith-chapter-filter input:focus{ outline: none; }
.hadith-chapter-filter-n{
  font-family: var(--font-mono); font-size: 0.68rem;
  color: rgb(var(--text-muted));
  font-variant-numeric: tabular-nums;
}

/* A table of contents, not a wall of cards. One line per chapter; as many
   columns as the screen has room for; NO SCROLLBAR OF ITS OWN — it is
   closed until asked for, so it can be exactly as long as the book. */
.hadith-chapter-grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 1px 10px;
  max-height: none;
  overflow: visible;
}
.hadith-chapter-grid.is-empty::after{
  content: 'No chapter matches that.';
  grid-column: 1 / -1;
  padding: 22px 4px;
  text-align: center;
  font-family: var(--font-ui); font-size: 0.86rem;
  color: rgb(var(--text-muted));
}

.hadith-chapter-cell{
  display: grid;
  grid-template-columns: 2.2em minmax(0, 1fr) auto auto;
  align-items: baseline;
  column-gap: 10px;
  padding: 9px 10px;
  border-radius: 9px;
  border: 1px solid transparent;
  color: inherit;
  font-size: 0.85rem;
  line-height: 1.45;
  transition: background var(--dur) var(--ease-soft), border-color var(--dur) var(--ease-soft);
}
.hadith-chapter-cell:hover{ background: rgb(var(--accent) / 0.07); }
.hadith-chapter-cell.is-on{
  background: rgb(var(--accent) / 0.10);
  border-color: rgb(var(--accent) / 0.30);
}
.hadith-chapter-cell.is-all{ grid-column: 1 / -1; }
.hadith-chapter-num{
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
  color: rgb(var(--text-muted));
  text-align: right;
}
.hadith-chapter-name{
  font-family: var(--font-ui);
  font-size: 1em;
  font-weight: 600;
  color: rgb(var(--heading));
  min-width: 0;
  overflow-wrap: anywhere;
}
/* Size comes from the paired-label rule in layer 10: 1em, i.e. exactly
   the size of the English beside it. Only the colour is set here. */
.hadith-chapter-ar{
  color: rgb(var(--text-muted));
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 11em;
}
.hadith-chapter-n{
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-variant-numeric: tabular-nums;
  color: rgb(var(--text-muted));
  min-width: 3.2em;
  text-align: right;
  opacity: 0.85;
}
.hadith-chapter-cell.is-on .hadith-chapter-n{ color: rgb(var(--accent-ui)); opacity: 1; }

@media (max-width: 720px){
  .hadith-chapter-grid{ grid-template-columns: 1fr; }
  .hadith-goto{ flex: 1 1 100%; }
  .hadith-chapter-ar{ max-width: 8em; }
  .hadith-book-header{ padding: var(--sp-7) var(--sp-4) var(--sp-6); }
}
@media (max-width: 420px){
  /* Below this the Arabic name and the count cannot both sit on the line
     without one of them becoming three characters and an ellipsis. The
     Arabic goes under the English, which is the paired-label layout used
     everywhere else on the site. */
  .hadith-chapter-cell{
    grid-template-columns: 2.2em minmax(0, 1fr) auto;
    row-gap: 1px;
  }
  .hadith-chapter-ar{
    grid-column: 2 / 3;
    max-width: none;
    text-align: right;
  }
  .hadith-chapter-n{ grid-row: 1 / 2; grid-column: 3 / 4; }
}

/* ---- 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 ------------------------------------------------------- */
.site-header .mega-panel{ padding: 8px; }
.site-header .mega-panel-head{
  padding: 4px 10px 8px;
  margin-bottom: 2px;
}

/* ---- a row ----------------------------------------------------------- */
.site-header .hadith-menu-row{
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  column-gap: 11px;
  padding: 9px 11px;
  min-width: 0;
  /* THE ROW OWNS THE SIZE. Everything inside it is 1em, so the English
     title and the Arabic title are the same size by construction and
     stay that way when a panel changes its scale. */
  font-size: 0.85rem;
}
.site-header .hadith-menu-main{
  display: flex; flex-direction: column;
  gap: 1px; min-width: 0;
}
.site-header .hadith-menu-title{
  font-family: var(--font-ui);
  font-size: 1em;
  font-weight: 600;
  line-height: 1.4;
  color: rgb(var(--heading));
  min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* The quiet second line, whatever it holds: an Arabic title, a count, a
   sentence. One size, one colour, one line box, all four panels. */
.site-header .hadith-menu-count,
.site-header .tafsir-menu-ar,
.site-header .adhkar-menu-ar{
  font-size: 1em;
  line-height: 1.5;
  color: rgb(var(--text-muted));
  min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.site-header .tafsir-menu-ar,
.site-header .adhkar-menu-ar{
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: 1em;              /* level with the title above it */
  direction: rtl; unicode-bidi: isolate;
  text-align: left;            /* it is a LABEL under a label, not prose */
}
.site-header .hadith-menu-count{
  font-family: var(--font-mono);
  font-size: 0.8em;
  letter-spacing: 0.03em;
  color: rgb(var(--accent-ui));
}
.site-header .hadith-menu-ic{
  width: 30px; height: 30px;
  border-radius: 9px;
  flex: 0 0 auto;
  align-self: center;
}
.site-header .hadith-menu-ic svg{ width: 16px; height: 16px; }

/* ---- 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. */
.site-header .quran-panel{ width: 540px; }
.site-header .quran-panel .hadith-menu-row{
  grid-template-columns: 5.1em minmax(0, 1fr);
  column-gap: 13px;
  padding: 8px 12px;
}
.site-header .quran-panel .hadith-menu-row .hadith-menu-count{
  font-family: var(--font-ui);
  font-size: 0.87em;
  letter-spacing: 0;
  color: rgb(var(--text-muted));
}

/* ---- 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. */
.site-header .tafsir-panel{ width: 560px; }
.site-header .tafsir-panel .hadith-menu-row{
  grid-template-columns: minmax(0, 1fr);
  padding: 9px 12px;
}
.site-header .tafsir-panel .quran-menu-resume{ grid-column: 1 / -1; }

/* ---- the adhkār panel ------------------------------------------------ */
/* Thirteen sets in three columns of one-line rows: about 300px of panel
   rather than the 700 it was. */
.site-header .adhkar-panel{
  width: 690px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.site-header .adhkar-panel .adhkar-menu-row{
  column-gap: 10px;
  padding: 8px 10px;
}
.site-header .adhkar-panel .hadith-menu-row{ font-size: 0.83rem; }
.site-header .adhkar-panel .hadith-menu-ic{
  width: 26px; height: 26px;
  border-radius: 8px;
}
.site-header .adhkar-panel .hadith-menu-ic svg{ width: 15px; height: 15px; }

/* 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. */
.site-header .adhkar-menu-row.is-now{
  background: rgb(var(--accent) / 0.06);
  box-shadow: inset 2px 0 0 rgb(var(--accent) / 0.8);
}
.site-header .hadith-menu-now{
  display: inline-block;
  margin-inline-start: 6px;
  padding: 1px 5px 2px;
  border-radius: 999px;
  background: rgb(var(--gilt) / 0.9);
  color: rgb(var(--on-gilt));
  font-family: var(--font-mono);
  font-size: 0.55rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  vertical-align: 1px;
}

@media (max-width: 1180px){
  .site-header .adhkar-panel{
    width: 500px;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* The drawer lays every panel out in one column and sets its own padding;
   none of the widths above apply there. */
@media (max-width: 900px){
  .site-header .main-nav .adhkar-panel,
  .site-header .main-nav .quran-panel,
  .site-header .main-nav .tafsir-panel{
    width: 100%;
    grid-template-columns: 1fr;
  }
  .site-header .main-nav .hadith-menu-row{ padding: 9px 10px; }
}
/* ---- 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).
   ========================================================================= */

/* ---- the chooser ------------------------------------------------------ */
.adhkar-index-grid{
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

/* Two rows, two columns, and everything lines up down the whole grid:

     [mark]  Morning                          27
             أذكار الصباح       From Fajr until Dhuhr

   THE ROW OWNS THE SIZE (see the note in layer 10) — one font-size here,
   and both names inside are 1em, so they are level by construction. */
.adhkar-tile{
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "ic en n"
    "ic ar when";
  align-items: center;
  column-gap: 12px;
  row-gap: 1px;
  width: 100%;
  padding: 11px 13px;
  border-radius: var(--radius);
  border: 1px solid rgb(var(--heading) / 0.08);
  background: rgb(var(--bg) / 0.55);
  text-align: left;
  cursor: pointer;
  font-size: 0.88rem;
  transition:
    border-color var(--dur) var(--ease-soft),
    background var(--dur) var(--ease-soft),
    box-shadow var(--dur) var(--ease-soft);
}
.adhkar-tile:hover{
  border-color: rgb(var(--gilt-edge) / 0.42);
  background: rgb(var(--surface));
  box-shadow: var(--e1);
}
.adhkar-tile:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }
.adhkar-tile.is-on{
  border-color: rgb(var(--gilt-edge) / 0.65);
  background: rgb(var(--gilt) / 0.12);
}

.adhkar-tile-ic{
  grid-area: ic;
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px;
  border-radius: 10px;
  background: rgb(var(--accent) / 0.11);
  color: rgb(var(--accent-ui));
}
.adhkar-tile-ic svg{ width: 18px; height: 18px; }
.adhkar-tile.is-on .adhkar-tile-ic{
  background: rgb(var(--gilt) / 0.28);
  color: rgb(var(--gilt-edge));
}

.adhkar-tile-en{
  grid-area: en;
  min-width: 0;
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 1em;
  line-height: 1.4;
  color: rgb(var(--heading));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.adhkar-tile-ar{
  grid-area: ar;
  min-width: 0;
  font-family: var(--font-arabic);
  font-weight: var(--ar-weight);
  font-size: 1em;                 /* level with the English above it */
  line-height: 1.5;
  color: rgb(var(--text-muted));
  direction: rtl; unicode-bidi: isolate; text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.adhkar-tile-n{
  grid-area: n;
  justify-self: end;
  font-family: var(--font-mono);
  font-size: 0.76em;
  font-variant-numeric: tabular-nums;
  color: rgb(var(--accent-ui));
}
.adhkar-tile-when{
  grid-area: when;
  justify-self: end;
  max-width: 15ch;
  font-family: var(--font-ui);
  font-size: 0.74em;
  line-height: 1.5;
  color: rgb(var(--text-muted));
  text-align: right;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.adhkar-tile-now{
  display: inline-block;
  margin-inline-start: 6px;
  padding: 1px 6px 2px;
  border-radius: 999px;
  background: rgb(var(--gilt) / 0.9);
  color: rgb(var(--on-gilt));
  font-family: var(--font-mono);
  font-size: 0.58em;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  vertical-align: 1px;
}
/* Progress today, and the tick that replaces it when the set is done.
   Both sit over the top-right corner so neither can move the grid. */
.adhkar-tile-done{
  position: absolute; top: 6px; inset-inline-end: 8px;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  color: rgb(var(--text-muted));
  opacity: 0.75;
}
.adhkar-tile-tick{
  position: absolute; top: 7px; inset-inline-end: 8px;
  width: 15px; height: 15px;
  color: rgb(var(--accent-3));
  opacity: 0;
  transition: opacity var(--dur) var(--ease-soft);
}
.adhkar-tile.is-complete .adhkar-tile-tick{ opacity: 1; }
.adhkar-tile.is-complete .adhkar-tile-done{ display: none; }

@media (max-width: 1100px){
  .adhkar-index-grid{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 700px){
  .adhkar-index-grid{ grid-template-columns: minmax(0, 1fr); gap: 7px; }
  .adhkar-tile{ padding: 10px 12px; font-size: 0.86rem; }
  .adhkar-tile-ic{ width: 32px; height: 32px; }
  .adhkar-tile-when{ max-width: 15ch; }
}

/* =========================================================================
   WHAT TO SHOW — the Aa button (item 6).

   Bottom right, above the back-to-top arrow when that arrow is up. Three
   switches, one glyph each: ع, Aa, EN. The full word is on every one of
   them for a screen reader and as a tooltip; it is not printed, because
   "translation" and "transliteration" set beside each other at 11px is
   the clutter this was asked to avoid.
   ========================================================================= */
.adhkar-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);
}
.adhkar-aa.has-arrow{ bottom: calc(24px + 44px + 10px + env(safe-area-inset-bottom)); }

.adhkar-aa-btn{
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid rgb(var(--gilt-edge) / 0.34);
  background: rgb(var(--surface));
  color: rgb(var(--heading));
  font-family: var(--font-ui);
  font-size: 0.9rem; font-weight: 600; letter-spacing: 0.01em;
  box-shadow: 0 14px 34px -16px rgb(var(--shadow) / 0.45);
  cursor: pointer;
  transition: background var(--dur) var(--ease-soft), border-color var(--dur) var(--ease-soft);
}
.adhkar-aa-btn:hover,
.adhkar-aa.is-open .adhkar-aa-btn{
  background: rgb(var(--gilt) / 0.22);
  border-color: rgb(var(--gilt-edge) / 0.65);
}
.adhkar-aa-btn:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 2px; }

.adhkar-aa-pop{
  position: absolute;
  bottom: calc(100% + 8px);
  inset-inline-end: 0;
  display: flex;
  gap: 4px;
  padding: 5px;
  border-radius: 999px;
  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 18px 40px -18px rgb(var(--shadow) / 0.5);
}
.adhkar-aa-opt{
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px;
  border-radius: 50%;
  border: 1px solid transparent;
  background: transparent;
  color: rgb(var(--text-muted));
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
.adhkar-aa-opt:hover{ background: rgb(var(--heading) / 0.06); color: rgb(var(--heading)); }
.adhkar-aa-opt:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 1px; }
.adhkar-aa-opt.is-on{
  background: rgb(var(--gilt) / 0.2);
  border-color: rgb(var(--gilt-edge) / 0.45);
  color: rgb(var(--heading));
}
.adhkar-aa-glyph{ font-size: 0.82rem; font-weight: 600; line-height: 1; }
.adhkar-aa-opt[data-line="ar"] .adhkar-aa-glyph{
  font-family: var(--font-arabic); font-weight: var(--ar-weight); font-size: 1rem;
}
.adhkar-aa-opt[data-line="tr"] .adhkar-aa-glyph{ font-family: var(--font-display); font-style: italic; }
.adhkar-aa-opt[data-line="en"] .adhkar-aa-glyph{ font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.04em; }

/* The last switch cannot be turned off. It says so by flinching — the
   same refusal the Qur'an reader's switches use. */
.adhkar-aa-opt.is-refusing{ animation: ppLineRefuse 240ms var(--ease-soft); }
@media (prefers-reduced-motion: reduce){
  .adhkar-aa{ transition: none; }
  .adhkar-aa-opt.is-refusing{ animation: none; }
}

/* ---- 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,
.site-header .seerah-menu-ar,
.sirah-book-unwan-ar,
.sirah-book-bab-ar,
.sirah-book-salawat-text,
.sirah-book-toc-ar,
.tafsir-book-ar,
.tafsir-pop-row-ar,
.tafsir-shelf-ar,
.tafsir-col-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-ayah-ar{
  font-size: calc(clamp(1.45rem, 1.1rem + 1.7vw, 2.05rem) * var(--tafsir-fs, 1));
}
.tafsir-ayah-en{
  font-size: calc(var(--fs-sm) * var(--tafsir-fs, 1));
}
.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);
    max-height: calc(100vh - var(--header-h) - 76px);
    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(--accent) / 0.06);
  border: 1px solid rgb(var(--accent) / 0.16);
  color: inherit;
  transition: background var(--dur) var(--ease-soft), border-color var(--dur) var(--ease-soft);
}
.tr-where:hover{
  background: rgb(var(--accent) / 0.11);
  border-color: rgb(var(--accent) / 0.34);
}
.tr-where-ar{
  font-family: var(--font-surah);
  font-weight: 400;
  font-size: 1.02rem;
  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 */
.tr-range{
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 6px;
}
.tr-num{ display: block; min-width: 0; }
.tr-num > span{
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.tr-num input{
  width: 100%; min-width: 0;
  height: 32px; padding: 0 8px;
  border: 1px solid var(--hairline); border-radius: 9px;
  background: rgb(var(--surface)); color: rgb(var(--heading));
  font-family: var(--font-mono); font-size: 0.86rem;
  text-align: center;
  -moz-appearance: textfield;
}
.tr-num-dash{ padding: 0; color: rgb(var(--text-muted)); }
.tr-range .tr-go{ grid-column: auto; margin-top: 0; padding: 0 10px; min-height: 32px; }

/* 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. */
.tr-go{
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 32px; padding: 0 10px;
  border-radius: 9px; cursor: pointer;
  border: 1px solid rgb(var(--gilt-edge) / 0.34);
  background: rgb(var(--gilt) / 0.18);
  color: rgb(var(--heading));
  font-family: var(--font-ui); font-size: 0.76rem; font-weight: 600;
  letter-spacing: 0.012em;
  box-shadow: none;
  transition: background var(--dur) var(--ease-soft), border-color var(--dur) var(--ease-soft);
}
.tr-go:hover{
  background: rgb(var(--gilt) / 0.34);
  border-color: rgb(var(--gilt-edge) / 0.62);
}
.tr-note{
  margin: 0;
  font-size: 0.66rem; line-height: 1.55;
  color: rgb(var(--text-muted));
  opacity: 0.92;
}

/* compare — the fixed first row is a caption, not a control */
.tr-cmp-row.is-fixed{ opacity: 0.85; }
.tr-cmp-sel{
  width: 100%; min-width: 0; height: 31px;
  padding: 0 6px;
  border: 1px solid var(--hairline); border-radius: 9px;
  background: rgb(var(--surface)); color: rgb(var(--heading));
  font-family: var(--font-ui); font-size: 0.76rem;
}
.tr-compare{ display: flex; flex-direction: column; gap: 5px; }

/* reading */
.tr-size{ display: flex; align-items: center; gap: 9px; padding-block: 1px; }

@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-count{ font-size: 0.62rem; color: rgb(var(--accent-ui)); letter-spacing: 0.04em; }
.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);
}
.tr-step:hover{ border-color: rgb(var(--accent) / 0.45); color: rgb(var(--accent-ui)); }
.tr-step svg{ width: 14px; height: 14px; }
.tr-step.is-off{ opacity: 0; pointer-events: none; }
.tr-num input::-webkit-outer-spin-button,
.tr-num input::-webkit-inner-spin-button{ -webkit-appearance: none; margin: 0; }
.tr-num input:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: 1px; }
.tr-go-wide{ width: 100%; margin-top: 3px; }
.tr-reset{
  font-family: var(--font-ui); font-size: 0.72rem; font-weight: 600;
  color: rgb(var(--accent-ui));
}
.tr-cmp-row{ display: grid; grid-template-columns: 20px minmax(0, 1fr); align-items: center; gap: 7px; }
.tr-cmp-dot{
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 50%;
  background: rgb(var(--accent) / 0.12);
  color: rgb(var(--accent-ui));
  font-family: var(--font-mono); font-size: 0.62rem;
}
.tr-cmp-name{
  font-family: var(--font-ui); font-size: 0.78rem; font-weight: 600;
  color: rgb(var(--heading));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tr-cmp-row.is-fixed .tr-cmp-dot{ background: rgb(var(--accent) / 0.2); }
.tr-size .pp-typesize-track{ flex: 1; }
.tr-switch{
  display: flex; align-items: center; justify-content: space-between; gap: 9px;
  width: 100%; min-height: 34px; padding: 0 10px;
  border: 1px solid var(--hairline); border-radius: 9px;
  background: rgb(var(--surface)); cursor: pointer;
  font-family: var(--font-ui); font-size: 0.78rem; font-weight: 600;
  color: rgb(var(--heading-soft));
}
.tr-switch-track{
  position: relative; flex: 0 0 auto;
  width: 34px; height: 19px; border-radius: 999px;
  background: rgb(var(--heading) / 0.16);
  transition: background var(--dur) var(--ease-soft);
}
.tr-switch-knob{
  position: absolute; top: 2px; inset-inline-start: 2px;
  width: 15px; height: 15px; border-radius: 50%;
  background: rgb(var(--surface));
  box-shadow: 0 1px 2px rgb(var(--shadow) / 0.3);
  transition: transform var(--dur) var(--spring);
}
.tr-switch[aria-pressed="true"] .tr-switch-track{ background: rgb(var(--accent)); }
.tr-switch[aria-pressed="true"] .tr-switch-knob{ transform: translateX(15px); }
[dir="rtl"] 
.tr-switch[aria-pressed="true"] .tr-switch-knob{ transform: translateX(-15px); }

/* =========================================================================
   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.
   ========================================================================= */
.tafsir-pop-modes{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3px;
  padding: 3px;
  margin-bottom: 8px;
  border-radius: 999px;
  background: rgb(var(--heading) / 0.06);
}
.tafsir-pop-mode{
  min-height: 28px;
  border: 0; border-radius: 999px;
  background: transparent;
  color: rgb(var(--text-muted));
  font-family: var(--font-ui); font-size: 0.74rem; font-weight: 600;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
.tafsir-pop-mode:hover{ color: rgb(var(--heading)); }
.tafsir-pop-mode.is-on{
  background: rgb(var(--surface));
  color: rgb(var(--heading));
  box-shadow: 0 1px 2px rgb(var(--shadow) / 0.14);
}
.tafsir-pop-mode:focus-visible{ outline: 2px solid rgb(var(--accent-ui)); outline-offset: -2px; }

.tafsir-pop-hint{
  margin: 0 0 8px;
  font-family: var(--font-ui);
  font-size: 0.7rem;
  line-height: 1.45;
  color: rgb(var(--text-muted));
  min-height: 1.45em;
}

.tafsir-pop-num.is-from{
  background: rgb(var(--gilt) / 0.85);
  border-color: rgb(var(--gilt-edge) / 0.7);
  color: rgb(var(--on-gilt));
  font-weight: 700;
}
.tafsir-pop-num.is-in-span{
  background: rgb(var(--gilt) / 0.22);
  border-color: rgb(var(--gilt-edge) / 0.34);
  color: rgb(var(--heading));
}
.tafsir-pop-nums.is-range .tafsir-pop-num{ cursor: crosshair; }

/* ---- 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-menu-ar,
.site-header .quran-menu-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. */
.site-header .quran-panel .hadith-menu-row{ font-size: 0.86rem; }
.site-header .quran-menu-ar{ font-size: 1.12em; }

/* ---- 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.
   ========================================================================= */
@media (max-width: 430px){
  .site-header .pp-scheme-btn{ display: none; }
  .site-header .logo{ gap: 8px; }
  .site-header .logo-mark{ width: 30px; height: 30px; }
  .site-header .logo-text .name{ font-size: 1.08rem; }
  .site-header .header-actions{ gap: 4px; }
}

/* ---- 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; }
}
