/* ============================================================================
   QUAKERS HILL MASJID — Homepage stylesheet
   Built strictly on design-system.md.
   Structure:
     LAYER 1  Tokens (:root)
     LAYER 2  Base + Primitives
     LAYER 3  Components
     LAYER 4  Page sections (Landing, About, Services, Programs, Donate, Footer)
     RESPONSIVE  Tablet + Mobile overrides
   ============================================================================ */

/* ============================================================
   LAYER 1 · DESIGN TOKENS  (single source of truth)
   ============================================================ */
:root {
  /* COLOR · BRAND (mandated) */
  --color-text-primary:   #1D3922;
  --color-text-secondary: #5B5A59;
  --color-primary:        #224A37;
  --color-secondary:      #FFD67B;

  /* COLOR · DERIVED GREENS */
  --color-primary-hover:  #1C3C2C;
  --color-primary-active: #142B1F;
  --color-primary-soft:   #E7EFE9;
  --color-on-primary:     #FFFFFF;
  --color-on-primary-dim: rgba(255,255,255,.72);
  --color-border-on-dark: rgba(255,255,255,.38);

  /* COLOR · DERIVED GOLDS */
  --color-secondary-hover:  #F4C65C;
  --color-secondary-active: #E8B645;
  --color-on-secondary:     #1D3922;
  --color-accent-amber:     #B5811C;
  /* Filter equivalent of --color-accent-amber. CSS `color`/`fill` cannot reach
     inside an <img>-embedded external SVG, so single-color .icon-tile icons are
     recolored to the amber token via this filter instead. Solved output
     rgb(182,128,29) ≈ #B5811C. One source of truth so the token still drives it. */
  --filter-accent-amber: brightness(0) saturate(100%) invert(55%) sepia(80%) saturate(344%) hue-rotate(0deg) brightness(80%) contrast(120%);

  /* COLOR · SURFACES */
  --color-bg:            #FFFFFF;
  --color-surface:       #FFFFFF;
  --color-surface-cream: #FCF8EF;
  --color-surface-sand:  #F8FBF0;
  --color-surface-stone: #F8F7F2; /* warm neutral — prayer times card */
  --color-bg-about:      #F8F7F2;
  --color-surface-dark:  #224A37;
  --color-highlight:     #FFEDC7;

  /* COLOR · BORDERS */
  --color-border:        #E9E3D5;
  --color-border-strong: #D8D2C2;
  --color-divider:       #ECE7DA;

  /* COLOR · FEEDBACK  (documented in design-system.md §Tokens; NOT a brand
     hue — used only for form validation messages and :user-invalid borders) */
  --color-error:         #B23B33;

  /* TYPOGRAPHY */
  --font-display: 'El Messiri', 'Segoe UI', serif;
  --font-body:    'Albert Sans', system-ui, -apple-system, sans-serif;
  --text-display: 3.5rem;
  --text-h1: 2.5rem;
  --text-h2: 2rem;
  --text-h3: 1.5rem;
  --text-h4: 1.25rem;
  --text-lg: 1.125rem;
  --text-base: 1rem;
  --text-sm: 0.875rem;
  --text-xs: 0.75rem;
  --leading-tight: 1.15;
  --leading-snug: 1.3;
  --leading-base: 1.6;
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;

  /* SPACING (4px base) */
  --space-1: 4px;   --space-2: 8px;   --space-3: 12px;  --space-4: 16px;
  --space-5: 20px;  --space-6: 24px;  --space-8: 32px;  --space-10: 40px;
  --space-12: 48px; --space-16: 64px; --space-20: 80px; --space-24: 96px;

  /* LAYOUT */
  --container-max:  1400px; /* single unified page width — navbar + every section route through this */
  --container-wide: 1320px;
  --container-hero: 1560px; /* wider wrapper for the landing/navbar so 2:6:2 sides stay roomy */
  --gutter: 30px; /* global left/right page margin (desktop; drops to 16px ≤1024) */

  /* RADIUS — corners unified to 4px globally (pills kept for pill/circle shapes) */
  --radius-sm: 4px;   --radius-md: 4px;   --radius-lg: 4px;
  --radius-xl: 4px;   --radius-2xl: 4px;  --radius-pill: 4px;
  --radius-tile: 4px;

  /* ELEVATION */
  --shadow-xs: 0 1px 2px rgba(29,57,34,.06);
  --shadow-sm: 0 2px 8px rgba(29,57,34,.06);
  --shadow-md: 0 8px 24px rgba(29,57,34,.08);
  --shadow-lg: 0 16px 40px rgba(29,57,34,.12);
  --shadow-focus:      0 0 0 3px rgba(45,99,73,.35);
  --shadow-focus-gold: 0 0 0 3px rgba(255,214,123,.55);

  /* BORDERS */
  --border-width: 1px;
  --border-width-strong: 1.5px;

  /* MOTION */
  --ease: cubic-bezier(.4, 0, .2, 1);
  --ease-out: cubic-bezier(0, 0, .2, 1);
  --duration-fast: 120ms;
  --duration-base: 200ms;
  --duration-slow: 320ms;

  /* Z-INDEX */
  --z-base: 0; --z-sticky: 100; --z-dropdown: 200;
  --z-overlay: 900; --z-modal: 1000; --z-toast: 1100;

  /* Asset paths for decorative shape backgrounds */
  --bg-navbar: url("Resources/sections/home/backgrounds/web_navbar.svg");
  --bg-navbar-mobile: url("Resources/sections/home/backgrounds/mobile_navbar.svg");
  --bg-announcement: url("Resources/sections/home/backgrounds/web_announcement.svg");
  --bg-service: url("Resources/sections/home/backgrounds/web_service card.svg");
  --bg-service-mobile: url("Resources/sections/home/backgrounds/mobile_service card.svg");
  --bg-donation: url("Resources/sections/home/backgrounds/web_donation-right-side-ng.svg");

  /* Per-card Service shapes (Our Services section) */
  --bg-service-quran:     url("Resources/sections/home/quran-classes-shape.svg");
  --bg-service-funeral:   url("Resources/sections/home/funeral-services.svg");
  --bg-service-nikah:     url("Resources/sections/home/nikah-services.svg");
  --bg-service-education: url("Resources/sections/home/islamic-education.svg");
  --bg-service-community: url("Resources/sections/home/community-support.svg");
  --bg-service-youth:     url("Resources/sections/home/youth-program.svg");
}

/* ============================================================
   LAYER 2 · BASE + PRIMITIVES
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* keep anchor targets clear of the sticky navbar (≈68px bar + 16px offset) */
  scroll-padding-top: 96px;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-base);
  color: var(--color-text-secondary);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  color: var(--color-text-primary);
  line-height: var(--leading-tight);
  margin: 0 0 var(--space-4);
}
h1 { font-size: var(--text-h1); }
h2 { font-size: var(--text-h2); }
h3 { font-size: var(--text-h3); font-weight: var(--weight-bold); }
h4 { font-size: var(--text-h4); }
p { margin: 0 0 var(--space-4); }
img { max-width: 100%; display: block; }

a { color: var(--color-accent-amber); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--radius-sm); }

/* Primitives ------------------------------------------------ */
.container {
  width: min(var(--container-max), 100% - 2 * var(--gutter));
  margin-inline: auto;
}
/* Unified section width: every wrapper routes through --container-max so all
   sections share identical left/right edges. Switching the whole site to
   --container-wide later is a one-token swap here (and on .landing below). */
.container--wide {
  width: min(var(--container-max), 100% - 2 * var(--gutter));
  margin-inline: auto;
}
.section { padding-block: clamp(var(--space-16), 8vw, var(--space-20)); }

.eyebrow {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-accent-amber);
  margin: 0;
}

.section-header { text-align: center; max-width: 640px; margin-inline: auto; margin-bottom: var(--space-12); }
.section-header__title { margin-block: var(--space-2); }
.section-header__intro { color: var(--color-text-secondary); font-size: var(--text-lg); margin: 0; }

.list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-1); }

/* ============================================================
   LAYER 3 · COMPONENTS
   ============================================================ */

/* --- Button ------------------------------------------------ */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  line-height: 1;
  padding: var(--space-3) var(--space-6);
  border: var(--border-width-strong) solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease),
              transform var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease);
  background: var(--color-primary);
  color: var(--color-on-primary);
}
.btn:hover  { background: var(--color-primary-hover); text-decoration: none; }
.btn:active { background: var(--color-primary-active); transform: translateY(1px); }
.btn:focus-visible { box-shadow: var(--shadow-focus); }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.btn--secondary { background: var(--color-secondary); color: var(--color-on-secondary); }
.btn--secondary:hover  { background: var(--color-secondary-hover); }
.btn--secondary:active { background: var(--color-secondary-active); }

.btn--outline { background: transparent; color: var(--color-secondary); border-color: var(--color-secondary); }
.btn--outline:hover { background: rgba(255,214,123,.14); }

.btn--solid-light { background: #FFFFFF; color: var(--color-text-primary); box-shadow: var(--shadow-sm); }
.btn--solid-light:hover { background: #F4F1EA; }

/* Inline text link. Defaults to dark green (light surfaces are the common case);
   the ONE dark-surface use (arabic-school hero) is re-gilded by the scoped
   .arabic-hero .btn--link override further down. */
.btn--link { background: transparent; border: 0; padding: 0; color: var(--color-primary); font-weight: var(--weight-semibold); }
.btn--link:hover { background: transparent; color: var(--color-primary-hover); text-decoration: underline; }
/* Inline text link: neutralise the solid-button focus pill (.btn / global :focus-visible)
   and use a subtle ring appropriate for an inline link. Scoped to .btn--link only. */
.btn--link:focus-visible { background: transparent; box-shadow: none; outline: var(--border-width-strong) solid var(--color-primary); outline-offset: 2px; text-decoration: underline; }

.btn--sm { font-size: var(--text-sm); padding: var(--space-2) var(--space-4); }
.btn--lg { font-size: var(--text-lg); padding: var(--space-4) var(--space-8); }
.btn--block { width: 100%; }

/* --- Icon tile (pastel-tile prayer/program/volunteer icons) - */
.icon-tile {
  width: 40px; height: 40px;
  border-radius: var(--radius-tile);
  flex: none;
  aspect-ratio: 1 / 1;      /* always square — prevents squished icons */
  object-fit: contain;
  /* These are <img>-embedded external SVGs, so `color`/currentColor can't reach
     inside — the single-color icons are authored with currentColor and recolored
     to the amber token via filter. Prayer icons hard-code #B5811C in-source and
     are two-tone (amber + white), so they opt out of the filter below. */
  filter: var(--filter-accent-amber);
}

/* --- List row (prayer times / volunteer) ------------------- */
.list-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  min-width: 0; /* let the label track shrink instead of overflowing */
}
.list-row__label { font-weight: var(--weight-medium); color: var(--color-text-primary); min-width: 0; white-space: nowrap; }
.list-row__value { color: var(--color-text-secondary); font-variant-numeric: tabular-nums; white-space: nowrap; }
.list-row__chevron { color: var(--color-text-secondary); transition: transform var(--duration-fast) var(--ease); }
.list-row--active { background: var(--color-highlight); }
.list-row--active .list-row__value { color: var(--color-text-primary); font-weight: var(--weight-semibold); }
.list-row--link { cursor: pointer; transition: background var(--duration-fast) var(--ease); }
.list-row--link:hover { background: var(--color-surface-cream); }
.list-row--link:hover .list-row__chevron { transform: translateX(3px); }

/* --- Progress bar (donation meter) ------------------------- */
.progress__track { height: 8px; border-radius: var(--radius-pill); background: #D9DFD3; overflow: hidden; }
.progress__fill  { height: 100%; border-radius: var(--radius-pill); background: var(--color-primary); transition: width var(--duration-slow) var(--ease); }
.progress__meta  { display: flex; justify-content: space-between; align-items: center; margin-top: var(--space-2); font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--color-text-primary); }
.progress__pct   { color: var(--color-text-secondary); }

/* --- Summary rows with dotted leader ----------------------- */
.summary { margin: 0; display: grid; gap: var(--space-1); }
.summary__row { display: flex; align-items: baseline; gap: var(--space-3); padding-block: var(--space-3); color: var(--color-text-secondary); }
.summary__row dt { margin: 0; order: 0; }
.summary__row dd { margin: 0; order: 2; color: var(--color-text-primary); font-weight: var(--weight-semibold); }
.summary__row::before {
  content: ""; flex: 1; align-self: flex-end; order: 1;
  border-bottom: 2px dotted var(--color-border-strong);
  transform: translateY(-4px);
}

/* --- Chip: pending / "to be confirmed" marker ---------------
   Reusable label for a value that is NOT yet confirmed. Muted
   neutral surface + amber text — deliberately NOT green, which
   on this site reads as confirmed/positive. Existing tokens only. */
.chip {
  display: inline-flex; align-items: center;
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs); font-weight: var(--weight-semibold);
  line-height: 1.5; white-space: nowrap;
}
.chip--pending {
  background: var(--color-surface-cream);
  border: var(--border-width) solid var(--color-border);
  color: var(--color-accent-amber);   /* #B5811C on cream ≈ 4.5:1, AA */
}
/* One neutral line describing WHAT a pending block will hold (never the
   content itself). Italic + muted so it never reads as final copy. */
.pending-note {
  margin: var(--space-3) 0 0;
  color: var(--color-text-secondary);
  font-size: var(--text-sm); font-style: italic;
}

/* --- Social button ----------------------------------------- */
.social-btn {
  display: grid; place-items: center;
  width: 42px; height: 42px; border-radius: var(--radius-pill);
  border: var(--border-width) solid var(--color-border-on-dark);
  color: var(--color-on-primary);
  transition: background var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.social-btn:hover { background: rgba(255,255,255,.1); border-color: var(--color-secondary); color: var(--color-secondary); }

/* ============================================================
   COMPONENT: Navbar
   ============================================================ */
.navbar {
  /* Full-bleed white bar, attached flush to the top. Sits at the dropdown layer
     (--z-dropdown, 200) — one above the sticky rails (--z-sticky, 100) — so its
     open submenu paints over any sticky rail it overhangs. The navbar establishes
     a stacking context, so its dropdown can never rise above a sibling rail on its
     own; lifting the whole navbar context is the root-cause fix. */
  position: sticky; top: 0; z-index: var(--z-dropdown);
  width: 100%;
  margin: 0;
  background: var(--color-bg);
  /* Hairline separation from the white page content below. */
  border-bottom: var(--border-width) solid var(--color-border);
}
.navbar__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-5);
  /* Content is constrained to the same unified 1400 frame + gutter as every
     section, so the navbar's left/right edges line up flush with them. */
  width: min(var(--container-max), 100% - 2 * var(--gutter));
  margin: 0 auto;
  padding: var(--space-3) 0;
}
.navbar__brand { display: flex; align-items: center; gap: var(--space-3); color: var(--color-text-primary); }
.navbar__brand:hover { text-decoration: none; }
/* Coloured emblem + text wordmark lockup (visible on the white bar). */
.navbar__logo-img { height: 44px; width: auto; display: block; }

.navbar__nav { display: flex; align-items: center; gap: clamp(var(--space-3), 1.5vw, var(--space-6)); }
.navbar__link { color: var(--color-text-primary); font-weight: var(--weight-medium); font-size: var(--text-sm); padding-block: var(--space-1); white-space: nowrap; }
.navbar__link:hover { color: var(--color-primary); text-decoration: none; }
.navbar__link--active { color: var(--color-primary); font-weight: var(--weight-semibold); }

/* Programs hover/focus dropdown (desktop nav) */
.navbar__dropdown { position: relative; display: flex; align-items: center; }
/* Trigger rendered as a <button> so it opens the menu without navigating;
   reset the native button chrome so it matches a plain .navbar__link. */
.navbar__dropdown-trigger {
  margin: 0;
  background: transparent;
  border: 0;
  cursor: pointer;
  font-family: inherit;
  line-height: inherit;
}
.navbar__submenu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: var(--z-dropdown);
  min-width: 220px;
  margin: 0;
  /* Top padding acts as a hover-bridge so the cursor can travel from the
     trigger to the menu without crossing a dead gap. */
  padding: var(--space-2) 0 0;
  list-style: none;
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  transition: opacity var(--duration-base) var(--ease), transform var(--duration-base) var(--ease), visibility var(--duration-base) var(--ease);
}
.navbar__submenu > li {
  background: var(--color-surface);
  border-inline: var(--border-width) solid var(--color-border);
}
.navbar__submenu > li:first-child {
  border-top: var(--border-width) solid var(--color-border);
  border-top-left-radius: var(--radius-lg);
  border-top-right-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
.navbar__submenu > li:last-child {
  border-bottom: var(--border-width) solid var(--color-border);
  border-bottom-left-radius: var(--radius-lg);
  border-bottom-right-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
.navbar__dropdown:hover .navbar__submenu,
.navbar__dropdown:focus-within .navbar__submenu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.navbar__submenu-link {
  display: block;
  padding: var(--space-2) var(--space-4);
  color: var(--color-text-primary);
  font-weight: var(--weight-medium);
  font-size: var(--text-sm);
  white-space: nowrap;
}
.navbar__submenu-link:hover,
.navbar__submenu-link:focus-visible {
  color: var(--color-primary);
  background: var(--color-surface-stone);
  text-decoration: none;
}

/* Mobile drawer: tap-to-toggle Programs sub-list */
.navbar__mobile-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;
  margin: 0;
  padding-inline: 0;
  background: transparent;
  border: 0;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  line-height: inherit;
}
.navbar__mobile-chevron {
  flex-shrink: 0;
  transition: transform var(--duration-base) var(--ease);
}
.navbar__mobile-toggle[aria-expanded="true"] .navbar__mobile-chevron {
  transform: rotate(180deg);
}
.navbar__mobile-submenu {
  list-style: none;
  margin: 0;
  padding: 0 0 0 var(--space-4);
  display: none;
  flex-direction: column;
  gap: var(--space-1);
  border-left: var(--border-width) solid var(--color-border);
}
.navbar__mobile-toggle[aria-expanded="true"] + .navbar__mobile-submenu {
  display: flex;
}
.navbar__mobile-subitem { font-size: var(--text-sm) !important; }

.navbar__actions { display: flex; align-items: center; gap: var(--space-3); }

.navbar__toggle { display: none; flex-direction: column; gap: 4px; width: 44px; height: 44px; align-items: center; justify-content: center; background: transparent; border: 0; cursor: pointer; }
.navbar__toggle span { width: 22px; height: 2px; background: var(--color-text-primary); border-radius: 2px; transition: transform var(--duration-base) var(--ease), opacity var(--duration-base) var(--ease); }
.navbar__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.navbar__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.navbar__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* Mobile drawer — a contained white card on the white bar (matches the 1400 frame). */
.navbar__mobile { display: none; flex-direction: column; gap: var(--space-2); width: min(var(--container-max), 100% - 2 * var(--gutter)); margin: var(--space-2) auto 0; padding: var(--space-5); background: var(--color-surface); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-xl); box-shadow: var(--shadow-md); }
.navbar__mobile .navbar__link { font-size: var(--text-base); padding-block: var(--space-2); }
.navbar__mobile-actions { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-2); }

/* ============================================================
   COMPONENT: Myth vs Fact  (accessible disclosure accordion)
   -------------------------------------------------------------
   *** NEW BEM BLOCK — flagged addition (did not exist before). ***
   A stack of disclosure items: each is a <button aria-expanded> that
   reveals a labelled region (role="region") holding a calm, factual
   answer. NOT tabs. Progressive enhancement: answers are visible by
   default (no JS); the Learn-page module (Phase 7) collapses them and
   toggles on click. Composes existing tokens ONLY — surface/border/
   cream/amber/green — no new colours, radii, or fonts.
   ============================================================ */
.myth { display: grid; gap: var(--space-3); }
.myth__item {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
/* The heading is a semantic wrapper only — the button carries the styling. */
.myth__heading { margin: 0; }
.myth__trigger {
  display: flex; align-items: center; gap: var(--space-3);
  width: 100%;
  min-height: 44px;                 /* a11y §6 — 44px minimum hit target */
  padding: var(--space-4) var(--space-5);
  background: transparent; border: 0; cursor: pointer;
  text-align: left;
  font-family: var(--font-display);
  font-size: var(--text-h4);
  font-weight: var(--weight-semibold);
  color: var(--color-text-primary);
  transition: background var(--duration-fast) var(--ease);
}
.myth__trigger:hover { background: var(--color-surface-cream); }
.myth__trigger:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
/* "Myth" chip — amber outline, mirrors the .eyebrow overline treatment. */
.myth__label {
  flex: none;
  font-family: var(--font-body);
  font-size: var(--text-xs); font-weight: var(--weight-semibold);
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--color-accent-amber);
  padding: var(--space-1) var(--space-2);
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius-sm);
}
.myth__claim { flex: 1 1 auto; min-width: 0; }
.myth__chevron {
  flex: none; color: var(--color-text-secondary);
  transition: transform var(--duration-base) var(--ease);
}
.myth__trigger[aria-expanded="true"] .myth__chevron { transform: rotate(180deg); }
.myth__panel {
  padding: var(--space-4) var(--space-5) var(--space-5);
  border-top: var(--border-width) solid var(--color-border);
}
.myth__panel[hidden] { display: none; }
.myth__fact { margin: 0; color: var(--color-text-secondary); }
/* "Fact." lead-in — green, so myth (amber) and fact (green) read distinctly. */
.myth__fact-label { font-family: var(--font-body); font-weight: var(--weight-semibold); color: var(--color-primary); }

/* ============================================================
   COMPONENT: Enrolment Status Band  (.enrol-status)
   -------------------------------------------------------------
   A calm, full-width callout announcing whether enrolment is
   open / full / closed. Hand-set to one state in the markup; a
   future CMS will drive it. Three status modifiers are defined so
   any one activates by class alone — --open (green tint), --full
   (gold tint), --closed (neutral surface). Message text stays dark
   on every fill for AA contrast. Button is the solid green .btn
   (light band → green per our button rule). Tokens only, no JS.
   ============================================================ */
/* The band is a full-width flow wrapper only — vertical rhythm, no fill.
   The visible card is the .container-width __inner, so the tinted, bordered,
   rounded card respects --container-max + the standard --gutter and never
   runs full-bleed. */
.enrol-status {
  margin-block: var(--space-6);
}
.enrol-status__inner {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5);
  border: var(--border-width) solid var(--color-border);   /* hairline outlines the card, not the viewport */
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
/* Gold medallion holding a dark-green line-icon (--color-on-secondary is the
   AA-legible text colour on gold — not white). 44px matches the .btn hit rhythm. */
.enrol-status__icon {
  flex: none;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--color-secondary);
  color: var(--color-on-secondary);
}
.enrol-status__icon svg { width: 22px; height: 22px; display: block; }
.enrol-status__message {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  font-weight: var(--weight-semibold);
  color: var(--color-text-primary);   /* dark on every fill — AA on all three */
}
.enrol-status__cta {
  flex: none;
  min-height: 44px;                    /* a11y — 44px minimum hit target */
  align-self: center;
}
/* Status tints live on the card (inner), driven by the section modifier so a
   single class on <section> still switches the state. */
.enrol-status--closed .enrol-status__inner { background: var(--color-surface-cream); }
.enrol-status--open   .enrol-status__inner { background: var(--color-primary-soft); }
.enrol-status--full   .enrol-status__inner { background: var(--color-highlight); }

/* Stack to icon/message-over-button on mobile; message may wrap. */
@media (max-width: 640px) {
  .enrol-status__inner {
    flex-wrap: wrap;
  }
  .enrol-status__cta {
    flex-basis: 100%;
  }
}

/* ============================================================
   LAYER 4 · LANDING (3-column grid)
   ============================================================ */
/* Landing shares the unified --container-max width so it lines up edge-for-edge
   with About/Services/Programs/Donate/footer. Side columns are 2.5:5:2.5 —
   left and right kept equal so the prayer card and the support/volunteer column
   are the same width; widened from 2:6:2 to give the side cards breathing room
   (the prayer rows in particular) at the current hero width. */
.landing { width: min(var(--container-max), 100% - 2 * var(--gutter)); margin: var(--space-6) auto 0; }
.landing__grid {
  display: grid; gap: 10px; align-items: stretch;
  grid-template-columns: minmax(0, 2.5fr) minmax(0, 5fr) minmax(0, 2.5fr);
  grid-template-rows: 1fr 1fr;
  grid-template-areas: "prayer hero support" "prayer hero volunteer";
}
.prayer-card    { grid-area: prayer; }
.hero           { grid-area: hero; }
.support-card   { grid-area: support; }
.volunteer-card { grid-area: volunteer; }

/* --- Prayer Times Card --- */
.prayer-card {
  background: var(--color-surface-stone);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-xl);
  padding: 14px;
  display: flex; flex-direction: column; gap: var(--space-3);
  min-height: 0;
}
.prayer-card__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.prayer-card__title { margin: 0; font-size: 1.125rem; }
.prayer-card__date { margin: 0; color: var(--color-text-secondary); font-size: var(--text-sm); white-space: nowrap; }
/* mosq.svg recoloured to gold via mask (SVG ships white-stroked) */
.prayer-card__mark {
  flex: none; width: 26px; height: 26px;
  background: var(--color-secondary-active);
  -webkit-mask: url("Resources/icons/mosq.svg") center / contain no-repeat;
          mask: url("Resources/icons/mosq.svg") center / contain no-repeat;
}
.prayer-card__list { gap: var(--space-1); }
/* Three columns — Name | Starts | Iqamah. The name track is flexible and
   shrinkable (minmax(0,1fr) + min-width:0 on the cell) so it can never push
   into or be overrun by the two fixed value tracks; the fixed value tracks keep
   the Starts/Iqamah header labels and every row's times (prayers, Sunrise,
   Jumu'ah) in line. --pc-time-col is sized to hold "12:30 PM" (tabular-nums)
   and no wider, leaving maximum room for the name. */
.prayer-card { --pc-icon-col: 26px; --pc-time-col: 3.5rem; }
.prayer-card__colhead,
.prayer-card .list-row {
  grid-template-columns: minmax(0, 1fr) var(--pc-time-col) var(--pc-time-col);
  column-gap: var(--space-3);
}
.prayer-card .list-row { padding: var(--space-1) var(--space-3); font-size: 0.875rem; }
.prayer-card .list-row__value { text-align: right; }
/* Name cell: icon-tile + label share the first track so every row starts its
   value columns at the same place. min-width:0 lets the track collapse instead
   of overflowing; the label then truncates *inside* the cell (below) rather
   than spilling over the Starts column. */
.prayer-card__name { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
/* Safety net so the name can never overlap the Starts time at any width: cap
   the label to its cell and ellipsis-truncate. Scoped to .prayer-card only —
   the shared base .list-row__label (Volunteer) is untouched. (Jumu'ah labels
   set flex-shrink:0 below and stay full-width, so this never clips them.) */
.prayer-card .list-row__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* Iqamah = emphasised value (dark, semibold); Starts stays lighter (secondary,
   regular — inherited from .list-row__value). */
.prayer-card__iqamah { color: var(--color-text-primary); font-weight: var(--weight-semibold); }
/* Muted em-dash placeholder wherever a value doesn't exist (Sunrise Iqamah,
   Jumu'ah Starts) so the three columns always align. */
.prayer-card__value--empty { color: var(--color-text-secondary); font-weight: var(--weight-regular); }
/* Next-prayer highlight: gold fill (base .list-row--active) + amber left accent
   bar via inset shadow (no layout shift) to read as one system with the amber
   countdown. Only real prayer rows ever get this class (see prayerTimes()). */
.prayer-card .list-row--active { box-shadow: inset 2px 0 0 0 var(--color-accent-amber); }
/* Jumu'ah group: subtle divider + small eyebrow heading; rows reuse the grid. */
.prayer-card__jumuah-group {
  margin-top: var(--space-2);
  padding-top: var(--space-3);
  border-top: var(--border-width) solid var(--color-border);
}
.prayer-card__group-label {
  margin: 0 0 var(--space-1);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
.prayer-card__jumuah-list { gap: var(--space-1); }
/* Keep the Jumu'ah label full-width; the chip then overflows into the empty left
   of the right-aligned Starts column instead of covering the label text. */
.prayer-card__jumuah .list-row__label { flex-shrink: 0; }
/* "(Br Only)" as a small 4px chip — soft brand tint, never a pill; flex:none so
   it doesn't fight the time columns. */
.prayer-card__chip {
  flex: none;
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  line-height: 1.4;
  padding: 1px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-highlight);
  color: var(--color-accent-amber);
}
.prayer-card__colhead {
  display: grid;
  align-items: center;
  padding: 0 var(--space-3) var(--space-1);
  margin-bottom: var(--space-1);
  border-bottom: var(--border-width) solid var(--color-border);
}
.prayer-card__coltitle {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
  text-align: right;
}
/* Iqamah header carries slightly more emphasis than Starts. */
.prayer-card__coltitle--iqamah { color: var(--color-accent-amber); }
/* Prayer icons are authored two-tone (hard-coded #B5811C amber + white detail),
   already correct via <img>; opt them out of the .icon-tile amber filter so the
   white accents aren't flattened. */
.prayer-card .icon-tile { width: var(--pc-icon-col); height: var(--pc-icon-col); filter: none; }
/* Next iqamah change card — white card with a muted label, large prayer name,
   and gold time line; auto-populated + revealed by main.js. */
.prayer-card__change {
  margin-top: var(--space-3);
  background: var(--color-surface); border-radius: var(--radius-lg);
  padding: var(--space-3); text-align: center; box-shadow: var(--shadow-xs);
}
.prayer-card__change-label { margin: 0; color: var(--color-text-secondary); font-size: var(--text-sm); }
.prayer-card__change-name { margin: var(--space-1) 0 0; font-family: var(--font-display); font-weight: var(--weight-semibold); color: var(--color-text-primary); font-size: var(--text-h4); }
.prayer-card__change-count { margin: var(--space-1) 0 0; color: var(--color-accent-amber); font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; letter-spacing: .04em; }

.prayer-card .btn { margin-top: auto; }

/* --- Hero --- */
.hero { position: relative; border-radius: var(--radius-xl); overflow: hidden; min-height: 0; height: 100%; isolation: isolate; }
.hero__media { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center 55%; z-index: -2; }
.hero__overlay {
  position: absolute; inset: 0; z-index: -1;
  /* Two stacked scrims over --color-text-primary (#1D3922 → 29,57,34):
     a diagonal scrim weighted to the top-left (where .hero__content sits)
     that fades to transparent toward the lower-right, keeping the bright
     roof/sky on the right vibrant; plus a soft vertical wash that lifts
     legibility across the text band and anchors the bottom edge. Slight
     by design — enough for AA-level white text, not a heavy flat wash. */
  background:
    linear-gradient(105deg, rgba(29,57,34,.62) 0%, rgba(29,57,34,.28) 45%, transparent 78%),
    linear-gradient(180deg, rgba(29,57,34,.45) 0%, rgba(29,57,34,.10) 40%, rgba(29,57,34,.55) 100%);
}
.hero__content { padding: clamp(var(--space-6), 3.5vw, var(--space-10)); max-width: 620px; }
.hero__title { color: #fff; font-size: clamp(2rem, 3.4vw, 3.25rem); margin-bottom: var(--space-4); }
.hero__subtitle { color: rgba(255,255,255,.92); font-size: var(--text-lg); max-width: 520px; margin: 0; }

.hero__badge {
  position: absolute; left: clamp(var(--space-4), 3vw, var(--space-8)); right: clamp(var(--space-4), 3vw, var(--space-8));
  bottom: clamp(var(--space-10), 6vw, 72px);
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  /* subtle frosted neutral-grey glass panel */
  background: rgba(38,38,42,0.34);
  border: 1px solid rgba(255,255,255,0.14);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-md);
  -webkit-backdrop-filter: blur(12px) saturate(120%); backdrop-filter: blur(12px) saturate(120%);
  color: #fff;
}
/* annountment.svg already includes the gold disc + white mosque */
/* Two-tone badge icon (amber body + white detail) authored with #B5811C
   in-source like the prayer icons — renders correctly via <img>, no filter. */
.hero__badge-icon { flex: none; width: 52px; height: 52px; display: block; aspect-ratio: 1 / 1; object-fit: contain; }
.hero__badge-text { flex: 1; min-width: 0; }
.hero__badge-text h4 { color: #fff; margin: 0 0 2px; }
.hero__badge-text p { color: rgba(255,255,255,.85); margin: 0; font-size: var(--text-sm); line-height: var(--leading-snug); }
.hero__badge .btn { flex: none; }

.dots { position: absolute; bottom: var(--space-5); left: 50%; transform: translateX(-50%); display: flex; gap: var(--space-2); }
.dot { width: 8px; height: 8px; padding: 0; border: 0; border-radius: var(--radius-pill); background: rgba(255,255,255,.55); cursor: pointer; transition: width var(--duration-base) var(--ease), background var(--duration-base) var(--ease); }
.dot--active { width: 22px; background: var(--color-secondary); }

/* --- Support / Volunteer cards (shared shell) --- */
.support-card, .volunteer-card {
  background: var(--color-surface-cream);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-xl);
  padding: 14px;
  display: flex; flex-direction: column; gap: var(--space-3);
  min-height: 0;
}
.support-card__head, .volunteer-card__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.support-card__title, .volunteer-card__title { margin: 0; font-size: 1.125rem; line-height: 1.2; white-space: nowrap; }
.support-card__sub, .volunteer-card__sub { margin: var(--space-1) 0 0; color: var(--color-text-secondary); font-size: var(--text-sm); }
.volunteer-card__list { gap: 0; }
.volunteer-card .list-row { padding: var(--space-1) var(--space-2); gap: var(--space-2); font-size: 0.875rem; }
.volunteer-card .icon-tile { width: 26px; height: 26px; }
.volunteer-card .btn, .support-card .btn--block { margin-top: auto; }

/* ============================================================
   SECTION: About Us + Prayer Facilities + Our Services
   ============================================================ */
.about--three-column .about__grid {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr) minmax(0, 5fr);
  grid-template-areas: "header-panel header-panel services" "media media services";
  align-items: stretch;
  column-gap: var(--space-6);
  row-gap: var(--space-8);
  background: var(--color-bg-about);
  border-radius: var(--radius-2xl);
  padding: clamp(var(--space-10), 5vw, var(--space-20)) clamp(var(--space-6), 4vw, var(--space-16));
}
.about--three-column .about__header-panel {
  grid-area: header-panel;
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  grid-template-areas: "about facilities";
  column-gap: var(--space-6);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-xl);
  padding: var(--space-8);
}
.about--three-column .about__text { grid-area: about; display: flex; flex-direction: column; min-width: 0; max-width: 44rem; padding: 0 var(--space-6) 0 0; }
.about--three-column .about__text p { max-width: 48ch; }
.about--three-column .facilities-col {
  grid-area: facilities;
  min-width: 0;
  padding: 0 var(--space-4) 0 var(--space-6);
  border-left: var(--border-width) solid var(--color-border);
}
.about--three-column .facilities-col__title { margin: 0; }
.about--three-column .about__heading { font-size: 32px; color: var(--color-primary); margin: 0 0 var(--space-5); max-width: 12ch; }
.about--three-column .about__text p { color: var(--color-text-secondary); margin: 0 0 var(--space-8); }
.about--three-column .about__media {
  grid-area: media;
  position: relative; isolation: isolate; aspect-ratio: 16 / 9; border-radius: var(--radius-xl);
  overflow: hidden; box-shadow: var(--shadow-md);
  background: var(--color-primary) var(--photo-pattern);
  background-size: 72px 72px;
  border: var(--border-width) solid var(--color-border);
  width: 100%;
  max-width: none;
  justify-self: stretch;
  margin-top: 0;
}
.about--three-column .about__media iframe {
  display: block;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  pointer-events: none;
}
.about--three-column .about__cta { align-self: flex-start; margin-bottom: 0; }
.about--three-column .facilities-list { display: grid; gap: var(--space-4); list-style: none; margin: var(--space-5) 0 0; padding: 0; }
.about--three-column .facilities-list__item { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.about--three-column .facilities-list__icon { display: grid; place-items: center; flex: none; width: 52px; height: 52px; border-radius: 50%; background: var(--color-surface); border: var(--border-width) solid var(--color-border); }
.about--three-column .facilities-list__icon .icon-tile { width: 28px; height: 28px; }
.about--three-column .facilities-list__label { color: var(--color-text-primary); font-weight: var(--weight-semibold); }

/* RIGHT — Our Services */
.about--three-column .services-col { grid-area: services; display: flex; flex-direction: column; min-width: 0; padding-left: clamp(var(--space-6), 3vw, var(--space-12)); border-left: var(--border-width) solid var(--color-border); }
.about--three-column .services-col__title { font-size: var(--text-h2); color: var(--color-primary); margin: var(--space-2) 0 0; }
.about--three-column .svc-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(0, 1fr));
  gap: var(--space-3); margin-top: var(--space-5);
  flex: 1;
}
.svc-card {
  display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center;
  min-width: 0; min-height: 0;
  gap: var(--space-3);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-4);
  transition: box-shadow var(--duration-base) var(--ease), transform var(--duration-base) var(--ease);
}
.svc-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
/* When a tile is itself a link (homepage Services grid → services.html#…),
   keep the card's own look: no underline, inherit the text colour. The
   existing hover lift doubles as the click affordance; global focus ring applies. */
a.svc-card { text-decoration: none; color: inherit; }
/* a reused .icon-tile SVG framed inside a circle */
.svc-card__icon {
  display: grid; place-items: center; flex: none;
  width: 64px; height: 64px; border-radius: 50%;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
}
.svc-card__icon .icon-tile { width: 30px; height: 30px; }
.svc-card__title { margin: 0; font-size: var(--text-h4); color: var(--color-primary); }
.svc-card__caption { margin: 0; color: var(--color-text-secondary); font-size: var(--text-sm); }

/* ============================================================
   SECTION: Our Services (mihrab cards — services.html detail pages)
   ============================================================ */
.services__grid {
  display: grid; grid-template-columns: repeat(6, 1fr);
  gap: var(--space-4); align-items: start;
}
.service-card {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start; text-align: center;
  gap: var(--space-3);
  padding: var(--space-8) var(--space-4) var(--space-10);
  /* fixed to the shape SVG's own aspect ratio (188 x 364) so background-size:100% 100%
     scales uniformly instead of stretching a different amount per card based on content height */
  aspect-ratio: 188 / 364;
  /* mihrab (pointed-arch) shape background */
  background: var(--bg-service) center/100% 100% no-repeat;
}
/* Hover: tint the card gold (--color-secondary), clipped to the same mihrab
   silhouette via mask-image so the tint never bleeds past the arch shape. */
.service-card::after {
  content: "";
  position: absolute; inset: 0; z-index: 0;
  background: var(--color-secondary);
  -webkit-mask: var(--card-shape, var(--bg-service)) center/100% 100% no-repeat;
          mask: var(--card-shape, var(--bg-service)) center/100% 100% no-repeat;
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease);
  pointer-events: none;
}
.service-card:hover::after { opacity: .28; }
/* Per-card background shapes */
.service-card--quran     { --card-shape: var(--bg-service-quran);     background-image: var(--card-shape); }
.service-card--funeral   { --card-shape: var(--bg-service-funeral);   background-image: var(--card-shape); }
.service-card--nikah     { --card-shape: var(--bg-service-nikah);     background-image: var(--card-shape); }
.service-card--education { --card-shape: var(--bg-service-education); background-image: var(--card-shape); }
.service-card--community { --card-shape: var(--bg-service-community); background-image: var(--card-shape); }
.service-card--youth     { --card-shape: var(--bg-service-youth);     background-image: var(--card-shape); }
.service-card__icon {
  width: 28px; height: 28px; position: relative; z-index: 1;
  /* <img> external SVG: recolored to the amber token via filter (color can't
     reach inside). The hover rule below fully replaces this single filter
     property with the green chain — no stacking/double-filtering. */
  filter: var(--filter-accent-amber);
  transition: filter var(--duration-base) var(--ease);
}
/* Keep the icon gold on hover — same amber token as the rest state, so the icon
   stays consistent with the homepage service icons. Icons are <img>s referencing
   external SVGs, so filter is the only CSS-only way to recolor them. */
.service-card:hover .service-card__icon {
  filter: var(--filter-accent-amber);
}
.service-card__title {
  margin: var(--space-1) 0 0; font-size: var(--text-h4);
  /* reserve 2 lines so 1-line and 2-line titles don't shift the rest of the content */
  display: flex; align-items: center; justify-content: center;
  min-height: calc(2 * var(--text-h4) * var(--leading-tight));
  position: relative; z-index: 1;
}
.service-card__media {
  /* spacer only — the circular photo is baked into the shape SVG background.
     Sized as a %-of-width + 1:1 aspect-ratio (not fixed px) so it scales with
     the card exactly like the SVG's own background-size:100% 100% does. */
  width: 44%; /* ≈ 82/188 — the shape SVG's circle diameter ratio */
  aspect-ratio: 1 / 1;
  flex: none;
}
.service-card__caption { margin: 0; color: var(--color-text-secondary); font-size: var(--text-sm); max-width: 16ch; position: relative; z-index: 1; }

/* ============================================================
   SECTION: Our Programs (light surface — mirrors About/Services)
   ============================================================ */
.programs__panel {
  overflow: hidden;   /* clip content to the rounded corners */
  background: var(--color-surface-cream);
  border-radius: var(--radius-2xl);
  padding: clamp(var(--space-10), 5vw, var(--space-20)) clamp(var(--space-6), 4vw, var(--space-16));
}
/* Header uses the same dark/green treatment as the other sections — no overrides needed */

.programs__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-6); }
/* Modifier: four grouped cards read as a 2×2 curriculum, not an awkward 3+1
   row (used by the Learn "deepen" disciplines). Placed before the responsive
   overrides below so the ≤1024 / ≤640 media rules still win at their widths. */
.programs__grid--pairs { grid-template-columns: repeat(2, 1fr); }
.program-card {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-3);
  background: var(--color-surface); border-radius: var(--radius-lg);
  padding: var(--space-6); box-shadow: var(--shadow-sm);
  transition: box-shadow var(--duration-base) var(--ease), transform var(--duration-base) var(--ease);
}
.program-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.program-card__title { margin: var(--space-1) 0 0; font-size: var(--text-h4); }
.program-card__body { margin: 0; color: var(--color-text-secondary); }
.program-card .btn--link { margin-top: auto; }

/* Light-surface treatment mirroring .svc-card — scoped to the Programs grid so the
   shared .program-card component stays neutral where it is reused (services.html). */
.programs__grid .program-card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  transition: box-shadow var(--duration-base) var(--ease), transform var(--duration-base) var(--ease);
}
.programs__grid .program-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.programs__grid .program-card__title { color: var(--color-primary); }
.programs__grid .program-card__body { color: var(--color-text-secondary); }

/* ============================================================
   SECTION: Donate Now (interactive)
   ============================================================ */
.donate.section { padding-block: clamp(var(--space-12), 6vw, var(--space-16)); }
.donate__grid { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: var(--space-6); align-items: stretch; }

/* LEFT selector — on desktop it stretches to the summary's height; space-between
   distributes the internal spacing so it fills cleanly with no gap at the bottom. */
.donate__selector {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-2xl);
  padding: clamp(var(--space-5), 2.5vw, var(--space-8));
  display: flex; flex-direction: column; justify-content: space-between; gap: var(--space-5);
}
.donate__title { margin: 0; font-size: var(--text-h2); }
.donate__step { display: flex; flex-direction: column; gap: var(--space-3); }
.donate__step-label {
  display: flex; align-items: center; gap: var(--space-2);
  margin: 0; font-size: var(--text-xs); font-weight: var(--weight-semibold);
  letter-spacing: .12em; text-transform: uppercase; color: var(--color-accent-amber);
}
.donate__num { color: var(--color-secondary-active); font-family: var(--font-body); letter-spacing: .1em; }

/* cause grid */
.cause-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.cause {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3); text-align: left; cursor: pointer;
  background: var(--color-surface);
  border: var(--border-width-strong) solid var(--color-border);
  border-radius: var(--radius-lg);
  transition: border-color var(--duration-fast) var(--ease), background var(--duration-fast) var(--ease), box-shadow var(--duration-fast) var(--ease);
}
.cause:hover { border-color: var(--color-secondary); }
.cause__icon { flex: none; width: 38px; height: 38px; display: grid; place-items: center; border-radius: var(--radius-tile); border: var(--border-width) solid var(--color-border); color: var(--color-accent-amber); }
.cause__text { display: flex; flex-direction: column; line-height: 1.3; }
.cause__text strong { font-family: var(--font-display); color: var(--color-text-primary); font-weight: var(--weight-semibold); }
.cause[aria-checked="true"] { border-color: var(--color-primary); background: var(--color-primary-soft); box-shadow: var(--shadow-sm); }
.cause[aria-checked="true"] .cause__icon { border-color: var(--color-primary); background: #fff; color: var(--color-primary); }

/* frequency toggle */
.freq-toggle { display: inline-flex; padding: var(--space-1); gap: var(--space-1); background: var(--color-surface-cream); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-pill); width: max-content; }
.freq {
  padding: var(--space-2) var(--space-4); border: 0; cursor: pointer; border-radius: var(--radius-pill);
  background: transparent; color: var(--color-text-secondary);
  font-family: var(--font-body); font-weight: var(--weight-semibold); font-size: var(--text-xs);
  letter-spacing: .01em;
  transition: background var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.freq[aria-checked="true"] { background: var(--color-primary); color: #fff; }

/* amount grid */
.amount-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); }
.amount {
  padding: var(--space-3); cursor: pointer;
  background: var(--color-surface);
  border: var(--border-width-strong) solid var(--color-border);
  border-radius: var(--radius-md);
  font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--text-base);
  color: var(--color-text-primary);
  transition: border-color var(--duration-fast) var(--ease), background var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.amount:hover { border-color: var(--color-secondary); }
.amount[aria-checked="true"] { background: var(--color-primary); border-color: var(--color-primary); color: var(--color-on-primary); }
.amount[aria-checked="true"]:focus-visible { box-shadow: var(--shadow-focus-gold); }

.amount-other { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); border: var(--border-width-strong) solid var(--color-border); border-radius: var(--radius-md); }
.amount-other:focus-within { border-color: var(--color-primary); box-shadow: var(--shadow-focus); }
.amount-other__sign { color: var(--color-text-secondary); font-weight: var(--weight-semibold); font-size: var(--text-sm); }
.amount-other__input { border: 0; outline: none; width: 100%; font-family: var(--font-body); font-size: var(--text-sm); color: var(--color-text-primary); background: transparent; }
.amount-other__input:focus-visible { box-shadow: none; }

/* RIGHT live summary */
.donate__summary { position: sticky; top: 96px; display: flex; flex-direction: column; }
.donate-summary {
  position: relative; overflow: hidden;
  border-radius: var(--radius-2xl);
  border: var(--border-width) solid var(--color-border);
  /* cream + geometric pattern + masjid illustration shape */
  background: var(--bg-donation) bottom center/cover no-repeat, var(--color-surface-cream);
  box-shadow: var(--shadow-sm);
  min-height: 500px;
  flex: 1 0 auto;
}
.donate-summary__head {
  background: linear-gradient(135deg, var(--color-primary) 0%, #1B3C2C 100%);
  color: #fff; padding: var(--space-6) var(--space-8) var(--space-5);
}
.donate-summary__eyebrow { margin: 0; font-size: var(--text-xs); font-weight: var(--weight-semibold); letter-spacing: .14em; text-transform: uppercase; color: var(--color-on-primary-dim); }
.donate-summary__amount { margin: var(--space-2) 0 0; font-family: var(--font-display); font-size: var(--text-h1); line-height: 1; color: #fff; }
.donate-summary__for { margin: var(--space-2) 0 0; color: var(--color-on-primary-dim); }
.donate-summary__body { padding: var(--space-5) var(--space-8) var(--space-6); }
.donate-summary__cta { margin-top: var(--space-4); }
.donate-summary__note { display: flex; align-items: center; justify-content: center; gap: var(--space-2); margin: var(--space-4) 0 0; color: var(--color-accent-amber); font-size: var(--text-sm); }

/* ============================================================
   COMPONENT: Footer
   ============================================================ */
.footer { background: var(--color-surface-cream); color: var(--color-text-primary); border-top: var(--border-width) solid var(--color-border); border-radius: var(--radius-2xl) var(--radius-2xl) 0 0; margin-top: var(--space-16); padding-block: clamp(var(--space-12), 6vw, var(--space-20)); }
.footer__cols { display: grid; grid-template-columns: 1.4fr 1fr 1.2fr 1fr; gap: var(--space-10); }
.footer__brand-row { display: flex; align-items: center; gap: var(--space-3); color: var(--color-text-primary); }
.footer__brand-row:hover { text-decoration: none; }
.footer__logo { flex: none; display: grid; place-items: center; }
.footer__logo img { height: 44px; width: auto; display: block; }
.footer__brand-text strong { display: block; font-family: var(--font-display); font-size: var(--text-h4); letter-spacing: .04em; }
.footer__brand-text small { color: var(--color-text-secondary); }
.footer__social { display: flex; gap: var(--space-3); margin-top: var(--space-6); }

/* Social buttons: scoped on-light restyle so the base .social-btn component
   stays reusable on dark surfaces elsewhere. */
.footer .social-btn { border-color: var(--color-border); color: var(--color-accent-amber); }
.footer .social-btn:hover { background: var(--color-primary-soft); border-color: var(--color-primary); color: var(--color-accent-amber); }

.footer__heading { color: var(--color-primary); font-size: var(--text-xs); font-weight: var(--weight-semibold); letter-spacing: .12em; text-transform: uppercase; margin: 0 0 var(--space-5); }
.footer__col { display: flex; flex-direction: column; gap: var(--space-4); }
.footer__col a { color: var(--color-text-primary); font-size: var(--text-base); }
.footer__col a:hover { color: var(--color-primary); text-decoration: none; }
.footer__qr { width: 132px; height: 132px; background: #fff; border: var(--border-width) solid var(--color-border); border-radius: var(--radius-lg); padding: var(--space-2); display: grid; place-items: center; }
.footer__qr img { width: 100%; height: 100%; object-fit: contain; }

.footer__bottom { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; margin-top: var(--space-12); padding-top: var(--space-6); border-top: var(--border-width) solid var(--color-border); }
.footer__copy { margin: 0; color: var(--color-text-secondary); font-size: var(--text-sm); }
.footer__legal { display: flex; gap: var(--space-6); }
.footer__legal a { color: var(--color-text-secondary); font-size: var(--text-sm); }
.footer__legal a:hover { color: var(--color-primary); text-decoration: none; }

/* ============================================================
   COMPONENT: Back to Top
   ============================================================ */
.back-to-top {
  position: fixed; right: clamp(var(--space-4), 3vw, var(--space-8)); bottom: clamp(var(--space-4), 3vw, var(--space-8));
  z-index: var(--z-sticky);
  width: 52px; height: 52px; border-radius: var(--radius-pill);
  display: grid; place-items: center; cursor: pointer;
  background: var(--color-primary); color: #fff; border: 0;
  box-shadow: var(--shadow-lg);
  opacity: 0; visibility: hidden; transform: translateY(12px);
  transition: opacity var(--duration-base) var(--ease), transform var(--duration-base) var(--ease), background var(--duration-fast) var(--ease), visibility var(--duration-base);
}
.back-to-top.is-visible { opacity: 1; visibility: visible; transform: translateY(0); }
.back-to-top:hover { background: var(--color-primary-hover); }

/* ============================================================
   COMPONENT: Services Hero  (services.html)
   -------------------------------------------------------------
   *** NEW BEM BLOCK — flagged addition (did not exist before). ***
   Hero band that layers a decorative background image over the
   dark-green base surface, mirroring index.html's .hero overlay
   pattern. --color-surface-dark is the base layer, so the green
   shows through underneath on ratios the image can't fully cover.
   Foreground text uses the on-dark text tokens. Composes existing
   tokens/radii ONLY — the overlay rgba reuses the same darkening
   gradient as .hero__overlay (RGB of --color-text-primary,
   #1D3922 → 29,57,34), no new colours introduced.
   ============================================================ */
.services-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  width: min(var(--container-max), 100% - 2 * var(--gutter));
  /* Top margin matches .landing's navbar-to-content rhythm (var(--space-6))
     so the hero sits flush under the floating navbar with no white band.
     Bottom margin is 0 so the sticky tab bar butts directly against the
     hero's bottom edge (the section below zeroes its top padding to match). */
  margin: var(--space-6) auto 0;
  border-radius: var(--radius-lg);   /* 4px */
  /* Decorative image (cover, centred, no-repeat) over the dark-green
     base; green is the fallback layer beneath it. */
  background: url("Resources/sections/services/hero-img.jpg") center / cover no-repeat,
              var(--color-surface-dark);
}
.services-hero__overlay {
  position: absolute; inset: 0; z-index: -1;
  /* Token-based rgba over --color-text-primary (#1D3922 → 29,57,34),
     same overlay approach as .hero__overlay. Vertical gradient that
     holds a solid ~82% dark-green plateau across the CENTRED text band
     (32%–68%) and fades to ~50% at the top/bottom edges, so white/gold
     text clears WCAG AA over the busiest part of the image (measured
     ≥4.6:1 even against a near-white region) while the photo still
     reads at the edges. */
  background: linear-gradient(180deg,
    rgba(29,57,34,.5) 0%,
    rgba(29,57,34,.82) 32%,
    rgba(29,57,34,.82) 68%,
    rgba(29,57,34,.5) 100%);
}
/* Eyebrow uses the on-dark gold (--color-secondary), the same gold the
   navbar uses on this green surface — the default #B5811C accent-amber
   is too dark to read over the darkened image. */
.services-hero .eyebrow { color: var(--color-secondary); }
.services-hero__content {
  text-align: center;
  max-width: 640px;
  margin-inline: auto;
  padding: clamp(var(--space-10), 6vw, var(--space-16)) var(--space-6);
}
.services-hero__title { color: var(--color-on-primary); margin-block: var(--space-2); }
.services-hero__intro { color: var(--color-on-primary-dim); font-size: var(--text-lg); margin: 0; }

/* ============================================================
   COMPONENT: Page Hero  (reusable — privacy-policy.html, and future
   legal/utility pages such as Terms)
   -------------------------------------------------------------
   *** NEW BEM BLOCK — flagged addition (did not exist before). ***
   A green intro band, modelled on .services-hero but with NO required
   background image: the default is a SOLID green band on
   --color-surface-dark. Same width / top-margin / radius rhythm as
   .services-hero, so the two read as the same family. Foreground text
   uses the on-dark text tokens; white/gold on the solid #224A37 green
   clears WCAG AA comfortably (white ≈ 9:1, gold ≈ 7:1). Composes
   existing tokens/radii ONLY — no new colours.

   Optional image: a page may add its own `background-image` to
   .page-hero and include a .page-hero__overlay element to darken it
   (the overlay reuses the same token-based darkening as .hero /
   .services-hero — RGB of --color-text-primary, #1D3922 → 29,57,34).
   The overlay is inert on the solid-green default and is omitted from
   the markup there.
   ============================================================ */
.page-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  width: min(var(--container-max), 100% - 2 * var(--gutter));
  margin: var(--space-6) auto 0;    /* same top rhythm as .services-hero */
  border-radius: var(--radius-lg);
  background: var(--color-surface-dark);   /* solid green — no image required */
}
.page-hero__overlay {
  position: absolute; inset: 0; z-index: -1;
  /* Only meaningful when a page layers a background image on .page-hero;
     inert over the solid-green default. Same darkening plateau as
     .services-hero__overlay so text stays AA over a busy image. */
  background: linear-gradient(180deg,
    rgba(29,57,34,.5) 0%,
    rgba(29,57,34,.82) 32%,
    rgba(29,57,34,.82) 68%,
    rgba(29,57,34,.5) 100%);
}
/* Eyebrow uses the on-dark gold (--color-secondary), like .services-hero —
   the default accent-amber is too dark to read on green. */
.page-hero .eyebrow { color: var(--color-secondary); }
.page-hero__content {
  text-align: center;
  max-width: 640px;
  margin-inline: auto;
  padding: clamp(var(--space-10), 6vw, var(--space-16)) var(--space-6);
}
.page-hero__title { color: var(--color-on-primary); margin-block: var(--space-2); }
.page-hero__intro { color: var(--color-on-primary-dim); font-size: var(--text-lg); margin: 0; }

/* ============================================================
   COMPONENT: Legal / Long-form Reading Layout  (.legal)
   -------------------------------------------------------------
   *** NEW BEM BLOCK — flagged addition (did not exist before). ***
   The site's first long-form reading column, for policy/legal
   pages (privacy-policy.html, and future pages such as Terms).
   A narrow measure (~66ch) centred in the .container for a
   comfortable line length, with generous vertical rhythm.
   Section <h2>s inherit El Messiri from the base h1–h4 rule and
   are held in brand green (--color-primary); body copy inherits
   Albert Sans / --color-text-secondary / --leading-base from the
   base. Spacing and type tokens ONLY — no radius/colour changes.
   ============================================================ */
.legal {
  max-width: 66ch;                 /* comfortable reading measure */
  margin-inline: auto;
  padding-block: clamp(var(--space-16), 8vw, var(--space-20));
}
.legal__section { margin-top: var(--space-12); }
.legal__section:first-child { margin-top: 0; }
.legal h2 { color: var(--color-primary); margin-bottom: var(--space-4); }
.legal p { margin-bottom: var(--space-4); }
.legal p:last-child { margin-bottom: 0; }
.legal ul {
  list-style: disc;
  margin: 0 0 var(--space-4);
  padding-left: var(--space-6);
}
.legal li { margin-bottom: var(--space-2); }
.legal li:last-child { margin-bottom: 0; }
/* "Last updated" line — smaller and muted, set off from the body. */
.legal__updated {
  margin-top: var(--space-12);
  font-size: var(--text-sm);
  font-style: italic;
  color: var(--color-text-secondary);
}

/* Print — legal/policy pages (.page-hero + .legal). Printers commonly drop
   background fills, which would leave the hero's WHITE title on white paper;
   render the band as ink-safe dark-on-white instead, and let the reading
   column use the full page width. No fixed heights anywhere in these blocks,
   so nothing clips. Scoped to these two components only (privacy-policy.html
   and future legal pages) — the rest of the site's print output is unchanged,
   apart from hiding the fixed back-to-top control. Tokens only. */
@media print {
  .page-hero { background: none; margin-top: 0; overflow: visible; }
  .page-hero__content { padding: 0 0 var(--space-6); }
  .page-hero__title { color: var(--color-primary); }
  .page-hero .eyebrow,
  .page-hero__intro { color: var(--color-text-secondary); }
  .legal { max-width: none; padding-block: var(--space-6); }
  .back-to-top { display: none !important; }
}

/* The services section's tab bar is its first child; zero the section's
   TOP padding (keep the bottom) so the sticky tab bar sits flush against
   the hero above it. Resting position only — sticky offset is unchanged.
   A warm-neutral page ground (--color-bg-about) so the white .service-detail
   cards below read as raised figures, not a flat white-on-white wireframe.
   Horizontal padding/container behaviour is unchanged (the inner .container
   still controls the measure). */
.services.section { padding-top: 0; background: var(--color-bg-about); }

/* ============================================================
   COMPONENT: Service Tabs  (shared: services / library / about-us)
   -------------------------------------------------------------
   *** NEW BEM BLOCK — flagged addition (did not exist before). ***
   A sticky, horizontally-scrollable tab bar linking to each section.
   Composes existing tokens ONLY — no new colours/radii. ONE global
   appearance — NO colour variants. Hover reuses the surface-cream
   token; the active tab is a solid green pill (--color-primary + white
   label/icon), consistent with the brand's filled-selection convention.
   ============================================================ */
.service-tabs {
  position: sticky;
  /* Sit just below the sticky navbar. Composed from tokens:
     navbar top (--space-4, 16px) + navbar height (~68px) ≈ 84px
     → --space-16 (64) + --space-5 (20) = 84px. */
  top: calc(var(--space-16) + var(--space-5));
  z-index: var(--z-sticky);
  display: flex;
  /* Tabs cluster from the START of the bar (NOT stretched edge-to-edge): a
     small, even --space-2 gap between each, with any slack trailing to the
     right. Reads as a left-aligned nav at every tab count — 3 tabs no longer
     scatter to the corners. When the tabs overflow (narrow screens) they pack
     from the start, so overflow-x:auto still scrolls them on mobile. */
  justify-content: flex-start;
  gap: var(--space-2);
  margin-bottom: var(--space-12);
  /* Tight --space-1 track (matches the Learn toggle's .freq-toggle) so the band
     hugs the compact pills. */
  padding: var(--space-1);
  /* Cream track — shares the Learn toggle's (.freq-toggle) active-pill surface
     language: cream band + solid-green active pill. */
  background: var(--color-surface-cream);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  /* Horizontal scroll on narrow screens without wrapping/breaking the row. */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}
.service-tabs__tab {
  flex: none;                 /* keep tabs on one row; the bar scrolls instead */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  /* Compact pill matching the Learn toggle's .freq scale (deliberate exception
     to §6's 44px — still ≥ WCAG 2.5.8 24px AA). Padding rhythm = the .freq
     button; with the 14px label this yields a ~32–34px pill. */
  min-height: 32px;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  letter-spacing: .01em;
  font-weight: var(--weight-medium);
  color: var(--color-text-secondary);
  white-space: nowrap;
  transition: background var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease);
}
.service-tabs__tab:hover {
  /* Soft-green tint, NOT surface-cream — that is now the track colour, so a
     cream hover would be invisible. Reads on cream and hints toward the green
     active state. */
  background: var(--color-primary-soft);
  color: var(--color-text-primary);
  text-decoration: none;
}
.service-tabs__tab:focus-visible { box-shadow: var(--shadow-focus); }
.service-tabs__icon { width: 18px; height: 18px; flex: none; aspect-ratio: 1 / 1; object-fit: contain; filter: var(--filter-accent-amber); }
/* Active tab — solid green pill with a white label + white icon; reads clearly
   as "selected" against the cream rail (the brand's filled-selection convention).
   Re-declared for :hover so the green pill holds through hover. */
.service-tabs__tab--active,
.service-tabs__tab--active:hover {
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-weight: var(--weight-semibold);
}
.service-tabs__tab--active .service-tabs__icon { filter: brightness(0) invert(1); }

/* ============================================================
   COMPONENT: Service Detail sections  (services.html)
   -------------------------------------------------------------
   *** NEW BEM BLOCK — flagged addition (did not exist before). ***
   Two-column per-service layout: a sticky identity rail (green medallion +
   header) in column 1 beside the stacked detail blocks (.program-card body +
   Common questions) in column 2. Composes existing components; only the
   layout wrapper, the medallion, and a few scoped tweaks are new, all reading
   existing tokens ONLY.
   ============================================================ */
/* Each service is a distinct raised white card on the warm-neutral page
   ground, so the four sections read as separate figures rather than one flat
   sheet. Surface + border + --radius-lg + soft shadow, with comfortable
   interior padding (block --space-12 / inline --space-10 on desktop). */
.service-detail {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding-block: var(--space-12);
  padding-inline: var(--space-10);
  /* html already sets scroll-padding-top:96px (clears the navbar); add the
     sticky tab-bar height (~62px → --space-16) so headings aren't hidden
     under the tab bar when a tab anchor is jumped to. */
  scroll-margin-top: var(--space-16);
}
/* Consecutive cards are separated by vertical whitespace (not a hairline):
   the warm ground shows between the raised surfaces. */
.service-detail + .service-detail { margin-top: var(--space-16); }
.service-detail__grid {
  display: grid;
  /* identity rail (left) + detail column (right) */
  grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
  /* ONE block rhythm: --space-8 row gap between the stacked detail blocks
     (content · questions), matching the stacked-layout gap below; the wider
     column gap opens the rail off the details. */
  gap: var(--space-8) var(--space-12);
  align-items: start;
}
/* LEFT COLUMN — the identity rail: green medallion + amber eyebrow + green H2 +
   one muted intro line. It spans BOTH implicit rows of column 1 (the two
   stacked detail blocks) and is sticky on desktop, so the service's identity
   stays beside the details as the reader scrolls the taller right column. */
.service-detail__rail {
  grid-column: 1;
  grid-row: 1 / span 2;
  position: sticky;
  /* Clear the navbar AND the sticky .service-tabs bar. Mirror the tab bar's
     own navbar offset (--space-16 + --space-5 = 84px) then add --space-16 for
     the tab bar's height, so the rail parks just beneath it. */
  top: calc(var(--space-16) + var(--space-5) + var(--space-16));
  align-self: start;
}
/* Green medallion — a filled --color-primary rounded square (--space-20 ≈ 80px)
   that anchors the rail. Holds the service icon rendered WHITE via the same
   brightness/invert filter the active service tab uses (no new coloured SVG).
   Purely a visual anchor — the service title is the adjacent H2, never repeated
   here as a caption. */
.service-detail__medallion {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-20);
  height: var(--space-20);
  margin-bottom: var(--space-5);
  background: var(--color-primary);
  border-radius: var(--radius-lg);
}
.service-detail__medallion-icon {
  width: var(--space-10);
  height: var(--space-10);
  flex: none;
  filter: brightness(0) invert(1);   /* icon white on green — same trick as .service-tabs__tab--active */
}
/* RIGHT COLUMN — the detail blocks stack in column 2 (What's included /
   At a glance, then Common questions). */
.service-detail__content,
.service-detail__questions { grid-column: 2; }
/* content reuses .program-card; neutralise its hover-lift at this large size */
.service-detail__content { width: 100%; }
.service-detail__content:hover { transform: none; box-shadow: var(--shadow-sm); }
/* "What's included" — reuse .list/.list-row but allow multi-line labels
   (list-row was built for short label+value rows, hence the nowrap reset) */
.service-detail__list { width: 100%; gap: var(--space-1); }
.service-detail__list .list-row { align-items: start; }
.service-detail__list .list-row__label { white-space: normal; font-weight: var(--weight-regular); color: var(--color-text-secondary); }
.service-detail__check { color: var(--color-accent-amber); margin-top: 2px; }

/* Stack the identity rail above the details from tablet down: the 300px rail
   crowds the detail column below ~1024px. Reuses the existing 1024px breakpoint
   used elsewhere in this file — NOT a new one. The rail un-sticks and the
   medallion + title lead each service as a stacked anchor. */
@media (max-width: 1024px) {
  .service-detail__grid { grid-template-columns: 1fr; gap: var(--space-8); }
  /* Single column: reset the rail's row-span and DISABLE stickiness so it
     scrolls away above the details instead of pinning. */
  .service-detail__rail {
    grid-column: auto;
    grid-row: auto;
    position: static;
  }
  .service-detail__content,
  .service-detail__questions { grid-column: auto; }
}

/* Scale the card's interior padding down on the smallest screens so the
   content keeps its edge breathing room without crowding — reuses the
   homepage 640px breakpoint. */
@media (max-width: 640px) {
  .service-detail { padding-block: var(--space-8); padding-inline: var(--space-6); }
}

/* ============================================================
   RESPONSIVE · Navbar collapse (≤1160px)
   Collapses earlier than the tablet layout: the full link row +
   action buttons, including Past Programs, need about 970px of space.
   ============================================================ */
@media (max-width: 1160px) {
  .navbar__nav, .navbar__actions { display: none; }
  .navbar__toggle { display: flex; }
  .navbar.is-open .navbar__mobile { display: flex; }
}

/* ============================================================
   RESPONSIVE · Tablet (≤1024px)
   ============================================================ */
@media (max-width: 1024px) {
  /* Tablet + mobile share one 16px page gutter (inherited down through ≤640). */
  :root { --gutter: 16px; }

  /* Landing → mobile order: Hero > Prayer Times > Donation(Support) > Volunteer */
  .landing__grid {
    grid-template-columns: 1fr;
    grid-template-rows: none;
    grid-template-areas: "hero" "prayer" "support" "volunteer";
    gap: var(--space-6);
    height: auto; /* let stacked cards size to content below desktop */
  }
  .hero { min-height: 440px; height: auto; }

  /* Services 6 → 3 */
  .services__grid { grid-template-columns: repeat(3, 1fr); gap: var(--space-6); row-gap: var(--space-8); }
  /* Programs 3 → 2 */
  .programs__grid { grid-template-columns: repeat(2, 1fr); }

  /* Donate stacks: selector then summary below */
  .donate__grid { grid-template-columns: 1fr; gap: var(--space-6); }
  .donate__summary { position: static; }
  .donate-summary { min-height: 0; }

  .about--three-column .about__grid {
    grid-template-columns: 1fr;
    grid-template-areas: "header-panel" "media" "services";
  }
  .about--three-column .services-col {
    padding: var(--space-8) 0 0;
    border-left: 0;
    border-top: var(--border-width) solid var(--color-border);
  }

  /* Footer → 2 columns */
  .footer__cols { grid-template-columns: 1fr 1fr; gap: var(--space-8); }
  .footer__brand { grid-column: 1 / -1; }
}

/* ============================================================
   RESPONSIVE · Mobile (≤640px)
   ============================================================ */
@media (max-width: 640px) {
  /* --gutter stays 16px (inherited from the ≤1024 rule); only type shrinks here. */
  :root { --text-h1: 2rem; --text-h2: 1.625rem; }

  .navbar { top: 0; margin: 0; }
  .navbar__inner { padding: var(--space-2) 0; }

  /* Service tabs stick below the shorter mobile navbar (~68px):
     --space-16 (64) + --space-1 (4) = 68px. */
  .service-tabs { top: calc(var(--space-16) + var(--space-1)); }

  /* Services 3 → 2 ; mihrab uses the mobile shape */
  .services__grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-4); }
  .service-card { padding: var(--space-6) var(--space-3) var(--space-8); }

  /* Programs 2 → 1 */
  .programs__grid { grid-template-columns: 1fr; }

  /* Homepage About section → one column: About panel, video, services. */
  .about--three-column .about__grid {
    grid-template-columns: 1fr;
    grid-template-areas: "header-panel" "media" "services";
  }
  .about--three-column .about__header-panel {
    grid-template-columns: 1fr;
    grid-template-areas: "about" "facilities";
    row-gap: var(--space-6);
    padding: var(--space-6) var(--space-5);
  }
  .about--three-column .about__text { max-width: 48rem; padding: 0; }
  .about--three-column .about__heading { max-width: none; }
  .about--three-column .about__media { width: 100%; max-width: none; justify-self: stretch; }
  .about--three-column .facilities-col { padding: var(--space-6) 0 0; border-left: 0; border-top: var(--border-width) solid var(--color-border); }
  .about--three-column .services-col {
    padding: var(--space-8) 0 0;
    border-left: 0;
    border-top: var(--border-width) solid var(--color-border);
  }
  .about--three-column .svc-grid { grid-template-columns: 1fr; }
  .svc-card { min-height: 84px; padding-inline: var(--space-4); }

  /* Cause grid → 1 column */
  .cause-grid { grid-template-columns: 1fr; }
  .amount-grid { grid-template-columns: repeat(2, 1fr); }

  /* Donate summary head amount a touch smaller */
  .donate-summary__amount { font-size: var(--text-h1); }

  /* Footer → single column */
  .footer__cols { grid-template-columns: 1fr; }
  .footer__bottom { flex-direction: column; align-items: flex-start; }

  /* Announcement badge joins the flow below the hero copy instead of
     floating over it — prevents title/badge overlap on short screens. */
  .hero { display: flex; flex-direction: column; }
  .hero__badge {
    position: static;
    flex-wrap: wrap;
    margin: auto var(--space-4) var(--space-12);
  }
  .hero__badge .btn { width: 100%; }
}

/* Small phones */
@media (max-width: 380px) {
  .amount-grid { grid-template-columns: 1fr 1fr; }
  .freq { padding-inline: var(--space-4); }
}

/* ============================================================
   Scroll reveal  (progressive enhancement — hidden state scoped to .js)
   Elements start faded + nudged down, then ease into place when observed.
   ============================================================ */
.js .reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity var(--duration-slow) var(--ease-out),
              transform var(--duration-slow) var(--ease-out);
}
.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* Stagger children of a card grid; --i set per-card in JS, capped so the
   last card never lags far behind. */
.js .reveal--stagger.is-visible > * {
  transition-delay: calc(var(--i, 0) * 80ms);
}

/* ============================================================
   COMPONENT: Modal — full-month prayer times dialog
   ============================================================ */
.modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  animation: modal-fade var(--duration-base) var(--ease-out);
}
.modal[hidden] { display: none; }

@keyframes modal-fade { from { opacity: 0; } to { opacity: 1; } }

.modal__scrim {
  position: absolute;
  inset: 0;
  z-index: var(--z-overlay);
  /* RGB of --color-text-primary (#1D3922) at partial alpha — matches shadow rgba convention */
  background: rgba(29, 57, 34, .55);
}

.modal__panel {
  position: relative;
  z-index: var(--z-modal);
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: min(920px, 92vw);
  max-height: 88vh;
  background: var(--color-surface);
  border-radius: var(--radius-2xl);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

.modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-6);
  border-bottom: 1px solid var(--color-divider);
}

.modal__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-h4);
  color: var(--color-text-primary);
}

.modal__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  color: var(--color-text-primary);
  background: transparent;
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease);
}
.modal__close:hover { background: var(--color-surface-stone); }
.modal__close:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

.modal__body {
  padding: var(--space-4) var(--space-6) var(--space-6);
  overflow: auto;
}

.modal__note {
  margin: var(--space-4) 0;
  color: var(--color-text-secondary);
  font-family: var(--font-body);
  font-size: var(--text-sm);
}

.modal__table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.modal__table th,
.modal__table td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border);
  text-align: center;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.modal__table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--color-surface-stone);
  color: var(--color-text-primary);
  font-weight: var(--weight-semibold);
}
/* First column (Date) reads as a row label — left-aligned, non-numeric */
.modal__table th:first-child,
.modal__table td:first-child {
  text-align: left;
  font-variant-numeric: normal;
}
.modal__table tbody tr:nth-child(even) { background: var(--color-surface-cream); }
/* Today's row wins over the zebra stripe — same gold as .list-row--active */
.modal__table tbody tr.modal__row--today { background: var(--color-highlight); }
.modal__table tbody tr.modal__row--today td { color: var(--color-text-primary); font-weight: var(--weight-semibold); }

@media (max-width: 640px) {
  .modal__head { padding: var(--space-4); }
  .modal__body { padding: var(--space-3) var(--space-4) var(--space-4); }
}

/* ============================================================
   Reduced motion
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  /* Never hide or move content for users who prefer reduced motion. */
  .reveal { opacity: 1 !important; transform: none !important; }
}

/* ============================================================
   PAGE: Learn About Islam  (learn-about-islam.html)
   -------------------------------------------------------------
   *** NEW BEM BLOCKS — flagged addition (did not exist before). ***
   Entry chooser (intent fork) + sticky path switcher + path panels.
   Composes existing tokens/patterns ONLY — no new colours, radii,
   or fonts. The intent cards mirror the .svc-card frame; the switcher
   reuses the .freq-toggle segmented control from the Donate section;
   the sticky offset mirrors .service-tabs so it sits under the navbar.
   ============================================================ */

/* Entry chooser — a deliberate threshold, not a page that ran out of content.
   Warm cream ground so the white intent cards lift off it (they were dissolving
   into a white page). Owns the first viewport: min-height minus the 68px navbar,
   with the container vertically centred. Tokens only — no new colours. */
.learn-chooser {
  display: flex;
  align-items: center;
  min-height: calc(100vh - 68px);
  background: var(--color-surface-cream);
}

/* Eyebrow as a centred ornament: the amber overline flanked by two short gold
   hairlines. Pseudo-elements keep the markup untouched. */
.learn-chooser .eyebrow {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
}
.learn-chooser .eyebrow::before,
.learn-chooser .eyebrow::after {
  content: "";
  width: var(--space-8);
  height: var(--border-width);
  background: var(--color-accent-amber);
}

/* Display-scale title (El Messiri, inherited from the base h1 rule) and a
   comfortable measure on the intro so it stops centring awkwardly. */
.learn-chooser .section-header__title { font-size: var(--text-display); }
.learn-chooser .section-header__intro { max-width: 46ch; margin-inline: auto; }

/* Entry chooser — two equal-weight intent cards + a quiet escape hatch. */
.choice-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-6);
  max-width: 760px;
  margin: var(--space-10) auto 0;
}
/* Equal-weight cards: identical surface/border for both — no primary vs
   secondary hierarchy. Interactive anchors so they work without JS (jump to
   the matching path panel). Left-aligned content; a 3px gold top rule marks
   each as a distinct panel against the cream (flush with the 4px radius). */
.choice-card {
  display: flex; flex-direction: column; align-items: stretch; text-align: left;
  gap: var(--space-4);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-top: 3px solid var(--color-secondary);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  color: inherit;
  transition: box-shadow var(--duration-base) var(--ease),
              transform var(--duration-base) var(--ease),
              border-color var(--duration-base) var(--ease);
}
.choice-card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
  border-color: var(--color-border-strong);
  border-top-color: var(--color-secondary);
  text-decoration: none;
}
/* Header row — icon inline with the title, left-aligned. */
.choice-card__head { display: flex; align-items: center; gap: var(--space-4); }
/* Circular amber icon frame — same construction as .svc-card__icon, but the
   inline SVG uses currentColor (like .cause__icon) so it reads gold. */
.choice-card__icon {
  display: grid; place-items: center; flex: none;
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  color: var(--color-accent-amber);
}
.choice-card__icon svg { width: 22px; height: 22px; }
.choice-card__title { margin: 0; font-size: var(--text-h4); color: var(--color-primary); }
.choice-card__desc  { margin: 0; color: var(--color-text-secondary); font-size: var(--text-base); }

/* "What's inside" peek — a short contents list under a hairline divider, each
   line led by a small gold check. Tells the user what's behind the door. */
.choice-card__list {
  list-style: none; margin: 0; padding: var(--space-4) 0 0;
  border-top: var(--border-width) solid var(--color-divider);
  display: grid; gap: var(--space-2);
}
.choice-card__list li {
  position: relative; padding-left: var(--space-6);
  color: var(--color-text-secondary); font-size: var(--text-sm);
}
.choice-card__list li::before {
  content: "\2713"; position: absolute; left: 0; top: 0;
  color: var(--color-accent-amber); font-weight: var(--weight-semibold);
}
/* Affordance — a "Start here" label + circular green arrow. Pushed to the foot
   so the card ends on a clear call to act; the arrow eases right on hover. */
.choice-card__cta {
  margin-top: auto; display: flex; align-items: center; gap: var(--space-3);
  font-weight: var(--weight-semibold); color: var(--color-primary);
}
.choice-card__arrow {
  display: grid; place-items: center; flex: none;
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--color-primary); color: var(--color-on-primary);
  transition: transform var(--duration-base) var(--ease);
}
.choice-card:hover .choice-card__arrow { transform: translateX(4px); }
.choice-card__meta { margin: 0; color: var(--color-text-secondary); font-size: var(--text-sm); }

.choice-more { text-align: center; margin: var(--space-6) 0 0; }
/* Quiet escape hatch — mirrors .cta-band__quiet: muted + underlined at rest,
   gold on hover, so it defers to the two cards instead of shouting over them. */
.choice-more a { color: var(--color-text-secondary); text-decoration: underline; font-size: var(--text-sm); }
.choice-more a:hover { color: var(--color-accent-amber); }

/* Sticky path switcher — reuses .freq-toggle; the wrapper centres it and
   sticks under the navbar using the same offset as .service-tabs. */
.learn-switcher {
  position: sticky;
  top: calc(var(--space-16) + var(--space-5)); /* navbar height (~68px) + gap ≈ 84px */
  z-index: var(--z-sticky);
  display: flex; justify-content: center; align-items: center; gap: var(--space-4);
  padding-block: var(--space-3);
  background: var(--color-bg);
  border-bottom: var(--border-width) solid var(--color-border);
}

/* Path panels — both visible by default (no JS). */
.learn-path { padding-block: clamp(var(--space-12), 6vw, var(--space-16)); }

/* New-to-Islam introduction — one shared frame with a calm reading panel and
   a compact on-dark connection rail. It is path-level supporting content, not
   a typed .learn-block, so the CMS block contract stays unchanged. */
.learn-path__intro {
  display: grid;
  grid-template-columns: minmax(20rem, 0.82fr) minmax(0, 1.18fr);
  grid-template-areas: "connect lead";
  align-items: stretch;
  margin-bottom: var(--space-12);
  background: var(--color-surface-cream);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-2xl);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}
.learn-path__lead {
  grid-area: lead;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  margin: 0;
  padding: clamp(var(--space-10), 6vw, var(--space-16));
  background: var(--color-surface-cream);
  text-align: left;
}
.learn-path__caption {
  margin: 0 0 var(--space-3);
  color: var(--color-accent-amber);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.learn-path__lead .section-header__title { max-width: 16ch; }
.learn-path__lead .section-header__intro {
  max-width: 46ch;
  margin-top: var(--space-5);
  color: var(--color-text-primary);
  font-size: var(--text-lg);
}
.learn-path__body {
  max-width: 58ch;
  margin: var(--space-3) 0 0;
  color: var(--color-text-secondary);
  font-size: var(--text-lg);
}
.learn-connect {
  grid-area: connect;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: clamp(var(--space-8), 4vw, var(--space-10));
  background: var(--color-surface-dark);
}
.learn-connect__header { max-width: 38ch; }
.learn-connect__title {
  margin: 0;
  color: var(--color-on-primary);
  font-size: var(--text-h3);
  line-height: var(--leading-tight);
}
.learn-connect__text {
  margin: var(--space-3) 0 0;
  color: var(--color-on-primary-dim);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}
.learn-connect__qr {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: var(--space-4);
  margin: var(--space-6) 0 0;
  padding: var(--space-4);
  background: var(--color-border-on-dark);
  border-radius: var(--radius-lg);
}
.learn-connect__qr-code {
  display: block;
  width: 8.5rem;
  aspect-ratio: 1;
  object-fit: contain;
  padding: var(--space-2);
  background: var(--color-surface);
  border-radius: var(--radius-md);
}
.learn-connect__qr-note {
  margin: 0;
  color: var(--color-on-primary);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  line-height: var(--leading-snug);
  text-align: left;
}
.learn-connect__form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-3);
  align-items: end;
  margin-top: auto;
  padding-top: var(--space-6);
}
.learn-connect__form-title {
  grid-column: 1 / -1;
  margin: 0;
  color: var(--color-on-primary);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
}
.learn-connect .field__label { color: var(--color-on-primary); }
.learn-connect .input {
  min-width: 0;
  min-height: 44px;
  background: var(--color-surface);
  border-color: var(--color-surface);
}
.learn-connect .btn { min-height: 44px; white-space: nowrap; }
.learn-connect .btn:hover { background: var(--color-secondary-hover); }
.learn-connect .btn:focus-visible,
.learn-connect .input:focus-visible { box-shadow: var(--shadow-focus-gold); }
/* Anchor targets inside the path panels: html already sets scroll-padding-top:96px
   (clears the navbar), but the sticky .learn-switcher sits below it — add its
   height (~62px → --space-16) so a jumped-to card lands clear of both, not hidden
   under the switcher. Mirrors .service-detail. */
.learn-paths [id] { scroll-margin-top: var(--space-16); }

/* --- View states (progressive enhancement) --------------------------
   WITHOUT JS every part is visible: chooser + switcher + both paths, so
   the page degrades to "show everything". WITH JS (the module sets
   data-learn-view on .learn) we gate the switcher and path panels behind
   a view, defaulting to the chooser — so the FIRST render never depends
   on localStorage. All display-toggles are instant (no motion), so they
   are inherently safe under prefers-reduced-motion. */
.js .learn-switcher { display: none; }
.js .learn-path     { display: none; }
.js .learn-chooser  { display: block; }

.js .learn[data-learn-view="new"]    .learn-chooser,
.js .learn[data-learn-view="deepen"] .learn-chooser,
.js .learn[data-learn-view="all"]    .learn-chooser { display: none; }

.js .learn[data-learn-view="new"]    .learn-switcher,
.js .learn[data-learn-view="deepen"] .learn-switcher,
.js .learn[data-learn-view="all"]    .learn-switcher { display: flex; }

.js .learn[data-learn-view="new"]    [data-path-panel="new"],
.js .learn[data-learn-view="deepen"] [data-path-panel="deepen"],
.js .learn[data-learn-view="all"]    [data-path-panel] { display: block; }

/* Typed content block within a path (data-block-type = faq | articles | links |
   cards). The vertical rhythm lives on these SHARED wrappers, so it is uniform
   regardless of block type or content length: a fixed block→block gap and a
   fixed head→body gap. Per-type item spacing lives on each body container below
   (.myth / .learn-topics / .list / .programs__grid). Tokens only — no one-offs. */
.learn-block + .learn-block { margin-top: var(--space-16); }
.learn-block__head { margin-bottom: var(--space-6); max-width: 640px; }
.learn-block__title { margin: 0; font-size: var(--text-h3); color: var(--color-primary); }
.learn-block__intro { margin: var(--space-2) 0 0; color: var(--color-text-secondary); }

/* "Explore the basics" — real prose sections, NOT cards. Each topic is a
   self-contained read (icon + heading + a few short paragraphs), stacked
   vertically with a hairline rule between them. scroll-margin-top so a jump-list
   anchor lands clear of the sticky switcher (also covered by .learn-paths [id],
   set here explicitly on the component). Tokens only; no new colours. */
.learn-topics { display: flex; flex-direction: column; }
.learn-topic { scroll-margin-top: var(--space-16); max-width: 68ch; }
/* One owner for the inter-topic gap: margin-top + padding-top sit symmetrically
   around the hairline rule (no separate flex-gap stacking on top). */
.learn-topic + .learn-topic {
  border-top: var(--border-width) solid var(--color-border);
  margin-top: var(--space-10); padding-top: var(--space-10);
}
.learn-topic__head { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-4); }
.learn-topic__title { margin: 0; font-size: var(--text-h4); color: var(--color-primary); }
.learn-topic__body { margin: 0; color: var(--color-text-secondary); }
.learn-topic__body + .learn-topic__body { margin-top: var(--space-3); }

/* Sub-discipline list inside a grouped discipline card (Learn "deepen" panel).
   Small, quiet, gold-check bullets — mirrors .choice-card__list. Pushed to the
   card foot so the cards align. Tokens only; no new colours. */
.discipline-list {
  list-style: none; margin: auto 0 0; padding: var(--space-4) 0 0; width: 100%;
  border-top: var(--border-width) solid var(--color-divider);
  display: grid; gap: var(--space-2);
}
.discipline-list li {
  position: relative; padding-left: var(--space-6);
  color: var(--color-text-secondary); font-size: var(--text-sm);
}
.discipline-list li::before {
  content: "\2713"; position: absolute; left: 0; top: 0;
  color: var(--color-accent-amber); font-weight: var(--weight-semibold);
}

/* "In this section" jump list — quiet navigation, NOT content. Deliberately
   lighter than any card grid: a single hairline-underlined row of small text
   anchors. Replaces the old "Start here" step cards that duplicated the blocks
   directly below them. Tokens only; no new colours. */
.learn-jump {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) var(--space-5);
  margin-bottom: var(--space-16);
  padding-bottom: var(--space-4);
  border-bottom: var(--border-width) solid var(--color-border);
}
.learn-jump__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
.learn-jump__link {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-text-secondary);
  text-decoration: none;
}
.learn-jump__link:hover { color: var(--color-primary); text-decoration: underline; }

/* Per-path CTA band — green panel (--color-surface-dark). Reuses the on-dark
   .btn variants (gold fill + gold outline); text switches to the on-primary
   tokens. No new colours. */
.cta-band {
  margin-top: var(--space-16);
  background: var(--color-surface-dark);
  border-radius: var(--radius-2xl);
  padding: clamp(var(--space-10), 5vw, var(--space-16));
  text-align: center;
}
.cta-band__title { color: var(--color-on-primary); margin: 0 0 var(--space-3); }
.cta-band__text  { color: var(--color-on-primary-dim); font-size: var(--text-lg); max-width: 560px; margin: 0 auto var(--space-8); }
.cta-band__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); justify-content: center; }
/* Gold focus ring for controls on the green surface (design-system §3.6). */
.cta-band .btn:focus-visible { box-shadow: var(--shadow-focus-gold); }
/* Quiet, optional link — never a hard CTA: dim by default, gold on hover. */
.cta-band__quiet { margin: var(--space-6) 0 0; }
.cta-band__quiet a { color: var(--color-on-primary-dim); text-decoration: underline; font-size: var(--text-sm); }
.cta-band__quiet a:hover { color: var(--color-secondary); }
.cta-band__quiet a:focus-visible { box-shadow: var(--shadow-focus-gold); border-radius: var(--radius-sm); }

/* "Wrong path?" — a single quiet line at the FOOT of each path panel (below the
   CTA band, on the light page surface) that switches to the other path. Mirrors
   the .cta-band__quiet treatment — muted by default, gold on hover — but small
   and secondary so it never competes with the CTA above it. The link drives
   setView() via JS (data-path-switch) and falls back to its #learn-* anchor
   without JS. Tokens only; no new colours. Focus ring inherited from the global
   :focus-visible (green) since this sits on the light surface. */
.learn-switch {
  margin: var(--space-8) 0 0;
  text-align: center;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.learn-switch__link { color: var(--color-text-secondary); text-decoration: underline; }
.learn-switch__link:hover { color: var(--color-secondary); }

@media (max-width: 1024px) {
  .learn-path__intro {
    grid-template-columns: 1fr;
    grid-template-areas: "lead" "connect";
  }
  .learn-connect__form { margin-top: var(--space-6); }
}

@media (max-width: 640px) {
  /* Drop the first-viewport framing on mobile: with a single column the two
     cards can't share one screen, so 100vh centring would strand the second
     card below a lap of empty space. Let the section size to its content.
     (Switching off flex also lets the .container shrink to the viewport,
     which its flex min-width:auto was preventing — killing the h-overflow.) */
  .learn-path__lead { padding: var(--space-8) var(--space-6); }
  .learn-connect { padding: var(--space-8) var(--space-6); }
  .learn-connect__qr { margin-top: var(--space-6); }
  .learn-connect__qr-code { width: 7rem; }
  .learn-connect__form { grid-template-columns: 1fr; }
  .learn-connect__form-title { grid-column: auto; }
  .learn-connect .btn { width: 100%; }
  .learn-chooser { display: block; min-height: 0; }
  .choice-grid { grid-template-columns: 1fr; gap: var(--space-4); }
  .choice-card { padding: var(--space-8) var(--space-6); }
  /* Stick below the shorter mobile navbar (~68px), matching .service-tabs. */
  .learn-switcher { top: calc(var(--space-16) + var(--space-1)); }
}

/* ============================================================
   PAGE: Arabic School  (arabic-school.html)
   -------------------------------------------------------------
   *** NEW page-scoped block — flagged addition. ***
   Composes existing tokens + components ONLY — no new colours,
   no new custom properties. The hero reuses the index .hero
   (media + overlay + frosted .hero__badge); the "at a glance"
   band reuses the .svc-card tile in its own 4-up grid (the base
   .svc-grid is the 2×2 About-column variant, so it isn't reused
   directly here).
   ============================================================ */

/* Anchor targets clear the sticky navbar — mirrors .service-detail's
   scroll-margin-top and .learn-paths [id]. */
.arabic-school section[id] { scroll-margin-top: var(--space-16); }

/* Standalone page hero — a compact, contained header (NOT a landing canvas).
   Two-column split inside the unified frame: copy on a solid dark-green ground
   (~55%), a contained school photo (~45%). Capped near ~380px on desktop so it
   reads as a header. Dark ground (over the shared white .hero shell) gives a
   crisp edge under the white navbar and lets the inherited white title/subtitle,
   the gold CTA, and the frosted badge all pop — no text ever sits on the photo,
   so the base .hero__overlay is dropped from the markup. */
.arabic-hero {
  display: grid;
  grid-template-columns: 55% 45%;
  align-items: stretch;
  height: auto;
  min-height: 320px; /* shorter now the badge is gone — title → subtitle → CTA only */
  width: min(var(--container-max), 100% - 2 * var(--gutter));
  margin: var(--space-6) auto 0;
  background: var(--color-surface-dark);
}
/* Left copy column: fills the column and vertically centres its short stack. */
.arabic-hero .hero__content {
  display: flex;
  flex-direction: column;
  justify-content: center;
  max-width: none;
  min-width: 0; /* grid item: allow shrink below content min so the long badge/copy wrap instead of forcing overflow */
  padding: clamp(var(--space-6), 3vw, var(--space-10));
}
.arabic-hero .hero__title {
  font-size: clamp(1.75rem, 2.6vw, 2.5rem);
  margin-bottom: var(--space-3);
}
.arabic-hero .hero__subtitle { max-width: 42ch; margin-bottom: var(--space-6); }

/* Right image column: the contained photo fills its half via object-fit. */
.arabic-hero .hero__media-col { position: relative; overflow: hidden; }
.arabic-hero .hero__media {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  z-index: auto;
}

/* CTA row inside .hero__content: one loud gold button + one quiet text link. */
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
}
/* The demoted "level" link, sitting on the dark ground beside the gold CTA. */
.arabic-hero .btn--link { color: var(--color-secondary); }
.arabic-hero .btn--link:hover { color: var(--color-secondary-hover); }
/* Gold focus ring for the gold buttons over the dark hero (design-system §3.6),
   same treatment the .cta-band uses on its green surface. */
.arabic-hero .btn:focus-visible { box-shadow: var(--shadow-focus-gold); }

/* Values line relocated out of the hero into the About block, where it reads
   as amber-on-cream instead of grey-on-terracotta. */
.about-values {
  margin: var(--space-4) 0 0;
  color: var(--color-accent-amber);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.08em;
}

/* Stack to a single content-sized column on phones: copy first, photo below. */
@media (max-width: 768px) {
  .arabic-hero {
    grid-template-columns: 1fr;
    min-height: 0;
  }
  .arabic-hero .hero__media-col { min-height: 180px; }
}

/* "At a glance" band — four facts directly under the hero, answering a parent's
   first questions on the first screen. Now adjusted to a 2x2 grid of curriculum cards. */
.glance { padding-block: clamp(var(--space-10), 5vw, var(--space-16)); }
.glance__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-6);
}
/* NSW registration — the page's strongest credibility signal, so it reads as a
   trust badge rather than a footnote: a centered gold-tint pill seated in the
   full-width row under the tiles, lifted off the section with a hairline border
   and soft shadow. The announcement glyph is pre-coloured gold (no icon filter). */
.glance__note {
  grid-column: 1 / -1;
  justify-self: center;
  display: flex; align-items: center; justify-content: center;
  gap: var(--space-3);
  max-width: 100%;
  margin: 0 0 var(--space-2);
  padding: var(--space-3) var(--space-5);
  text-align: left;
  background: var(--color-highlight);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  color: var(--color-text-secondary); font-size: var(--text-base);
}
.glance__note strong { color: var(--color-text-primary); font-weight: var(--weight-semibold); }
.glance__note-icon { flex: none; width: 26px; height: 26px; display: block; }
@media (max-width: 480px) { .glance__note { flex-direction: column; text-align: center; gap: var(--space-2); } }

/* Curriculum glance cards matching the 2nd design layout */
.glance-card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--duration-base) var(--ease), transform var(--duration-base) var(--ease);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-4);
}
.glance-card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}
.glance-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.glance-card__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-h3);
  color: var(--color-primary);
}
.glance-card__badges {
  display: flex;
  gap: var(--space-2);
  align-items: center;
}
.glance-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--space-3);
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: 100px;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--color-text-primary);
  background: var(--color-surface-cream);
  line-height: var(--leading-tight);
  white-space: nowrap;
}
.glance-card__details {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--space-2);
  border-top: var(--border-width) solid var(--color-divider);
  padding-top: var(--space-4);
}
.glance-card__item {
  margin: 0;
  font-size: var(--text-base);
  color: var(--color-text-secondary);
  line-height: var(--leading-snug);
}

@media (max-width: 768px) {
  .glance__grid { grid-template-columns: 1fr; }
}

/* About block — a short intro over a photo strip. Prose reuses the section-header
   rhythm; the strip is a simple contained image grid (now two photos; the other
   two were moved to the Teachers and "A Sunday" blocks). */
.about-prose {
  max-width: 62ch;
  margin: 0 auto;
  text-align: center;
  color: var(--color-text-secondary);
  font-size: var(--text-lg);
}
.about-prose p:last-child { margin-bottom: 0; }

.photo-strip {
  display: grid;
  /* minmax(0, 1fr) — NOT the implicit minmax(auto, 1fr) — lets each track shrink
     to its equal share of the row. Without it a wide image's intrinsic size
     forces the track past its share, so the right-hand image clips at the
     container edge (the ~1440px overflow). This is the overflow fix. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-12);
  /* §3.10 decorative girih placeholder — faint 8-point stars in the sanctioned
     decorative amber over cream, baked as a data-URI because a background can't
     read a token. Reused by the image background AND its broken-state overlay. */
  --photo-pattern: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20width='72'%20height='72'%20viewBox='0%200%2072%2072'><g%20fill='none'%20stroke='%23B5811C'%20stroke-width='1.5'%20stroke-opacity='0.12'><path%20d='M18,18H54V54H18Z'/><path%20d='M36,12L60,36L36,60L12,36Z'/></g></svg>");
}
.photo-strip img {
  position: relative;                 /* contains the broken-state ::after */
  width: 100%;
  /* Fixed 3:2 landscape band → height is DERIVED from the column width, never
     free. Sources are 4:3 (800x600); cover + centre trims only a thin, even
     top/bottom sliver (no side crop, so subjects stay safe) and gives a shorter,
     more editorial band than the taller source 4:3. */
  aspect-ratio: 3 / 2;
  object-fit: cover;
  object-position: center;
  border-radius: var(--radius-lg);
  border: var(--border-width) solid var(--color-border);
  /* Placeholder shown while loading / if the TODO asset is missing: cream + a
     faint girih, never a bare box. A loaded photo paints over it opaquely. */
  background-color: var(--color-surface-cream);
  background-image: var(--photo-pattern);
  background-size: 72px;
  background-position: center;
  color: transparent;                 /* suppress alt text in the broken state */
}
/* Broken / missing image: overlay the same cream + girih so the browser's
   broken-image glyph is covered too. ::after renders ONLY when the <img> has no
   replaced content (missing/failed load); a loaded photo hides it automatically. */
.photo-strip img::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--color-surface-cream);
  background-image: var(--photo-pattern);
  background-size: 72px;
  background-position: center;
  border-radius: inherit;
}
@media (max-width: 640px) { .photo-strip { grid-template-columns: minmax(0, 1fr); } }

/* Content|image split — puts a photo beside the "A Sunday" list and the Teachers
   lead so the lower 70% of the page isn't pure type. Reuses the .photo-strip image
   treatment; stacks to one column on tablet/phone. */
.media-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(var(--space-6), 4vw, var(--space-12));
  align-items: center;
}
.media-split--stretch { align-items: stretch; }
.media-split__media {
  width: 100%; height: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-lg);
  border: var(--border-width) solid var(--color-border);
}
/* In the Teachers split the lead card stretches to the photo's height; drop its
   own bottom margin (the wrapper carries the gap before the staff grid). */
.teacher-intro { margin-bottom: var(--space-8); }
.teacher-intro .teacher-lead { margin-bottom: 0; height: 100%; }
@media (max-width: 768px) {
  .media-split { grid-template-columns: 1fr; }
}

/* Levels ladder — the four levels as a VISIBLE progression, not a 2×2 grid of
   parallel options. An <ol> of numbered stages joined by a connecting rule reads
   as one path: Beginner → Intermediate → Advanced → Senior. Reuses the
   .program-card component; horizontal row on desktop, vertical stepper on phones
   (CSS-only — no JS). Tokens only, no new colours or custom properties. */
.level-ladder {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-6);
}
.level-stage { display: flex; flex-direction: column; min-width: 0; }

/* Numbered marker + the connecting rule that makes the progression legible. */
.level-stage__marker {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: var(--space-5);
}
/* Two half-rules meet in the middle of the column gap, so the line runs unbroken
   across the whole row; the opaque disc (above) hides where the rule crosses it. */
.level-stage__marker::before,
.level-stage__marker::after {
  content: ""; position: absolute; top: 50%;
  height: var(--border-width-strong); background: var(--color-divider);
}
.level-stage__marker::before { left: calc(var(--space-6) / -2); right: 50%; }
.level-stage__marker::after  { left: 50%; right: calc(var(--space-6) / -2); }
.level-stage:first-child .level-stage__marker::before { display: none; }
.level-stage:last-child  .level-stage__marker::after  { display: none; }

.level-stage__num {
  position: relative; z-index: 1;
  display: grid; place-items: center; flex: none;
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--color-primary); color: var(--color-on-primary);
  font-family: var(--font-display); font-weight: var(--weight-bold); font-size: var(--text-lg);
}

/* Stage card reuses .program-card; grow to equal heights across the row. */
.level-stage__card {
  flex: 1; width: 100%;
  border: var(--border-width) solid var(--color-border);
}
/* Hierarchy inside the card: level name is loudest; the age is the second-loudest
   thing, in brand green directly under it (so a parent scans name → age); body
   copy; then Materials demoted to a hairline footnote. */
.level-stage__card .program-card__title {
  margin: 0; font-size: var(--text-h3); color: var(--color-primary);
}
.level-card__age {
  margin: 0;
  font-family: var(--font-display); font-weight: var(--weight-semibold);
  font-size: var(--text-h4); color: var(--color-primary);
}
.level-stage__card .program-card__body { font-size: var(--text-sm); }
.level-card__materials {
  margin: auto 0 0;                 /* pin to the card foot so footnotes align */
  padding-top: var(--space-3);
  border-top: var(--border-width) solid var(--color-divider);
  width: 100%;
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
}
.level-card__materials strong { color: var(--color-text-primary); font-weight: var(--weight-semibold); }

/* Vertical stepper on phones: the marker moves beside the card and the rule turns
   to run downward through the numbered discs. */
@media (max-width: 768px) {
  .level-ladder { grid-template-columns: 1fr; gap: var(--space-6); }
  .level-stage { flex-direction: row; gap: var(--space-4); }
  .level-stage__marker {
    flex: none; width: 44px; margin-bottom: 0; align-items: flex-start;
  }
  .level-stage__marker::before { display: none; }
  .level-stage__marker::after {
    left: 50%; right: auto; top: 44px; bottom: calc(var(--space-6) * -1);
    width: var(--border-width-strong); height: auto; transform: translateX(-50%);
  }
  .level-stage:last-child .level-stage__marker::after { display: none; }
}

/* "A Sunday at the school" — the shape of the day as a numbered sequence.
   Reuses the .list / .list-row container with the multi-line reset the
   .service-detail__list uses (list-row was built for short label+value rows).
   The marker is a small numbered disc in the same construction as .svc-card__icon. */
.day-flow { max-width: 640px; margin-inline: auto; }
.day-flow .list-row { align-items: start; padding-block: var(--space-3); }
.day-flow .list-row__label { white-space: normal; font-weight: var(--weight-regular); color: var(--color-text-secondary); }
.day-flow__num {
  display: grid; place-items: center; flex: none;
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--color-primary); color: var(--color-on-primary);
  font-family: var(--font-body); font-size: var(--text-sm); font-weight: var(--weight-semibold);
}

/* Our teachers — a prominent lead card for the Principal over a grid of staff.
   The staff cards reuse .svc-card wholesale; its circular .svc-card__icon frame
   becomes the avatar slot (initials placeholder until photos are supplied). */
.teacher-lead {
  display: flex; align-items: center; gap: var(--space-6);
  background: var(--color-surface-cream);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-8);
  margin-bottom: var(--space-8);
}
.teacher-lead__name { margin: 0; font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--text-h3); color: var(--color-primary); }
.teacher-lead__role { margin: var(--space-1) 0 0; color: var(--color-text-secondary); font-weight: var(--weight-semibold); letter-spacing: 0.04em; }

/* Avatar placeholder — same circle construction as .svc-card__icon, sized up for
   the lead card. TODO: swap the initials for a photo when supplied. */
.teacher-avatar {
  display: grid; place-items: center; flex: none;
  width: 88px; height: 88px; border-radius: 50%;
  background: var(--color-surface); border: var(--border-width) solid var(--color-border);
  font-family: var(--font-display); font-weight: var(--weight-semibold);
  color: var(--color-primary); font-size: var(--text-h2);
}
/* Initials sitting inside the reused .svc-card__icon circle (staff cards). */
.teacher-initials { font-family: var(--font-display); font-weight: var(--weight-semibold); color: var(--color-primary); font-size: var(--text-h4); }

/* Seven staff cards. 4-up (4+3) above 900px and 2-up below both avoid a lone
   dangling card — except the 7th at 2-up, which would sit alone, so it spans the
   full row instead. A 3-up layout is deliberately skipped: 7 in 3 columns leaves
   an orphan (3+3+1). */
.teacher-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-4); }
@media (max-width: 900px) {
  .teacher-grid { grid-template-columns: repeat(2, 1fr); }
  .teacher-grid > :last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@media (max-width: 640px)  {
  .teacher-lead { flex-direction: column; text-align: center; }
}

/* "Working together" — the parent partnership. These are REQUESTS, not benefits,
   so each row takes a neutral amber dot (.pact-list__marker), never a checkmark.
   Seven items flow DOWN the columns (4 then 3) so the odd item sits at a column
   foot instead of dangling alone on its own row. Reuses .list / .list-row. */
.pact-list {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: repeat(4, auto);
  grid-auto-flow: column;
  column-gap: var(--space-8); row-gap: var(--space-2);
  max-width: 900px; margin-inline: auto;
}
.pact-list .list-row { align-items: start; padding-block: var(--space-2); }
.pact-list .list-row__label { white-space: normal; font-weight: var(--weight-regular); color: var(--color-text-secondary); }
/* Neutral "here's what we ask" marker — a small amber dot, aligned to the first
   text line. Deliberately NOT the green benefit checkmark. */
.pact-list__marker {
  flex: none;
  width: 7px; height: 7px; margin-top: 0.55em;
  border-radius: 50%;
  background: var(--color-accent-amber);
}
@media (max-width: 640px) {
  .pact-list { grid-template-columns: 1fr; grid-template-rows: none; grid-auto-flow: row; }
}

/* How to enrol — numbered steps living INSIDE the green .cta-band (the page's
   visual anchor). Left-aligned over the centred band; gold numbered discs; body
   text uses the on-primary tokens. The nested payment disclosure reuses the .myth
   accordion (a white card on the green surface). Tokens only, no new colours. */
#enrol .cta-band { margin-top: 0; }
.enrol__steps {
  list-style: none; margin: var(--space-10) auto 0; padding: 0;
  max-width: 640px; text-align: left;
  display: grid; gap: var(--space-6);
}
.enrol__step { display: flex; gap: var(--space-4); align-items: flex-start; }
.enrol__num {
  display: grid; place-items: center; flex: none;
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--color-secondary); color: var(--color-on-secondary);
  font-family: var(--font-display); font-weight: var(--weight-bold); font-size: var(--text-lg);
}
.enrol__body { flex: 1 1 auto; min-width: 0; }
.enrol__body > p { margin: 0; color: var(--color-on-primary-dim); }

/* Next-term line — a bordered pill on the green band, centred by the .cta-band's
   text-align. The date reads in gold; the --tbc variant dims it and italicises it
   so an unconfirmed date never masquerades as a real one. */
.enrol__term {
  display: inline-flex; align-items: baseline; flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  margin: 0 0 var(--space-8);
  padding: var(--space-3) var(--space-5);
  border: var(--border-width) solid var(--color-border-on-dark);
  border-radius: var(--radius-lg);
}
.enrol__term-label {
  font-size: var(--text-sm); font-weight: var(--weight-semibold);
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--color-on-primary-dim);
}
.enrol__term-date {
  font-family: var(--font-display); font-weight: var(--weight-bold);
  font-size: var(--text-h4); color: var(--color-secondary);
}
.enrol__term--tbc .enrol__term-date {
  font-weight: var(--weight-semibold); font-style: italic; color: var(--color-on-primary-dim);
}

/* Payment details disclosure sits back on a light card, so its inner text returns
   to the default (dark-on-light) tokens the .myth component already sets. Full
   width of the step-3 body so it reads as a disclosure, not a stray field. */
.enrol__payment { margin-top: var(--space-5); width: 100%; }
.enrol__payment .summary { margin-top: 0; }
/* Always-visible warning strip at the top of the payment card — OUTSIDE the
   collapsible panel, so "don't pay yet" shows in the closed state. Amber highlight
   ground marks it as an alert, not an input. */
.enrol__pay-warning {
  margin: 0;
  padding: var(--space-3) var(--space-5);
  background: var(--color-highlight);
  border-bottom: var(--border-width) solid var(--color-border);
  color: var(--color-text-primary);
  font-size: var(--text-sm); line-height: var(--leading-snug);
}
.enrol__pay-warning-label { font-weight: var(--weight-bold); color: var(--color-accent-amber); }

/* The conversion button — the loudest element in the band: large gold primary,
   set apart below the steps. */
.enrol__cta { margin-top: var(--space-10); }
.enrol__cta .btn { padding: var(--space-4) var(--space-10); }

/* Quiet mid-page CTA — one line, left-aligned to the page's content edge. Muted
   copy with a gold link; not a banner or card. */
.inline-cta {
  margin-inline: auto;
  padding-block: var(--space-10);
  color: var(--color-text-secondary);
  font-size: var(--text-lg);
}
.inline-cta a { font-weight: var(--weight-semibold); }

/* Contact — reuses .list / .list-row--link as tel: / mailto: / Facebook rows.
   Inline line-icons stand in because Resources/icons has no phone/mail/social
   glyph. The email label is allowed to wrap (the component defaults to nowrap)
   so a long address never overflows the row on a narrow screen. Tokens only. */
.contact-list { max-width: 520px; margin-inline: auto; }
.contact-list__icon { width: 24px; height: 24px; flex: none; color: var(--color-accent-amber); }
.contact-list .list-row__label { white-space: normal; overflow-wrap: anywhere; }

/* Two-column Contact: the list stays the primary element (left, wider); a light
   action aside fills the right half so the section no longer leaves it empty.
   Stacks to one column (list first) on narrow screens. Tokens only. */
.contact-grid {
  display: grid;
  grid-template-columns: 1fr 0.9fr;
  gap: clamp(var(--space-8), 5vw, var(--space-16));
  align-items: start;
}
.contact-aside {
  padding: var(--space-8);
  background: var(--color-primary-soft);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
}
.contact-aside__title { font-size: var(--text-h4); margin: 0 0 var(--space-3); }
.contact-aside__text  { color: var(--color-text-secondary); margin: 0 0 var(--space-6); }
.contact-aside__cta   { width: 100%; }
.contact-aside__link  {
  display: inline-block;
  margin-top: var(--space-4);
  font-weight: var(--weight-semibold);
  color: var(--color-primary);
}
@media (max-width: 720px) {
  .contact-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   Vertical rhythm — alignment + weight modifiers
   -------------------------------------------------------------
   The page was eleven identical centred sections with matching
   padding, so nothing read as more important than anything else.
   These modifiers give the page a left edge, a loud/quiet
   cadence (the At a glance -> Levels -> How to enrol spine gets
   extra room; Contact/Fees/A Sunday compress), and two cream
   grounds so the eye registers movement while scrolling. The
   dark enrol band stays the strongest surface. Tokens only.
   ============================================================ */

/* ALIGNMENT — left-align the header for content-heavy sections so the page
   reads against a left edge instead of a stack of centred blocks. */
.section-header--left {
  text-align: left;
  margin-inline: 0;
  max-width: 60ch;
}
/* De-centre the body blocks in a left-aligned section: each of these otherwise
   centres itself with margin-inline:auto (and About also centres its text). */
.section--left .about-prose,
.section--left .day-flow,
.section--left .pact-list,
.section--left .contact-list { margin-inline: 0; }
.section--left .about-prose { text-align: left; }

/* WEIGHT — the spine of the page (At a glance -> Levels -> How to enrol) gets
   more vertical room and a louder header than the surrounding content. */
.section--feature { padding-block: clamp(var(--space-20), 10vw, var(--space-24)); }
.section--feature .section-header { margin-bottom: var(--space-16); }
.section--feature .section-header__title,
.section--feature .cta-band__title { font-size: clamp(var(--text-h2), 4vw, var(--text-h1)); }

/* WEIGHT — short, factual blocks (Contact, Fees, A Sunday) compress so they
   don't carry a full section's padding. */
.section--tight { padding-block: clamp(var(--space-10), 5vw, var(--space-12)); }
.section--tight .section-header { margin-bottom: var(--space-8); }

/* SURFACE — a couple of mid-page grounds so the eye has something to register
   while scrolling. Kept to two; the dark enrol band stays the strongest.
   The tint is an INSET, rounded panel that lives inside .container (mirroring
   .about__grid on index.html and .cta-band below), never on the <section>
   itself — a block-level <section> spans the viewport, so a background on it
   paints edge-to-edge and blows through the site's left/right gutter. */
.cream-panel {
  background: var(--color-surface-cream);
  border-radius: var(--radius-2xl);
  padding: clamp(var(--space-10), 5vw, var(--space-20)) clamp(var(--space-6), 4vw, var(--space-16));
}

/* ============================================================
   PAGE: About Us  (about-us.html)
   -------------------------------------------------------------
   *** NEW flagged page-scoped block. ***  Hero, the section rail,
   and the six sections (Our Story · What Happens Here · Our Mission ·
   Our Sheikhs · Board of Directors · Get Involved). LAYOUT ONLY —
   composes existing tokens; NO new colours or custom properties. The
   rail reuses the .service-tabs component (styled above) and the
   shared serviceTabs() scroll-spy in main.js (generic — binds as-is).
   ============================================================ */

/* HERO — left-aligned header on the warm cream surface (NOT centred:
   the reference page's centred homepage-style title reads wrong for an
   About page). Contained width via the shared .container; section
   rhythm mirrors .section. No CTA — that belongs at the page foot. */
.about-hero {
  background: var(--color-surface-cream);
  padding-block: clamp(var(--space-16), 8vw, var(--space-20));
}
.about-hero__title { margin: var(--space-2) 0 var(--space-4); color: var(--color-primary); }
.about-hero__intro {
  max-width: 68ch;
  margin: 0;
  color: var(--color-text-secondary);
  font-size: var(--text-lg);
}

/* SECTION-RAIL anchor targets — clear the sticky navbar AND the sticky
   .service-tabs rail, mirroring the .service-detail scroll-margin-top
   pattern in services.html (html already sets scroll-padding-top:96px
   for the navbar; --space-16 adds the rail's height). */
.about-section {
  scroll-margin-top: var(--space-16);
  padding-block: var(--space-12);
}
/* Hairline divider between consecutive sections (reuses --color-border,
   like .service-detail + .service-detail). */
.about-section + .about-section { border-top: var(--border-width) solid var(--color-border); }
/* Body prose held to a readable measure, left-aligned (default flow). */
.about-section > p { max-width: 68ch; }

/* Section titles in brand green (El Messiri via the base h1–h4 rule), held at
   --text-h2 (2rem) — one clear step of the §3.2 scale above --text-base body
   copy. This is the page's main lift of green ink: six green section anchors
   where the headings previously read near-black. Tokens only. */
.about-section h2 { font-size: var(--text-h2); color: var(--color-primary); }

/* MEMBERS CALLOUT — section-width tinted panel that lifts #members from a flat
   heading+button. Reuses the .enrol-status__inner recipe (soft-green fill,
   hairline, --radius-lg, --shadow-sm) and the .service-detail__medallion
   pattern (green tile + white line-icon). Two columns: content left, a purely
   decorative girih rosette right. Tokens only, one green + one gold. */
.members-callout {
  padding: var(--space-8) var(--space-10);
  background: var(--color-primary-soft);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
/* Two-column split: content ~1.2fr, decorative aside ~1fr, both centred so the
   motif sits level with the heading + button block. */
.members-callout__grid {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: var(--space-10);
  align-items: center;
}
.members-callout__main { max-width: 60ch; }
/* DECORATIVE aside: quieter than the left column so the heading/button lead. */
.members-callout__aside {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.members-callout__motif {
  width: 100%;
  max-width: 200px;
  height: auto;
}
/* Green line-work kept low-contrast so it reads as quiet ornament, not a
   billboard; single gold accent on the inner rosette + centre dot. */
.members-callout__motif-ring   { stroke: var(--color-primary);   stroke-width: 1; opacity: .18; }
.members-callout__motif-line   { stroke: var(--color-primary);   stroke-width: 2; opacity: .30; }
.members-callout__motif-accent { stroke: var(--color-secondary); stroke-width: 2; opacity: .70; }
.members-callout__motif-dot    { fill:   var(--color-secondary); }
/* Discreet, non-disclosing tagline — names no document or record. */
.members-callout__tagline {
  margin-top: var(--space-4);
  margin-bottom: 0;
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
/* Single column on tablet/mobile — the decorative aside hides so it never
   becomes a lonely block below the content. */
@media (max-width: 720px) {
  .members-callout__grid { grid-template-columns: 1fr; }
  .members-callout__main { max-width: none; }
  .members-callout__aside { display: none; }
}
/* Modest green medallion; white icon via the same brightness/invert trick as
   .service-detail__medallion-icon (SVG ships dark). */
.members-callout__medallion {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-12);
  height: var(--space-12);
  margin-bottom: var(--space-4);
  background: var(--color-primary);
  border-radius: var(--radius-lg);
}
.members-callout__icon {
  width: var(--space-6);
  height: var(--space-6);
  flex: none;
  filter: brightness(0) invert(1);   /* icon white on green — same trick as .service-detail__medallion-icon */
}
/* Heading stays brand-green (inherits .about-section h2); dark body copy on the
   green-tint fill clears AA. */
.members-callout__title { margin-bottom: var(--space-3); }
.members-callout__text { max-width: none; color: var(--color-text-secondary); }
.members-callout__actions { margin-top: var(--space-6); margin-bottom: 0; }

/* NOTE: the section rail is the shared .service-tabs component with NO page
   overrides — its sizing (--space-3 padding, --text-base label, 24px icon,
   --space-12 margin) and solid-green active pill now live in the base rules
   (see "COMPONENT: Service Tabs" above), so every page's rail is identical. */

/* WHAT HAPPENS HERE — the activity list reuses .list / .list-row wholesale,
   spanning the FULL container measure like every other grid/panel/band on the
   page. The trailing "when" sits in .list-row__value (right-aligned). */
.about-life__list { margin-top: var(--space-8); }
/* Connect each activity to its right-aligned "when" with the §5.8 Summary Row
   dotted leader, so the value pairs with its label instead of floating far to
   the right of the full-width row. The leader fills the flexible label cell;
   long activity names still wrap (never overflow) and the leader is dropped ≤640
   where the row is already narrow. Applies to EVERY .list-row in the list. */
.about-life__list .list-row__label {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  white-space: normal;
}
.about-life__list .list-row__label::after {
  content: "";
  flex: 1 1 auto;
  min-width: var(--space-8);
  align-self: flex-end;
  border-bottom: 2px dotted var(--color-border-strong);
  transform: translateY(-4px);
}
@media (max-width: 640px) { .about-life__list .list-row__label::after { display: none; } }

/* OUR MISSION — the interfaith line pulled out with visual weight. A cream
   panel with a weighted GREEN accent edge (4px, was a 1.5px gold hairline) and
   large display type; the key clause STAYS accessible amber so it remains the
   one gold highlight in the quote. Tokens only. */
.mission-quote {
  margin: var(--space-8) 0 0;
  padding: clamp(var(--space-6), 4vw, var(--space-8));
  background: var(--color-surface-cream);
  border: var(--border-width) solid var(--color-border);
  border-left: var(--space-1) solid var(--color-primary);
  border-radius: var(--radius-lg);
}
.mission-quote p {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-h3);
  line-height: var(--leading-snug);
  color: var(--color-primary);
}
.mission-quote strong { color: var(--color-accent-amber); font-weight: var(--weight-semibold); }

/* OUR SHEIKHS — trust card with the reference's overlapping circular avatar
   (lifted above the card's top edge). Deliberately NO overflow:hidden so the
   avatar overlap AND any focus ring stay fully visible; the grid reserves top
   room (--avatar/2) so the lifted avatars never clip the prose above or the
   viewport on mobile. Avatar/initials reuse the arabic-school teacher-avatar
   construction. Tokens only; the 88px avatar + its 44px half are geometry. */
.sheikh-grid {
  display: grid;
  /* Centred 2-up: only two light-content cards, so cap each column and centre
     the pair (justify-content) rather than stretching them across the full
     ~1200px measure — full width would leave each card mostly empty. minmax(0,…)
     lets the columns shrink on tablet without overflow; ≤640 collapses to one. */
  grid-template-columns: repeat(2, minmax(0, 22rem));
  justify-content: center;
  gap: var(--space-8);
  margin-top: calc(var(--space-8) + 44px);    /* space-8 visual gap + room for the lifted avatars */
}
.sheikh-card {
  position: relative;                          /* own stacking context; no clip */
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-1);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-8) var(--space-6) var(--space-6);
  transition: box-shadow var(--duration-base) var(--ease),
              transform var(--duration-base) var(--ease);
}
.sheikh-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.sheikh-card__avatar {
  /* lift so the avatar centre sits on the card's top edge:
     padding-top (--space-8, 32px) + half the 88px avatar (44px) = 76px. */
  margin-top: calc(-1 * (var(--space-8) + 44px));
  margin-bottom: var(--space-2);
  display: grid;
  place-items: center;
  flex: none;
  width: 88px;
  height: 88px;
  border-radius: 50%;
  overflow: hidden;                            /* clip the photo to the circle */
  background: var(--color-surface-cream);
  border: var(--border-width-strong) solid var(--color-border);
  box-shadow: var(--shadow-sm);
}
/* Photo + initials share one grid cell so the initials sit BEHIND the photo:
   with the asset missing the photo (alt="") is an empty transparent box and the
   initials show through; when a real headshot lands it fills the ring (cover)
   and covers them — no markup change needed then. */
.sheikh-card__avatar > * { grid-area: 1 / 1; }
/* Circular headshot filling the avatar ring. */
.sheikh-card__photo { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Initials fallback — the same treatment as the Arabic School .teacher-avatar /
   .teacher-initials (El Messiri, semibold, green), sized to --text-h2 to match
   the 88px .teacher-avatar so the overlapping circle stays legible with no photo. */
.sheikh-card__initials {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-h2);
  color: var(--color-primary);
}
.sheikh-card__name { margin: 0; font-size: var(--text-h4); color: var(--color-primary); }
.sheikh-card__title {
  margin: 0;
  color: var(--color-accent-amber);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.sheikh-card__bio { margin: var(--space-2) 0 0; color: var(--color-text-secondary); font-size: var(--text-sm); }
/* Visibly provisional until real copy lands — never reads as a real credential. */
.sheikh-card__bio--todo { font-style: italic; }
@media (max-width: 640px) {
  /* Single column: the row gap MUST exceed the avatar's 44px overhang so a
     stacked card's lifted avatar clears the card above it (default --space-8
     = 32px would overlap by ~12px). --space-16 (64px) = 44px + breathing room. */
  .sheikh-grid { grid-template-columns: 1fr; gap: var(--space-16); }
}

/* BOARD OF DIRECTORS — name + role cards on a hard-LEFT grid, so the board reads
   like every other grid on the page instead of centring its tail (which looked
   like a bug). 11 is prime, so no column count fills the last row exactly; at
   4-up the tail is 4·4·3, left-aligned — a normal partial row, not a centred
   orphan. 4 columns also narrow each card, fixing the old wide-and-short
   proportion. (To fill the last row with no gap instead, give .board-card a
   flex-grow — at the cost of a slightly wider last row.) No paper-plane / contact
   icon (see markup). Tokens only. 4 → 2 (≤1024) → 1 (≤640) columns. */
.board-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-6);
  margin-top: var(--space-8);
}
.board-card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-6);
  text-align: center;
  transition: box-shadow var(--duration-base) var(--ease),
              transform var(--duration-base) var(--ease);
}
.board-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.board-card__name { margin: 0; font-size: var(--text-h4); color: var(--color-primary); }
.board-card__role {
  margin: var(--space-1) 0 0;
  color: var(--color-text-secondary);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.04em;
}
@media (max-width: 1024px) { .board-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px)  { .board-grid { grid-template-columns: minmax(0, 1fr); } }

/* GET INVOLVED — practical facts (address + prayer times) as two cream info
   cards above the reused .cta-band. Tokens only; 2 → 1 column ≤640. */
.visit-facts {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-6);
  margin-top: var(--space-12);   /* block → block rhythm */
}
.visit-facts__card {
  background: var(--color-surface-cream);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}
.visit-facts__title { margin: 0 0 var(--space-2); font-size: var(--text-h4); color: var(--color-primary); }
.visit-facts__body  { margin: 0 0 var(--space-3); color: var(--color-text-secondary); }
@media (max-width: 640px) { .visit-facts { grid-template-columns: 1fr; } }

/* GOVERNANCE — short prose beneath the board grid. Held to a readable measure. */
.governance { margin-top: var(--space-12); max-width: 68ch; }   /* block → block rhythm */
.governance__title { margin: 0 0 var(--space-2); font-size: var(--text-h4); color: var(--color-primary); }
.governance p { margin: 0; color: var(--color-text-secondary); }

/* ============================================================
   FORM CONTROLS — design-system §5.8 (.field / .input), first use on
   the site. Implemented from the spec, tokens only. Placeholder uses
   --color-text-secondary (a token) instead of the spec's raw #9A9892
   so no new colour is introduced.
   ============================================================ */
.field { display: grid; gap: var(--space-2); }
.field__label { font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--color-text-primary); }
.input {
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--color-text-primary);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border: var(--border-strong);
  border-radius: var(--radius-md);
  transition: border-color var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease);
}
.input::placeholder { color: var(--color-text-secondary); opacity: 0.7; }
.input:focus { outline: none; border-color: var(--color-primary); box-shadow: var(--shadow-focus); }
/* Only flag a field as invalid AFTER the user has interacted with it. */
.input:user-invalid { border-color: var(--color-error); }
textarea.input { resize: vertical; min-height: 120px; }

/* BECOME A MEMBER — eligibility criteria as a scannable checklist in a bordered
   cream panel with a gold accent edge (mirrors the .mission-quote treatment).
   Tokens only. */
.membership-criteria {
  margin-top: var(--space-8);   /* heading/intro → first content rhythm */
  padding: var(--space-5) var(--space-6);
  background: var(--color-surface-cream);
  border: var(--border-width) solid var(--color-border);
  border-left: var(--border-width-strong) solid var(--color-secondary);
  border-radius: var(--radius-lg);
}
.membership-criteria__lead { margin: 0 0 var(--space-3); color: var(--color-text-primary); font-weight: var(--weight-semibold); }
.membership-criteria__list { margin: 0; padding-left: var(--space-6); color: var(--color-text-secondary); }
.membership-criteria__list li { margin-bottom: var(--space-1); }
.membership-criteria__list li:last-child { margin-bottom: 0; }

/* Standardise the closing CTA's gap to the page's block → block rhythm
   (--space-12), overriding the shared .cta-band default (--space-16) for this
   page only (mirrors #enrol .cta-band on arabic-school.html). */
.about-section .cta-band { margin-top: var(--space-12); }

/* ============================================================
   PAGE: Services  (services.html)
   -------------------------------------------------------------
   Layout only — composes existing components (Section Header, Service
   Card, List Row, Summary Row, Myth vs Fact, CTA Band, Form Controls).
   NO new tokens or colours; every value reads an existing token. The
   four .service-detail sections share one shape and one measure: the
   .section-header--left prose measure (60ch) for the header, and the
   full .container for every grid, list, panel and band.
   ============================================================ */

/* STRUCTURE IN GREEN — brand green carries every service <h2> (the base
   h2 is --color-text-primary; About Us made the same move). El Messiri +
   the h2 size come from the base h2 / .section-header__title rules. Gold
   stays a secondary highlight (eyebrow, card icon) and never a heading. */
.service-detail .section-header__title { color: var(--color-primary); }

/* The section header carries its own bottom gap; drop the shared centred
   default so the left measure controls it. */
.service-detail .section-header { margin-bottom: 0; }

/* Vertical rhythm within a service is now owned by .service-detail__grid: the
   identity rail sits in column 1, and the stacked detail blocks (content ·
   questions) are paced by the grid's row-gap (--space-10). The section itself
   holds a single child (the grid), so no block-level spacing rule is needed. */

/* Small non-heading slot labels ("What's included" · "At a glance" ·
   "Common questions") — keep the outline at h1 → h2 → h3 (no h4 under the
   Myth h3s) and keep gold out (secondary text, not amber). */
.service-detail__subhead {
  margin: 0 0 var(--space-3);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
/* The "At a glance" facts sit below the "What's included" list inside the
   content card; give the second slot label room from the list above. */
.service-detail__content > * + .service-detail__subhead { margin-top: var(--space-6); }

/* Shared enquiry form anchor clears the sticky navbar + tab rail on jump. */
#enquiry { scroll-margin-top: var(--space-16); }

/* VERTICAL RHYTHM (§3.3) — whitespace between the raised service cards.
   Consecutive .service-detail cards sit --space-16 (64px) apart via their
   margin-top, with the warm page ground showing between them. The closing
   CTA band follows the same measure so the run of cards keeps one even
   cadence to the bottom — no magic numbers, all §3.3 tokens. */
.services-cta { margin-top: var(--space-16); }

/* ============================================================
   PAGE: Library  (library.html)
   -------------------------------------------------------------
   *** NEW flagged page-scoped block. ***  Hero, the sticky rail
   wrapper, and the three zones (Borrow · Catalogue · Join). LAYOUT
   ONLY — composes existing components (Section Header, Service Tabs,
   List Row, Chip Pending, Myth vs Fact, CTA Band) and existing
   tokens; NO new colours or custom properties. The rail reuses the
   shared .service-tabs component (styled above) and the shared, generic
   serviceTabs() scroll-spy in main.js (binds as-is). The Catalogue zone
   is an empty anchored stub pending the data export.
   ============================================================ */

/* HERO — left-aligned header on the warm cream surface (mirrors the
   About Us hero). Contained width via .container; rhythm mirrors .section.
   Brand green carries the title; gold stays on the eyebrow only. */
.library-hero {
  background: var(--color-surface-cream);
  padding-block: clamp(var(--space-16), 8vw, var(--space-20));
}
.library-hero__title { margin: var(--space-2) 0 var(--space-4); color: var(--color-primary); }
.library-hero__intro {
  max-width: 68ch;
  margin: 0;
  color: var(--color-text-secondary);
  font-size: var(--text-lg);
}

/* ZONE anchor targets — the three zones share ONE .container with the
   sticky rail, so each must clear the navbar AND the rail on jump (html
   already sets scroll-padding-top:96px for the navbar; --space-16 adds
   the rail's height — same value services.html uses on .service-detail). */
.library-zone {
  scroll-margin-top: var(--space-16);
  padding-block: var(--space-12);
}
/* Hairline divider between consecutive zones (reuses --color-border). */
.library-zone + .library-zone { border-top: var(--border-width) solid var(--color-border); }
/* Section header carries its own bottom gap; drop the shared centred default
   so the left measure controls it (mirrors .service-detail). */
.library-zone .section-header { margin-bottom: 0; }
/* Structure in green — brand green carries every zone <h2> (base h2 is
   --color-text-primary; About Us / Services made the same move). Gold stays
   secondary (eyebrow) and never a heading. */
.library-zone .section-header__title { color: var(--color-primary); }
/* UNIFORM RHYTHM — every zone type shares one wrapper (.library-zone__body)
   that carries the vertical rhythm, so spacing is identical regardless of zone
   type or content length. One step between the header and the body, and the
   SAME step between the body's blocks (cards→rules, policy→cta). Tokens only —
   no zone sets its own block margins. */
.library-zone .section-header + .library-zone__body { margin-top: var(--space-8); }
.library-zone__body { display: grid; gap: var(--space-8); }
/* The .cta-band ships a default top margin (space-16) for standalone use; inside
   the zone body the grid gap owns the spacing, so neutralise it here. */
.library-zone__body .cta-band { margin-top: 0; }

/* BORROW — the two borrow-window cards are the page's visual anchor:
   a 2-up grid that collapses to one column on mobile. Off-white cards on
   the page surface, hairline border, soft resting shadow (the Program /
   Service-Tile pattern). Brand green carries each card title. */
.borrow-windows {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6);
}
@media (max-width: 640px) { .borrow-windows { grid-template-columns: 1fr; } }
.borrow-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  padding: clamp(var(--space-6), 4vw, var(--space-8));
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.borrow-card__title { margin: 0; color: var(--color-primary); font-size: var(--text-h3); }
/* The window is the card's key fact — the DAY reads large (display type), the
   time sits below as secondary. Both from tokens; the flex gap spaces them. */
.borrow-card__window {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-h3);
  font-weight: var(--weight-semibold);
  color: var(--color-text-primary);
}
.borrow-card__time { margin: 0; color: var(--color-text-secondary); font-size: var(--text-base); }

/* CATALOGUE — the searchable book table (rendered inside .catalogue by the
   catalogue() module from library-catalog.json). Controls stay hidden until
   the data loads (module adds .catalogue--ready); the base table shows every
   row, search/filter only narrow it. Layout only; availability chips use the
   §3.1.7 feedback tokens. */
.catalogue__controls { display: none; }
.catalogue--ready .catalogue__controls {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--space-4);
  align-items: end;
  margin-bottom: var(--space-6);
}
.catalogue__controls .field { margin: 0; }
@media (max-width: 640px) { .catalogue--ready .catalogue__controls { grid-template-columns: 1fr; } }

.catalogue__count { margin: 0 0 var(--space-4); color: var(--color-text-secondary); font-size: var(--text-sm); }

/* The wrap scrolls INTERNALLY on mid widths so the PAGE never overflows;
   ≤640 the table becomes cards, so a phone needs no horizontal scroll. */
.catalogue__tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.catalog-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.catalog-table th,
.catalog-table td {
  padding: var(--space-3) var(--space-4);
  text-align: left;
  border-bottom: var(--border-width) solid var(--color-border);
  vertical-align: middle;
}
.catalog-table thead th {
  font-family: var(--font-body);
  font-weight: var(--weight-semibold);
  color: var(--color-text-primary);
  background: var(--color-surface-cream);
  white-space: nowrap;
}
.catalog-table tbody tr:hover { background: var(--color-surface-cream); }
.catalog-table td:first-child { font-weight: var(--weight-medium); color: var(--color-text-primary); }
.catalog-table__empty td { color: var(--color-text-secondary); font-style: italic; text-align: center; }

/* PAST PROGRAMS - static archive table. It reuses the catalogue table's
   desktop and mobile-card behavior while keeping archive-only presentation
   scoped so the Library catalogue is unchanged. */
.past-programs-archive__tablewrap {
  margin-top: var(--space-8);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.past-programs-table { min-width: 760px; }
.past-programs-table th:first-child { width: 22%; }
.past-programs-table th:nth-child(3),
.past-programs-table th:nth-child(4) { width: 15%; }
.past-programs-table td { vertical-align: top; }
.past-programs-table__action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 36px;
  padding: var(--space-2) var(--space-3);
  color: var(--color-primary);
  background: var(--color-surface-cream);
  border: var(--border-width) solid var(--color-primary);
  border-radius: var(--radius-md);
  font-weight: var(--weight-semibold);
  line-height: 1;
  white-space: nowrap;
}
a.past-programs-table__action:hover,
a.past-programs-table__action:focus-visible {
  color: var(--color-on-primary);
  background: var(--color-primary);
  text-decoration: none;
}
.past-programs-table__action--disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
.past-programs-table__row[hidden],
.past-programs-pagination[hidden] { display: none; }
.past-programs-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  margin: var(--space-6) auto 0;
}
.past-programs-pagination__arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-primary);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.past-programs-pagination__arrow:hover:not(:disabled) {
  background: var(--color-primary-soft);
  border-color: var(--color-primary);
  color: var(--color-primary);
}
.past-programs-pagination__arrow:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.past-programs-pagination__arrow:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.past-programs-pagination__pages {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.past-programs-pagination__page {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  height: 40px;
  padding: 0 var(--space-2);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.past-programs-pagination__page:hover:not(.past-programs-pagination__page--active) {
  background: var(--color-surface-stone);
  border-color: var(--color-border-strong);
}
.past-programs-pagination__page:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.past-programs-pagination__page--active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-on-primary);
  font-weight: var(--weight-bold);
  cursor: default;
}

/* Availability chips — §3.1.7 feedback tokens; both pairs are WCAG AA
   (white on success green ≈ 7.8:1; primary-text on warning gold ≈ 8:1). */
.chip--in  { background: var(--color-success); color: var(--color-on-primary); }
.chip--out { background: var(--color-warning); color: var(--color-on-secondary); }

/* MOBILE (≤640) — the table reflows to stacked cards: the header row is
   visually hidden and each cell labels itself from its data-label. */
@media (max-width: 640px) {
  .catalog-table thead {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
  .catalog-table, .catalog-table tbody, .catalog-table tr, .catalog-table td { display: block; width: 100%; }
  .catalog-table tr {
    margin-bottom: var(--space-4);
    padding: var(--space-2) var(--space-4);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
  }
  .catalog-table td {
    display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4);
    padding: var(--space-2) 0;
    text-align: right;
    border-bottom: var(--border-width) solid var(--color-border);
  }
  .catalog-table tr td:last-child { border-bottom: 0; }
  .catalog-table td::before {
    content: attr(data-label);
    font-weight: var(--weight-semibold);
    color: var(--color-text-primary);
    text-align: left;
  }
  .catalog-table__empty td { justify-content: center; }
  .catalog-table__empty td::before { content: ""; }

  .past-programs-archive__tablewrap {
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
  }
  .past-programs-table { min-width: 0; }
  .past-programs-table__action { min-height: 32px; }
}

/* The two borrowing rules — reuse .list / .list-row wholesale at the full
   container measure. The block gap below the window cards is owned by the
   shared .library-zone__body grid (no one-off margin here). */

/* JOIN — the disclosure accordion + CTA band both span the full container.
   The block gap between the policy list and the CTA band is owned by the shared
   .library-zone__body grid (see UNIFORM RHYTHM above), so neither sets a one-off
   margin here — the rhythm stays identical to the other zones. */
/* Bulleted lists inside a policy disclosure panel (Membership types, Borrowing)
   — a plain disc list at the body measure, spaced on the token scale. The panel
   already colours body text; this is layout only. */
.join-policy .myth__panel ul {
  margin: var(--space-2) 0 0;
  padding-left: var(--space-5);
  color: var(--color-text-secondary);
}
.join-policy .myth__panel li { margin-bottom: var(--space-1); }
.join-policy .myth__panel li:last-child { margin-bottom: 0; }

/* ============================================================
   COMPONENT: Contact  (contact-us.html — "Get in touch")
   -------------------------------------------------------------
   *** NEW BEM BLOCK — flagged addition (did not exist before). ***
   A warm-neutral section (--color-bg-about) holding two white cards
   in a 2-column grid: a detail card (address / phone / email / hours)
   and a map card that is itself an anchor to Google Maps. Card
   treatment mirrors .program-card (white --color-surface, --radius-lg,
   1px --color-border, --shadow-sm, hover lift). Green line-icons keep
   the brand green present on a light ground. Tokens/radii ONLY — no
   new colours, no radius changes.
   ============================================================ */
.contact.section { background: var(--color-bg-about); }
.contact__grid {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: var(--space-6);
  align-items: stretch;
}

/* Shared card shell for every card in the grid (mirrors .program-card). */
.contact__detail,
.contact__map,
.contact__form {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

/* Left column stacks the detail card above the map card. */
.contact__info { display: grid; gap: var(--space-6); align-content: start; }

/* --- Left: detail rows --- */
.contact__detail { list-style: none; margin: 0; padding: 0; overflow: hidden; }
.contact__row {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
}
.contact__row + .contact__row { border-top: var(--border-width) solid var(--color-border); }
/* Light circle framing the gold line-icon — the homepage service-list
   treatment (.svc-card__icon): surface fill + hairline border, icon in gold. */
.contact__icon {
  display: grid; place-items: center;
  width: 44px; height: 44px; flex: none;
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  color: var(--color-accent-amber);   /* gold stroke via currentColor — inline SVG */
}
.contact__icon svg { width: 22px; height: 22px; }
.contact__label { margin: 0; font-weight: var(--weight-semibold); color: var(--color-text-primary); }
.contact__value { margin: var(--space-1) 0 0; color: var(--color-text-secondary); overflow-wrap: anywhere; }
.contact__value a { color: var(--color-primary); font-weight: var(--weight-medium); }
.contact__value a:hover { text-decoration: underline; }

/* --- Right: map card (whole card is an anchor) --- */
.contact__map {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--space-3); text-align: center;
  padding: var(--space-8) var(--space-6);
  color: var(--color-text-primary);
  transition: box-shadow var(--duration-base) var(--ease), transform var(--duration-base) var(--ease);
}
.contact__map:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.contact__map-pin {
  display: grid; place-items: center;
  width: 64px; height: 64px;
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  color: var(--color-accent-amber);
}
.contact__map-pin svg { width: 34px; height: 34px; }
.contact__map-title { font-family: var(--font-display); font-size: var(--text-h4); color: var(--color-text-primary); }
.contact__map-cta { font-weight: var(--weight-semibold); color: var(--color-primary); }

/* --- Right: form card --- */
.contact__form { padding: var(--space-6); display: grid; gap: var(--space-4); align-content: start; }
.contact__form-title { margin: 0 0 var(--space-1); font-family: var(--font-display); font-size: var(--text-h4); color: var(--color-text-primary); }
/* Give the form controls a present resting border on the white card. Scoped to
   the contact form only (never the global .input rule): uses --color-border-strong,
   the token intended for inputs/dividers needing more presence. The :focus rule
   restores the green primary border — needed because a plain .contact__form .input
   ties .input:focus on specificity and would otherwise win on source order. */
.contact__form .input { border: var(--border-width) solid var(--color-border-strong); }
.contact__form .input:focus { border-color: var(--color-primary); }
.contact__actions { margin-top: var(--space-1); }
.contact__actions .btn { width: 100%; }
/* Honeypot — kept in the a11y tree label-wise but pulled off-screen so no
   sighted user sees it; bots that autofill it get rejected server-side. */
.contact__hp {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

/* Stack to one column at the site's standard two-column→one breakpoint
   (matches .landing / .service-detail__grid / .board-grid). DOM order puts
   details + map above the form — context before the action. */
@media (max-width: 1024px) {
  .contact__grid { grid-template-columns: 1fr; }
}

/* ============================================================
   PAGE: Member Verification  (member-verification.html)
   *** NEW BEM BLOCK — flagged addition (did not exist before). ***
   A single centered card holding the OTP form on the same warm-neutral
   ground (--color-bg-about) the Contact block uses. Reuses the Form
   Controls §5.8 (.field / .input) and mirrors the .contact__form card
   shell + honeypot. FRONTEND SHELL ONLY — no auth, no OTP checking; all
   verification + file delivery is a backend (Laravel) TODO. Tokens only,
   no new hue.
   ============================================================ */
.member-verify.section { background: var(--color-bg-about); }

/* Two-step request → verify flow. PROGRESSIVE ENHANCEMENT: the step-hiding
   is scoped to html.js, so with JS OFF both steps stay visible (request above
   code) and a no-JS user is never trapped; memberVerify() toggles [data-active]
   when JS runs. data-active="request" in the markup is inert without .js. */
.js [data-member-verify][data-active="request"] [data-step="code"] { display: none; }
.js [data-member-verify][data-active="code"] [data-step="request"] { display: none; }
.js [data-parent-login][data-active="request"] [data-step="code"] { display: none; }
.js [data-parent-login][data-active="code"] [data-step="request"] { display: none; }
/* Separate the two stacked cards only in the no-JS both-visible view; under JS
   exactly one step shows, so no gap is needed (and none is applied). */
:not(.js) [data-member-verify] [data-step="request"] { margin-bottom: var(--space-6); }
:not(.js) [data-parent-login] [data-step="request"] { margin-bottom: var(--space-6); }

/* The card: same shell as .contact__form, but narrow + centered (one field). */
.member-verify__card {
  max-width: 30rem;
  margin-inline: auto;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-6);
  display: grid;
  gap: var(--space-4);
  align-content: start;
}
.member-verify__card[hidden] { display: none; }
.member-verify__title { margin: 0 0 var(--space-1); font-family: var(--font-display); font-size: var(--text-h4); color: var(--color-text-primary); }
/* Present resting border on the white card, restored to green on focus
   (mirrors the .contact__form .input scoping + specificity note). */
.member-verify__card .input { border: var(--border-width) solid var(--color-border-strong); }
.member-verify__card .input:focus { border-color: var(--color-primary); }
/* The code reads as a code: centered, spaced digits, larger. Layout only. */
.member-verify__code { text-align: center; letter-spacing: 0.4em; font-size: var(--text-lg); }
/* Helper line under the field (id target of the input's aria-describedby). */
.member-verify__helper { margin: var(--space-1) 0 0; font-size: var(--text-sm); color: var(--color-text-secondary); }
.member-verify__actions { margin-top: var(--space-1); }
.member-verify__actions .btn { width: 100%; }
/* Resend link + muted note, stacked and quiet under the button. */
.member-verify__aux { display: grid; gap: var(--space-2); justify-items: center; text-align: center; }
.member-verify__resend,
.member-verify__change { font-weight: var(--weight-medium); color: var(--color-primary); }
.member-verify__resend:hover,
.member-verify__change:hover { text-decoration: underline; }
.member-verify__note { margin: 0; font-size: var(--text-sm); color: var(--color-text-secondary); }
/* Neutral confirmation banner on the code step — empty (hidden) until the
   memberVerify() module fills it on advance from step 1. */
.member-verify__confirm { margin: 0; font-size: var(--text-sm); color: var(--color-text-secondary); }
.member-verify__confirm:empty { display: none; }
/* Error region — empty until the backend populates it; reserves no fixed
   height so nothing shifts, but announces politely when filled. */
.member-verify__error { margin: 0; color: var(--color-error); font-size: var(--text-sm); }
.member-verify__error:empty { display: none; }
/* Honeypot — off-screen, identical treatment to .contact__hp. */
.member-verify__hp {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

/* ============================================================
   PAGE: Member Documents  (member-documents.html)
   *** NEW BEM BLOCK — flagged addition (did not exist before). ***
   The post-verification documents viewer: a document list beside a stage
   that previews the current PDF via NATIVE browser rendering (an <iframe> —
   NO PDF.js / library / CDN). Same warm --color-bg-about ground as Contact /
   Member Verification. Two columns on desktop (list beside stage), stacked on
   mobile (list above stage). FRONTEND SHELL ONLY — file protection + real,
   session-checked document URLs are backend (Laravel) work. Tokens only,
   no new hue.
   ============================================================ */
.docs-viewer-section.section { background: var(--color-bg-about); }

/* Two-column layout: fixed-ish list rail beside a fluid stage. minmax(0,…)
   on both tracks lets the stage (and the iframe inside it) shrink instead of
   forcing overflow. */
.docs-viewer {
  display: grid;
  grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
  gap: var(--space-6);
  align-items: start;
}

/* --- Document list (reuses .list-row / .list-row--link) --------------- */
.docs-viewer__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
/* Each doc is an <a> on the .list-row grid — give it a white card, reset the
   anchor underline/colour, and guarantee the 44px min hit target. */
.docs-viewer__doc {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  min-height: 44px;
  text-decoration: none;
  color: var(--color-text-primary);
}
.docs-viewer__doc:hover { background: var(--color-surface-cream); }
.docs-viewer__doc-icon { display: grid; place-items: center; color: var(--color-primary); }
.docs-viewer__doc-icon svg { width: 20px; height: 20px; }
/* The doc title can wrap (the base .list-row__label is nowrap for short rows). */
.docs-viewer__doc-title { white-space: normal; }
.docs-viewer__doc .list-row__chevron { display: grid; place-items: center; }
/* Active document — green-soft fill + green border (the on-light echo of the
   .list-row--active gold highlight, which is barred here on a light card). */
.docs-viewer__doc[aria-current="true"] {
  background: var(--color-primary-soft);
  border-color: var(--color-primary);
}
.docs-viewer__doc[aria-current="true"] .list-row__label { font-weight: var(--weight-semibold); }

/* --- Stage (title + Open/Download action, then the native preview) ---- */
.docs-viewer__stage { display: grid; gap: var(--space-3); min-width: 0; }
.docs-viewer__stage-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); flex-wrap: wrap;
}
.docs-viewer__stage-title {
  margin: 0; min-width: 0;
  font-family: var(--font-display); font-size: var(--text-h4);
  color: var(--color-text-primary);
}

/* Native PDF preview surface. min-height 70vh on desktop, reduced on mobile
   (below). The inner fallback shows if the browser can't render the PDF. */
.docs-viewer__frame {
  display: block;
  width: 100%;
  min-height: 70vh;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  background: var(--color-surface);
}
/* Fallback copy — inside the <iframe> and as a sibling note for browsers that
   render the frame blank rather than surfacing its inner content. */
.docs-viewer__fallback { margin: 0; padding: var(--space-4); color: var(--color-text-secondary); text-align: center; }
.docs-viewer__fallback--note { padding: 0; font-size: var(--text-sm); }

/* Stack on mobile: list above stage, shorter preview. */
@media (max-width: 768px) {
  .docs-viewer { grid-template-columns: 1fr; gap: var(--space-4); }
  .docs-viewer__frame { min-height: 60vh; }
}

/* PAGE: Membership Application (become-a-member.html) */
.membership-application.section { background: var(--color-bg-about); }
/* Same max-width as .membership-form below, so the intro copy, the required-field
   note and the cards under them all share ONE left edge. */
.membership-application__intro { max-width: 48rem; margin: 0 auto var(--space-8); }
.membership-application__intro h2 { margin: 0 0 var(--space-3); color: var(--color-primary); }
.membership-application__intro p { color: var(--color-text-secondary); }
.membership-application__required { margin: var(--space-4) 0 0; font-size: var(--text-sm); color: var(--color-error); }
.membership-form { max-width: 48rem; margin-inline: auto; display: grid; gap: var(--space-5); }

/* Each card is a <fieldset>. Left to the UA, its <legend> becomes a "rendered
   legend": extracted from the content box and drawn straddling the card's top
   border, so the heading reads as if it escaped the card. Setting the fieldset
   to display:grid does NOT prevent this — the legend is extracted before the
   grid container is established. `float:left; width:100%` opts the legend out
   of that treatment and makes it an ordinary block INSIDE the card;
   .membership-form__body then clears the float and owns the vertical rhythm
   (one wrapper, one token gap — same convention as .library-zone__body). */
.membership-form__card { min-inline-size: 0; margin: 0; padding: var(--space-6); background: var(--color-surface); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); display: block; }
.membership-form__legend { float: left; width: 100%; margin: 0 0 var(--space-4); padding: 0; font-family: var(--font-display); font-size: var(--text-h4); font-weight: var(--weight-semibold); color: var(--color-text-primary); }
.membership-form__body { clear: both; display: grid; gap: var(--space-4); }
.membership-form__card .input { border: var(--border-width) solid var(--color-border-strong); }
.membership-form__card .input:focus { border-color: var(--color-primary); }
/* Two-up only in the "Your details" card; --wide is an explicit opt-out so the
   full-width fields stay correct if a field is ever added or reordered. */
.membership-form__details .membership-form__body { grid-template-columns: 1fr 1fr; }
.membership-form__field--wide { grid-column: 1 / -1; }
.membership-form__statement { margin: 0; color: var(--color-text-secondary); }
.membership-choice { display: flex; align-items: flex-start; gap: var(--space-3); min-height: 44px; padding-block: var(--space-2); color: var(--color-text-primary); cursor: pointer; }
.membership-choice input { flex: 0 0 auto; width: 1.25rem; height: 1.25rem; margin-top: .1rem; accent-color: var(--color-primary); }
.membership-choice input:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.membership-form__choices { display: grid; gap: var(--space-2); }
.membership-form__other { max-width: 28rem; }

/* Verification document = one checkbox + the upload it reveals. The reveal is
   indented to the checkbox's text so it visibly belongs to that option.
   PROGRESSIVE ENHANCEMENT: the hidden state is scoped to html.js, so with JS
   OFF every upload stays visible and usable (mirrors the .member-verify steps).
   data-doc-state="off" ships in the markup — inert without .js, so the first
   paint is already correct and no panel flashes open. */
.membership-doc { display: grid; gap: var(--space-2); }
.membership-doc__reveal { display: grid; gap: var(--space-4); margin-left: calc(1.25rem + var(--space-3)); padding-bottom: var(--space-2); }
.js [data-doc][data-doc-state="off"] [data-doc-reveal] { display: none; }
.membership-doc__hint { margin: 0; font-size: var(--text-sm); color: var(--color-text-secondary); }
.membership-doc__file { padding: var(--space-2) var(--space-3); min-height: 44px; cursor: pointer; }
.membership-doc__file::file-selector-button { margin-inline-end: var(--space-3); padding: var(--space-2) var(--space-4); font-family: var(--font-body); font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--color-primary); background: var(--color-surface-cream); border: var(--border-width) solid var(--color-border-strong); border-radius: var(--radius-md); cursor: pointer; transition: background-color var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease); }
.membership-doc__file::file-selector-button:hover { background: var(--color-highlight); border-color: var(--color-primary); }

/* --text-lg (not --text-h3) so these sub-headings stay a step BELOW the
   card's own legend (--text-h4); the type scale stops at h4. */
.membership-form__terms h3 { margin: var(--space-2) 0 0; font-family: var(--font-display); font-size: var(--text-lg); font-weight: var(--weight-semibold); color: var(--color-primary); text-decoration: underline; }
.membership-form__terms p { margin: 0; color: var(--color-text-secondary); }
.membership-form__error { margin: 0; color: var(--color-error); font-size: var(--text-sm); }
.membership-form__error:empty { display: none; }
.membership-form__notice { margin: 0; color: var(--color-text-secondary); font-size: var(--text-sm); text-align: center; }
.membership-form__actions .btn { width: 100%; }
.membership-form__hp { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ============================================================
   SECTION: Volunteer Application  (volunteer.html)
   -------------------------------------------------------------
   Reuses the membership-form cards, shared controls and choice tiles.
   The additions only supply the form's two-column details grid, compact
   multi-select tile layout, minor-consent message and group error state.
   ============================================================ */
.volunteer-application.section { background: var(--color-bg-about); }
.volunteer-form { max-width: 48rem; margin-inline: auto; display: grid; gap: var(--space-5); }
.volunteer-form__grid { grid-template-columns: 1fr 1fr; }
.volunteer-form__minor-note { grid-column: 1 / -1; margin: 0; padding: var(--space-3) var(--space-4); color: var(--color-text-secondary); background: var(--color-primary-soft); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-md); font-size: var(--text-sm); }
.js .volunteer-form__minor-note[hidden] { display: none; }
.volunteer-form__choices { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.volunteer-form__choices .choice-tile { min-height: 4.75rem; }
.volunteer-form__error { min-height: 1.4em; margin: var(--space-2) 0 0; color: var(--color-error); font-size: var(--text-sm); }
.volunteer-form__consent .membership-choice { align-items: flex-start; }
@media (max-width: 640px) {
  .volunteer-form__grid, .volunteer-form__choices { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .membership-form__details .membership-form__body { grid-template-columns: 1fr; }
  .membership-form__card { padding: var(--space-5); }
  /* Reclaim the indent — at this width the reveal needs the full card. */
  .membership-doc__reveal { margin-left: var(--space-3); }
}

/* ============================================================
   SECTION: Student Enrolment  (student-enrolment.html)
   -------------------------------------------------------------
   *** NEW BEM BLOCKS — flagged addition (did not exist before). ***
   .enrol-form reuses the membership form's card chrome
   (.membership-form__card / __legend / __body / __terms / __actions
   / __notice / __hp) and the shared Form Controls (.field / .input),
   and adds only what the enrolment form needs: a two-column field
   grid, a sub-heading inside a card, selectable .choice-tile radios,
   the .phone-field + .country-select pair, an in-button spinner
   (.btn--loading) and the .dialog confirmation.
   Tokens only — no new colours, no new radii.
   ============================================================ */
.enrol-application.section { background: var(--color-bg-about); }
/* Same measure as .membership-form so the intro, the required-field note and
   the cards all share one left edge. */
.enrol-form { max-width: 48rem; margin-inline: auto; display: grid; gap: var(--space-5); }

/* Two-column field grid inside a card; --wide spans the row. Mirrors
   .membership-form__details / .membership-form__field--wide. */
.enrol-form__grid { grid-template-columns: 1fr 1fr; }
.enrol-form__field--wide { grid-column: 1 / -1; }

/* A titled group INSIDE a card. The fieldset carries no chrome of its own —
   the card already provides it — so it is stripped back to a plain block.
   The legend floats for the same reason .membership-form__legend does: a bare
   legend is lifted out by the browser into the (invisible) fieldset border. */
.enrol-form__group { min-inline-size: 0; margin: 0; padding: 0; border: 0; display: block; }
.enrol-form__group[hidden] { display: none; }
.enrol-form__group + .enrol-form__group { margin-top: var(--space-6); }
/* One step below .membership-form__legend, matching the legend-to-h3 step in
   the membership declaration card. No underline here. */
.enrol-form__subhead {
  float: left; width: 100%; margin: 0 0 var(--space-4); padding: 0;
  font-family: var(--font-display); font-size: var(--text-lg);
  font-weight: var(--weight-semibold); color: var(--color-primary);
}
.enrol-form__aside,
.enrol-form__note { clear: both; margin: var(--space-3) 0 0; font-size: var(--text-sm); }
.enrol-form__note { color: var(--color-text-secondary); }

/* --- Selectable tile (radio) -------------------------------- */
/* The <input> is visually hidden but still focusable and still the thing the
   browser validates, so the group works with JS off and by keyboard. */
.choice-tiles { clear: both; display: grid; gap: var(--space-3); }
.choice-tiles[hidden] { display: none; }
.choice-tiles--four { grid-template-columns: repeat(4, 1fr); }
.choice-tiles--two  { grid-template-columns: repeat(2, 1fr); }

.choice-tile {
  position: relative;
  display: grid; align-content: start; gap: var(--space-1);
  min-height: 44px;
  padding: var(--space-4) var(--space-8) var(--space-4) var(--space-4);
  background: var(--color-surface);
  border: var(--border-width-strong) solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease),
              background var(--duration-fast) var(--ease);
}
.choice-tile:hover { border-color: var(--color-primary); }
.choice-tile[hidden] { display: none; }
.choice-tile__input {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.choice-tile__title { font-family: var(--font-display); font-size: var(--text-h4); font-weight: var(--weight-semibold); color: var(--color-text-primary); line-height: var(--leading-snug); }
/* Age line drops to body size — it is a qualifier, not a second title. */
.choice-tile__meta { font-size: var(--text-base); color: var(--color-text-secondary); }

/* Filled green tick, top-right. Hidden until the tile's own radio is checked. */
.choice-tile__mark {
  position: absolute; top: var(--space-3); right: var(--space-3);
  display: grid; place-items: center;
  width: 22px; height: 22px;
  background: var(--color-primary); color: var(--color-on-primary);
  border-radius: var(--radius-pill);
  opacity: 0; transform: scale(.6);
  transition: opacity var(--duration-fast) var(--ease), transform var(--duration-fast) var(--ease);
}
.choice-tile__mark svg { width: 14px; height: 14px; }
.choice-tile__input:checked ~ .choice-tile__mark { opacity: 1; transform: scale(1); }
/* The frame belongs to the label, which no sibling selector can reach, so the
   checked border needs :has(). Browsers without it still show the tick above. */
.choice-tile:has(.choice-tile__input:checked) { border-color: var(--color-primary); background: var(--color-primary-soft); }
.choice-tile:has(.choice-tile__input:focus-visible) { box-shadow: var(--shadow-focus); }

/* --- Phone field (dialling code + number) ------------------- */
.phone-field { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-2); align-items: start; }
/* No-JS baseline: a plain, narrow text input for the dialling code.
   countrySelect() hides it and keeps writing the chosen code into it. */
.phone-field__code { width: 5.5rem; }
.phone-field[data-phone-enhanced] .phone-field__code { display: none; }

/* --- Country select (searchable, flags) --------------------- */
.country-select { position: relative; }
.country-select__trigger {
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-height: 44px; padding: var(--space-3);
  font-family: var(--font-body); font-size: var(--text-base); color: var(--color-text-primary);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease);
}
.country-select__trigger:hover { border-color: var(--color-primary); }
.country-select__trigger:focus-visible { outline: none; border-color: var(--color-primary); box-shadow: var(--shadow-focus); }
.country-select__chevron { width: 14px; height: 14px; color: var(--color-text-secondary); }
.country-select__flag { width: 22px; height: 16px; object-fit: cover; border-radius: 2px; flex: 0 0 auto; }

.country-select__popup {
  position: absolute; z-index: var(--z-dropdown); top: calc(100% + var(--space-1)); left: 0;
  width: max(18rem, 100%);
  display: grid; grid-template-rows: auto minmax(0, 1fr);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.country-select__popup[hidden] { display: none; }
.country-select__search { margin: var(--space-2); width: calc(100% - 2 * var(--space-2)); }
.country-select__list { margin: 0; padding: 0 0 var(--space-2); list-style: none; max-height: 16rem; overflow-y: auto; }
.country-select__option {
  display: flex; align-items: center; gap: var(--space-3);
  width: 100%; min-height: 44px; padding: var(--space-2) var(--space-3);
  font-family: var(--font-body); font-size: var(--text-sm); text-align: left; color: var(--color-text-primary);
  background: transparent; border: 0; cursor: pointer;
}
.country-select__option:hover,
.country-select__option:focus-visible { outline: none; background: var(--color-surface-cream); }
.country-select__option[aria-selected="true"] { background: var(--color-primary-soft); font-weight: var(--weight-semibold); }
.country-select__name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.country-select__dial { flex: 0 0 auto; color: var(--color-text-secondary); }
.country-select__empty { margin: 0; padding: var(--space-4) var(--space-3); font-size: var(--text-sm); color: var(--color-text-secondary); }

/* --- Button loading state ----------------------------------- */
/* The label stays in place (no layout jump) and the spinner sits beside it.
   .btn is already an inline-flex row with a gap, so nothing else is needed. */
.btn__spinner { display: none; }
.btn--loading .btn__spinner {
  display: block; width: 1em; height: 1em;
  border: 2px solid currentColor; border-top-color: transparent;
  border-radius: var(--radius-pill);
  animation: btn-spin .7s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .btn--loading .btn__spinner { animation-duration: 2.4s; }
}

/* --- Dialog (confirmation) ---------------------------------- */
/* Same scrim / centring / z-index as .modal, in a short message shape. */
.dialog {
  position: fixed; inset: 0; z-index: var(--z-modal);
  display: grid; place-items: center;
  padding: var(--space-4);
}
.dialog[hidden] { display: none; }
.dialog__scrim { position: absolute; inset: 0; background: rgba(29, 57, 34, .55); }
.dialog__panel {
  position: relative;
  width: min(30rem, 100%);
  padding: var(--space-8) var(--space-6);
  text-align: center;
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}
.dialog__icon {
  display: grid; place-items: center;
  width: 48px; height: 48px; margin: 0 auto var(--space-4);
  background: var(--color-primary); color: var(--color-on-primary);
  border-radius: var(--radius-pill);
}
.dialog__icon svg { width: 26px; height: 26px; }
.dialog__title { margin: 0 0 var(--space-3); font-size: var(--text-h3); color: var(--color-primary); }
.dialog__body { margin: 0; color: var(--color-text-secondary); }
.dialog__actions { margin-top: var(--space-6); }
.dialog__actions .btn { width: 100%; }

/* --- Parent portal dashboard ---------------------------------
   Reuses existing tokens only (surface / border / shadow-sm / space
   scale) so the portal reads as part of the same site, not a bolted-on
   admin skin. .chip is the existing pending/confirmed pill; the status
   modifiers below extend it for the six Student::STATUSES values. */
.parent-dashboard { background: var(--color-bg-about); }
.parent-dashboard__grid {
  display: grid; gap: var(--space-6);
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.parent-card {
  display: block;
  padding: var(--space-6);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: border-color var(--duration-fast) var(--ease), transform var(--duration-fast) var(--ease);
}
a.parent-card:hover { border-color: var(--color-primary); transform: translateY(-2px); }
.parent-card__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.parent-card__name { margin: 0; font-family: var(--font-display); font-size: var(--text-h4); color: var(--color-text-primary); }
.parent-card__meta { margin: var(--space-2) 0 0; color: var(--color-text-secondary); font-size: var(--text-sm); }
.parent-card__id { margin: var(--space-1) 0 0; color: var(--color-text-secondary); font-size: var(--text-xs); font-weight: var(--weight-semibold); letter-spacing: .02em; text-transform: uppercase; }

.chip--active     { background: var(--color-primary-soft); color: var(--color-primary); }
.chip--pending-status { background: var(--color-surface-cream); border: var(--border-width) solid var(--color-border); color: var(--color-accent-amber); }
.chip--inactive,
.chip--graduated,
.chip--suspended,
.chip--withdrawn { background: var(--color-surface-stone); border: var(--border-width) solid var(--color-border); color: var(--color-text-secondary); }
.chip--suspended  { color: var(--color-error); }

.parent-panel {
  padding: var(--space-6);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.parent-panel + .parent-panel { margin-top: var(--space-6); }
.parent-panel__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-5); }
.parent-panel__title { margin: 0; font-family: var(--font-display); font-size: var(--text-h4); color: var(--color-text-primary); }

.parent-tabs { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-6); }
.parent-tabs__link {
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  border: var(--border-width) solid var(--color-border);
  color: var(--color-text-secondary);
  font-size: var(--text-sm); font-weight: var(--weight-semibold);
}
.parent-tabs__link:hover { border-color: var(--color-primary); color: var(--color-primary); }
.parent-tabs__link--active { background: var(--color-primary); border-color: var(--color-primary); color: var(--color-on-primary); }
.parent-tabs__link--locked { color: var(--color-text-secondary); opacity: .55; cursor: not-allowed; }

.parent-locked {
  padding: var(--space-8) var(--space-6);
  text-align: center;
  background: var(--color-surface-cream);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  color: var(--color-text-secondary);
}
.parent-locked p { margin: var(--space-2) 0 0; }

.parent-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.parent-table th { text-align: left; padding: var(--space-2) var(--space-3); color: var(--color-text-secondary); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: .04em; border-bottom: var(--border-width) solid var(--color-border); }
.parent-table td { padding: var(--space-3); border-bottom: var(--border-width) solid var(--color-border); }
.parent-table tr:last-child td { border-bottom: 0; }

.parent-empty { padding: var(--space-8) 0; text-align: center; color: var(--color-text-secondary); }

/* --- Responsive --------------------------------------------- */
@media (max-width: 900px) {
  .choice-tiles--four { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .enrol-form__grid { grid-template-columns: 1fr; }
  .choice-tiles--four,
  .choice-tiles--two { grid-template-columns: 1fr; }
  /* The popup would overflow the gutter if it kept the trigger's left edge. */
  .country-select__popup { width: min(18rem, 78vw); }
}
