/* overrides.css — hand-maintained corrections that MUST win the cascade.
   Enqueued LAST (after canonical-mobile.css), so it survives regeneration of the
   generated canonical*.css. Keep it small: only cross-cutting fixes that cannot
   live in the generated layer. Added 2026-06-08 to clear systemic QA findings. */

/* ── THE BRIGHT LINE ───────────────────────────────────────────────────────
   Every Quran verse surface is set in the certified mushaf font (--font-quran /
   KFGQPC) — never an editorial naskh (Scheherazade) or a display face. Belt-and-
   braces over any per-screen assignment. The Arabic STRING on each surface must
   still be verified verbatim against the certified Keller/mushaf store before
   publish — AI is never the authority on Quran text or harakat. */
.ayah,
.v4-foot-verse .ar,
.v4-verse-ar,
.v4-banner-ayah,
.v4-ans-quote .ayah,
.quran-slot[lang="ar"] .quran-ayah,
.gv-verse .ayah,
.gv-promise-card p .ayah,
.xt-404-verse { font-family: var(--font-quran) !important; direction: rtl; }

/* ── Mobile touch targets (WCAG 2.5.5 / 2.5.8 — ≥ 44×44) ───────────────────
   The export's mobile top-bar icon button is 38px; guarantee 44px, and floor
   the primary mobile interactive controls at a 44px hit area. */
.v4-m-top .ic { width: 44px; height: 44px; min-width: 44px; min-height: 44px; }
.v4-m-top .ic svg, .v4-m-top .ic img { width: 22px; height: 22px; }
@media (max-width: 760px) {
  .v4-mf-btn,
  .v4-mc-fchip,
  .v4-m-cta a,
  .v4-mf-todo > li { min-height: 44px; }
}

/* (resolved 2026-06-11) The util-bar target-size issue is fixed at the source in
   global.css: every util link/button carries padding-block:6px (a ≥24px box, both
   directions) with the container padding reduced to keep the bar height unchanged. */

/* ── RTL arrow correction (BUILD-AUDIT B1) ─────────────────────────────────
   Directional → glyphs hardcoded in shared / only-ar markup that lacked an RTL
   flip, so they pointed the wrong way in Arabic. Scoped to the specific arrow
   classes/components that need it — NEVER the bare global `.arrow`, which is used
   elsewhere as a properly PAIRED only-en →/only-ar ← and must not be double-flipped. */
[dir="rtl"] .st-opt-arrow,
[dir="rtl"] .wtb-option-arrow,
[dir="rtl"] .v4-course-notify .arrow,
[dir="rtl"] .v4-answer-readmore .arrow,
[dir="rtl"] .co-teacher-link .arrow { display: inline-block; transform: scaleX(-1); }

/* ── Type legibility (BUILD-AUDIT — type-sizes) ────────────────────────────
   The generated canonical layer ports literal Latin px + line-height and gives
   Arabic NO size uplift and NO prose leading — the [lang=ar] --lh-read:2.0 token
   in tokens.css is bypassed by hardcoded line-heights. Corrected here so it wins
   the cascade and survives canonical regeneration. The durable counterpart is a
   .build-canonical.py change to emit line-height:var(--lh-read) on prose rules. */

/* (1) Arabic reading uplift — RTL-scoped, so the English view is untouched.
   1.18em multiplies whatever Latin px the element carries (18px→~21, 17px→~20);
   1.9 leading gives naskh + harakat the room they need. */
[dir="rtl"] :is(p, li, blockquote, dd,
  .lede, .deck, .dek, .dek2, .sub, .subframe,
  .v4-ab-body p, .v4-td-body p, .sc-bio p, .bio, .note, .answer-body p, .gloss) {
  font-size: 1.18em;
  line-height: 1.9;
}
[dir="rtl"] :is(h1, h2, h3, .h1, .h2, .h3) { line-height: 1.34; }

/* (2) Chrome legibility floor — lift the 14.5px default and the sub-13 tier.
   Reading prose is set per-component (18–19px) and is unaffected. */
body, body.sg-v4 { font-size: 15px; }
.bar .nav a, .util-inner a, .v4-util a, .v4-foot a, .foot a,
.meta, .cite, .dateline, .seam-note, .role, .eyebrow-dot, .kicker { font-size: 13px; }
/* The Daily Answer body sits a touch low at 17px — nudge to 18px for parity. */
.v4-td-body p { font-size: 18px; }

/* ── Reduced motion (WCAG 2.3.3 / vestibular safety) ───────────────────────
   Global guard — the theme has ~164 motion rules + a live-dot animation; honor
   the user's OS preference everywhere in one place. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Per-seeker prayer location (assets/sg-prayer.js) ──────────────────────
   The "Change" affordance + the location popover the script builds inside the
   prayer rail. JS-only UI: with scripts off none of this markup exists, so the
   rail stays the clean server render. Logical properties throughout — one
   source, both directions. */
.sg-pray-set {
  margin-inline-start: auto;
  display: inline-flex;            /* honor min-height so the hit area clears WCAG 2.5.8 */
  align-items: center;
  min-height: 24px;                /* the "Change" affordance was 13px tall → target-size fail */
  border: 1px solid var(--hair);
  border-radius: var(--radius);
  background: transparent;
  color: var(--astral);
  font: inherit;
  font-size: .72em;
  padding: .15em .6em;
  cursor: pointer;
}
.sg-pray-set:hover, .sg-pray-set:focus-visible { border-color: var(--astral); }
[data-sg-prayer-rail] h3 { display: flex; align-items: baseline; gap: .5em; }

.sg-pray-pop {
  border: 1px solid var(--rule);
  border-top: 2px solid var(--gamboge); /* emphasis = gold top-rule, never a fill */
  border-radius: var(--radius);
  background: var(--card);
  padding: .85em;
  margin-block: .5em;
  display: grid;
  gap: .6em;
  font-size: .85em;
}
.sg-pray-pop label { display: grid; gap: .25em; color: var(--muted); }
.sg-pray-pop select {
  font: inherit;
  color: var(--ink);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper);
  padding: .3em .4em;
}
.sg-pray-pop .sg-pp-geo {
  justify-self: start;
  border: 1px solid var(--hair);
  border-radius: var(--radius);
  background: transparent;
  color: var(--astral);
  font: inherit;
  font-size: .9em;
  padding: .25em .6em;
  cursor: pointer;
}
.sg-pray-pop .sg-pp-geo.ok { border-color: var(--astral); }
.sg-pray-pop .sg-pp-note { margin: 0; color: var(--subtle); font-size: .85em; }
.sg-pray-pop .sg-pp-row { display: flex; gap: .5em; }
.sg-pray-pop .sg-pp-save,
.sg-pray-pop .sg-pp-cancel {
  border: 1px solid var(--astral);
  border-radius: var(--radius);
  font: inherit;
  font-size: .9em;
  padding: .3em .9em;
  cursor: pointer;
}
.sg-pray-pop .sg-pp-save { background: var(--astral); color: #fff; }
.sg-pray-pop .sg-pp-cancel { background: transparent; color: var(--astral); }

/* ── WCAG 2.2 AA contrast pass (2026-06-11; palette approved) ──────────────
   The cascade-final layer (generated canonical*.css is never hand-edited), so
   AA wins with !important where canonical selectors are more specific.
   Rule: gold TEXT on LIGHT → --gold-ink; gold/light TEXT on DARK → a light
   cream-gold that clears 4.5:1 (gold-ink is invisible on dark); faded-opacity
   labels restored; the too-light deep-olive band darkened. */

/* gold text on LIGHT backgrounds → AA-safe gold-ink */
.v4-cur-stream-num,
.gv-verse-ref { color: var(--gold-ink) !important; }
/* …except inside the give DARK hero (canonical .gv-hero, astral gradient — live
   since the 2026-06-11 de-prefix reconciliation): gold-ink is invisible on dark,
   so the verse ref takes the on-dark cream-gold there. Same !important layer,
   higher specificity ⇒ wins. */
.gv-hero .gv-verse-ref { color: #F3E9CE !important; }

/* gold / dark-gold text on DARK bands → light cream-gold (passes on astral) */
.hs-panel .panel-label,
.donor-band .dlabel,
.pk-donor-eyebrow,
.scholar-isnad .si-label { color: #F3E9CE !important; } /* AUDIT a11y MEDIUM-4: gamboge on isnad gradient was ~4.1:1 */

/* light label text on astral pills → full white for AA */
.v4-lib-switch button.on .ct { color: #ffffff !important; }

/* faded-opacity de-emphasis that fell below AA → readable muted, no opacity */
.v4-cat-crumbs span:not(a) { opacity: 1 !important; color: var(--muted) !important; }

/* deep-olive band + olive avatar circles were too light for AA small text in any
   on-brand color → darken (cream/white text on them was 3.9:1). Token + the
   literal-bg avatar variants. */
:root { --sg-deep-olive: #4A5636; }
.v4-ch-roster .pile .av.alt2,
.v4-wait-seekers .pile .av.alt2,
.v4-cur-course .by .av,
.v4-lib-by .av { background: #4A5636 !important; }

/* pocket-cover kickers sit on per-pocket DYNAMIC cover colors (can't guarantee
   4.5:1 against an arbitrary cover) → a subtle dark text-shadow scrim lifts the
   light kicker text to legible on any cover, the standard overlay-text technique. */
.pk-cover-kicker { color: #FFFFFF !important; text-shadow: 0 1px 3px rgba(0,0,0,0.55), 0 0 1px rgba(0,0,0,0.7) !important; }

/* contrast — cases caught by the WIDE sweep (dashboard, listen, scholars-fund, zakat) */
.sf-tier-freq { color: var(--astral) !important; }                 /* light astral tint → astral */
.v4-lst-show-meta, .v4-lst-show-teacher { opacity: 1 !important; color: var(--muted) !important; } /* opacity-faded labels */
/* /listen/{show}/ (show-friday) filter-chip COUNT badges (.ct): opacity 0.6 faded --muted
   (#4A5A63) to #929ca1 on white = 2.8:1 (WCAG AA fail, axe serious ×9; caught when the
   sg_show taxonomy archive was gated 2026-07-01). --muted passes at full strength; drop the
   fade. The selected (.on) chip is white-on-astral and unaffected. */
.v4-sh-filter-row .chips button .ct { opacity: 1 !important; }
/* gold on the DARK .live-soon session card → light cream (only there; the default
   light session card keeps its gold-ink, which passes on light) */
.v4-dash-sess.live-soon .v4-dash-sess-when .day { color: #F3E9CE !important; }
.zk-nisab-note { color: var(--ink) !important; }                   /* gold-ink on cream 4.39 → ink */

/* --sg-burnt-umber #8A5A44 fails on the tan tint (#E5D3B3, 3.94:1) → darken the
   token (still passes on white). Fixes the dashboard ask-link + fund kicker. */
:root { --sg-burnt-umber: #6E4632; }
/* in-text links in prose must be distinguishable (1.4.1 / link-in-text-block) */
.v4-lst-show-body a, [data-region=instructions] a, .activity-description a { text-decoration: underline !important; }

/* the opacity that fades these is on the inner SPANs, not the container */
.v4-lst-show-meta span, .v4-lst-show-teacher span { opacity: 1 !important; }
.sf-tier-freq, .sf-tier-freq * { opacity: 1 !important; }
/* dashboard saved-queue meta: canonical's `.v4-dash-queue .m span{opacity:.45}`
   targets the "·" separator spans, but the bilingual .only-en/.only-ar spans wrap
   the WHOLE line → the entire meta faded to 1.9:1 (caught when /dashboard/ joined
   the permanent gate). Restore the language spans; inner separators stay faded. */
.v4-dash-queue .m > .only-en, .v4-dash-queue .m > .only-ar { opacity: 1 !important; }
/* same pattern on the listen player meta — caught by the FIRST real AR-page render
   (/ar/listen/, served via the shared-slug shim): the .only-ar span faded to 1.9
   and its nested .ltr-iso numerals compounded to 1.31. Restore language spans AND
   their nested ltr-iso wrappers; the separator spans stay de-emphasized. */
.v4-lst-player-meta > .only-en, .v4-lst-player-meta > .only-ar,
.v4-lst-player-meta .only-en .ltr-iso, .v4-lst-player-meta .only-ar .ltr-iso { opacity: 1 !important; }

/* .scholar → dark/muted: it renders on a LIGHT card body (even on .live-soon, whose
   dark styling is only on the -when header), so cream failed. (If real live-soon
   content gives the -body a dark bg, restore cream there — a design call.) */
.v4-dash-sess-body .scholar { color: var(--muted) !important; }

/* bare in-prose links underlined for 1.4.1 (styled button/component links keep
   their look). Covers p / dd / li prose contexts. */
p a:not([class]), dd a:not([class]), li a:not([class]) { text-decoration: underline !important; }

/* ── course-detail (single-sg_course) — first axe scan 2026-06-11 ───────────
   This single template was never in the surfaces list, so these slipped the
   earlier sweep. All on-brand, in the cascade-final layer. */
/* the "Open for enrolment" badge: --sg-success green #4f7a4a on its light tint = 4.1 → darken the
   TEXT (the dot keeps --sg-success — decorative). */
.co-status-open { color: #3A5E36 !important; }
/* the closing-letter reassurance line: cream@0.5 on the dark band = 4.37 → lift opacity to clear AA */
.co-close-letter .sg-letter-reassure,
.v4-foot-letter .sg-letter-reassure { color: rgba(245, 236, 218, 0.82) !important; }
/* course-detail's closing-verse ref uses the dark-footer cream styling but sits on the LIGHT page
   (1.04 — invisible). `.v4-foot-verse` is course-detail-only (the real footer uses `.foot-verse`),
   so scoping here is safe. Muted reads correctly on light; ayah already inherits dark. */
.v4-foot-verse .ref { color: var(--muted) !important; }

/* (The .v4-pwy-* pathway-page overrides were removed 2026-06-28 when the three
   /pathways/ pages were retired; the rules had no element left to match.) */

/* This is the cascade-winning fix layer (enqueued last). Render-surface changes
   are gated EN+AR × desktop+mobile — see tests/singles.spec.ts + tests/axe.spec.ts. */

/* ── Skip-link: fully off-screen until focused (WCAG 2.5.8 target-size) ─────
   The sg/daily-answer block emits its own .skip link; canonical's unfocused
   inset-block-start (-48px) doesn't clear the link's rendered height on the
   390px mobile breakpoint, so its bottom edge poked into the viewport and
   partially obscured the .zakat utility link → axe target-size (serious) on
   every block-bearing single in mobile EN + AR. Found by the singles a11y gate
   (tests/singles.spec.ts) 2026-06-14. translateY is height-independent, so it
   stays clear no matter how tall the (bilingual) label renders; the focused
   state is untouched and still slides in. Correct for every .skip site-wide. */
.skip:not(:focus) { transform: translateY(-150%); }

/* ── Certified citation / evidence box (Quran + hadith) ─────────────────────
   Design-fidelity port of the comp's .v4-ans-quote (design-export/v4_pages.css):
   a SQUARE, gold-top-ruled cream box — emphasis is the Gamboge top-rule, never a
   left-accent bar (CLAUDE.md). One component for both Quran ([Q|Quran X:Y]) and
   hadith ([H key]); bilingual via logical properties + the role-font swap, so EN
   (LTR) and AR (RTL) render from one source. The 3-class ancestor beats the
   placeholder dashed .quran-slot in global.css / daily-answer/style.css.
   THE BRIGHT LINE: the box only ever shows verbatim store text; an empty store
   renders the quiet placeholder state below — never AI-authored sacred text. */
.wp-block-sg-daily-answer .answer-body .quran-slot,
.wp-block-sg-daily-answer .answer-body .hadith-slot,
.answer-body .quran-slot,
.answer-body .hadith-slot {
  margin-block: var(--s5);
  padding: var(--s4);
  border: 0;
  border-block-start: 2px solid var(--gamboge);  /* gold top-rule, not a left bar */
  background: var(--paper-alt);
  border-radius: var(--radius);                   /* 2px — the theme's square box */
  font-family: var(--font-display);
  font-size: 1.1875rem;                           /* ≈19px, matches the comp */
  line-height: 1.55;
  color: var(--ink);
}

/* The verbatim verse / narration line. */
.answer-body .quran-slot .quran-ayah,
.answer-body .hadith-slot .hadith-text {
  display: block;
  font-family: var(--font-display);
  font-size: 1.5rem;                              /* ≈24px, matches the comp .ar */
  line-height: 1.6;
  margin-block-end: var(--s2);
  color: var(--ink);
}
/* Quran Arabic = certified mushaf (enforced with !important by the bright-line
   rule near the top of this file). Hadith Arabic = reading naskh — NEVER the
   mushaf font, which is Quran-only. */
.answer-body .hadith-slot[lang="ar"] .hadith-text {
  font-family: var(--font-read);
  direction: rtl;
}

/* Citation line + verification footer (both slots). */
.answer-body .quran-slot .quran-cite,
.answer-body .hadith-slot .hadith-cite {
  display: block;
  margin-block-start: var(--s2);
  font-family: var(--font-ui);
  font-size: 0.78rem;                             /* ≈12.5px, matches the comp .src */
  letter-spacing: 0.06em;
  color: var(--muted);
}
.answer-body .quran-slot .quran-verify,
.answer-body .hadith-slot .hadith-verify {
  display: block;
  margin-block-start: var(--s1);
  font-family: var(--font-ui);
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  color: var(--subtle);
}

/* Empty-store placeholder — same gold box, quiet "awaiting certification" tone.
   Mirrors how /ask returns an empty vetted seam: a styled slot, no fabricated
   text. (:not() lifts specificity above the base rule, so this wins.) */
.answer-body .quran-slot:not(.quran-certified),
.answer-body .hadith-slot:not(.hadith-certified) {
  font-family: var(--font-ui);
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--muted);
}

/* Inline source reference, e.g. [Sahih al-Bukhari] → a quiet citation (not a box).
   UI font, Astral, non-italic (italics retired). Coherent EN/AR via the font swap. */
.answer-body cite.sg-ref,
.wp-block-sg-daily-answer cite.sg-ref {
  font-family: var(--font-ui);
  font-style: normal;
  font-size: 0.95em;
  color: var(--astral);
}

/* ── Brand discipline sweep (2026-06-22, from the comprehensive UI/UX + speed audit) ──
   The generated canonical.css gives nearly every card a floating drop-shadow plus a
   translateY lift on hover, rounds the loudest CTAs to 4px, and rings focus with a
   gamboge glow — the generic "SaaS/AI" look the brand rejects (square ruled boxes;
   emphasis = a rule or a crisp ring, never a floating shadow; --radius is 2px).
   overrides.css is enqueued last, so these win the cascade live without editing the
   generated layer. Adversarially confirmed against the live build at the cited
   selectors; verify four-way (EN/AR × desktop/mobile). */

/* 1 — Kill the floating card-lift; replace with a crisp, flat astral ring (no blur,
       no offset → reads as "active", not "floating"). */
.v4-answer-lead:hover,
.v4-course:hover,
.v4-bk-card:hover,
.co-teacher:hover,
.v4-cur-course:hover,
.v4-fed-card:hover,
.v4-hm-pillar:hover,
.v4-lib-card:hover {
  box-shadow: 0 0 0 1.5px var(--astral) !important;
  transform: none !important;
}

/* 2 — Square boxes: force the --radius (2px) token onto the CTAs the export rounded
       to 4px. A no-op where a class is absent, so it is safe across the set. */
.v4-hm-btn, .v4-hm-door, .v4-hm-donate,
.gv-give-btn, .v4-si-submit, .v4-si-sso,
.v4-dash-btn, .fp-cta {
  border-radius: var(--radius) !important;
}

/* 3 — Focus: one crisp ring (WCAG 2.4.11/2.4.13), no ambient glow shadow. Astral,
       not gamboge — gamboge on paper fails the 3:1 focus-appearance contrast. */
.sc-ask:focus-within {
  box-shadow: 0 0 0 2px var(--astral) !important;
}

/* 4 — Motion safety (WCAG 2.3.3): no hover-lift for reduced-motion users. */
@media (prefers-reduced-motion: reduce) {
  .v4-answer-lead:hover,
  .v4-course:hover,
  .v4-bk-card:hover,
  .co-teacher:hover,
  .v4-cur-course:hover,
  .v4-fed-card:hover,
  .v4-hm-pillar:hover,
  .v4-lib-card:hover {
    transform: none !important;
    transition: none !important;
  }
}

/* 5 — The per-card EN/AR language toggle rendered ~20px tall; floor it for the
       WCAG 2.5.8 (24px AA) touch-target minimum across catalogue/library/books. */
.v4-lib-cardtoggle button {
  min-block-size: 24px;
  padding-block: 5px;
}

/* ── /course-home/ mobile tune (≤640) — overflow root-cause fix (2026-06-22) ──
   Both EN (+21px) and AR (+138px) overflow trace to one cause: canonical's
   @media(max-width:900px) collapses the page grids to `1fr`, but 1fr ===
   minmax(auto,1fr) and the `auto` floor sizes the single track to the widest
   item's MIN-CONTENT — the .v4-ch-week-row title inflates the track and shifts
   the whole RTL page off-edge. minmax(0,1fr) lets the track shrink; the 2-row
   week-row + overflow-wrap let long titles wrap. Validated live: EN 21→0, AR 138→0. */
@media (max-width: 640px) {
  .v4-ch-main-inner,
  .v4-ch-hero-inner,
  .v4-ch-bar-inner { grid-template-columns: minmax(0, 1fr); }

  .v4-ch-week-row {
    grid-template-columns: 44px minmax(0, 1fr);
    grid-template-areas: "num title" "num status";
    gap: 4px 14px;
    padding: 16px 18px;
    align-items: start;
  }
  .v4-ch-week-row .wk    { grid-area: num; }
  .v4-ch-week-row .t     { grid-area: title; min-width: 0; }
  .v4-ch-week-row .state { grid-area: status; justify-self: start; margin-top: 4px; }
  .v4-ch-week .wk b { font-size: 18px; }

  .v4-ch-week .t h3,
  .v4-ch-card p,
  .v4-ch-main-inner :is(h1, h2, h3, h4, p, li) { overflow-wrap: anywhere; }

  /* logical indent so AR mirrors (canonical's 900px rule used physical padding-left) */
  .v4-ch-week-body { padding-inline-start: 62px; padding-inline-end: 18px; }
}

/* ── iOS focus-zoom guard + footer CTA touch floor (≤640, 2026-06-22) ──────────
   Safari auto-zooms when a focused field renders <16px. Found <16 site-wide:
   /ask 13.3, /courses search 14.5 + sort 14, /give 15, /sign-in 15, /books 14.
   !important beats canonical's class-scoped input rules; checkbox/radio/range
   excluded (no zoom risk). The standalone footer CTA was ~20px tall — floored. */
@media (max-width: 640px) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="hidden"]),
  select,
  textarea { font-size: 16px !important; }

  .foot-begin { min-block-size: 24px; padding-block: 2px; }
}

/* ── Khatam corner pip on the certified evidence box (2026-06-22) ──────────────
   Pairs with the existing 2px gamboge top-rule (never a left bar). Decoration
   only (::before), gamboge at .6 like the empty-state emblem, masked from the
   canonical 8-point khatam path — the same mark used 37× across the site, so it
   unifies rather than introduces a motif. Logical-positioned → mirrors in RTL;
   never touches the certified-font verse text. */
.answer-body .quran-slot,
.answer-body .hadith-slot { position: relative; }
.answer-body .quran-slot::before,
.answer-body .hadith-slot::before {
  content: "";
  position: absolute;
  inset-block-start: 9px;
  inset-inline-start: 9px;
  inline-size: 11px;
  block-size: 11px;
  background: var(--gamboge);
  opacity: 0.6;
  pointer-events: none;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M98%2050L83.94%2064.06L83.94%2083.94L64.06%2083.94L50%2098L35.94%2083.94L16.06%2083.94L16.06%2064.06L2%2050L16.06%2035.94L16.06%2016.06L35.94%2016.06L50%202L64.06%2016.06L83.94%2016.06L83.94%2035.94Z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M98%2050L83.94%2064.06L83.94%2083.94L64.06%2083.94L50%2098L35.94%2083.94L16.06%2083.94L16.06%2064.06L2%2050L16.06%2035.94L16.06%2016.06L35.94%2016.06L50%202L64.06%2016.06L83.94%2016.06L83.94%2035.94Z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* ── /lesson/ mobile overflow (≤640, 2026-06-22) ──────────────────────────────
   Same root cause as course-home: the pattern collapses .sg-lsn-main-inner to
   `1fr` at ≤960, but 1fr === minmax(auto,1fr) and the auto floor sizes the single
   track to the widest child's min-content (a non-wrapping element → 423px), so the
   column overflows by 53px. minmax(0,1fr) lets the track shrink; media cap + text
   wrap let the content fit. !important beats the pattern's scoped 960px rule
   (non-important, later in source order — importance wins regardless). */
@media (max-width: 640px) {
  .sg-lsn-main-inner { grid-template-columns: minmax(0, 1fr) !important; }
  .sg-lsn-center, .sg-lsn-side, .sg-lsn-panel { min-width: 0; }
  .sg-lsn-center :is(p, h1, h2, h3, h4, li, a) { overflow-wrap: anywhere; }
  .sg-lsn-center img, .sg-lsn-center iframe,
  .sg-lsn-video, .sg-lsn-video > * { max-width: 100%; }
}

/* ── /dashboard/ mobile overflow — AR (≤640, 2026-06-22) ──────────────────────
   Same minmax(auto,1fr) floor: .v4-dash-layout collapses to `1fr` at ≤940, and a
   card's min-content (a non-wrapping .left line) inflated the track to ~435px,
   shoving the RTL column ~45px off the inline-end (left) edge. minmax(0,1fr) + text
   wrap + shrinkable flex children fix it; !important beats canonical's 940px rule. */
@media (max-width: 640px) {
  /* Let the cards grid, the layout grid, and each card's inner grid shrink below
     their fixed tracks (.v4-dash-main-inner is a fixed 350px column; the card is
     40px 250px). */
  .v4-dash-main-inner { grid-template-columns: minmax(0, 1fr) !important; }
  .v4-dash-layout { grid-template-columns: minmax(0, 1fr) !important; }
  .v4-dash-course { grid-template-columns: 40px minmax(0, 1fr) !important; }
  /* The actual overflow: a white-space:nowrap "Last watched · Week N · Lesson M"
     label (338px) inside a 250px column — overflow-wrap can't break a nowrap line,
     so unset nowrap here. */
  .v4-dash-course .left { white-space: normal; }
  .v4-dash-course-top { flex-wrap: wrap; }
  .v4-dash-course :is(p, h3, h4) { overflow-wrap: anywhere; }
}

/* ── /certificate/ mobile fit (2026-06-22) ────────────────────────────────────
   The certificate is a fixed 1040px ceremonial print layout (.sg-cert__credential
   width:1040px) with absolutely-positioned corner ornaments — making it fluid would
   break the frame proportions. Instead scale the whole block with `zoom`, which
   (unlike transform) shrinks the layout box too, so the document stops scrolling
   horizontally and every fixed-px ornament scales in proportion. `zoom` is supported
   in Chromium, Safari, and Firefox 126+. Two tiers so it isn't needlessly tiny on
   larger phones and small tablets. */
@media (max-width: 640px) { .sg-cert { zoom: 0.42; } }
@media (max-width: 480px) { .sg-cert { zoom: 0.34; } }

/* ── Home hero — wire the chosen photographic hero (a woman reading the Qur'an in
   a luminous mosque, already in the Astral duotone) into the Twin-Doors panel, in
   place of the abstract emblem-only block. The conversion + design audit (2026-06-25):
   an institution whose work is human converts on a real human face, not a mark; the
   ethos is kept (real photo, our own, Astral duotone, ornament as a quiet accent).
   Real photography only — bright line. */
.hs-panel .hs-photo{ position:absolute; inset:0; inline-size:100%; block-size:100%; object-fit:cover; object-position:center 26%; z-index:0; }
.hs-panel::after{ content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:linear-gradient(180deg, rgba(19,48,63,.34) 0%, rgba(19,48,63,.14) 46%, rgba(19,48,63,.80) 100%); }
.hs-panel .khatam-bg{ display:none; }                 /* the photo replaces the geometric fill */
.hs-panel .emblem-lg{ position:relative; z-index:1; inline-size:84px; block-size:84px; margin-block-start:auto;
  filter:drop-shadow(0 2px 10px rgba(0,0,0,.45)); }   /* gold mark as a quiet accent over the photo */
.hs-panel .panel-rule,.hs-panel .panel-label{ position:relative; z-index:1; }
.hs-panel .panel-label{ text-shadow:0 1px 6px rgba(0,0,0,.6); }

/* ── Scholar monogram — the dignified, on-brand fallback when no commissioned
   portrait exists yet (e.g. Shaykh Jamir Meah, Ustadha Shazia Ahmad today).
   Instead of a bare initial on a flat ground, the initials are seated inside
   the canonical khatam outline with a gold hairline frame, so every photo-less
   scholar still reads as one designed system — never a generic avatar. Scoped
   to the no-photo case via :not(:has(img)); a real portrait is untouched.
   Real commissioned photography stays the goal; this is the placeholder. THE
   BRIGHT LINE: no AI imagery — this is type + the brand ornament, nothing more. */
.v4-fed-portrait:not(:has(img)),
.portrait:not(:has(img)){
  box-shadow: inset 0 0 0 1px rgba(143,102,4,.55);   /* gold hairline frame; survives inline `background` */
}
.v4-fed-portrait:not(:has(img))::before,
.portrait:not(:has(img))::before{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><path d='M98 50L83.94 64.06L83.94 83.94L64.06 83.94L50 98L35.94 83.94L16.06 83.94L16.06 64.06L2 50L16.06 35.94L16.06 16.06L35.94 16.06L50 2L64.06 16.06L83.94 16.06L83.94 35.94Z' fill='none' stroke='%23E9C77E' stroke-width='1.1' opacity='0.45'/></svg>") center/58% no-repeat;
}
.v4-fed-portrait:not(:has(img)) > span,
.portrait:not(:has(img)) > span{ position:relative; z-index:1; letter-spacing:.05em; }

/* ── Give hero — the action in the fold (top-of-fold conversion proposal,
   lever 2). Emotion and the ask now sit together: a primary "Give now" that
   scrolls to the real giving form, plus a quiet Zakat alternate. The hero is
   the dark Astral band, so the alternate link is set in cream for AA contrast.
   No invented amounts — the real amount-chooser stays in the wired form. */
.gv-hero-cta{ display:flex; gap:var(--s3); align-items:center; justify-content:center; flex-wrap:wrap; margin-block:var(--s3) var(--s4); }
.gv-hero-cta-alt{ color:#F3E9CE; text-underline-offset:3px; }
.gv-hero-cta-alt:hover,.gv-hero-cta-alt:focus-visible{ color:#fff; }

/* ── Catalogue promise line (top-of-fold proposal, lever 3). A short
   seeker-outcome promise + quiet proof, seated between the title and the
   operational lede so the newcomer sees the value before the term mechanics.
   The detailed lede (counts/dates) and the search stay exactly as they were. */
.sg-catalogue .cat-promise{
  font-family: var(--sg-font-read); font-size: 20px; line-height: 1.5;
  color: var(--sg-fg); margin: 2px 0 14px; max-width: 54ch; text-wrap: pretty;
}
:root[lang="ar"] .sg-catalogue .cat-promise{ font-family: "Riwaya", serif; font-size: 21px; }

/* ── Mobile nav drawer hardening (i18n + mobile sweep). When the drawer is open,
   sg-chrome.js adds .sg-nav-open to <html> to lock the page behind it; the drawer
   itself scrolls if its content is tall, without chaining to the page. Pairs with
   the focus-trap + focus-return added in sg-chrome.js. Logical, so LTR == RTL. */
html.sg-nav-open, html.sg-nav-open body { overflow: hidden; }
.nav-drawer { overflow-y: auto; overscroll-behavior: contain; }
/* The drawer is a flex column; when its content is taller than the viewport the
   flex items would shrink — and the language switcher (.viewswitch has
   overflow:hidden, so its flex min-size is 0) collapsed to ~2px, clipping and
   obscuring its 32px buttons (a WCAG 2.2 target-size failure caught by
   tests/i18n-mobile.spec.ts). Pin each item to its natural height; the drawer
   scrolls instead. */
.nav-drawer > * { flex-shrink: 0; }

/* The "PORTRAIT SLOT" / "موضع الصورة" placeholder caption (global.css .portrait::after)
   is only meaningful while a scholar has no commissioned photo. Once a real portrait
   is in place (e.g. the imported Jamir Meah / Shazia Ahmad headshots), suppress it so
   the label never bleeds over the photograph. Scoped to the has-photo case. */
.portrait:has(img)::after { content: none; }

/* ── P0 brand-law fixes (visual audit 2026-06-30) ─────────────────────────────
   Gamboge is decoration/ACCENT only — never body/link text (→ --gold-ink); and
   emphasis is a gold TOP-rule, never a left-accent bar (→ border-block-start,
   logical so it is correct in RTL). canonical.css is generated; these win from
   the last-enqueued cascade layer. Verified four-way after application. */
.v4-donor .v4-donor-zakat b,
.v4-donor .v4-donor-impact b { color: var(--gold-ink, #8F6604) !important; }
.co-cover-term { color: var(--gold-ink, #8F6604) !important; }
.v4-banner-ayah-row {
  border-left: 0 !important;
  padding-left: 0 !important;
  border-block-start: 2px solid var(--sg-gamboge, #ECA608) !important;
  padding-block-start: 16px !important;
}
.v4-mlsn-mynotes .entry {
  border-left: 0 !important;
  border-block-start: 2px solid var(--sg-gamboge, #ECA608) !important;
  padding: 10px 0 6px 0 !important;
}

/* ── P1 (visual audit 2026-06-30): scholar-grid portrait distortion ──────────
   The scholar-grid block ships no style.css; scholar-profile sets object-fit but
   the grid context did not, so a non-square upload (e.g. a 300×200 portrait) is
   stretched in the square card frame. Cover the frame instead. */
.v4-fed-portrait .portrait-photo,
.v4-fed-portrait img.portrait-photo,
.v4-fed-portrait img { inline-size: 100% !important; block-size: 100% !important; object-fit: cover !important; display: block; }

/* ── AR / empty faculty holding page (visual audit 2026-06-30) ────────────────
   A dignified "in preparation" surface, not a bare error line: paper card, square
   ruled box, gold TOP-rule, khatam mark, logical CSS (RTL-correct). Shows when the
   faculty query is empty — today the AR archive, until the scholar AR pages land. */
.v4-fed-holding{
  max-inline-size: 40rem; margin: 8px auto 12px; padding: 36px 28px 32px;
  text-align: center; background: var(--paper, #FBF7EF);
  border: 1px solid var(--rule, #E5D3B3);
  border-block-start: 2px solid var(--gamboge, #ECA608);
  border-radius: 2px;
}
.v4-fed-holding-mark{ display: inline-block; margin-block-end: 12px; line-height: 0; }
.v4-fed-holding-h{
  font-family: var(--font-display, Georgia, serif); font-weight: 500;
  font-size: clamp(20px, 3vw, 26px); color: var(--ink, #23211C); margin: 0 0 10px;
}
.v4-fed-holding-note{
  font-family: var(--font-read, Georgia, serif); font-size: 16px; line-height: 1.6;
  color: var(--muted, #5F6A6E); max-inline-size: 34rem; margin: 0 auto 22px;
}
.v4-fed-holding-cta{
  display: inline-flex; align-items: center; min-height: 44px;
  font-family: var(--font-ui, sans-serif); font-weight: 600; font-size: 14px;
  color: var(--astral, #30708E); text-decoration: none;
  border: 1px solid var(--astral, #30708E); border-radius: 2px; padding: 0 20px;
}
.v4-fed-holding-cta:hover, .v4-fed-holding-cta:focus-visible{ background: var(--astral, #30708E); color: #fff; }
:root[lang="ar"] .v4-fed-holding-h{ font-family: "Zarid Display","Riwaya",serif; }
:root[lang="ar"] .v4-fed-holding-note{ font-family: "Riwaya",serif; line-height: 1.9; }

/* ==========================================================================
   AUDIT FIX (#23, 2026-07-12) — mobile catalogue RTL parity
   The generated canonical-mobile.css uses PHYSICAL margin-left / border-left on
   the catalogue cards + sort/level/when bits, which leak LTR spacing and a
   left-edge accent into the Arabic (RTL) mobile view. Restated here as LOGICAL
   properties (overrides.css is the cascade-winning layer; canonical*.css is never
   hand-edited) so English (LTR) and Arabic (RTL) render correctly from one source.
   NOTE: the card's inline-start accent bar is a separate DESIGN-RULE question
   (the system prefers a gold top-rule / khatam corner over an accent bar) —
   flagged for a design call, not silently redesigned here.
   ========================================================================== */
.v4-mc-sort             { margin-left: 0; margin-inline-start: auto; }
.v4-mc-dayhead .n       { margin-left: 0; margin-inline-start: auto; }
.v4-mc-card .lvl        { margin-left: 0; margin-inline-start: auto; }
.v4-mc-card .foot .when { margin-left: 0; margin-inline-start: auto; }
.v4-mc-card             { border-left: 0; border-inline-start: 3px solid var(--tint, var(--sg-astral)); }

/* ==========================================================================
   AUDIT FIXES — accessibility / RTL residue (deep a11y pass, 2026-07-12)
   overrides.css is the cascade-winning layer; canonical*.css is never hand-edited.
   Each fix carries its finding id. Pending the four-way axe/visual gate.
   ========================================================================== */

/* HIGH-1 (WCAG 2.4.7): the /answers search input sets outline:none as a BASE rule
   with no focus replacement, so keyboard focus is invisible on the primary Answers
   search box in all four views. Restore a visible focus ring on the wrapper. */
.sg-ans-hub .search-wrap:focus-within {
	outline: 2px solid var(--astral, #30708E);
	outline-offset: 2px;
	border-radius: 2px;
}

/* MEDIUM-3: the account-settings toggle knob travels a PHYSICAL +18px, so in RTL it
   slides further off the right edge instead of to the "on" position. Mirror it. */
[dir="rtl"] .v4-sw[aria-pressed="true"]::after { transform: translateX(-18px); }

/* LOW-6: two live classes fall through to canonical.css physical-direction CSS in
   Arabic desktop (no pattern re-style, no canonical-ar correction). Restate logical. */
.v4-res-side  { border-left: 0; border-inline-start: 1px solid rgba(15, 27, 34, 0.08); }
.v4-atlas-num { border-right: 0; border-inline-end: 1px solid rgba(15, 27, 34, 0.08); }
.v4-atlas-num:last-child { border-inline-end: 0; }

/* ── A21 (2026-07-18): the two screen-reader-only classes are used on ~13 surfaces
   but were defined only in two scoped stylesheets — hidden labels rendered as
   visible stray text while their assistive purpose silently failed (UX audit).
   The standard visually-hidden pattern, defined once, cascade-winning. ── */
.sr-only,
.screen-reader-text {
	position: absolute !important;
	width: 1px !important;
	height: 1px !important;
	padding: 0 !important;
	margin: -1px !important;
	overflow: hidden !important;
	clip: rect(0, 0, 0, 0) !important;
	white-space: nowrap !important;
	border: 0 !important;
}

/* Auth gate for the classroom surfaces (2026-07-18) — a calm, centered sign-in
   invitation shown to signed-out visitors in place of a fabricated classroom. */
.sg-classroom-signin { padding: 88px 24px; text-align: center; }
.sg-classroom-signin-inner { max-width: 30rem; margin-inline: auto; }
.sg-classroom-signin-line a {
	font-family: var(--sg-font-display, Georgia, serif);
	font-size: 20px; color: var(--sg-astral-shade-50, #30708E);
	text-decoration: none; border-bottom: 2px solid var(--sg-gamboge, #ECA608);
	padding-bottom: 3px;
}
.sg-classroom-signin-line a:hover { color: var(--sg-astral-shade-30, #22506A); }

/* #3 (2026-07-18, audit UX §4 RED): the canonical bridge left these role tokens
   undefined, so anything styled through them fell to inherit. The bright-line one is
   the QURAN font — verses reference var(--sg-font-quran) (never defined) and inherited
   an editorial face. Alias it to the certified mushaf token. Defined HERE (overrides.css),
   never in generated canonical.css (build law). */
:root {
	--sg-font-quran: var(--font-quran, "KFGQPC HAFS", serif);   /* certified mushaf ONLY — THE BRIGHT LINE */
	--sg-font-arabic-ui: "Bukra", "Readex Pro", system-ui, sans-serif;
	--sg-font-display-ar: "Zarid Display", "Riwaya", serif;   /* AR display face — matches tokens.css AR --font-display + overrides.css:657 */
	--font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;   /* was undefined → inherited; used at mobile-lesson.php:173 */
	--sg-radius-md: var(--radius, 2px);   /* square, ruled boxes — aliases canonical --radius (tokens.css:64) */
}
/* --pwy-tint left undefined DELIBERATELY: defining it activates a border-left accent bar
   (canonical.css:13343) that the constitution forbids ("never a left-accent bar"). The
   pathway-section decoration needs a design pass, not a blind token — flagged for Faraz §9.4. */
