/* =============================================================================
   AD DAWAH CENTER OF NEW JERSEY — main.css
   The entire stylesheet. Brand tokens (contract §1) verbatim, self-hosted fonts
   (§2), and every class in the shared dictionary (_redesign/ICGM-PLAN.md).
   Mobile-first. Only palette tokens for color (plus #FFF and rgba() shadows and
   overlays, allowed here).

   NO DECORATIVE ICONS. Type, the four real photographs, the colour bands, the
   Islamic pattern tile and the Rawdah widgets' own client-made artwork do all
   the work. The only SVGs the theme keeps are the nav chevron, the hamburger
   and the close X — every icon-slot rule (.card__icon, .info-card__icon,
   .quick-link__icon, the top-bar email/phone/social glyphs, the footer-contact
   glyphs, .app-stores__btn svg) was deleted with them on 2026-10-22.

   WCAG AA throughout. No horizontal scroll at 320/375/414/768/1024/1280.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   1. DESIGN TOKENS
   The brand block below is the contract's, derived from the client's logo, and
   is UNCHANGED — same values, same spelling. Everything after the "ADDED" rule
   is new: the shared scale/shape/motion tokens the component layer needs, which
   this file never had.
   -------------------------------------------------------------------------- */
:root{
  /* Brand — primary teal (from logo) */
  --color-primary:        #007296;
  --color-primary-light:  #0A8FB8;
  --color-primary-lighter:#E2F1F5;
  --color-primary-dark:   #015670;

  /* Brand — secondary gold/sand (from logo) */
  --color-secondary:        #BFA253;
  --color-secondary-light:  #D8C79A;
  --color-secondary-lighter:#F5EFDF;
  --color-secondary-dark:   #94793A;
  --color-gold-text:        #6E5621; /* AA-safe gold for TEXT (>=4.5:1 on white); decorative gold stays --color-secondary */

  /* Neutrals — warm-tinted */
  --color-white:    #FFFFFF;
  --color-off-white:#FCFBF8;  /* main page background */
  --color-cream:    #F5F1E8;  /* alternating warm sections */
  --color-gray-100: #F1F0EC;
  --color-gray-200: #E5E3DB;
  --color-gray-300: #D2CFC5;
  --color-gray-500: #8C887C;
  --color-gray-700: #4C4F54;
  --color-gray-900: #20242A;

  /* Semantic */
  --color-text:           #23262A;
  --color-text-secondary: #4C4F54;
  --color-text-muted:     #6B6F74; /* AA-safe (~4.6:1 on white) */
  --color-heading:        #015670;
  --color-link:           var(--color-primary);
  --color-link-hover:     var(--color-primary-dark);
  --color-cta:            var(--color-primary);
  --color-cta-hover:      var(--color-primary-dark);
  --color-cta-text:       #FFFFFF;
  --color-accent:         var(--color-secondary);
  --color-border:         #E6E4DC;
  --color-success:        #1E7A4D;
  --color-error:          #B23A2E;
  --color-error-lighter:  #FBEDEB;

  /* Layout / motion tokens */
  --container:1200px; --container-narrow:880px;
  --radius-sm:8px; --radius:12px; --radius-lg:20px; --radius-pill:999px;
  --shadow-sm:0 1px 3px rgba(0,0,0,.05),0 1px 2px rgba(0,0,0,.03);
  --shadow:0 4px 16px rgba(0,0,0,.06),0 2px 6px rgba(0,0,0,.04);
  --shadow-lg:0 18px 40px rgba(0,0,0,.10),0 8px 16px rgba(0,0,0,.05);
  --ease:cubic-bezier(.25,.1,.25,1);
  --t-fast:.2s var(--ease); --t:.3s var(--ease); --t-slow:.6s var(--ease);
  --space-section:clamp(3.5rem,7vw,6.5rem);

  /* ---- ADDED 2026-10-22 (the shared system; nothing above was altered) ----
     --space-section is the contract's own figure and stays. It is slightly
     tighter than DESIGN-LANGUAGE §3's clamp(4.5rem,8vw,7.5rem); if the client
     wants section rhythm identical to ICGM/ROIC, this one line is the change. */

  /* Spacing scale — 8px steps (8/12/16/24/32/48/64/96) */
  --sp-1:.5rem;
  --sp-2:.75rem;
  --sp-3:1rem;
  --sp-4:1.5rem;
  --sp-5:2rem;
  --sp-6:3rem;
  --sp-7:4rem;
  --sp-8:6rem;

  /* Rhythm — one container width, one section padding, one grid gap */
  --container-pad:clamp(1.25rem,4vw,2.5rem);
  --space-section-tight:clamp(2.25rem,4vw,3.25rem);
  --pad-card:clamp(1.5rem,3vw,2rem);
  --gap:clamp(1.5rem,3vw,2rem);
  --gap-tight:clamp(.75rem,2vw,1.25rem);
  --space-block:clamp(2rem,4vw,3rem); /* air after a heading block */
  --quick-bar-h:62px;  /* bar height; also its overlap onto the hero */
  --header-offset:150px; /* app banner + top bar + nav; fragment-scroll offset */
  --slides-cap:460px;  /* the capped slider column — see §6 and §16 */

  /* Display type scale */
  --fs-display-hero:clamp(2.4rem,5.2vw,4.2rem);
  --fs-display-xl:clamp(2.2rem,4.4vw,3.4rem);
  --fs-display-lg:clamp(1.9rem,3.4vw,2.9rem);
  --fs-display-md:clamp(1.45rem,2.4vw,1.95rem);
  --fs-display-sm:clamp(1.2rem,1.8vw,1.45rem);

  /* Body type */
  --fs-body:1.0625rem;
  --fs-lead:clamp(1.1rem,1.6vw,1.3rem);
  --fs-small:.9rem;
  --fs-eyebrow:.78rem;
  --lh-body:1.7;
  --lh-display:1.1;
  --measure:68ch;

  /* Shape + depth */
  --radius-card:18px;
  --shadow-card:0 10px 30px rgba(0,0,0,.07);
  --shadow-card-hover:0 18px 44px rgba(0,0,0,.12);

  /* Motion */
  --ease-out:cubic-bezier(.22,.61,.36,1);
  --t-zoom:700ms var(--ease-out);
  --t-reveal:620ms;
  --stagger:80ms;
}

/* -----------------------------------------------------------------------------
   2. FONTS (self-hosted woff2 in ../fonts/, font-display swap)
   -------------------------------------------------------------------------- */
@font-face{ font-family:"DM Sans"; font-style:normal; font-weight:400; font-display:swap; src:url("../fonts/dm-sans-latin-400-normal.woff2") format("woff2"); }
@font-face{ font-family:"DM Sans"; font-style:normal; font-weight:500; font-display:swap; src:url("../fonts/dm-sans-latin-500-normal.woff2") format("woff2"); }
@font-face{ font-family:"DM Sans"; font-style:normal; font-weight:600; font-display:swap; src:url("../fonts/dm-sans-latin-600-normal.woff2") format("woff2"); }
@font-face{ font-family:"DM Sans"; font-style:normal; font-weight:700; font-display:swap; src:url("../fonts/dm-sans-latin-700-normal.woff2") format("woff2"); }

@font-face{ font-family:"Cormorant Garamond"; font-style:normal; font-weight:600; font-display:swap; src:url("../fonts/cormorant-garamond-latin-600-normal.woff2") format("woff2"); }
@font-face{ font-family:"Cormorant Garamond"; font-style:normal; font-weight:700; font-display:swap; src:url("../fonts/cormorant-garamond-latin-700-normal.woff2") format("woff2"); }

@font-face{ font-family:"Amiri"; font-style:normal; font-weight:400; font-display:swap; src:url("../fonts/amiri-arabic-400-normal.woff2") format("woff2"); }
@font-face{ font-family:"Amiri"; font-style:normal; font-weight:700; font-display:swap; src:url("../fonts/amiri-arabic-700-normal.woff2") format("woff2"); }

/* -----------------------------------------------------------------------------
   3. RESET / BASE
   scroll-padding-top is STATIC on purpose: a cross-page /services#anchor scroll
   happens before DOMContentLoaded, so a JS-measured value would arrive too
   late. It also covers the no-JS case. assets/js/main.js does not measure the
   header; if it ever does, it must write to this same property (they override,
   never stack).
   -------------------------------------------------------------------------- */
*,*::before,*::after{ box-sizing:border-box; }
html{
  -webkit-text-size-adjust:100%; text-size-adjust:100%;
  scroll-behavior:smooth; scroll-padding-top:var(--header-offset);
}
html,body{ margin:0; padding:0; }
body{
  font-family:"DM Sans",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  font-weight:400;
  font-size:var(--fs-body);
  color:var(--color-text);
  line-height:var(--lh-body);
  background:var(--color-off-white);
  overflow-x:hidden; /* belt-and-braces: never horizontal scroll */
  min-height:100vh;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}
img,svg,video,iframe{ max-width:100%; }
img,video{ height:auto; display:block; }
a{ color:var(--color-link); text-decoration:none; transition:color var(--t-fast); }
a:hover{ color:var(--color-link-hover); }
ul,ol{ margin:0; padding:0; }
li{ list-style:none; }
button{ font-family:inherit; cursor:pointer; border:none; background:none; color:inherit; }
input,textarea,select{ font-family:inherit; }
hr{ border:none; border-top:1px solid var(--color-border); margin:var(--sp-5) 0; }
::selection{ background:var(--color-secondary-light); color:var(--color-gray-900); }
:target{ scroll-margin-top:var(--header-offset); }

/* Visible focus ring: 3.7:1 teal on light grounds, 4.9:1 gold on dark ones */
a:focus-visible,button:focus-visible,input:focus-visible,textarea:focus-visible,select:focus-visible,[tabindex]:focus-visible{
  outline:3px solid var(--color-primary-light);
  outline-offset:2px;
  border-radius:var(--radius-sm);
}
.btn:focus-visible,
.quick-bar__item:focus-visible,
.page-numbers:focus-visible{ outline-offset:3px; border-radius:var(--radius-pill); }
.section--dark :focus-visible,
.panel--dark :focus-visible,
.quick-bar :focus-visible,
.site-footer :focus-visible,
.top-bar :focus-visible,
.app-banner :focus-visible,
.page-hero :focus-visible,
.hero :focus-visible{
  outline-color:var(--color-secondary-light);
}

/* Body scroll lock while the mobile drawer is open (toggled by main.js) */
body.is-locked{ overflow:hidden; }

/* -----------------------------------------------------------------------------
   4. TYPOGRAPHY — Cormorant Garamond display scale over DM Sans body
   -------------------------------------------------------------------------- */
h1,h2,h3,.font-display{
  font-family:"Cormorant Garamond",Georgia,"Times New Roman",serif;
  font-weight:700; color:var(--color-heading);
  line-height:var(--lh-display); letter-spacing:-.01em;
  margin:0 0 .5em;
}
h4,h5,h6{
  font-family:"DM Sans",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  font-weight:600; color:var(--color-heading); line-height:1.35; margin:0 0 .5em;
}
h1{ font-size:var(--fs-display-xl); }
h2{ font-size:var(--fs-display-lg); }
h3{ font-size:var(--fs-display-md); }
h4{ font-size:var(--fs-display-sm); }
h5{ font-size:1.05rem; }
h6{ font-size:.95rem; }
p{ margin:0 0 1.15rem; }
p:last-child{ margin-bottom:0; }
strong,b{ font-weight:600; }
small{ font-size:.85rem; }

/* Body measure — prose never runs wider than 68ch */
.lead,
.card__text,
.hero__subtitle,
.page-hero__subtitle,
.section-heading__subtitle,
.panel p,
.media-row__body p,
.list-row__text,
.section > .container > p,
.container--narrow > p{ max-width:var(--measure); }
.u-center > p,
p.u-center,
.section-heading--center .section-heading__subtitle{ margin-inline:auto; }

.lead{ font-size:var(--fs-lead); color:var(--color-text-secondary); line-height:1.75; }

blockquote{
  margin:var(--sp-4) 0; padding:var(--sp-3) var(--sp-4);
  border-left:3px solid var(--color-secondary);
  background:var(--color-secondary-lighter);
  border-radius:0 var(--radius-sm) var(--radius-sm) 0;
  color:var(--color-text-secondary);
}
blockquote cite{ display:block; margin-top:var(--sp-1); font-style:normal; font-size:.9rem; color:var(--color-gold-text); font-weight:600; }

/* The client's own Arabic and Urdu only — the theme never adds any. This is
   also the theme's entire RTL mechanism (in place of a main-rtl.css) and the
   only consumer of the shipped Amiri face. Never track joined script. */
.text-arabic,.arabic{
  font-family:"Amiri","Noto Naskh Arabic",serif;
  direction:rtl; line-height:1.9;
  letter-spacing:normal;
}

/* -----------------------------------------------------------------------------
   5. EDITOR PROSE — what admin-typed content needs back after §3's reset
   Scope: the `page-content` class page.php (and index.php's singular branch)
   passes to post_class(), i.e. everything the_content() prints. §3 zeroes ul/ol
   margins and sets li{list-style:none} for the theme's own list components; a
   client's typed <ul> would otherwise render as unindented paragraphs with no
   bullets. Also styles the alignment and caption classes the block editor emits
   without any template asking for them.
   -------------------------------------------------------------------------- */
.page-content ul{ margin:0 0 1.15rem; padding-left:1.5rem; list-style:disc outside; }
.page-content ol{ margin:0 0 1.15rem; padding-left:1.5rem; list-style:decimal outside; }
.page-content li{ list-style:inherit; margin-bottom:.4rem; }
.page-content ul ul{ list-style-type:circle; }
.page-content ul ul ul{ list-style-type:square; }
.page-content li > ul,
.page-content li > ol{ margin-block:.4rem; }
.page-content li:last-child{ margin-bottom:0; }

.page-content figure{ margin:0 0 1.15rem; }
.page-content img{ border-radius:var(--radius-card); }
.page-content figcaption,
.page-content .wp-caption-text{
  margin-top:.5rem; font-size:var(--fs-small);
  color:var(--color-text-muted); text-align:center;
}
.page-content .alignleft{ float:left; margin:.35rem var(--sp-4) var(--sp-3) 0; }
.page-content .alignright{ float:right; margin:.35rem 0 var(--sp-3) var(--sp-4); }
.page-content .aligncenter{ display:block; margin-inline:auto; }
.page-content::after{ content:""; display:block; clear:both; } /* contain the floats */
.page-content > *:last-child{ margin-bottom:0; }

/* -----------------------------------------------------------------------------
   6. LAYOUT — container / section / grid / the capped slider column
   One container width sitewide; never nest two containers.
   -------------------------------------------------------------------------- */
.container{ width:100%; max-width:var(--container); margin-inline:auto; padding-inline:var(--container-pad); }
.container--narrow{ max-width:var(--container-narrow); }

.section{ padding-block:var(--space-section); position:relative; }
.section--tight{ padding-block:var(--space-section-tight); }
.section--cream{ background:var(--color-cream); }
.section--dark{ background:var(--color-primary-dark); color:var(--color-white); }
.section--dark h1,.section--dark h2,.section--dark h3,.section--dark h4,
.section--dark .panel__title{ color:var(--color-white); }
.section--dark p,.section--dark li{ color:rgba(255,255,255,.88); } /* 6.6:1 */
/* Plain links only — never override button or tile text colours on dark ground */
.section--dark a:not(.btn):not(.app-stores__btn):not(.quick-bar__item):not(.list-row){ color:var(--color-secondary-light); } /* 4.9:1 */
.section--dark a:not(.btn):not(.app-stores__btn):not(.quick-bar__item):not(.list-row):hover{ color:var(--color-white); }
/* Teal links clear AA on cream at 4.84:1; the dark teal is 7.25:1 — use it */
.section--cream a:not(.btn):not(.quick-bar__item):not(.list-row){ color:var(--color-primary-dark); }

/* Dark surfaces win over component defaults. Components further down set
   dark-on-light colours at the same specificity as `.section--dark p`, so these
   two-class selectors keep every one of them AA-readable on teal. */
.section--dark .section-heading__title,
.panel--dark .section-heading__title{ color:var(--color-white); }
.section--dark .section-heading__subtitle,
.panel--dark .section-heading__subtitle,
.section--dark .lead,
.panel--dark .lead,
.section--dark .small,
.panel--dark .small,
.section--dark .media-row__body p,
.panel--dark .media-row__body p{ color:rgba(255,255,255,.88); }
.section--dark .section-heading__eyebrow,
.panel--dark .section-heading__eyebrow{ color:var(--color-secondary-light); }

/* Patterned section — the Islamic tile, decorative only */
.section--patterned::before{
  content:""; position:absolute; inset:0; z-index:0;
  background-image:url("../images/patterns/islamic-pattern.svg");
  background-repeat:repeat; background-size:240px 240px;
  opacity:.04; pointer-events:none;
}
.section--dark.section--patterned::before{ opacity:.07; }
.section--patterned > *{ position:relative; z-index:1; }

/* --2 and --3 stay auto-fit: their consumers (index.php, search.php) carry a
   VARIABLE post count, and there a row of 3 correctly becomes 2 then 1.
   --4 is a different case and must NOT be auto-fit. It always holds exactly
   FOUR items — the client's four service names, page-services.php:95 — and
   auto-fit landed three across with the fourth orphaned across a wide band of
   real widths. At a 1024px viewport the container content box is 944px (929px
   once a 15px scrollbar is out) and --gap resolves to 30.72px, so the grid
   fitted floor((944+30.72)/(240+30.72)) = 3 tracks and "Youth Development
   Service" dropped to its own row; the orphan window ran from about 880px to
   1150px. DESIGN-LANGUAGE §3 forbids 3-then-1 outright and 1024px is one of
   PLAN §6's required test widths. Explicit column steps instead, as MCCSD
   does: 1 -> 2 (640px) -> 4 (1024px), both breakpoints in §29 beside
   .gallery-grid's and .stats-grid's, which had the identical defect. */
.grid{ display:grid; grid-template-columns:1fr; gap:var(--gap); }
.grid--2{ grid-template-columns:repeat(auto-fit,minmax(min(100%,26rem),1fr)); }
.grid--3{ grid-template-columns:repeat(auto-fit,minmax(min(100%,20rem),1fr)); }
.grid--4{ grid-template-columns:1fr; }

/* THE CAPPED SLIDER COLUMN (the Nur Ul Islam .slides-column pattern).
   The `slider` widget (slide-2) renders ONE portrait flyer. Full-container
   width it is marooned in white space on a wide screen, and — far worse — its
   height tracks its own width steeply below its 640px internal breakpoint
   (measured: 1.494 x width - 68). Capping the column at 460px pins the iframe
   at a fixed 458px, so the frame height becomes a single flat figure (§16).
   Below 640px the column is simply the container width and the viewport-slope
   floor in §16 covers it. The cap and that floor switch at the SAME breakpoint:
   move them together or the frame clips. */
.slides-column{ width:100%; }
@media (min-width:640px){
  .slides-column{ max-width:var(--slides-cap); margin-inline:auto; }
}

/* -----------------------------------------------------------------------------
   7. BUTTONS — fully round, 52px minimum, hover lift
   -------------------------------------------------------------------------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:.4rem;
  font-family:"DM Sans",system-ui,sans-serif; font-weight:600; font-size:1rem; line-height:1.25;
  padding:.85rem var(--sp-5); min-height:52px;
  border-radius:var(--radius-pill); border:2px solid transparent;
  text-align:center; cursor:pointer;
  -webkit-appearance:none; appearance:none;
  transition:background var(--t-fast),color var(--t-fast),border-color var(--t-fast),transform var(--t-fast),box-shadow var(--t-fast);
}
.btn:hover{ transform:translateY(-2px); }
.btn:active{ transform:translateY(0); }

.btn--primary{ background:var(--color-cta); color:var(--color-cta-text); border-color:var(--color-cta); } /* 5.5:1 */
.btn--primary:hover{ background:var(--color-cta-hover); border-color:var(--color-cta-hover); color:var(--color-cta-text); box-shadow:var(--shadow-card); }

.btn--secondary{ background:var(--color-secondary); color:var(--color-gray-900); border-color:var(--color-secondary); } /* 6.3:1 */
.btn--secondary:hover{ background:var(--color-secondary-light); border-color:var(--color-secondary-light); color:var(--color-gray-900); box-shadow:var(--shadow-card); } /* 9.3:1 */

.btn--outline{ background:transparent; color:var(--color-primary); border-width:1.5px; border-color:var(--color-primary); }
.btn--outline:hover{ background:var(--color-primary); color:var(--color-white); }

.btn--ghost-light{ background:transparent; color:var(--color-white); border-width:1.5px; border-color:rgba(255,255,255,.65); }
.btn--ghost-light:hover{ background:var(--color-white); color:var(--color-primary-dark); border-color:var(--color-white); }

.btn--donate{ background:var(--color-secondary); color:var(--color-gray-900); border-color:var(--color-secondary); font-weight:700; }
.btn--donate:hover{ background:var(--color-secondary-light); border-color:var(--color-secondary-light); color:var(--color-gray-900); box-shadow:var(--shadow-card); }

.btn--lg{ font-size:1.1rem; padding:1rem 2.25rem; min-height:56px; }
.btn--block{ display:flex; width:100%; }
.btn[disabled],.btn:disabled,.btn.is-loading{ opacity:.65; cursor:not-allowed; transform:none; box-shadow:none; }

/* -----------------------------------------------------------------------------
   8. SECTION HEADING — the one heading block, so titles align across sections
   The eyebrow is tracked caps and nothing else: the 32px gold rule the old
   ::before/::after drew was invented decoration and is gone.
   Markup (template-parts/components/section-heading.php):
     .section-heading[--center][--light] > p.section-heading__eyebrow
       + h2.section-heading__title + p.section-heading__subtitle
   -------------------------------------------------------------------------- */
.section-heading{ margin-bottom:var(--space-block); max-width:var(--measure); }
.section-heading--center{ margin-inline:auto; text-align:center; }
.section-heading__eyebrow,
.hero__eyebrow{
  display:block; margin:0 0 var(--sp-2);
  font-family:"DM Sans",system-ui,sans-serif;
  font-weight:500; font-size:var(--fs-eyebrow);
  letter-spacing:.14em; text-transform:uppercase;
}
.section-heading__eyebrow{ color:var(--color-gold-text); } /* 7.0:1 on white */
/* The hero eyebrow sits on the PHOTO, where the wash thins to .58 alpha at the
   right-hand end, so the mid gold would drop below AA there. The light cream
   gold clears it across the whole run. */
.hero__eyebrow{ color:var(--color-secondary-lighter); }
.section-heading__title{ margin:0 0 var(--sp-2); font-size:var(--fs-display-lg); }
.section-heading__subtitle{ font-size:1.08rem; color:var(--color-text-secondary); margin:0; }

/* Inside .media-row__body the column is flex with a gap — margins do not
   collapse there, they ADD to it. Zero the heading's own margin so the gap
   alone owns the rhythm. */
.media-row__body > .section-heading{ margin-bottom:0; }

.section-heading--light .section-heading__title{ color:var(--color-white); }
.section-heading--light .section-heading__subtitle{ color:rgba(255,255,255,.88); }
.section-heading--light .section-heading__eyebrow{ color:var(--color-secondary-light); }

/* -----------------------------------------------------------------------------
   9. CARDS — 18px radius, hairline border, soft shadow, hover lift
   No .card__icon: the four service cards carry the client's own service name
   in display type plus the "Coming Soon" badge, not a drawn glyph.
   -------------------------------------------------------------------------- */
.card{
  position:relative; display:flex; flex-direction:column;
  background:var(--color-white); border:1px solid var(--color-border);
  border-radius:var(--radius-card); overflow:hidden;
  box-shadow:var(--shadow-card);
  transition:transform var(--t),box-shadow var(--t),border-color var(--t);
  height:100%;
}
.card:hover,.card:focus-within{ transform:translateY(-4px); box-shadow:var(--shadow-card-hover); border-color:var(--color-secondary-light); }
.card__body{ display:flex; flex-direction:column; gap:.6rem; padding:var(--pad-card); flex:1 1 auto; }
.card__title{ margin:0; font-size:var(--fs-display-sm); }
.card__text{ margin:0; color:var(--color-text-secondary); font-size:1rem; }
.card__link{
  margin-top:auto; align-self:flex-start;
  display:inline-flex; align-items:center; gap:.35rem;
  font-weight:600; font-size:.95rem; color:var(--color-gold-text);
  padding-top:var(--sp-1);
}
.card__link::after{ content:"\2192"; transition:transform var(--t-fast); } /* plain arrow — the one allowed affordance */
.card__link:hover{ color:var(--color-primary-dark); }
.card__link:hover::after{ transform:translateX(4px); }

/* "Coming Soon" — the client's own badge on the four service names */
.card__badge{
  display:inline-flex; align-self:flex-start; align-items:center;
  padding:.3rem .75rem; border-radius:var(--radius-pill);
  font-family:"DM Sans",system-ui,sans-serif; font-size:.7rem; font-weight:600;
  letter-spacing:.06em; text-transform:uppercase;
  background:var(--color-secondary-lighter); color:var(--color-gold-text);
  border:1px solid var(--color-secondary-light);
}

/* Photo card (.card--photo) — 16:10 media with a quiet hover zoom.
   display:block is required: .card__media may sit on an <a>, and on an inline
   box neither aspect-ratio nor overflow:hidden applies. */
.card__media{ display:block; position:relative; aspect-ratio:16/10; overflow:hidden; background:var(--color-gray-100); }
.card__media img{ width:100%; height:100%; object-fit:cover; transition:transform var(--t-zoom); }
.card:hover .card__media img,
.card:focus-within .card__media img{ transform:scale(1.04); }
img.card__media{ width:100%; object-fit:cover; }
.card--photo .card__media{ border-bottom:1px solid var(--color-border); }
.card--photo .card__body{ gap:.5rem; }

/* -----------------------------------------------------------------------------
   10. PANEL + SPLIT — the equal-height two-column band
   Home: the `prayer` widget in .split__main beside a .panel--dark "Visit Us"
   carrying the address and phone exactly as the footer has them.
   -------------------------------------------------------------------------- */
.split{
  display:grid; grid-template-columns:1fr; gap:var(--gap);
  align-items:stretch;
}
.split__main,
.split__aside{ min-width:0; display:flex; flex-direction:column; gap:var(--gap-tight); }
.split__main > .panel,
.split__aside > .panel,
.split__main > .widget-frame,
.split__aside > .widget-frame{ flex:1 1 auto; }

.panel{
  display:flex; flex-direction:column; gap:var(--sp-3);
  padding:var(--pad-card);
  background:var(--color-white);
  border:1px solid var(--color-border);
  border-radius:var(--radius-card);
  box-shadow:var(--shadow-card);
}
.panel__title{ margin:0; font-size:var(--fs-display-md); color:var(--color-heading); }
.panel > .widget-frame{ margin-top:auto; }

.panel--dark{
  background:var(--color-primary-dark);
  border-color:transparent;
  color:rgba(255,255,255,.88);
}
.panel--dark .panel__title,
.panel--dark h2,.panel--dark h3,.panel--dark h4{ color:var(--color-white); }
.panel--dark p,.panel--dark li{ color:rgba(255,255,255,.88); }
.panel--dark a:not(.btn){ color:var(--color-secondary-light); }
.panel--dark a:not(.btn):hover{ color:var(--color-white); }
/* A paragraph that is nothing but one link is a single-destination row, not a
   link inside a sentence — give it the 44px tap target. */
.panel--dark p > a:only-child{ display:inline-flex; align-items:center; min-height:44px; }

/* -----------------------------------------------------------------------------
   11. LIST ROWS — hairline typographic rows (the four services, contact details)
   Expected markup: .list-rows > .list-row (an <a> where it is a destination,
   a <div> where it is not) containing .list-row__name, .list-row__text, an
   optional .card__badge, and an optional decorative arrow marked
   aria-hidden="true". Rows with no arrow collapse that column to zero.
   -------------------------------------------------------------------------- */
.list-rows{ border-top:1px solid var(--color-border); container-type:inline-size; }
.list-row{
  display:grid; grid-template-columns:1fr; gap:.3rem var(--sp-4);
  width:100%; padding:var(--sp-3) var(--sp-2);
  border-bottom:1px solid var(--color-border);
  color:var(--color-text);
  transition:background var(--t-fast);
}
.list-row:hover,
.list-row:focus-visible{ background:var(--color-primary-lighter); }
.list-row__name{
  margin:0;
  font-family:"Cormorant Garamond",Georgia,serif; font-weight:700;
  font-size:var(--fs-display-sm); line-height:1.2; letter-spacing:-.01em;
  color:var(--color-heading);
}
.list-row__text{ margin:0; color:var(--color-text-secondary); font-size:1rem; }
.list-row > [aria-hidden="true"]{
  display:inline-block; align-self:center; justify-self:start;
  color:var(--color-gold-text); font-size:1.15rem; line-height:1;
  transition:transform var(--t-fast);
}
.list-row:hover > [aria-hidden="true"]{ transform:translateX(4px); }

/* Name beside description only where the row itself is wide enough — a narrow
   list (contact details inside .split__aside) keeps the stacked layout. */
@container (min-width:34rem){
  .list-row{ grid-template-columns:minmax(10rem,18rem) 1fr auto; align-items:baseline; }
  .list-row > [aria-hidden="true"]{ align-self:center; justify-self:end; }
}

/* Rows on dark ground */
.panel--dark .list-rows,
.section--dark .list-rows{ border-top-color:rgba(255,255,255,.18); }
.panel--dark .list-row,
.section--dark .list-row{ border-bottom-color:rgba(255,255,255,.18); color:rgba(255,255,255,.88); }
.panel--dark .list-row:hover,
.section--dark .list-row:hover{ background:rgba(255,255,255,.08); }
.panel--dark .list-row__name,
.section--dark .list-row__name{ color:var(--color-white); }
.panel--dark .list-row__text,
.section--dark .list-row__text{ color:rgba(255,255,255,.88); }
.panel--dark .list-row > [aria-hidden="true"],
.section--dark .list-row > [aria-hidden="true"]{ color:var(--color-secondary-light); }
.panel--dark .card__badge,
.section--dark .card__badge{
  background:rgba(255,255,255,.12); color:var(--color-secondary-light);
  border-color:rgba(255,255,255,.28);
}

/* -----------------------------------------------------------------------------
   12. QUICK BAR + QUICK-LINK TILES
   .quick-bar is the hero-anchored destination row (Prayer Times, Events,
   Fundraising, Donate — TEXT ONLY). It works three ways: as the last child of
   .hero--tall, as a sibling that follows the hero (pulled onto its bottom
   edge), and standalone inside a .container with .quick-bar--boxed — which is
   the form 404.php:75 uses, its only consumer.
   (This comment used to name a .quick-links / .quick-link tile grid as the 404
   page's component. It was not: 404.php uses .quick-bar--boxed, no template
   emitted either class, and both rules were dead CSS. Deleted 2026-10-22.)
   -------------------------------------------------------------------------- */
.quick-bar{
  width:100%;
  background:rgba(1,86,112,.86); /* rgba of --color-primary-dark; white stays >=4.8:1 even over a blown-out hero highlight */
  border-top:1px solid rgba(255,255,255,.16);
  border-bottom:1px solid rgba(255,255,255,.08);
}
.quick-bar__list{
  display:grid; grid-template-columns:repeat(2,1fr); /* 2x2 on mobile */
  width:100%; max-width:var(--container);
  margin-inline:auto; padding-inline:var(--container-pad);
  gap:0;
}
/* Never double-pad when a template nests the list inside a .container */
.container .quick-bar__list{ max-width:none; margin-inline:0; padding-inline:0; }
/* The markup is ul > li > a.quick-bar__item, so the <li> is the grid item: let
   the link fill its cell, or a wrapped label leaves the hover ground short. */
.quick-bar__list > li{ display:flex; }
.quick-bar__list > li > .quick-bar__item{ flex:1 1 auto; }

.quick-bar__item{
  display:flex; align-items:center; justify-content:center;
  gap:.4rem; min-height:calc(var(--quick-bar-h) - 2px); padding:var(--sp-2) var(--sp-3);
  text-align:center; color:var(--color-white);
  transition:background var(--t-fast),color var(--t-fast);
}
.quick-bar__item:hover,
.quick-bar__item:focus-visible{ background:rgba(255,255,255,.12); color:var(--color-white); }
.quick-bar__label{
  font-family:"DM Sans",system-ui,sans-serif; font-weight:600; font-size:.95rem;
  letter-spacing:.01em; line-height:1.3;
}

/* Attached to the hero: inside .hero--tall, or as the hero's next sibling.
   As a sibling it is pulled up by exactly its own height so it lands on the
   hero's bottom edge and the next section still starts below the hero. The
   negative margin means the hero must reserve --quick-bar-h in its own bottom
   padding — that reserve lives in §29 beside the breakpoint that switches the
   bar to a single row. */
.hero--tall > .quick-bar{ position:relative; z-index:2; }
.hero + .quick-bar,
.hero--tall + .quick-bar{ position:relative; z-index:2; margin-top:calc(var(--quick-bar-h) * -1); }

/* Standalone (404): a free-standing block takes the card radius like every
   other block, and a SOLID ground — there is no photo under it. */
.quick-bar--boxed{ background:var(--color-primary-dark); border-radius:var(--radius-card); overflow:hidden; }

/* -----------------------------------------------------------------------------
   13. (REMOVED 2026-10-22) CAROUSEL
   .carousel / __track / __item / __btn were defined and emitted by nothing: no
   template in the theme renders a carousel, and .carousel__btn was already
   display:none at every width because assets/js/main.js has no stepper. 27
   lines of CSS for a component that did not exist.
   The section NUMBER is kept on purpose — PHP docblocks across the theme cite
   these numbers ("main.css §16", "§19", "§29"), so renumbering would silently
   make every one of those references wrong. §23 and §24 are the same.
   If a photo rail is ever wanted, the answers already here are the `slider`
   Rawdah widget (§16, real client flyers) or .gallery-grid (§22).
   -------------------------------------------------------------------------- */

/* -----------------------------------------------------------------------------
   14. PAGE HERO (inner pages) + BREADCRUMBS
   Default = NO image: solid --color-primary-dark + the pattern ::before +
   a token-based ::after overlay. When a template passes an image it emits ONLY
   inline background-image:url(...); the overlay keeps text AA-readable.
   -------------------------------------------------------------------------- */
.page-hero{
  position:relative; isolation:isolate;
  background-color:var(--color-primary-dark);
  background-size:cover; background-position:center; background-repeat:no-repeat;
  padding-block:clamp(3.5rem,8vw,6rem);
  color:var(--color-white); overflow:hidden;
}
.page-hero::after{
  content:""; position:absolute; inset:0; z-index:-1;
  /* rgba fallback of --color-primary-dark (#015670), then the token-based mix */
  background:linear-gradient(180deg,rgba(1,86,112,.84),rgba(1,86,112,.93));
  background:linear-gradient(180deg,
    color-mix(in srgb, var(--color-primary-dark) 84%, transparent),
    color-mix(in srgb, var(--color-primary-dark) 93%, transparent));
}
.page-hero::before{
  content:""; position:absolute; inset:0; z-index:0;
  background-image:url("../images/patterns/islamic-pattern.svg");
  background-repeat:repeat; background-size:200px 200px;
  opacity:.07; pointer-events:none;
}
/* NO max-width here. This element also carries .container
   (template-parts/components/page-hero.php:62 emits `class="container
   page-hero__inner"`), both selectors are 0,1,0 and this section comes after
   §6, so an 880px cap here beat .container's 1200px while .container's own
   margin-inline:auto kept centring it: measured at 1280px, the hero column was
   left 192 / width 880 and the <h1> started at x=224 while the first section
   below started its content at x=64 — every page title sat 160px right of the
   prose under it (64px at 1024px), on all nine inner pages plus page.php,
   index.php, search.php and 404.php. roic-theme/assets/css/main.css:605 has
   exactly this rule with no cap on the same markup. The strap line keeps its
   own measure: .page-hero__subtitle is in §4's max-width:var(--measure) list,
   which caps the TEXT without moving the column. */
.page-hero__inner{ position:relative; z-index:1; }
.page-hero__title{ color:var(--color-white); margin:0 0 var(--sp-2); font-size:var(--fs-display-xl); }
.page-hero__subtitle{ color:rgba(255,255,255,.88); font-size:var(--fs-lead); margin:0; }

.breadcrumbs{
  display:flex; flex-wrap:wrap; align-items:center; gap:.45rem;
  font-size:.875rem; margin-bottom:var(--sp-3); color:rgba(255,255,255,.8);
}
.breadcrumbs__item{ color:rgba(255,255,255,.8); }
a.breadcrumbs__item:hover{ color:var(--color-white); }
.breadcrumbs__item a{ color:rgba(255,255,255,.8); }
.breadcrumbs__item a:hover{ color:var(--color-white); }
.breadcrumbs__sep{ color:rgba(255,255,255,.5); user-select:none; }
.breadcrumbs__current{ color:var(--color-white); font-weight:600; }
/* Breadcrumbs outside the hero (a light page, e.g. page.php) */
.breadcrumbs--light{ color:var(--color-text-muted); margin-top:var(--sp-3); }
.breadcrumbs--light .breadcrumbs__item,
.breadcrumbs--light .breadcrumbs__item a{ color:var(--color-text-muted); }
.breadcrumbs--light .breadcrumbs__item a:hover{ color:var(--color-primary-dark); }
.breadcrumbs--light .breadcrumbs__current{ color:var(--color-gold-text); }
.breadcrumbs--light .breadcrumbs__sep{ color:var(--color-gray-300); }

/* -----------------------------------------------------------------------------
   15. HOME HERO — full-bleed photo, deep-teal wash, bottom-aligned content
   THE GREETING LOCKUP IS CLIENT CONTENT AND MUST SURVIVE BYTE-IDENTICAL: the
   Urdu line, then the Arabic line (both carrying lang/dir and .text-arabic, so
   Amiri + direction:rtl apply), then the English H1 as .hero__display. The two
   greeting lines live in .hero__welcome (the shared name) — .hero__greeting is
   accepted as a synonym because front-page.php already emits it.
   Both RTL lines keep the same LEFT column edge as the H1: dir="rtl" orders the
   script, text-align keeps the margin. Without that they hug the right side of
   the hero column and the lockup looks broken.
   -------------------------------------------------------------------------- */
.hero{
  position:relative; isolation:isolate; overflow:hidden;
  display:flex; flex-direction:column; justify-content:center;
  min-height:clamp(32rem,72vh,44rem);
  color:var(--color-white);
  background-color:var(--color-primary-dark);
}
/* Tall variant: content on the bottom edge so the quick bar can attach. The
   lockup is three lines plus two CTAs, so it is a little taller than ROIC's. */
.hero--tall{
  justify-content:flex-end;
  min-height:clamp(33rem,78vh,47rem);
}
.hero__bg{
  position:absolute; inset:0; z-index:-2;
  background-size:cover; background-position:center; background-repeat:no-repeat;
  animation:addawah-kenburns 24s var(--ease) infinite alternate;
  will-change:transform;
}
img.hero__bg{ width:100%; height:100%; object-fit:cover; }
/* banners/hero-home.webp is 1360x1020, so `cover` already upscales it ~1.4x at
   1920px. The old 1.02 -> 1.12 zoom compounded that past legibility; 1.02 ->
   1.05 keeps the pan visible without softening the image. */
@keyframes addawah-kenburns{
  from{ transform:scale(1.02) translateY(0); }
  to{ transform:scale(1.05) translateY(-1%); }
}
.hero::after{
  content:""; position:absolute; inset:0; z-index:-1;
  /* rgba overlay of --color-primary-dark (#015670) for AA text contrast */
  background:linear-gradient(100deg,rgba(1,86,112,.9) 0%,rgba(1,86,112,.78) 55%,rgba(1,86,112,.58) 100%);
}
.hero__content{
  position:relative; z-index:1; max-width:44rem;
  padding-block:clamp(4rem,10vw,6rem);
}
/* The bottom value is the FLUSH-bar padding used below 768px. From 768px up the
   bar is pulled onto the hero by --quick-bar-h, so §29 replaces this
   padding-bottom with one that reserves the bar's height. */
.hero--tall .hero__content{ padding-block:clamp(5rem,12vw,7rem) clamp(2.5rem,6vw,4rem); }

.hero__display,
.hero__title{ /* .hero__title = the synonym front-page.php currently emits */
  color:var(--color-white);
  font-size:var(--fs-display-hero);
  line-height:1.05; letter-spacing:-.01em;
  margin:0 0 var(--sp-4);
}
/* The one accent word, taken from the client's own headline — hero.php wraps
   the leading word ("Welcome") in <em>. It is a COLOUR accent, not an italic
   one: assets/fonts/ holds eight faces and every one is -normal, and §2
   declares font-style:normal on all of them, so `font-style:italic` only got
   the browser to shear Cormorant Garamond into a fake oblique. The theme
   already rejects that elsewhere for the same reason (page-donate.php's
   docblock moved the verse out of <em> over it), so the hero was contradicting
   the theme's own standard on its single largest piece of type.
   --color-secondary-light on the hero wash is 4.9:1 over the solid teal and
   3.8:1 in the worst case (the wash at .9 alpha over a blown-out highlight);
   the accent word sits at the left end, where the wash is thickest, and the
   display face is never smaller than 38.4px at weight 700, so AA large-text
   (3:1) holds across the whole run. Ship a real
   cormorant-garamond-latin-700-italic.woff2 and this can go back to italic. */
.hero__display em{ font-style:normal; color:var(--color-secondary-light); }

/* The client's two non-English welcome lines */
.hero__welcome,
.hero__greeting{
  display:flex; flex-direction:column; gap:var(--sp-1);
  margin:0 0 var(--sp-4); padding:0;
}
.hero__welcome-line,
.hero__welcome > p,.hero__welcome > li,.hero__welcome > span,
.hero__greeting > p,.hero__greeting > li,.hero__greeting > span{
  display:block; margin:0;
  color:rgba(255,255,255,.92);
  font-size:clamp(1.02rem,1.5vw,1.2rem);
  line-height:1.6;
}
/* Amiri needs a little more size and leading to match the Latin lines optically */
.hero__welcome .text-arabic,
.hero__welcome [dir="rtl"],
.hero__greeting .text-arabic,
.hero__greeting [dir="rtl"]{
  color:var(--color-secondary-light); /* 4.9:1 on the wash */
  font-size:clamp(1.15rem,2.2vw,1.6rem);
  line-height:1.85;
}
.hero__content [dir="rtl"]{ text-align:left; }

.hero__subtitle{ color:rgba(255,255,255,.9); font-size:var(--fs-lead); line-height:1.65; margin:0 0 var(--sp-5); }
.hero__actions{ display:flex; flex-wrap:wrap; gap:var(--sp-3); }

/* -----------------------------------------------------------------------------
   16. RAWDAH WIDGETS + MEASURED FRAME HEIGHTS
   RE-MEASURED 2026-10-22 against accessId 48beae61-0ea2-4d30-a2bd-c4d6a4502bcf
   (the client's own account) by loading each template at a controlled viewport
   width and reading document.body.scrollHeight.

   The Rawdah iframe cannot resize itself (it emits no postMessage), so the
   frame must be tall enough on its own. .widget-frame carries
   data-widget="<key>"; the iframe gets the MOBILE value inline from
   addawah_widget_min_height(), so the rules below need !important to beat that
   style attribute. Never put overflow:hidden on the wrapper — content must not
   be clipped if it grows. Re-measure whenever a widget starts scrolling inside
   its frame; more events or slides make these taller.

   CAVEAT, and it decides two of the rules below: these media queries key on
   VIEWPORT width, but each widget reflows on its OWN IFRAME width. For a
   full-container placement the iframe is
       min(1200, viewport - scrollbar) - 2 x clamp(1.25rem, 4vw, 2.5rem)
   i.e. about 80px narrower than the layout width from 1000px up, and a flat
   1136px once the container caps out at 1280px (§6, §29). Measured breakpoints
   in the widgets themselves sit at 640px and 1024px of IFRAME width, so the
   iframe only crosses 1024 once the VIEWPORT reaches 1104px + the scrollbar.
   That is why the third tier below is `min-width:1130px` and not 1024px:
     a media query matches on the viewport INCLUDING the scrollbar, so at a
     1024px viewport the iframe is 927px wide (1009 - 80 with a 15px bar) and
     still renders the TALL layout — and so does it at 1104px, where the iframe
     measures 1007px. 1130 - 17 - 80 = 1033px of iframe, clear of 1024.
   (Measured: prayer-7 526px at an iframe width of 1000 and 391px at 1024;
   event-5 819px at 1000 and 546px at 1024. Verified in-browser: at a 1104px
   viewport this page really does lay the iframe out at 1007px.)

   The SAME correction is needed at the widgets' OTHER internal breakpoint, 640,
   and the build had missed it there: a full-container iframe does not reach
   640px of width until the viewport is about 696px. Only one rule below really
   turns on content that changes at 640 — `events`, where event-5 goes from a
   635px single column to an 819px two-up — so only that one moved, to
   `min-width:696px`, with its arithmetic beside it. Nothing else wants moving:
   prayer, prayer_table, donation and fundraising differ by 22-82px either side
   of 640, which is inside their headroom, and `slider` is tallest JUST BELOW
   its own 640 breakpoint, so its 930px figure at a 640px viewport is correct
   and deliberate (see the note on that rule).
   Any widget moved into a narrower column needs its own column-scoped rule —
   the two that exist are at the end of this section.

   | key          | template                   | 375 | 639 | 768 | 944 | >=1024 iframe |
   |--------------|----------------------------|-----|-----|-----|-----|---------------|
   | prayer       | prayer-7                   | 558 | 558 | 526 | 526 | 391           |
   | prayer_table | prayer-2                   | 681 | 678 | 688 | 685 | 682           |
   | events       | event-5 (empty state)      | 635 | 635 | 819 | 819 | 546           |
   | donation     | donation-4                 | 422 | 419 | 438 | 435 | 438           |
   | fundraising  | fundraising-multi-portrait | 757 | 798 | 819 | 819 | 819           |
   | slider       | slide-2                    | 492 | 888 | 589 | 721 | 553 @1024     |

   slide-2 is the awkward one: it scales a portrait flyer with its own width in
   three linear bands — h = 1.494w - 68 below 640, 0.75w + 13 from 640 to 1023,
   0.5w + 41 from 1024 — so it is TALLEST just under each of its breakpoints
   (888px at an iframe width of 639). .slides-column (§6) is what tames it.

   The three gated keys — services (masjid-service-2, empty), live_stream
   (live-streaming-carousel, Rawdah's own promo video) and live_stream_inner
   (live-streaming, a Rawdah advert) — have NO rules here on purpose. There was
   nothing worth measuring. Measure the real content, add the key here AND in
   addawah_widget_min_height(), and only then switch its Customizer checkbox on.
   -------------------------------------------------------------------------- */
.widget-frame{ position:relative; width:100%; }
.rawdah-widget-container{
  width:100%; border-radius:var(--radius-card);
  background:var(--color-white); box-shadow:var(--shadow-card);
  border:1px solid var(--color-border);
}
.rawdah-widget-container iframe{ display:block; width:100%; border:none; border-radius:inherit; }
/* Inside a .panel the card chrome is already there — don't box a box */
.panel .rawdah-widget-container{ border:0; box-shadow:none; }
.rawdah-widget-placeholder{
  display:flex; align-items:center; justify-content:center;
  border:1px dashed var(--color-gray-300); border-radius:var(--radius-card);
  background:var(--color-cream); padding:var(--sp-6) var(--sp-4); text-align:center;
}
.rawdah-widget-placeholder__inner{ max-width:46ch; }
.rawdah-widget-placeholder__inner p{ margin:.25rem 0; color:var(--color-text-secondary); }
.small{ color:var(--color-text-muted); font-size:var(--fs-small); }

/* Base = the measured mobile figures (<640px viewport), matching
   addawah_widget_min_height() one-for-one. Change both together. */
.widget-frame[data-widget="prayer"] iframe{ min-height:610px !important; }
.widget-frame[data-widget="prayer_table"] iframe{ min-height:740px !important; }
.widget-frame[data-widget="events"] iframe{ min-height:695px !important; }
.widget-frame[data-widget="donation"] iframe{ min-height:475px !important; }
.widget-frame[data-widget="fundraising"] iframe{ min-height:815px !important; }
/* slide-2 below 640px: the container-width floor. need(viewport) =
   1.494 x (viewport - 2 x container-pad) - 68, and container-pad is 20px below
   a 500px viewport then 4vw above it. calc(139vw - 56px) clears that at every
   width below 640 — by +39px at 320, +33px at 375, +20px at 500 (tightest) and
   +22px at 639 — and the 545px floor keeps the smallest phones off the slope.
   This floor therefore depends on --container-pad: re-derive it if that token
   changes, and re-measure the slope if the client's slider gains slides. */
.widget-frame[data-widget="slider"] iframe{ min-height:max(545px,calc(139vw - 56px)) !important; }

/* 640px to 1129px. fundraising-multi-portrait is TALLEST here. event-5 is too,
   but not from 640 — its two-up regime starts at a 696px viewport, so it has
   its own block directly after this one. */
@media (min-width:640px){
  .widget-frame[data-widget="prayer_table"] iframe{ min-height:745px !important; }
  /* events is NOT here — it keys on 696px, see the rule below this block. */
  .widget-frame[data-widget="donation"] iframe{ min-height:490px !important; }
  .widget-frame[data-widget="fundraising"] iframe{ min-height:880px !important; }
  .widget-frame[data-widget="prayer"] iframe{ min-height:580px !important; }
  /* An UN-COLUMNED slider is 930px here. That is not a typo: between a 640px
     and a ~696px viewport the iframe is still under slide-2's own 640px
     breakpoint, where it measures up to 888px. Wrap the slider in
     .slides-column (§6) and the flat 670px rule at the end of this section
     applies instead — which is what every placement should do. */
  .widget-frame[data-widget="slider"] iframe{ min-height:930px !important; }
}

/* events: 696px, NOT 640px — the same viewport-vs-iframe correction the >=1130
   tier makes, applied at the bottom end where it was missing. event-5 reflows
   on its OWN iframe width, and both events placements are full-container
   (template-parts/home/events.php and page-events.php, each
   .container > .reveal > .widget-frame > .rawdah-widget-container > iframe), so
     iframe(V) = V - scrollbar - 2 x clamp(20px,4vw,40px) - 2px (the container's
                 1px border, each side)
   i.e. 53px narrower than the viewport at 640, rising with the 4vw padding
   (58px by 700).
   (Verified: at a 640px viewport the iframe measures ~587px, not 640 — still
   well inside event-5's narrow single-column regime, which the table above puts
   at 635px, while the old rule had already jumped the frame to 885px. That was
   ~250px of empty white box under the events list for every viewport from 640px
   up to about 700px, on two pages — the same dead-box defect PLAN §2b called
   out in the old map.)
   Solving for the viewport at which the iframe reaches event-5's own 640px
   breakpoint, with NO scrollbar and the border ignored — the EARLIEST crossing,
   and therefore the only safe one to key on:
     0.92 x V >= 640  ->  V >= 695.65  ->  696px
   Checked both sides: at 696px the iframe is 640.3px (696 - 55.68) and event-5
   is two-up, needing 819px; at 695px it is 639.4px and needs 635px, which the
   695px base covers with 9.4% headroom.
   Do NOT round this up to 700: at a 698-699px viewport the iframe is already
   past 640 and the base 695px would under-reserve by 124px, i.e. the widget
   would scroll inside its own frame, which PLAN §4 forbids outright. Rounding
   DOWN only costs a dead box, and a smaller one than before: on a browser with
   a 17px scrollbar the iframe does not cross 640 until a 717px viewport
   (0.92 x V - 19 >= 640), so 696-717 still reserves ~250px of white there — a
   ~21px window where it used to be ~77px (640-717). Nothing clips at any
   width, on any scrollbar.
   Re-measure against the client's real events before trusting either figure,
   and keep it in step with addawah_widget_min_height(). */
@media (min-width:696px){
  .widget-frame[data-widget="events"] iframe{ min-height:885px !important; }
}

/* >=1130px — the viewport width at which a full-container iframe finally
   crosses 1024px (scrollbar included, see the caveat above) and the widgets
   switch to their wide, shorter layouts. */
@media (min-width:1130px){
  .widget-frame[data-widget="prayer"] iframe{ min-height:440px !important; }
  .widget-frame[data-widget="prayer_table"] iframe{ min-height:740px !important; }
  .widget-frame[data-widget="events"] iframe{ min-height:600px !important; }
  .widget-frame[data-widget="slider"] iframe{ min-height:690px !important; }
  /* donation stays at 490 and fundraising at 880 — both are flat from 768px up */
}

/* COLUMN-SCOPED RULES (the caveat above). Both are measured, not derived.

   1. The slider inside the capped column: the iframe is a fixed 458px wide
      there, where slide-2 measures 616px. 670 gives it 8.8% headroom and one
      flat figure at every width from 640px up. More specific than the plain
      [data-widget="slider"] rules, so it wins wherever both apply.
   2. The prayer widget inside .split: that column is
      (container - gap) x 1.3/2.3 = 516px at a 1024px viewport and 624px from
      1280px up — always under prayer-7's own 1024px breakpoint, so it renders
      the 558px layout, NOT the 391px one the plain >=1130 rule reserves for.
      605 gives 8.4% headroom. Put the widget frame straight into .split__main
      (no .panel wrapper): a .panel's --pad-card would take another ~64px off
      the iframe and this figure with it. */
@media (min-width:640px){
  .slides-column .widget-frame[data-widget="slider"] iframe{ min-height:670px !important; }
}
@media (min-width:1024px){
  .split .widget-frame[data-widget="prayer"] iframe{ min-height:605px !important; }
}

/* -----------------------------------------------------------------------------
   17. HEADER — slim, sticky, compresses on scroll
   -------------------------------------------------------------------------- */
.site-header{
  position:sticky; top:0; z-index:1000; width:100%;
  background:var(--color-white);
  border-bottom:1px solid var(--color-border);
  transition:box-shadow var(--t-fast);
}
.site-header.is-stuck{ box-shadow:var(--shadow); border-bottom-color:transparent; }

/* App banner */
.app-banner{
  background:var(--color-primary-dark); color:var(--color-white);
  font-size:.9rem; position:relative;
}
.app-banner > .container,
.app-banner .container{
  display:flex; align-items:center; justify-content:center; gap:var(--sp-2) var(--sp-3);
  flex-wrap:wrap; padding-block:.55rem; position:relative; text-align:center;
  padding-right:3.25rem; /* room for the absolute 44px close button at every width */
}
.app-banner__text{ margin:0; color:rgba(255,255,255,.92); max-width:none; }
.app-banner__btn{
  display:inline-flex; align-items:center;
  background:var(--color-secondary); color:var(--color-gray-900);
  font-weight:600; font-size:.82rem; padding:.55rem 1.1rem; min-height:44px;
  border-radius:var(--radius-pill); white-space:nowrap;
  transition:background var(--t-fast),color var(--t-fast);
}
.app-banner__btn:hover{ background:var(--color-secondary-light); color:var(--color-gray-900); }
.app-banner__close{
  position:absolute; right:.5rem; top:50%; transform:translateY(-50%);
  width:44px; height:44px;
  display:inline-flex; align-items:center; justify-content:center;
  color:var(--color-white); border-radius:var(--radius-pill); line-height:1;
}
.app-banner__close:hover{ background:rgba(255,255,255,.14); }
.app-banner__close svg{ width:16px; height:16px; } /* close X — a functional control */
.app-banner.is-hidden{ display:none; }

/* Top bar — plain type, no icon slots */
.top-bar{ background:var(--color-primary); color:var(--color-white); font-size:.875rem; }
.top-bar > .container,
.top-bar .container{
  display:flex; align-items:center; justify-content:space-between;
  gap:.5rem var(--sp-3); flex-wrap:wrap; padding-block:.4rem; min-height:38px;
  transition:padding-block var(--t-fast);
}
.top-bar a{ color:var(--color-white); } /* 5.5:1 on --color-primary */
.top-bar a:hover{ color:var(--color-white); text-decoration:underline; }
.top-bar__email{ display:inline-flex; align-items:center; }
.top-bar__links{ display:inline-flex; align-items:center; gap:1.1rem; flex-wrap:wrap; }
.top-bar__links > a{ display:inline-flex; align-items:center; }
.top-bar__phone{ display:inline-flex; align-items:center; font-weight:600; }
/* Social links are the platform NAMES, as type: the six drawn glyphs that used
   to live in this bar are gone with the rest of the icons. */
.top-bar__social{ display:inline-flex; align-items:center; gap:1rem; flex-wrap:wrap; }
.top-bar__social a{ display:inline-flex; align-items:center; }

/* Main nav */
.main-nav{ position:relative; }
.main-nav > .container,
.main-nav .container{
  display:flex; align-items:center; justify-content:space-between;
  gap:var(--sp-3); padding-block:.55rem;
  transition:padding-block var(--t-fast);
}
.main-nav__logo{ display:inline-flex; align-items:center; gap:.6rem; flex-shrink:0; }
.main-nav__logo img{
  height:clamp(42px,5.2vw,52px); width:auto;
  transition:height var(--t-fast);
}
.main-nav__logo-text{
  font-family:"Cormorant Garamond",Georgia,serif; font-weight:700;
  font-size:1.3rem; color:var(--color-heading); line-height:1.1; letter-spacing:-.01em;
}
/* flex-wrap stays on as a safety valve: if a label is ever translated longer
   than the measurement below allows, the row wraps rather than overflowing. */
.main-nav__menu{ display:none; align-items:center; gap:.05rem; flex-wrap:wrap; }

/* .is-stuck compression */
.site-header.is-stuck .main-nav > .container,
.site-header.is-stuck .main-nav .container{ padding-block:.3rem; }
.site-header.is-stuck .top-bar > .container,
.site-header.is-stuck .top-bar .container{ padding-block:.25rem; min-height:34px; }
.site-header.is-stuck .main-nav__logo img{ height:clamp(36px,4.4vw,44px); }

/* NAV FIT ARITHMETIC — measured in-browser 2026-10-22 against this theme's own
   DM Sans woff2 (not estimated), laying out the real markup at the real type
   sizes. These are the SAME figures as the docblocks in header.php:21-33 and
   template-parts/header/mega-menu.php:10-22; all three must agree, so correct
   all three together. (They did not agree before 2026-10-22: this comment
   carried 1105 / 1173 / 944 / 112, none of which was the measured number, and
   it invited the next reader to re-run the arithmetic from them.)
   The nine flat items the theme shipped with, plus the Donate pill, measured
   939px of row, and 939 + 52 (the square logo at its clamp ceiling) + 16 (the
   flex gap) = 1007px required, against the 929px of content a 1024px viewport
   really offers — 1024 less a 15px scrollbar less 2 x 40px of --container-pad.
   The 944px this comment used to quote is the same figure with the scrollbar
   left out. It overflowed from 1024px to about 1102px, which is the defect
   PLAN §5 reports.
   Regrouped to 8 top-level items + the Donate pill —
     Home 59 - About Us 82 - Services 93 - Prayer Timings 119 - Events 65 -
     Media 76 - Giving 78 - Contact Us 95 - Donate pill 86
   the labels sum to 753px and the row measures 764px once its gaps are in
   (8 x .05rem between the items plus the pill's .4rem margin-left). logo.png is
   SQUARE (512x512), so at clamp(42px,5.2vw,52px) it is 52px wide at every
   viewport from 1000px up:
     764 + 52 + 16 = 832px required, against 929px available at the breakpoint.
   That clears by 97px, so the comfortable .9rem/.6rem type fits from 1024px
   and no tighter 1024-1199 branch is needed (ROIC needs one; this nav is two
   labels shorter). Re-run the arithmetic if a label changes: the margin is
   97px, which is about one average item. (Verified in-browser at 1024px:
   one nav row, 751px of items against 929px available, and the
   hamburger-to-row swap is clean across 1023/1024.) */
.nav-item{ position:relative; }
.nav-item > a,
.nav-item__trigger{
  display:inline-flex; align-items:center; gap:.35rem;
  min-height:44px; padding:.5rem .6rem;
  font-weight:500; font-size:.9rem;
  color:var(--color-text); border-radius:var(--radius-pill);
  background:transparent; border:0; white-space:nowrap;
  transition:color var(--t-fast),background var(--t-fast);
}
.nav-item > a:hover,
.nav-item__trigger:hover,
.nav-item.is-open > .nav-item__trigger,
.nav-item.is-active > a,
.nav-item.current-menu-item > a,
.nav-item > a[aria-current="page"]{
  color:var(--color-primary-dark); background:var(--color-primary-lighter); /* 7.2:1 */
}
.nav-item__trigger svg{ width:.7em; height:.7em; flex:none; transition:transform var(--t-fast); } /* the dropdown chevron — kept */
.nav-item.is-open .nav-item__trigger svg,
.nav-item__trigger[aria-expanded="true"] svg{ transform:rotate(180deg); }
.nav-item__cta{ margin-left:.4rem; }
.nav-item__cta .btn{ min-height:44px; padding:.5rem 1.15rem; font-size:.9rem; }

/* Mega menu. Opens on hover and on .is-open, which assets/js/main.js sets from
   Enter/Space and clears on Escape. There is deliberately NO :focus-within
   rule: it would keep the panel visible after Escape while focus is still on
   the trigger and aria-expanded says closed.
   `visibility` is deliberately NOT in the transition list, and must not be put
   back. main.js toggles .is-open and then calls firstLink.focus() in the SAME
   task; while visibility was transitioned, the panel's computed visibility was
   still `hidden` at that moment, so the link was not focusable and focus()
   silently no-opped — measured at 1280px, document.activeElement never left the
   <button> after an Enter keydown, at 0ms or at 500ms. Untransitioned,
   visibility flips with the class and the first link is focusable immediately.
   The panel still fades IN on opacity + transform; only the fade-OUT is now
   instant, which is a fair price for the keyboard path working at all.
   (If the fade-out is ever wanted back, the alternative is to defer the focus
   in main.js across two requestAnimationFrames — but do ONE of the two, not
   both halves of the same fix in two files.) */
.mega-menu{
  position:absolute; top:calc(100% + 8px); left:0; z-index:60;
  min-width:280px; padding:var(--sp-2); border-radius:var(--radius-card);
  background:var(--color-white); box-shadow:var(--shadow-lg);
  border:1px solid var(--color-border);
  opacity:0; visibility:hidden; transform:translateY(8px);
  transition:opacity var(--t-fast),transform var(--t-fast);
}
.nav-item--has-mega.is-open .mega-menu,
.nav-item--has-mega:hover .mega-menu{
  opacity:1; visibility:visible; transform:translateY(0);
}
.mega-menu__grid{ display:grid; grid-template-columns:1fr; gap:.1rem; }
.mega-menu__link{
  display:block; min-height:44px;
  padding:.6rem .75rem; border-radius:var(--radius-sm);
  color:var(--color-text); font-size:.93rem; font-weight:500;
}
.mega-menu__link:hover{ background:var(--color-primary-lighter); color:var(--color-primary-dark); }

/* Hamburger (below the 1024px nav-fit breakpoint — see the arithmetic above) */
.menu-toggle{
  display:inline-flex; align-items:center; justify-content:center;
  width:48px; height:48px; border:1px solid var(--color-border);
  border-radius:var(--radius-pill); background:var(--color-white);
  color:var(--color-primary-dark);
}
.menu-toggle:hover{ background:var(--color-primary-lighter); }
.menu-toggle svg{ width:24px; height:24px; } /* hamburger — a functional control */

/* Mobile drawer. The link list ships FLAT (every destination, one level), so
   the submenu rules only engage if a grouped drawer is ever emitted. */
.mobile-drawer{ position:fixed; inset:0; z-index:1100; visibility:hidden; pointer-events:none; }
.mobile-drawer.is-open{ visibility:visible; pointer-events:auto; }
.mobile-drawer__overlay{
  position:absolute; inset:0; background:rgba(1,86,112,.55);
  opacity:0; transition:opacity var(--t);
}
.mobile-drawer.is-open .mobile-drawer__overlay{ opacity:1; }
.mobile-drawer__panel{
  position:absolute; top:0; right:0; height:100%; width:min(86vw,360px);
  background:var(--color-white); box-shadow:var(--shadow-lg);
  display:flex; flex-direction:column;
  transform:translateX(100%); transition:transform var(--t);
  overflow-y:auto; -webkit-overflow-scrolling:touch;
}
.mobile-drawer.is-open .mobile-drawer__panel{ transform:translateX(0); }
.mobile-drawer__header{
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-3);
  padding:var(--sp-3) var(--sp-4); border-bottom:1px solid var(--color-border);
}
.mobile-drawer__header img{ max-height:44px; width:auto; }
.mobile-drawer__close{
  width:44px; height:44px; flex:none;
  display:inline-flex; align-items:center; justify-content:center;
  border:1px solid var(--color-border); border-radius:var(--radius-pill);
  background:var(--color-white); color:var(--color-primary-dark);
}
.mobile-drawer__close:hover{ background:var(--color-primary-lighter); }
.mobile-drawer__close svg{ width:22px; height:22px; } /* close X — a functional control */
.mobile-drawer__nav{ padding:var(--sp-2) var(--sp-3) var(--sp-4); display:flex; flex-direction:column; gap:.1rem; }
.mobile-drawer__nav a,
.mobile-drawer__nav button{
  display:flex; align-items:center; justify-content:space-between; gap:.5rem;
  width:100%; min-height:48px; padding:.7rem .75rem;
  font-weight:500; font-size:1.02rem; text-align:left;
  color:var(--color-text); border-radius:var(--radius-sm);
  border-bottom:1px solid var(--color-gray-100);
}
.mobile-drawer__nav a:hover,
.mobile-drawer__nav button:hover{ background:var(--color-primary-lighter); color:var(--color-primary-dark); }
.mobile-drawer__nav a[aria-current="page"]{ color:var(--color-primary-dark); background:var(--color-primary-lighter); }
.mobile-drawer__nav button svg{ width:.85em; height:.85em; flex:none; transition:transform var(--t-fast); }
.mobile-drawer__nav button[aria-expanded="true"] svg{ transform:rotate(180deg); }
.mobile-drawer__submenu{ padding-left:var(--sp-3); margin:.1rem 0 .35rem; }
.mobile-drawer__submenu a{ font-size:.94rem; color:var(--color-text-secondary); min-height:44px; border-bottom:0; }
.mobile-drawer__submenu[hidden]{ display:none; }
.mobile-drawer__cta{ margin:var(--sp-3) var(--sp-4) var(--sp-4); }

/* -----------------------------------------------------------------------------
   18. FORMS
   -------------------------------------------------------------------------- */
.form{ display:flex; flex-direction:column; gap:var(--sp-3); }
.form__row{ display:grid; grid-template-columns:1fr; gap:var(--sp-3); }
.form__row--inline{ display:flex; gap:.6rem; align-items:stretch; flex-wrap:wrap; }
.form__group{ display:flex; flex-direction:column; gap:.4rem; }
.form__label{ font-weight:600; font-size:.92rem; color:var(--color-heading); }
.form__label .req{ color:var(--color-error); }
.form__input,.form__textarea,.form__select{
  width:100%; font-family:inherit; font-size:1rem; color:var(--color-text);
  min-height:52px; padding:.8rem 1.1rem;
  border:1px solid var(--color-gray-300); border-radius:var(--radius);
  background:var(--color-white);
  transition:border-color var(--t-fast),box-shadow var(--t-fast);
}
.form__input:focus,.form__textarea:focus,.form__select:focus{
  outline:3px solid transparent; outline-offset:2px; /* visible under forced-colors */
  border-color:var(--color-primary);
  box-shadow:0 0 0 3px var(--color-primary-lighter);
}
.form__textarea{ min-height:150px; resize:vertical; }
/* assets/js/forms.js sets .has-error; .is-invalid is accepted as a synonym */
.form__input.has-error,.form__textarea.has-error,.form__select.has-error,
.form__input.is-invalid,.form__textarea.is-invalid,.form__select.is-invalid{
  border-color:var(--color-error);
  box-shadow:0 0 0 3px var(--color-error-lighter);
}
.form__consent{ display:flex; align-items:flex-start; gap:.6rem; font-size:.92rem; color:var(--color-text-secondary); }
.form__consent input[type="checkbox"]{ margin-top:.25rem; width:20px; height:20px; flex-shrink:0; accent-color:var(--color-primary); }
.form__consent.has-error,.form__consent.is-invalid{ color:var(--color-error); }
.form__hint{ font-size:.85rem; color:var(--color-text-muted); }
.form__error{ display:block; font-size:.85rem; color:var(--color-error); font-weight:500; min-height:1em; }
.form__submit{ align-self:flex-start; }
.form__honeypot{ position:absolute !important; left:-9999px !important; width:1px; height:1px; overflow:hidden; }

.form-message{
  padding:.9rem 1.1rem; border-radius:var(--radius); font-size:.95rem;
  margin-bottom:var(--sp-3); border:1px solid transparent;
}
.form-message--ok{ background:var(--color-primary-lighter); color:var(--color-primary-dark); border-color:var(--color-success); }
.form-message--err{ background:var(--color-error-lighter); color:var(--color-error); border-color:var(--color-error); }

/* Search form (searchform.php uses .form__row--inline + these) */
.search-form__input{
  flex:1 1 220px; min-width:0; font-family:inherit; font-size:1rem;
  min-height:52px; padding:.8rem 1.1rem; color:var(--color-text);
  border:1px solid var(--color-gray-300); border-radius:var(--radius-pill);
  background:var(--color-white);
  transition:border-color var(--t-fast),box-shadow var(--t-fast);
}
.search-form__input:focus{ outline:3px solid transparent; outline-offset:2px; border-color:var(--color-primary); box-shadow:0 0 0 3px var(--color-primary-lighter); }
.search-form__submit{
  flex-shrink:0; background:var(--color-cta); color:var(--color-cta-text);
  font-weight:600; padding:.8rem 1.6rem; border-radius:var(--radius-pill); min-height:52px;
  transition:background var(--t-fast);
}
.search-form__submit:hover{ background:var(--color-cta-hover); }

/* -----------------------------------------------------------------------------
   19. INFO CARDS — contact details, donation categories (gold left rule, no icon)
   -------------------------------------------------------------------------- */
.info-cards{ display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,22rem),1fr)); gap:var(--gap); }
.info-cards--3{ grid-template-columns:repeat(auto-fit,minmax(min(100%,18rem),1fr)); }
.info-card{
  display:flex; flex-direction:column; gap:.55rem;
  padding:var(--pad-card); background:var(--color-white);
  border:1px solid var(--color-border); border-left:3px solid var(--color-secondary);
  border-radius:var(--radius-card); box-shadow:var(--shadow-card);
}
.info-card h3{ margin:0; font-size:var(--fs-display-sm); }
.info-card p{ margin:0; color:var(--color-text-secondary); }
.info-card a{ color:var(--color-primary); font-weight:500; word-break:break-word; }
.info-card a:hover{ color:var(--color-primary-dark); }
/* A paragraph that is nothing but one link is a single-destination row, not a
   link inside a sentence — give it the 44px tap target PLAN §6 requires. The
   one consumer is the tel: link in the Phone card (page-contact.php:121), which
   measured 22px tall at 768px and at 1024px: the smallest target on the site.
   Same shape and same reasoning as the .panel--dark rule in §10, so a link in
   running text is left alone. Unconditional, as that rule is: an exactly-44px
   row is no worse on a desktop pointer. */
.info-card p > a:only-child{ display:inline-flex; align-items:center; min-height:44px; }
.info-card .btn{ margin-top:auto; align-self:flex-start; }

/* -----------------------------------------------------------------------------
   20. MEDIA ROW — a real photograph beside a text column
   One of only four distinct photographs in the theme goes here. Never repeat
   the same file twice on one screen (PLAN §4).
   -------------------------------------------------------------------------- */
.media-row{ display:grid; grid-template-columns:1fr; gap:var(--gap); align-items:center; }
.media-row__media{ border-radius:var(--radius-card); overflow:hidden; box-shadow:var(--shadow-card); }
.media-row__media img{ width:100%; height:100%; object-fit:cover; }
.media-row__body{ display:flex; flex-direction:column; gap:var(--sp-3); align-items:flex-start; }
.media-row__body h2,.media-row__body h3{ margin-top:0; }

/* -----------------------------------------------------------------------------
   21. STATS — the client's four figures (2012 / 1.7 / 200+ / 5)
   .counter[data-target] is animated by assets/js/main.js, which preserves any
   prefix/suffix. The number IS the graphic here: no tile, no icon, no border.
   -------------------------------------------------------------------------- */
/* Exactly FOUR figures, so explicit columns and not auto-fit — the same defect
   as .grid--4 (§6) and .gallery-grid (§22). With
   minmax(min(100%,10rem),1fr) the grid fitted floor((691.6+24)/(160+24)) = 3
   tracks at a 768px viewport (691.6px of content once a 15px scrollbar is out,
   --gap 24px) and orphaned the fourth figure, "5 / Daily Prayers", on a row of
   its own — 20px short of the 712px four columns would have needed. The orphan
   window ran about 620-791px, and 768px is one of PLAN §6's required test
   widths. Steps are 1 -> 2 (480px) -> 4 (1024px), both in §29, so the 620-791px
   band is now a 2x2 block. */
.stats-grid{ display:grid; grid-template-columns:1fr; gap:var(--gap); }
.stat{ text-align:center; padding:var(--sp-2) var(--sp-1); }
.stat__num{
  display:block; margin-bottom:.35rem;
  font-family:"Cormorant Garamond",Georgia,serif; font-weight:700;
  font-size:clamp(2.6rem,5vw,3.6rem); line-height:1;
  color:var(--color-primary); /* 5.5:1 on white */
}
.stat__label{
  font-family:"DM Sans",system-ui,sans-serif;
  font-size:.82rem; font-weight:500; letter-spacing:.14em; text-transform:uppercase;
  color:var(--color-text-secondary);
}
.section--dark .stat__num,
.panel--dark .stat__num{ color:var(--color-secondary-light); }
.section--dark .stat__label,
.panel--dark .stat__label{ color:rgba(255,255,255,.88); }

/* -----------------------------------------------------------------------------
   22. GALLERY GRID — the four real photographs, honestly labelled
   PLAN §4: these four tiles are the SAME images the page banners use, so the
   gallery page leads with the `slider` widget (real client flyers) and this
   grid sits beneath it. Tiles link to the full image.
   -------------------------------------------------------------------------- */
/* Four tiles, so explicit columns for the same reason as .grid--4 (§6) and
   .stats-grid (§21): auto-fit with minmax(min(100%,14rem),1fr) fitted
   floor((929+20)/(224+20)) = 3 tracks at a 1024px viewport and orphaned the
   fourth photograph, across an orphan window of roughly 790-1050px. Steps are
   1 -> 2 (640px) -> 4 (1024px), both in §29. */
.gallery-grid{ display:grid; grid-template-columns:1fr; gap:var(--gap-tight); }
.gallery-grid__item{
  position:relative; display:block; overflow:hidden; border-radius:var(--radius-card);
  aspect-ratio:4/3; background:var(--color-gray-100); box-shadow:var(--shadow-card);
}
.gallery-grid__item img{ width:100%; height:100%; object-fit:cover; transition:transform var(--t-zoom); }
.gallery-grid__item:hover img,
.gallery-grid__item:focus-visible img{ transform:scale(1.04); }
.gallery-grid__item::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(180deg,transparent 55%,rgba(1,86,112,.4));
  opacity:0; transition:opacity var(--t);
}
.gallery-grid__item:hover::after{ opacity:1; }

/* -----------------------------------------------------------------------------
   23. (REMOVED 2026-10-22) DATA TABLE
   .table-card / __scroll / .data-table and its four modifiers / .table-note:
   35 lines, and a grep of every class attribute in all 44 PHP templates found
   zero occurrences of any of them. WordPress core and the block editor do not
   emit them either — a table typed into the editor comes out as
   figure.wp-block-table > table, which none of these selectors matched — so
   nothing rendered differently before or after this deletion.
   The section NUMBER is kept, as §13's note explains.
   If the client starts typing prayer or schedule tables into pages, the place
   to style them is §5 (EDITOR PROSE), keyed on `.page-content table`, which is
   what the editor actually produces. Re-adding a `.data-table` class nothing
   emits would not help.
   Its one knock-on, `.table-card,.data-table tr{ break-inside:avoid }` in the
   print block, went with it (§30).
   -------------------------------------------------------------------------- */

/* -----------------------------------------------------------------------------
   24. (REMOVED 2026-10-22) STYLED LIST
   .styled-list / --check, 17 lines, emitted by no template. Its dark-ground
   overrides in §6 (`.section--dark .styled-list li`, `.panel--dark
   .styled-list li`) went with it. The theme's hairline typographic rows are
   .list-rows / .list-row (§11), which IS used — by page-services.php and the
   contact details in .split__aside — and that is the component to reach for.
   The section NUMBER is kept, as §13's note explains.
   -------------------------------------------------------------------------- */

/* -----------------------------------------------------------------------------
   25. FOOTER — no icon slots on any link
   The verse strip carries the client's 2:261 verse (Arabic + translation) and
   is the one place the footer uses Amiri. It is client content: keep it.
   -------------------------------------------------------------------------- */
.site-footer{ background:var(--color-primary-dark); color:rgba(255,255,255,.82); position:relative; }
.site-footer a{ color:rgba(255,255,255,.82); }
.site-footer a:hover{ color:var(--color-secondary-light); }

/* Newsletter strip */
.newsletter{ background:var(--color-primary); padding-block:clamp(2rem,4vw,2.75rem); }
.newsletter > .container,
.newsletter .container{ display:grid; grid-template-columns:1fr; gap:var(--sp-4); align-items:center; }
.newsletter h2{ color:var(--color-white); font-size:var(--fs-display-md); margin:0 0 .35rem; }
.newsletter__intro{ color:var(--color-white); margin:0; }
.newsletter__intro p{ margin:0; color:var(--color-white); max-width:var(--measure); }
.newsletter__form{ display:flex; gap:.6rem; flex-wrap:wrap; }
.newsletter__input{
  flex:1 1 240px; min-width:0; font-family:inherit; font-size:1rem;
  min-height:52px; padding:.8rem 1.1rem;
  border:1px solid rgba(255,255,255,.25); border-radius:var(--radius-pill);
  background:var(--color-white); color:var(--color-text);
}
.newsletter__input::placeholder{ color:var(--color-text-muted); }
.newsletter__input:focus{ outline:3px solid transparent; outline-offset:2px; box-shadow:0 0 0 3px rgba(255,255,255,.85); }

/* Footer main columns */
.footer-main{ padding-block:clamp(3rem,6vw,4.5rem); }
.footer-main > .container,
.footer-main .container{ display:grid; grid-template-columns:1fr; gap:var(--gap); }
.footer-col{ min-width:0; }
.footer-col__title{
  color:var(--color-white);
  font-family:"DM Sans",system-ui,sans-serif; font-size:.85rem; font-weight:600;
  letter-spacing:.14em; text-transform:uppercase;
  margin:0 0 var(--sp-3); padding-bottom:.6rem; position:relative;
}
.footer-col__title::after{
  content:""; position:absolute; left:0; bottom:0;
  width:36px; height:1px; background:var(--color-secondary);
}
.footer-links{ display:flex; flex-direction:column; gap:.2rem; }
/* Each of these is a single-destination row, so it takes the 44px tap target */
.footer-links a{ display:flex; align-items:center; min-height:44px; font-size:.95rem; padding-block:.35rem; }

/* Logo white chip (the teal logo needs it on dark) */
.footer-logo{
  background:#fff; padding:.5rem .75rem; border-radius:var(--radius-sm);
  display:inline-block; margin-bottom:var(--sp-3);
}
.footer-logo img{ max-height:52px; width:auto; }

/* The footer's own greeting lockup — the client's Arabic line + English line */
.footer-greeting{ display:flex; flex-direction:column; gap:.2rem; margin:0 0 var(--sp-3); }
.footer-greeting .text-arabic{ color:var(--color-secondary-light); font-size:1.25rem; }
.footer-greeting span{ color:rgba(255,255,255,.82); font-size:.95rem; }
.footer-greeting [dir="rtl"]{ text-align:left; }
.footer-tagline{ color:rgba(255,255,255,.8); font-size:.95rem; margin:0 0 var(--sp-4); max-width:42ch; }

/* App store links — text pills, not store badges */
.app-stores{ display:flex; flex-wrap:wrap; gap:.6rem; }
.app-stores__btn{
  display:inline-flex; align-items:center; justify-content:center;
  min-height:44px; padding:.55rem 1.2rem;
  background:rgba(255,255,255,.1); color:var(--color-white);
  border:1px solid rgba(255,255,255,.22); border-radius:var(--radius-pill);
  font-size:.88rem; font-weight:500;
  transition:background var(--t-fast),border-color var(--t-fast);
}
.app-stores__btn:hover{ background:rgba(255,255,255,.2); border-color:var(--color-secondary-light); color:var(--color-white); }

.footer-contact{ display:flex; flex-direction:column; gap:.2rem; }
.footer-contact a,
.footer-contact span,
.footer-contact address{
  display:block; padding-block:.35rem;
  color:rgba(255,255,255,.82); font-size:.95rem; font-style:normal; margin:0;
}
/* The <address> and the plain <span> are not link targets and keep display:block */
.footer-contact a{ display:flex; align-items:center; min-height:44px; }
.footer-contact a:hover{ color:var(--color-secondary-light); }

/* Verse strip — the client's 2:261 verse */
.verse-strip{
  border-top:1px solid rgba(255,255,255,.12); border-bottom:1px solid rgba(255,255,255,.12);
  padding-block:var(--sp-5); text-align:center;
}
.verse-strip__arabic{
  font-family:"Amiri","Noto Naskh Arabic",serif; direction:rtl; line-height:1.9;
  letter-spacing:normal;
  color:var(--color-secondary-light); font-size:clamp(1.3rem,3vw,1.75rem);
  margin:0 auto .75rem; max-width:40ch;
}
.verse-strip__translation{
  color:rgba(255,255,255,.86); max-width:60ch; margin:0 auto; font-size:.98rem;
}

/* Footer bottom */
.footer-bottom{ padding-block:var(--sp-4); border-top:1px solid rgba(255,255,255,.12); }
.footer-bottom > .container,
.footer-bottom .container{
  display:flex; flex-direction:column; gap:var(--sp-2);
  align-items:center; text-align:center;
}
.footer-bottom__legal{ color:rgba(255,255,255,.7); font-size:.85rem; margin:0; max-width:none; }
.footer-bottom__links{ display:flex; flex-wrap:wrap; gap:.4rem 1.25rem; justify-content:center; }
.footer-bottom__links a{ color:rgba(255,255,255,.78); font-size:.85rem; }
.footer-bottom__links a:hover{ color:var(--color-secondary-light); }

/* -----------------------------------------------------------------------------
   26. PAGINATION — keyed on WordPress's own output, not on theme classes.
   the_posts_pagination() (index.php, search.php) prints
     nav.navigation.pagination > h2.screen-reader-text + div.nav-links
   whose children are .page-numbers, with .current / .dots / .prev / .next.
   wp_link_pages() (index.php, page.php) prints div.page-links with
   .post-page-numbers children — a DIFFERENT class, so both are styled here.
   Without this block "Posts navigation" renders as visible body text.
   -------------------------------------------------------------------------- */
.pagination .nav-links{
  display:flex; flex-wrap:wrap; align-items:center;
  gap:var(--gap-tight); justify-content:center;
  margin-top:var(--space-block);
}
.page-numbers,
.post-page-numbers{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:48px; min-height:48px; padding:0 var(--sp-2);
  border:1px solid var(--color-border); border-radius:var(--radius-pill);
  color:var(--color-heading); font-weight:600; font-size:1rem;
  transition:background var(--t-fast),color var(--t-fast),border-color var(--t-fast);
}
a.page-numbers:hover,
a:hover > .post-page-numbers{
  background:var(--color-primary-lighter);
  border-color:var(--color-primary-lighter);
  color:var(--color-primary-dark);
}
.page-numbers.current,
.post-page-numbers.current{
  background:var(--color-primary); border-color:var(--color-primary);
  color:var(--color-white);
}
/* The ellipsis is not a destination — no pill chrome, no tap target */
.page-numbers.dots{
  min-width:auto; min-height:auto; padding:0 .25rem;
  border-color:transparent; color:var(--color-text-muted);
}
/* wp_link_pages(): "Pages:" is a bare text node, so it becomes its own item */
.page-links{
  display:flex; flex-wrap:wrap; align-items:center; gap:var(--gap-tight);
  margin-top:var(--sp-4); font-weight:600; color:var(--color-heading);
}
.page-links > a{ display:inline-flex; }

/* -----------------------------------------------------------------------------
   27. UTILITIES
   -------------------------------------------------------------------------- */
.visually-hidden,
.screen-reader-text{ /* core emits .screen-reader-text — e.g. the pagination's own <h2> */
  position:absolute !important; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;
}
.screen-reader-text:focus{
  position:static !important; width:auto; height:auto; margin:0;
  clip:auto; white-space:normal;
}
.skip-link{
  position:absolute; left:.5rem; top:-100px; z-index:2000;
  background:var(--color-primary-dark); color:var(--color-white);
  padding:.7rem 1.2rem; border-radius:var(--radius-sm); font-weight:600;
  transition:top var(--t-fast);
}
.skip-link:focus{ top:.5rem; color:var(--color-white); }
.u-center{ text-align:center; }
.u-flex-center{ display:flex; align-items:center; justify-content:center; gap:var(--sp-2); flex-wrap:wrap; }
/* A left-aligned button row, mirroring .hero__actions */
.u-actions{ display:flex; flex-wrap:wrap; gap:var(--sp-3); }
.u-mx-auto{ margin-inline:auto; }
.u-measure-sm{ max-width:32rem; }
.u-mb-0{ margin-bottom:0 !important; }
/* The one "air after a heading block" figure, so it cannot drift per template */
.u-mt-block{ margin-top:var(--space-block); }
.u-mb-block{ margin-bottom:var(--space-block); }
.u-mt-4{ margin-top:var(--sp-4); }
.u-mb-4{ margin-bottom:var(--sp-4); }
.u-mb-5{ margin-bottom:var(--sp-5); }
.is-hidden{ display:none !important; }

/* -----------------------------------------------------------------------------
   28. MOTION — reveal, stagger, hero load-in
   assets/js/main.js adds .is-visible to every .reveal when it scrolls into
   view. .reveal--stagger goes on a PARENT (together with .reveal) and steps its
   children in 80ms increments; the steps are plain CSS here, so they work with
   the current main.js, and an inline --d (which front-page.php already uses)
   overrides them.
   -------------------------------------------------------------------------- */
.reveal{
  opacity:0; transform:translateY(18px);
  transition:opacity var(--t-reveal) var(--ease-out),transform var(--t-reveal) var(--ease-out);
  transition-delay:var(--d,0s);
  will-change:opacity,transform;
}
.reveal--left{ transform:translateX(-28px); }
.reveal--right{ transform:translateX(28px); }
.reveal--scale{ transform:scale(.94); }
.reveal.is-visible{ opacity:1; transform:none; }

.reveal--stagger > *{
  opacity:0; transform:translateY(18px);
  transition:opacity var(--t-reveal) var(--ease-out),transform var(--t-reveal) var(--ease-out);
  transition-delay:var(--d,0s);
}
.reveal--stagger.is-visible > *,
.reveal--stagger > .is-visible{ opacity:1; transform:none; }
.reveal--stagger > *:nth-child(1){ --d:0ms; }
.reveal--stagger > *:nth-child(2){ --d:80ms; }
.reveal--stagger > *:nth-child(3){ --d:160ms; }
.reveal--stagger > *:nth-child(4){ --d:240ms; }
.reveal--stagger > *:nth-child(5){ --d:320ms; }
.reveal--stagger > *:nth-child(6){ --d:400ms; }
.reveal--stagger > *:nth-child(7){ --d:480ms; }
.reveal--stagger > *:nth-child(n+8){ --d:560ms; }

/* Hero load-in — on load, not on scroll; 120ms apart */
@keyframes addawah-rise{
  from{ opacity:0; transform:translateY(18px); }
  to{ opacity:1; transform:none; }
}
.hero__eyebrow,
.hero__welcome,
.hero__greeting,
.hero__display,
.hero__title,
.hero__subtitle,
.hero__actions{ animation:addawah-rise var(--t-reveal) var(--ease-out) both; }
.hero__eyebrow{ animation-delay:0ms; }
.hero__welcome,
.hero__greeting{ animation-delay:120ms; }
.hero__display,
.hero__title{ animation-delay:240ms; }
.hero__subtitle{ animation-delay:360ms; }
.hero__actions{ animation-delay:480ms; }
.hero--tall > .quick-bar,
.hero + .quick-bar{ animation:addawah-rise var(--t-reveal) var(--ease-out) 600ms both; }

/* NO-JAVASCRIPT SAFETY NET. The `no-js` body class IS set, on every request:
   addawah_body_classes() appends it (inc/theme-setup.php:28) and header.php
   passes it to body_class() as well, and an inline script then strips it before
   paint. So the body.no-js rules below are live for that first moment, and stay
   live for any visitor whose JS 404s or throws. The @media (scripting:none)
   copy is the belt-and-braces path for a visitor who has scripting switched
   off, where that remover never runs at all. Neither branch is hypothetical.
   (This comment used to say the opposite — "Nothing in this theme adds a
   `no-js` body class today ... the body.no-js selectors are there for the day
   header.php or main.js sets one". Both halves were false. Corrected
   2026-10-22.)
   The two branches must say the SAME thing: edit them together. Without
   either, a visitor with JS off would see empty sections, because .reveal
   starts at opacity:0 and only JS clears it.
   Showing the desktop nav row is NOT enough on its own, which is why each
   branch also flattens .mega-menu — see the note on the first one. */
@media (scripting: none){
  .reveal,.reveal--left,.reveal--right,.reveal--scale,
  .reveal--stagger > *{ opacity:1 !important; transform:none !important; }
  .hero__eyebrow,.hero__welcome,.hero__greeting,.hero__display,.hero__title,
  .hero__subtitle,.hero__actions,
  .hero--tall > .quick-bar,.hero + .quick-bar{ animation:none; opacity:1; transform:none; }
  .main-nav__menu{ display:flex; flex-wrap:wrap; }
  .menu-toggle,.app-banner__close{ display:none; }
  /* Forcing the full desktop row on at every width leaves the three .mega-menu
     panels position:absolute with min-width:280px, left:0 and nothing but
     visibility:hidden — and an absolutely positioned box still contributes to
     the document's scrollable overflow. Measured with the class applied:
     documentElement.scrollWidth was 501 against a 320px clientWidth (181px of
     overflow, widest out-of-bounds element .mega-menu) and 853 against 753 at
     768px, which breaks PLAN §6's "no horizontal overflow at 320". body's
     overflow-x:hidden only CLIPPED it, so the eight destinations under
     Services / Media / Giving sat ~177px off-screen with only :hover to open
     them — unreachable on a touch device with scripting off. Static takes the
     box out of flow-overflow and drops the sub-links inline, readable and
     clickable, which is what the drawer would otherwise have provided. */
  .mega-menu{
    position:static; opacity:1; visibility:visible; transform:none;
    min-width:0; padding:0; border:0; box-shadow:none;
  }
}
body.no-js .reveal,
body.no-js .reveal--left,
body.no-js .reveal--right,
body.no-js .reveal--scale,
body.no-js .reveal--stagger > *{ opacity:1 !important; transform:none !important; }
body.no-js .hero__eyebrow,
body.no-js .hero__welcome,
body.no-js .hero__greeting,
body.no-js .hero__display,
body.no-js .hero__title,
body.no-js .hero__subtitle,
body.no-js .hero__actions,
body.no-js .hero--tall > .quick-bar,
body.no-js .hero + .quick-bar{ animation:none; opacity:1; transform:none; }
body.no-js .main-nav__menu{ display:flex; flex-wrap:wrap; }
body.no-js .menu-toggle{ display:none; }
/* Same rule, same reason as the @media (scripting:none) copy above: without it
   the absolutely positioned panels put 181px of overflow on a 320px viewport
   and the eight grouped destinations are laid out off-screen. */
body.no-js .mega-menu{
  position:static; opacity:1; visibility:visible; transform:none;
  min-width:0; padding:0; border:0; box-shadow:none;
}
/* The dismiss button needs JS; remove the inert control without it */
body.no-js .app-banner__close{ display:none; }

/* -----------------------------------------------------------------------------
   29. RESPONSIVE — 480 / 640 / 768 / 1024 / 1280
   The min-/max-width pairs are deliberately non-overlapping (767.98 / 768 and
   1023.98 / 1024): at an exactly-equal pair BOTH queries match and the two
   branches fight, which is how a quick bar can end up flush AND overlapping at
   768px. 1024px is the nav-fit breakpoint — see the arithmetic in §17.
   The one exception is min-width:480px / max-width:480px, which DO both match
   at exactly 480px. It is harmless because the two branches set disjoint
   properties (.stats-grid columns here, .hero__actions .btn width and
   --quick-bar-h there), but do not add an overlapping declaration to either.
   640px is the two-up step for the three four-item grids (§6, §21, §22); it is
   a layout breakpoint only and has nothing to do with the Rawdah widgets'
   internal 640, which §16 keys on at 696px of viewport.
   -------------------------------------------------------------------------- */
@media (min-width:480px){
  .footer-bottom > .container,
  .footer-bottom .container{ flex-direction:row; justify-content:space-between; text-align:left; }

  /* The four client figures go 2x2 here and stay 2x2 until 1024 (§21). At
     480px each column is (440 - 24) / 2 = 208px, which takes the longest label
     ("Year Heritage Building") on two lines without crowding the figure. */
  .stats-grid{ grid-template-columns:repeat(2,1fr); }
}

/* The two four-item grids go two-up here; .stats-grid is already 2x2 from
   480px. See §6, §21 and §22 for why none of the three is auto-fit. This
   breakpoint is the shared system's, and has nothing to do with the Rawdah
   widgets' own internal 640 — §16 explains why the events frame keys on 696. */
@media (min-width:640px){
  .grid--4,
  .gallery-grid{ grid-template-columns:repeat(2,1fr); }
}

@media (min-width:768px){
  .newsletter > .container,
  .newsletter .container{ grid-template-columns:1fr 1fr; }
  .newsletter__form{ justify-content:flex-end; }
  .media-row{ grid-template-columns:1fr 1fr; }
  .media-row--reverse .media-row__media{ order:2; }
  .footer-main > .container,
  .footer-main .container{ grid-template-columns:repeat(2,1fr); }

  /* Quick bar goes to one row of equal columns, whatever the item count */
  .quick-bar__list{ grid-template-columns:none; grid-auto-flow:column; grid-auto-columns:minmax(0,1fr); }
  /* Hairline between items, whether or not the links are wrapped in <li> */
  .quick-bar__item + .quick-bar__item,
  .quick-bar__list > li + li > .quick-bar__item{ box-shadow:inset 1px 0 0 rgba(255,255,255,.16); }

  /* From here up the bar is pulled ONTO the hero by --quick-bar-h (§12), so the
     hero must reserve that height plus real clearance in its own bottom
     padding, or the translucent bar paints over the CTAs and swallows their
     clicks. Clearance = clamp(1rem,2vw,1.5rem), always more than the 3px focus
     outline-offset needs. */
  .hero--tall .hero__content{ padding-bottom:calc(var(--quick-bar-h) + clamp(1rem,2vw,1.5rem)); }
}

@media (min-width:1024px){
  .split{ grid-template-columns:minmax(0,1.3fr) minmax(0,1fr); }
  .footer-main > .container,
  .footer-main .container{ grid-template-columns:1.4fr 1fr 1fr 1.3fr; }

  /* All three four-item grids reach four across here and not before: three
     across would orphan the fourth item, which DESIGN-LANGUAGE §3 forbids.
     At 1024px that is 212.96px a column for .grid--4 and .stats-grid
     ((944 - 3 x 30.72) / 4) and 221px for .gallery-grid ((944 - 3 x 20) / 4);
     at 1280px, 260px and 269px. See §6, §21, §22. */
  .grid--4,
  .gallery-grid,
  .stats-grid{ grid-template-columns:repeat(4,1fr); }

  /* The nav fits on one row from here (see §17). Below this the hamburger and
     the drawer ARE the navigation, so the drawer must stay reachable. */
  .main-nav__menu{ display:flex; }
  .menu-toggle{ display:none; }
  .mobile-drawer{ display:none; }
}

@media (min-width:1280px){
  /* This also fixes the container's content width at 1200 - 64 = 1136px, which
     is what the >=1130px widget figures in §16 were measured against. */
  .container{ padding-inline:var(--sp-5); }
}

/* Touch layout runs up to the hamburger breakpoint — keep the 44px targets */
@media (max-width:1023.98px){
  .top-bar__phone,
  .top-bar__email,
  .top-bar__social a{ min-height:44px; padding-block:.4rem; }
}

@media (max-width:767.98px){
  /* Keep click-to-call phone + email visible; hide the other top-bar links */
  .top-bar__links > a:not(.top-bar__phone){ display:none; }
  .top-bar__social{ display:none; }
  .top-bar > .container,
  .top-bar .container{ justify-content:center; }

  /* Comfortable tap areas for small text links on touch screens */
  .card__link{ min-height:44px; align-items:center; }
  .breadcrumbs__item{ padding-block:.5rem; }
  .list-row{ padding-block:var(--sp-4); }

  /* The quick bar sits flush under a shorter hero rather than overlapping it,
     so the hero keeps its own smaller bottom padding from §15. */
  .hero + .quick-bar,
  .hero--tall + .quick-bar{ margin-top:0; }
}

@media (max-width:480px){
  .hero__actions .btn{ width:100%; }
  :root{ --quick-bar-h:58px; }
}

/* -----------------------------------------------------------------------------
   30. PRINT (lightweight, tokens only)
   -------------------------------------------------------------------------- */
@media print{
  .site-header,.site-footer,.app-banner,.skip-link,
  .mobile-drawer,.menu-toggle,.quick-bar,.pagination,
  .rawdah-widget-container iframe{ display:none !important; }
  .reveal,.reveal--stagger > *{ opacity:1 !important; transform:none !important; } /* never print blank sections */
  body{ background:var(--color-white); color:var(--color-text); }
  a{ color:var(--color-text); text-decoration:underline; }
  .section--dark,.panel--dark,.page-hero,.hero{ background:var(--color-white); color:var(--color-text); }
  .section--dark h1,.section--dark h2,.section--dark h3,.section--dark h4,
  .panel--dark .panel__title,
  /* .hero__display em is listed explicitly: §15 gives the accent word a gold
     that is ~1.6:1 on paper, and `.hero__display em` outranks `.hero__display`. */
  .page-hero__title,.hero__display,.hero__display em,.hero__title{ color:var(--color-heading); }
  .section--dark p,.section--dark li,.panel--dark p,.panel--dark li,
  .page-hero__subtitle,.hero__subtitle,
  .hero__welcome-line,.hero__welcome > p,.hero__greeting > span,
  .verse-strip__arabic,.verse-strip__translation{ color:var(--color-text-secondary); }
  .page-hero::before,.page-hero::after,.hero::after,.section--patterned::before{ display:none; }
}

/* -----------------------------------------------------------------------------
   31. PREFERS-REDUCED-MOTION — full off-switch
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    transition-delay:0s !important;
    scroll-behavior:auto !important;
  }
  html{ scroll-behavior:auto; }
  .hero__bg{ animation:none !important; transform:none !important; }
  .hero__eyebrow,.hero__welcome,.hero__greeting,.hero__display,.hero__title,
  .hero__subtitle,.hero__actions,
  .hero--tall > .quick-bar,.hero + .quick-bar{ animation:none !important; opacity:1 !important; transform:none !important; }
  .reveal,.reveal--left,.reveal--right,.reveal--scale,
  .reveal--stagger > *{ opacity:1 !important; transform:none !important; }
  .card:hover,.btn:hover,
  .list-row:hover > [aria-hidden="true"],
  .card:hover .card__media img,
  .gallery-grid__item:hover img{ transform:none !important; }
}
