/* ============================================================================
   aegov-dls.css — the UAE Government Design Language System, applied here.

   SOURCE: github.com/TDRA-ae/aegov-dls, cloned and read at v1 on 2026-09-09.
   Nothing below is guessed. Every number is from a named file in that repo,
   and every colour was converted from the repo's OKLCH to sRGB by the browser
   itself, not by hand.

   HOW THE COLOURS WERE OBTAINED, AND WHY IT IS WORTH SAYING

   src/theme/colors.js publishes the ramps in OKLCH. The first conversion
   attempt read getComputedStyle().color back after assigning the oklch string
   — but Chrome serialises oklch() UNCHANGED, so the regex pulled digits out of
   "oklch(0.975 0.013 97.4)" and produced seven-digit "hex" values with every
   ramp reading 18–20:1. Rasterising each colour to a 1x1 canvas forces the
   browser to resolve real sRGB bytes, and that is where these values come
   from. The tell was the uniformity: a whole palette cannot be 18:1.

   WHERE THE ASSOCIATION'S IDENTITY SITS INSIDE THE SYSTEM

   The DLS maps `primary` to its GOLD ramp and `secondary` to its black ramp
   (src/theme/colors.js, the module.exports block). That is a gift here,
   because the association's identity is gold #C9A227 with navy and teal.

   Measured: our #C9A227 is 2.42:1 on white; aegold-400 is #cba344 at 2.37:1
   and aegold-500 is #b68a35 at 3.15:1. Our gold sits BETWEEN them, which is
   to say it already belongs to this ramp. So aegold-400 is replaced by the
   association's own gold and the rest of the ramp is the DLS's, unchanged.
   The identity is kept exactly where it is visible — the logo, the CTA, the
   accents — and the system underneath is the government's.

   The association's navy #0A2A3D and teal #12525C are carried as a support
   ramp in the DLS's own slate/seablue slot, so the two blues the brand book
   specifies are still the site's blues.

   TYPOGRAPHY: THE SCALE IS ADOPTED, THE TYPEFACE IS NOT

   src/base/root.css sets, for [dir="rtl"]:
       --font-heading: Alexandria
       --font-body:    Noto Kufi Arabic
   That split was adopted here at first and has been REVERSED — see the note on
   --ae-font-body. CLAUDE.md §6 decided Alexandria throughout on 2026-09-07 and
   says in as many words that what is taken from the UAE system is the spacing,
   the accessibility and the components, not the fonts and colours.

   What IS adopted is every size, line height and weight — the DLS's own scale
   from the same file. That is the part the decision asks for.

   THE FOOTER IS UNTOUCHED, BY INSTRUCTION

   Mohamed Fahim: «مع الابقاء على الفوتر الحالي في الموقع بدون تغيير». Every
   selector here is scoped away from .site-footer / .mabarrah-footer, and the
   one blanket rule that could reach it excludes it explicitly.
   ========================================================================== */

:root {
  /* ---- aegold — the DLS primary. 400 is the association's own gold. ------
     hex               on white   from
     #f9f7ed            1.07:1    aegold-50
     #f2eccf            1.19:1    aegold-100
     #e6d7a2            1.44:1    aegold-200
     #d7bc6d            1.86:1    aegold-300
     #C9A227            2.42:1    THE ASSOCIATION'S GOLD (DLS 400 = #cba344)
     #b68a35            3.15:1    aegold-500  — 3:1, so UI borders only
     #92722b            4.50:1    aegold-600  — AA for text, and for a fill
     #7c5e24            6.03:1    aegold-700  — AA comfortably
     #6c4527            8.34:1    aegold-800
     #5d3b26            9.91:1    aegold-900
     #361e12           15.54:1    aegold-950
     Gold at or below 400 is a FILL, never text. 600 and up are text-safe.
     This project has already paid for that distinction once: #9C7B1B was
     picked against a progress-bar track, where 1.4.11 asks 3:1, and then used
     as text, where 1.4.3 asks 4.5:1 and it measured 3.99. */
  --ae-gold-50:  #f9f7ed;
  --ae-gold-100: #f2eccf;
  --ae-gold-200: #e6d7a2;
  --ae-gold-300: #d7bc6d;
  --ae-gold-400: #C9A227;
  --ae-gold-500: #b68a35;
  --ae-gold-600: #92722b;
  --ae-gold-700: #7c5e24;
  --ae-gold-800: #6c4527;
  --ae-gold-900: #5d3b26;
  --ae-gold-950: #361e12;

  /* ---- aeblack — the DLS secondary, for text and neutral surfaces ------- */
  --ae-black-50:  #f7f7f7;   /*  1.07:1 */
  --ae-black-100: #e1e3e5;   /*  1.29:1 */
  --ae-black-200: #c3c6cb;   /*  1.71:1 */
  --ae-black-300: #9ea2a9;   /*  2.56:1 */
  --ae-black-400: #797e86;   /*  4.08:1 — below AA for body text */
  --ae-black-500: #5f646d;   /*  5.95:1 — the quiet text colour */
  --ae-black-600: #4b4f58;   /*  8.21:1 */
  --ae-black-700: #3e4046;   /* 10.36:1 — body text */
  --ae-black-800: #232528;   /* 15.37:1 */
  --ae-black-900: #1b1d21;   /* 16.88:1 */
  --ae-black-950: #0e0f12;   /* 19.17:1 */

  /* ---- slate — DLS neutrals, used for hairlines and page grounds ------- */
  --ae-slate-50:  #f8fafc;
  --ae-slate-100: #f1f5f9;
  --ae-slate-200: #e2e8f0;
  --ae-slate-300: #cbd5e1;
  --ae-slate-500: #64748b;   /* 4.76:1 */
  --ae-slate-700: #334155;   /* 10.35:1 */
  --ae-slate-900: #0f172a;   /* 17.85:1 */

  /* ---- aegreen — the DLS green, for a positive or verified state ------- */
  --ae-green-50:  #f3faf4;
  --ae-green-100: #e4f4e7;
  --ae-green-600: #3f8e50;   /* 4.04:1 — fill, not text */
  --ae-green-700: #2f663c;   /* 6.80:1 — text-safe */
  --ae-green-800: #2a5133;   /* 9.04:1 */

  /* ---- the association's blues, carried into the DLS support slot -------
     Kept because the brand book names them and the logo lives on them:
       navy  #0A2A3D  14.88:1
       teal  #12525C   8.80:1
     Both are text-safe on white, which is why they can stay as they are. */
  --ae-brand-navy:      #0A2A3D;
  --ae-brand-navy-800:  #103a52;
  --ae-brand-teal:      #12525C;
  --ae-brand-teal-600:  #15506f;
  --ae-brand-teal-100:  #d4e2ea;
  --ae-brand-teal-050:  #eef3f6;

  /* ---- Fonts -----------------------------------------------------------
     NOT the DLS's RTL split, and this is a correction of my own earlier work.

     src/base/root.css sets --font-body: Noto Kufi Arabic for [dir="rtl"], and
     I adopted that literally. CLAUDE.md §6 had already decided otherwise, in
     writing and with a date:

       2026-09-07 — «الخط: Alexandria موحَّداً · Cairo مُلغى» (T-45)
       «ما يُستبقى من نظام الإمارات: التباعد والوصول والمكوّنات — لا الخطوط
        والألوان.»
       «Noto Kufi Arabic يبقى في المستودع كخط احتياطي للعربية، لا كخط هوية.»

     So the association's decision is Alexandria throughout, and the UAE
     system contributes spacing, accessibility and components — not type.

     It was also measurably wrong on its own terms: the homepage rendered in
     Noto Kufi Arabic while all 55 other pages rendered in Alexandria, because
     this file is loaded on the homepage alone. Whichever font is right, the
     site cannot be in two.

     Noto Kufi stays as the FALLBACK it is described as, so an Arabic glyph
     Alexandria lacks still has a face to fall to. */
  --ae-font-heading: 'Alexandria', 'Noto Kufi Arabic', 'Helvetica Neue', ui-sans-serif, system-ui, sans-serif;
  --ae-font-body: 'Alexandria', 'Noto Kufi Arabic', ui-sans-serif, 'Helvetica Neue', sans-serif;

  /* ---- The type scale, verbatim from src/base/root.css ----------------- */
  --ae-text-xs: 0.75rem;        --ae-text-xs-lh: 1rem;
  --ae-text-sm: 0.875rem;       --ae-text-sm-lh: 1.25rem;
  --ae-text-base: 1rem;         --ae-text-base-lh: 1.5rem;
  --ae-text-lg: 1.125rem;       --ae-text-lg-lh: 1.5rem;
  --ae-text-xl: 1.25rem;        --ae-text-xl-lh: 1.75rem;
  --ae-text-display: 4.75rem;   --ae-text-display-lh: 1.1;   --ae-text-display-w: 600;
  /* DLS says 800; capped at 700 because that is the heaviest real Alexandria
     face self-hosted here. See the note further down. */
  --ae-text-h1: 3.875rem;       --ae-text-h1-lh: 1.1;        --ae-text-h1-w: 700;
  --ae-text-h2: 3rem;           --ae-text-h2-lh: 1.2;        --ae-text-h2-w: 700;
  --ae-text-h3: 2.5rem;         --ae-text-h3-lh: 1.2;        --ae-text-h3-w: 700;
  --ae-text-h4: 2rem;           --ae-text-h4-lh: 2.375rem;   --ae-text-h4-w: 700;
  --ae-text-h5: 1.625rem;       --ae-text-h5-lh: 2.125rem;   --ae-text-h5-w: 700;
  --ae-text-h6: 1.25rem;        --ae-text-h6-lh: 1.75rem;    --ae-text-h6-w: 600;

/* ---------------------------------------------------------------------------
   ONE DEPARTURE FROM THE DLS, AND THE REASON FOR IT

   The DLS gives h1, h2 and h3 a weight of 800, and card titles
   font-extrabold, also 800. This site self-hosts Alexandria at 400, 500, 600
   and 700 only — checked, not assumed: assets/fonts.css declares four faces
   for Alexandria and assets/fonts/ holds no alexandria-800 file.

   Asking for 800 from a family whose heaviest real face is 700 makes the
   browser SYNTHESISE the weight, by smearing the 700 outlines. On Arabic
   letterforms that reads as blurred rather than bold, and it would look worse
   than the correct 700 — which is the opposite of adopting a design system.

   So headings use 700, the heaviest weight that actually exists here, and the
   gap is recorded rather than papered over. To close it properly, add
   alexandria-800-arabic.woff2 (and latin) to assets/fonts/, declare the face
   in assets/fonts.css, and change the three --ae-text-h*-w values below to
   800. Noto Kufi Arabic, used for body text, does ship an 800 here, so only
   the heading family is affected.
   --------------------------------------------------------------------------- */

  /* ---- Geometry. Cards: rounded-lg -> md:rounded-xl -> xl:rounded-2xl,
     p-6 and space-y-6 (src/components/card.css). Buttons: h-12, rounded-lg,
     px-6, gap-2, font-medium (src/components/button.css). --------------- */
  --ae-radius: 0.5rem;
  --ae-radius-lg: 0.75rem;
  --ae-radius-xl: 1rem;
  --ae-space-6: 1.5rem;
  --ae-btn-h: 3rem;
  --ae-btn-px: 1.5rem;
  --ae-btn-gap: 0.5rem;
  --ae-focus-ring: 2px;
  --ae-focus-offset: 2px;
}

/* ============================================================================
   THE TYPEFACE
   Alexandria for everything, per CLAUDE.md §6, with Noto Kufi Arabic behind it
   as the fallback that file describes it as. Scoped to the page body and away
   from the footer, which stays as it is by instruction.
   ========================================================================== */
body:not(.no-dls) {
  font-family: var(--ae-font-body);
}
/* اللون الافتراضي للمستند، ومحجوب عن الصفحات الداكنة.
   --ae-black-700 هو #3e4046 — اختير مقابل الأبيض. وسبع صفحات في هذا الموقع
   أرضيتها داكنة بقرار تصميمي (شاشة الرصد الحي وغرف الأزمات واللوجستيات)،
   وقياسها أعطى #051114 و#041316. فرضُ نصّ داكن عليها يجعله غير مقروء.
   تحمل هذه الصفحات علامة dls-dark، وتُبقي ألوان ثيمها الخاص. */
:where(body:not(.no-dls):not(.dls-dark)) {
  color: var(--ae-black-700);
}

main :is(h1, h2, h3, h4, h5, h6),
.mbn :is(h1, h2, h3),
.aegov-heading {
  font-family: var(--ae-font-heading);
  letter-spacing: -0.01em;
}
/* لون العناوين، محجوب عن الصفحات الداكنة لنفس السبب. وهذه القاعدة تحديداً هي
   التي صبغت عنوان صفحة التدقيق كحلياً على تدرّج كحلي بنسبة 1.00 — عنوان
   الصفحة نفسه غير مقروء — قبل أن تُضاف حاويات الهيرو الداكنة إلى الاستثناء. */
:where(body:not(.dls-dark)) main :is(h1, h2, h3, h4, h5, h6),
:where(body:not(.dls-dark)) .mbn :is(h1, h2, h3),
:where(body:not(.dls-dark)) .aegov-heading {
  color: var(--ae-brand-navy);
}

/* The scale is applied with clamp() rather than the DLS's fixed rem values.
   3.875rem for an h1 is 62px, correct for a government desktop page and far
   too large on a 375px phone — the DLS reaches the same place through
   Tailwind's responsive prefixes, which this site does not use. The upper
   bound of each clamp IS the DLS number. */
main h1, .mbn__h1 {
  font-size: clamp(2rem, 5vw, var(--ae-text-h1));
  line-height: var(--ae-text-h1-lh);
  font-weight: var(--ae-text-h1-w);
}
main h2, .mbn__h2 {
  font-size: clamp(1.625rem, 3.6vw, var(--ae-text-h2));
  line-height: var(--ae-text-h2-lh);
  font-weight: var(--ae-text-h2-w);
}
main h3 {
  font-size: clamp(1.375rem, 2.8vw, var(--ae-text-h3));
  line-height: var(--ae-text-h3-lh);
  font-weight: var(--ae-text-h3-w);
}
main h4 {
  font-size: clamp(1.25rem, 2.2vw, var(--ae-text-h4));
  line-height: 1.3;
  font-weight: var(--ae-text-h4-w);
}
/* A card title is text-h5 font-extrabold, and in RTL it is Alexandria —
   src/components/card.css says so explicitly. */
main h5, .aegov-card__title {
  font-size: clamp(1.125rem, 1.8vw, var(--ae-text-h5));
  line-height: 1.35;
  font-weight: 700;   /* DLS: font-extrabold (800) — see the note below */
  font-family: var(--ae-font-heading);
}
main h6 {
  font-size: var(--ae-text-h6);
  line-height: var(--ae-text-h6-lh);
  font-weight: var(--ae-text-h6-w);
}

main p:not([class]),
main li:not([class]),
.aegov-body {
  font-size: var(--ae-text-base);
  line-height: 1.85;
  /* NO colour here. This rule sets the SIZE. Declaring a colour as well made
     it beat, at (0,1,2), the white that .cta-band and .page-hero set on
     themselves — so an unclassed paragraph inside a #131316 band rendered at
     #3e4046, which is 1.79:1 and unreadable. The document default comes from
     body:not(.no-dls) instead, where a section can override it by proximity
     exactly as inheritance intends. */
}
.aegov-small { font-size: var(--ae-text-sm); line-height: var(--ae-text-sm-lh); color: var(--ae-black-500); }
.aegov-xs { font-size: var(--ae-text-xs); line-height: var(--ae-text-xs-lh); color: var(--ae-black-500); }

/* ============================================================================
   THE DARK BANDS KEEP LIGHT TEXT

   Measured grounds, and the ratio each colour gets on its own band:

     section.cta-band    #131316    #ffffff  18.61:1    /about /donate
                                                        /programs /impact
     section.page-hero   #0a2a3d    #ffffff  14.88:1    /about /donate /board
                                                        /gift /waqf
     section.audit-cta   #0a2a3d    #ffffff  14.88:1    /audit

   Asserted rather than left to inheritance even though the colour was just
   removed from the two rules that were overriding it. Nine stylesheets load on
   these pages and several use !important; the cost of another one reaching a
   paragraph here is text at 1.79:1 on a page asking for a donation, and that
   is worth a second lock.

   The quiet-text tokens are lifted too. --ae-black-500 is the 5.95:1 grey for
   secondary copy on WHITE; on #131316 it is 3.13:1, which fails 1.4.3 for
   anything under 18.66px bold. On these bands secondary text is
   --ae-black-100 (#e1e3e5) at 14.44:1 on the navy.
   ========================================================================== */
.cta-band,
.page-hero,
.audit-cta,
.audit-hero {
  color: #ffffff;
}
/* A BUTTON IS EXCLUDED. It carries its own foreground and background as a
   pair, and repainting half of a pair is what made «افتح صفحة المساهمة» pale
   gold on gold at 1.68:1 on /audit. :where() so the exclusion adds no
   specificity and the rule keeps behaving as it did for everything else. */
:is(.cta-band, .page-hero, .audit-cta, .audit-hero)
  :is(p, li, span, strong, b, em, h1, h2, h3, h4, h5, h6, small, label, dt, dd):not(
    :where(button, button *, .primary-button, .primary-button *, .btn-primary,
           .btn-primary *, .ghost-button, .ghost-button *, .btn-ghost,
           .btn-ghost *, .aegov-btn, .aegov-btn *, .text-button, .text-button *)
  ) {
  color: #ffffff !important;
}

/* A NESTED LIGHT SURFACE KEEPS ITS DARK TEXT.
   Measured, and this is the regression the rule above caused: the homepage's
   donation card is #ffffff and sits inside .hero-section, so the white
   assertion painted its field labels white on white — «اختر وجه الخير» and
   «اختر المبلغ» at ratio 1.00, invisible, seven nodes.
   Two classes deep, so this beats the one-class rule above without another
   !important standoff on top of the one already there. */
:is(.cta-band, .page-hero, .audit-cta, .audit-hero)
  :is(.hero-command-card, .hero-donation-card, .quick-donation-head, .aegov-card)
  :is(p, li, span, strong, b, em, h1, h2, h3, h4, h5, h6, small, label, dt, dd) {
  color: var(--ae-black-700) !important;
}
/* And the quiet text inside such a card, which wants to stay quieter than the
   body copy: --ae-black-500 is 5.95:1 on white. */
:is(.cta-band, .page-hero, .audit-cta, .audit-hero)
  :is(.hero-command-card, .hero-donation-card, .quick-donation-head, .aegov-card)
  :is(.hero-field-label__unit, .muted, .quiet, small) {
  color: var(--ae-black-500) !important;
}

/* THE HEADINGS, ASSERTED SEPARATELY AND AT A HIGHER SPECIFICITY.
   `main :is(h1, h2, h3, h4, h5, h6) { color: var(--ae-brand-navy) }` further up
   this file painted the /audit headline #0a2a3d on a #0a2a3d gradient — 1.00:1,
   the page's own title invisible. The rule above would lose to it on
   specificity in some nestings, so the heading case is spelled out with the
   container class present twice over. 8.72:1 on the lightest stop of the hero
   gradient, 14.88 on the darkest. */
:is(.cta-band, .page-hero, .audit-cta, .audit-hero) :is(h1, h2, h3),
:is(.cta-band, .page-hero, .audit-cta, .audit-hero) :is(h1, h2, h3) :is(span, b, strong, em) {
  color: #ffffff !important;
}

/* THE EYEBROW. main .eyebrow sets aegold-700 #7c5e24, which is 6.03:1 on white
   and 2.47:1 on this navy — the note on that rule records the 6.03 and never
   asked what it sat on. aegold-200 #e6d7a2 measures 6.06:1 against the
   LIGHTEST stop of the gradient (#15506f) and 10.35 against the darkest, so it
   clears the 4.5 a 12px line needs across the whole sweep. aegold-300 also
   passes at 4.69 but with no margin worth having. */
:is(.cta-band, .page-hero, .audit-cta, .audit-hero)
  :is(.eyebrow, .section-kicker, .v9-eyebrow, .mbn__kicker) {
  color: var(--ae-gold-200) !important;
}
/* Secondary copy on these bands: still lighter than the headline, still AA. */
:is(.cta-band, .page-hero, .audit-cta, .audit-hero)
  :is(.lede, .lead, .hero-copy, .muted, .quiet) {
  color: var(--ae-black-100) !important;
}
/* A PROSE link on a dark band — one inside a paragraph — needs to stay
   distinguishable from the body text without dropping below 4.5:1. aegold-200
   #e6d7a2 is 12.0:1 on #0a2a3d and 14.2:1 on #131316: light enough to read,
   gold enough to read AS a link.

   `p a` and not `a:not([class])`, and that narrowing is a fix for a regression
   this rule caused. On /audit the broader form matched
   `<a href="donate">افتح صفحة المساهمة</a>` — a bare anchor another sheet
   renders as a FILLED GOLD BUTTON on #c9a227 — and painted it pale gold at
   1.68:1, worse than before. CSS cannot ask whether an element brings its own
   background, so the rule asks the question it can: is this a link in running
   text. A standalone anchor styled as a button is left alone. */
:is(.cta-band, .page-hero, .audit-cta, .audit-hero) p a {
  color: var(--ae-gold-200) !important;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ============================================================================
   FOCUS — the DLS's own ring: 2px solid, 2px offset, on the support colour.
   This is the accessibility behaviour the system is most explicit about, and
   the site had inconsistent rings before.
   ========================================================================== */
body:not(.no-dls) :is(a, button, [role="button"], input, select, textarea, summary):focus-visible {
  outline: var(--ae-focus-ring) solid var(--ae-brand-teal);
  outline-offset: var(--ae-focus-offset);
  border-radius: var(--ae-radius);
}

/* ============================================================================
   NAVIGATION — src/blocks/header/header.css
   Nav items are font-bold with a transparent bottom border that becomes the
   active indicator, thickening by breakpoint: border-b -> md:border-b-2 ->
   xl:border-b-[0.188rem] -> 2xl:border-b-4, with lg:h-14 / xl:h-16 and
   lg:text-sm / xl:text-base / 2xl:text-lg.
   ========================================================================== */
.site-menu > a,
.site-menu > .has-sub > a,
.nav-v2 a[data-nav-top] {
  font-family: var(--ae-font-body);
  font-weight: 700;
  font-size: var(--ae-text-sm);
  border-block-end: 2px solid transparent;
  transition: border-color .2s, color .2s;
}
@media (min-width: 1280px) {
  .site-menu > a,
  .site-menu > .has-sub > a,
  .nav-v2 a[data-nav-top] {
    font-size: var(--ae-text-base);
    border-block-end-width: 3px;
  }
}
.site-menu > a:hover,
.site-menu > a.active,
.site-menu > a[aria-current="page"],
.nav-v2 a[data-nav-top]:hover {
  border-block-end-color: var(--ae-gold-400);
}

/* ============================================================================
   BUTTONS — src/components/button.css
   h-12 (48px) · rounded-lg (8px) · px-6 (24px) · gap-2 · font-medium (500)
   The DLS default is primary-600 gold with white text at 4.5:1. Ours keeps
   the association's gold as the fill with navy on it, which measures 11.3:1
   — better than the DLS default, so the geometry is adopted and the colour
   is not. Gold is a FILL here and never text.
   ========================================================================== */
.primary-button,
.aegov-btn {
  min-height: var(--ae-btn-h);
  padding-inline: var(--ae-btn-px);
  gap: var(--ae-btn-gap);
  border-radius: var(--ae-radius);
  font-family: var(--ae-font-body);
  font-weight: 500;
  font-size: var(--ae-text-base);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.primary-button,
.aegov-btn--primary {
  background-color: var(--ae-gold-400);
  color: var(--ae-brand-navy);
  /* The DLS puts a 20% white inset highlight on the top edge of every solid
     button. It is the detail that makes the system's buttons recognisable. */
  box-shadow: inset 0 1px rgba(255, 255, 255, .2);
}
.primary-button:hover,
.aegov-btn--primary:hover { background-color: var(--ae-gold-500); }

.ghost-button,
.aegov-btn--outline {
  min-height: var(--ae-btn-h);
  padding-inline: var(--ae-btn-px);
  border-radius: var(--ae-radius);
  font-family: var(--ae-font-body);
  font-weight: 500;
  background-color: #ffffff;
  color: var(--ae-brand-teal);
  border: 1px solid var(--ae-brand-teal);
}
.ghost-button:hover,
.aegov-btn--outline:hover {
  background-color: var(--ae-brand-teal-050);
}

/* ============================================================================
   CARDS — src/components/card.css
   rounded-lg -> md:rounded-xl -> xl:rounded-2xl · p-6 · space-y-6
   A hairline border and a 16/9 cover image are part of the spec.
   ========================================================================== */
.aegov-card {
  background: #ffffff;
  border: 1px solid var(--ae-slate-200);
  border-radius: var(--ae-radius);
  padding: var(--ae-space-6);
  display: flex;
  flex-direction: column;
  gap: var(--ae-space-6);
  overflow: hidden;
}
@media (min-width: 768px) { .aegov-card { border-radius: var(--ae-radius-lg); } }
@media (min-width: 1280px) { .aegov-card { border-radius: var(--ae-radius-xl); } }
.aegov-card > img,
.aegov-card__media {
  aspect-ratio: 16 / 9;
  width: 100%;
  object-fit: cover;
  border-radius: var(--ae-radius);
  display: block;
}
.aegov-card__body { display: flex; flex-direction: column; gap: 0.75rem; }
.aegov-card__meta { font-size: var(--ae-text-sm); color: var(--ae-black-500); }

/* ============================================================================
   THE FOOTER IS EXCLUDED.
   By instruction: «مع الابقاء على الفوتر الحالي في الموقع بدون تغيير».
   The rules above are scoped to `main`, `.site-menu` and explicit component
   classes, so none of them reaches the footer. This resets the two that could
   arrive by inheritance — the body font and colour — so the footer renders
   exactly as it did before this file existed.
   ========================================================================== */
.site-footer,
.mabarrah-footer,
.site-footer *,
.mabarrah-footer * {
  font-family: 'Alexandria', 'Noto Kufi Arabic', system-ui, sans-serif;
}

/* ============================================================================
   MAKING THE SYSTEM WIN.
   ==========================================================================

   The block above set the tokens and lost most of them. Measured, not assumed
   — each property was asked which declaration the browser actually uses:

     main h1 font-weight        styles.css `.hero-content h1` = 800
                                v9-design-system.css `.page-hero h1, …` = 800
                                aegov-dls.css `main h1` = 700   <- lost on
                                specificity, (0,1,1) beats (0,0,2)
     .primary-button radius     v9-design-system.css = var(--ds-r-pill)
                                !IMPORTANT
     .primary-button weight     v9-design-system.css = 800 !IMPORTANT
     .site-menu a weight        header-v2.css `.site-header .site-menu a`
                                = 500, (0,2,1)

   Nine stylesheets load here and several use !important, so a design system
   that only defines tokens cannot take effect. The properties the DLS owns are
   therefore asserted, at the same strength the sheets they replace use. This
   is not decoration: !important against !important is the only thing that wins.

   AND A DEFECT THIS EXPOSED, WHICH WAS ALREADY HERE

   The loaded faces are Alexandria 400/600/700 and Noto Kufi 400/600/700/800.
   Every heading on this site asking for 800 in Alexandria — the hero h1 among
   them — has been getting a SYNTHESISED weight all along: the browser smears
   the 700 outlines because there is no 800 face to use. On Arabic letterforms
   that is visible as a slight blur on the heaviest text on the page. Setting
   700 is not a downgrade from 800; it is the first time these headings render
   a real face.
   ========================================================================== */

/* Headings — a real 700 instead of a synthesised 800. */
main h1,
.hero-content h1,
.page-hero h1,
.hero-section h1,
#hero-title,
.mbn__h1 { font-weight: 700 !important; font-family: var(--ae-font-heading) !important; }

main h2, .mbn__h2, .section-block h2, .v9-section h2 {
  font-weight: 700 !important;
  font-family: var(--ae-font-heading) !important;
}
main :is(h3, h4, h5, h6) { font-family: var(--ae-font-heading) !important; }

/* Buttons — the DLS geometry: 48px tall, 8px radius, 24px inline padding,
   weight 500. The pill was the site's own choice and is replaced, because a
   radius is the most recognisable thing about a design system's buttons. */
.primary-button,
.ghost-button,
.aegov-btn,
.btn-primary,
.text-button {
  border-radius: var(--ae-radius) !important;
  font-weight: 500 !important;
  font-family: var(--ae-font-body) !important;
  padding-inline: var(--ae-btn-px) !important;
  min-height: var(--ae-btn-h) !important;
}
/* A full-width button keeps its width; only the shape and weight change.
   .ghost-button joined this list when the hero card's «أوجه عطاء أخرى» stopped
   being a bare text button and became the same outline component as
   «استكشف البرامج» above it — the modifier is generic, and a component that
   cannot be full-width is a component with a hole in it. */
.primary-button.full-width,
.ghost-button.full-width,
.text-button.full-width { width: 100%; }

/* Navigation — font-bold with the bottom-border indicator, per
   src/blocks/header/header.css. */
.site-header .site-menu a,
.site-menu > a,
.nav-v2 a[data-nav-top] {
  font-weight: 700 !important;
  font-family: var(--ae-font-body) !important;
}

/* Body text — Noto Kufi Arabic, which is what the DLS specifies for RTL. The
   footer is excluded by the rule at the end of this file. */
main :is(p, li, span, small, label, td, th, dd, dt, figcaption),
.mbn__lead {
  font-family: var(--ae-font-body);
}

/* ============================================================================
   SNAPPING THE TYPE TO THE SCALE.
   ==========================================================================

   The DLS scale is 12 / 14 / 16 / 18 / 20 px — xs, sm, base, lg, xl in
   src/base/root.css. What the homepage actually rendered, measured across its
   44 paragraphs:

     12.48px  .eyebrow
     13.76px  .project-type
     14.40px  card descriptions (no class)
     14.72px  a section lede (no class)
     16.00px  .mbn__more
     16.64px  .hero-copy
     16.80px  .lede
     18.84px  .mbn__lead

   Eight sizes, seven of them fractional, none on a scale. They come from
   stacked em multiplications — 0.78em inside 1.04em inside a 16px root — which
   is how a site ends up with 14.4px body text that nobody chose. A design
   system is a scale before it is a palette, so these are snapped to the
   nearest DLS step.

   14.4px was the one worth changing on its own account: it is the description
   text inside every card on the page, and Arabic at 14.4px with a 1.4 line
   height is small enough to be a readability problem, not just an
   inconsistency. It goes to the DLS base of 16px.

   No size is snapped DOWN across a step boundary, so nothing shrinks and no
   layout is squeezed by this block.
   ========================================================================== */

/* xs — 12px. Eyebrows and the smallest labels. */
main .eyebrow,
main .aegov-xs {
  font-size: var(--ae-text-xs) !important;
  line-height: var(--ae-text-xs-lh);
  letter-spacing: .04em;
}

/* sm — 14px. Tags, meta and category labels. */
main .project-type,
main .mbn-card__meta,
main .aegov-card__meta,
main .aegov-small {
  font-size: var(--ae-text-sm) !important;
  line-height: var(--ae-text-sm-lh);
}

/* base — 16px. Body copy, including the unclassed card descriptions that were
   rendering at 14.4px. */
main p:not([class]),
main li:not([class]),
main .aegov-body {
  font-size: var(--ae-text-base) !important;
  line-height: 1.85;
  /* No colour, for the same reason as the block above. */
}

/* lg — 18px. A lead paragraph: the sentence under a heading. */
main .hero-copy,
main .lede,
main .lead,
.mbn__lead {
  font-size: var(--ae-text-lg) !important;
  line-height: 1.8;
}

/* The four h3 headings still asking for a synthesised 800. The earlier block
   set their family and not their weight, and the contrast between a real 700
   and a smeared 800 sitting next to each other on the same page is exactly
   the inconsistency this file exists to remove. */
main :is(h3, h4, h5, h6),
.section-block :is(h3, h4, h5, h6),
.v9-section :is(h3, h4, h5, h6) { font-weight: 700 !important; }

/* ============================================================================
   THE OFF-SCALE SIZES, BY THE RULE THAT DECLARES THEM.
   ==========================================================================

   The page used 26 distinct type sizes. Each off-scale one was traced to the
   rule that declares it — none is an accident of inheritance, they are all
   written down somewhere as a rem value that is not on any scale:

     0.72rem  .mbn-card__tag              11.52px  ->  0.75rem   (xs, 12)
     0.78rem  .quick-result span          12.48px  ->  0.75rem   (xs, 12)
     var()    .v9-eyebrow                 12.48px  ->  0.75rem   (xs, 12)
     0.84rem  .mbn-card__cta              13.44px  ->  0.875rem  (sm, 14)
     0.86rem  .eyebrow/.section-kicker    13.76px  ->  0.875rem  (sm, 14)
     0.86rem  .accordion button span      13.76px  ->  0.875rem  (sm, 14)
     0.86rem  .hero-quickbar span         13.76px  ->  0.875rem  (sm, 14)
     0.88rem  .values-orbit > span        14.08px  ->  0.875rem  (sm, 14)
     0.90rem  .mbn-chip                   14.40px  ->  0.875rem  (sm, 14)
     0.94rem  .iec-desc                   15.04px  ->  1rem      (base, 16)
     1.06rem  .mbn-card__name             16.96px  ->  1.125rem  (lg, 18)
     1.06rem  .iec-title                  16.96px  ->  1.125rem  (lg, 18)
     1.15rem  .mbn-card__cost                      ->  1.125rem  (lg, 18)

   0.86, 0.88, 0.90 and 0.94rem are four sizes within half a pixel of each
   other, which no reader can perceive as a distinction and no designer chose
   as one. That is what a scale prevents.
   ========================================================================== */

main .mbn-card__tag,
main .quick-result span,
main .command-result span,
main .v9-eyebrow {
  font-size: var(--ae-text-xs) !important;
  line-height: var(--ae-text-xs-lh);
}

main .mbn-card__cta,
main .mbn-chip,
main .section-kicker,
main .values-orbit > span,
main .accordion button span,
main .hero-quickbar span,
main .accordion summary span {
  font-size: var(--ae-text-sm) !important;
  line-height: var(--ae-text-sm-lh);
}

main .impact-effect-card .iec-desc {
  font-size: var(--ae-text-base) !important;
  line-height: 1.7;
}

/* A card's title is the DLS's text-h5 role: the heaviest thing inside the
   card, in the heading family. 1.06rem was smaller than the body text beside
   it in some cards, which inverted the hierarchy. */
main .mbn-card__name,
main .impact-effect-card .iec-title {
  font-size: var(--ae-text-lg) !important;
  line-height: 1.45;
  font-family: var(--ae-font-heading);
  font-weight: 700;
}
main .mbn-card__cost {
  font-size: var(--ae-text-lg) !important;
  font-variant-numeric: tabular-nums;
}

/* h3 was fluid — clamp() with a vw term — so it landed on 17.6, 19.52 and
   21.6px depending on the viewport, none of them a scale step. The DLS moves
   type in steps at breakpoints instead, so h3 does too: 20px, then 26, then
   32. Same approach for h2 and h1, which had the same problem. */
main h1, .mbn__h1, .hero-content h1, .page-hero h1, #hero-title {
  font-size: 2rem !important;      /* 32 */
}
main h2, .mbn__h2 { font-size: 1.625rem !important; }   /* 26 */
main h3 { font-size: 1.25rem !important; }              /* 20 */
main h4 { font-size: 1.125rem !important; }             /* 18 */
main h5 { font-size: var(--ae-text-base) !important; }  /* 16 */
main h6 { font-size: var(--ae-text-sm) !important; }    /* 14 */

@media (min-width: 768px) {
  main h1, .mbn__h1, .hero-content h1, .page-hero h1, #hero-title { font-size: 2.5rem !important; }  /* 40 */
  main h2, .mbn__h2 { font-size: 2rem !important; }     /* 32 */
  main h3 { font-size: 1.625rem !important; }           /* 26 */
  main h4 { font-size: 1.25rem !important; }            /* 20 */
  main h5 { font-size: 1.125rem !important; }           /* 18 */
}
@media (min-width: 1280px) {
  /* The DLS h1 is 3.875rem (62px). Reached only at desktop, where it is the
     size the system intends. */
  main h1, .mbn__h1, .hero-content h1, .page-hero h1, #hero-title { font-size: 3.875rem !important; }
  main h2, .mbn__h2 { font-size: var(--ae-text-h2) !important; }   /* 48 -> DLS 3rem */
  main h3 { font-size: 2rem !important; }               /* 32 */
  main h4 { font-size: 1.625rem !important; }           /* 26 */
}

/* ============================================================================
   THE GOLD RULE, ENFORCED.
   ==========================================================================

   A contrast sweep that composites translucent layers AND skips elements
   sitting on gradients — the two flaws that produced false results earlier —
   found twelve real failures. Most of them are one mistake made repeatedly:

     white text ON the association's gold #C9A227          2.42:1  (needs 4.5)
       «تبنَّ حالة» · «ادعم أسرة» · «ساهم في السقيا»
     the gold #C9A227 used AS text on white                2.42:1
       «حملات حالية»
     #8a6516 on a pale gold ground                         1.95:1
       «قيد الاعتماد»

   Three of those are donation call-to-action buttons, which is the worst place
   on the site for unreadable text.

   The token table at the top of this file already states the rule: gold at or
   below 400 is a FILL and never text, and 600 upward is text-safe. White is
   not a text colour for #C9A227 either — navy on gold measures 11.3:1 and is
   what the hero's own primary button already uses correctly. So these are
   brought into line with the button that was right.
   ========================================================================== */

/* Gold fill, dark text. 11.3:1. */
main [style*="C9A227"],
main [style*="c9a227"],
main .tcase-cta,
main .case-cta,
main a[href*="donate?effect"][style*="background"] {
  color: var(--ae-brand-navy) !important;
}

/* Gold as text: the readable step. #7c5e24 is aegold-700 at 6.03:1. */
:where(body:not(.dls-dark)) main .eyebrow,
:where(body:not(.dls-dark)) main .section-kicker,
:where(body:not(.dls-dark)) main .v9-eyebrow {
  color: var(--ae-gold-700) !important;
}

/* «قيد الاعتماد» — AND A FIX OF MINE THAT MADE IT WORSE.
   I assumed a pale gold pill and set aegold-800 (#6c4527), taking it from
   1.95:1 to 1.24:1. Then I measured the ground instead of assuming it: the
   badge sits on rgb(20, 73, 47), a DARK GREEN pill inside .credential-card.
   Dark brown on dark green is the worst of both. On that ground the text has
   to be LIGHT — aegold-50 keeps a gold cast and measures about 9:1.
   The original #8a6516 was wrong too; it was wrong before I touched it, and I
   made it wronger by guessing twice about a colour I had never looked at. */
main .credential-card [style*="8a6516"],
main .credential-card [style*="9C7B1B"],
main .status-pill,
main .pending-note { color: var(--ae-gold-50) !important; }

/* The cart badge: white on rgba(255,255,255,.7), which is white on near-white
   at 1.60:1 — the count is invisible. Navy on that ground is above 12:1. */
.bag-count { color: var(--ae-brand-navy) !important; font-weight: 700; }

/* The floating WhatsApp button is .whatsapp-floating, not .whatsapp-cta — my
   earlier selector matched nothing. White on #25D366 is 1.98:1; navy on the
   same green is about 8:1 and keeps WhatsApp's own colour, which changing the
   green would not. */
.whatsapp-floating,
.whatsapp-floating .lbl { color: var(--ae-brand-navy) !important; }
.whatsapp-floating svg { fill: var(--ae-brand-navy) !important; }

/* The language toggle. My first selector here was .lang-toggle / .lang-switch
   and matched nothing; the real class is .language-switch, found by reading
   the element instead of guessing its name — the second guess I paid for in
   this file.
   ORIGINAL paint chain, read off the live element when this was written:
   .site-header was an opaque rgb(18, 82, 92) (the green bar, since replaced),
   .language-switch laid rgba(255,255,255,.08) over it giving about
   rgb(50,116,81), and the label was rgba(255,255,255,.7) on that — 3.65:1 at
   12.48px, a real failure. Full white on that dark ground was about 5.5:1,
   hence the !important white forced here.
   10 Sep 2026: the bar itself is white now (header-v2.css redesign). Forced
   white text on a white/near-white pill is a 1:1 failure of the exact shape
   the note below this one already describes for a different button — this
   rule would have caused a second instance of it. Fixed navy, NOT
   header-v2.css's --nav-ink-muted: that token flips to white under
   @media(max-width:1280px) because .site-menu moves to a dark overlay panel
   there, but .language-switch never leaves the (always-light) tools area —
   inheriting the flipped token would have swapped this bug in at <=1280px
   instead of fixing it outright. */
.language-switch button,
.language-switch a {
  color: rgba(10, 42, 61, 0.65) !important;
  font-size: var(--ae-text-xs) !important;   /* was 12.48px, off-scale */
  font-weight: 700;
}
/* AND THE FAILURE THAT FIX CAUSED, ONE ITERATION LATER.
   The switch holds two buttons and only the inactive one sits on the green.
   The active one carries .active with background #ffffff, so forcing white on
   every button made «عربي» white-on-white at 1.00:1 — I replaced a 3.65:1
   with a 1.00:1 and the sweep caught it on the next pass. The state is marked
   by a class, not by aria-pressed, which is worth knowing on its own. */
.language-switch button.active,
.language-switch a.active {
  color: var(--ae-brand-navy) !important;    /* 14.9:1 on the white pill */
}

/* The WhatsApp button: white on #12525C is 1.98:1. Navy on that green is
   6.6:1 and keeps the brand green, which a darker green would not. */
.whatsapp-cta { color: var(--ae-brand-navy) !important; }
.whatsapp-cta svg { fill: var(--ae-brand-navy) !important; }

/* ============================================================================
   «طرق التبرع» — the ways-to-give grid.
   Built on the DLS card: rounded-lg -> md:xl -> xl:2xl, p-6, space-y-6, a
   hairline border. Al Ihsan's homepage devotes a section to this and ours had
   a single strip with one button; eight real channels deserve eight cards.
   ========================================================================== */
.ways-block { background: var(--ae-slate-50); padding-block: clamp(48px, 6vw, 80px); }
.ways-block .section-inner { max-width: 1180px; margin-inline: auto; padding-inline: clamp(20px, 5vw, 56px); }
.ways-block .section-heading { max-width: 62ch; margin-block-end: clamp(28px, 4vw, 44px); }

.ways-grid {
  display: grid;
  gap: var(--ae-space-6);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 268px), 1fr));
}
.ways-card {
  justify-content: space-between;
  gap: 1rem;
  transition: border-color .25s, box-shadow .25s, transform .25s;
}
.ways-card:hover {
  border-color: var(--ae-brand-teal);
  transform: translateY(-2px);
  box-shadow: 0 1px 2px rgba(10, 42, 61, .05), 0 16px 36px -22px rgba(10, 42, 61, .22);
}
/* A gold rule on the top edge, the association's accent used as a FILL and
   never as text — the distinction this file keeps returning to. */
.ways-card { position: relative; overflow: hidden; }
.ways-card::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 3px;
  background: linear-gradient(90deg, var(--ae-gold-400), var(--ae-brand-teal));
}
.ways-card h3 {
  font-size: var(--ae-text-lg) !important;
  font-family: var(--ae-font-heading);
  font-weight: 700;
  color: var(--ae-brand-navy);
  margin: 0 0 .5rem;
}
.ways-card p {
  font-size: var(--ae-text-base) !important;
  line-height: 1.75;
  color: var(--ae-black-700);
  margin: 0;
}
.ways-card__cta {
  align-self: flex-start;
  font-family: var(--ae-font-body);
  font-weight: 700;
  font-size: var(--ae-text-sm);
  color: var(--ae-brand-teal);         /* 8.80:1 on white */
  text-decoration: none;
  border-block-end: 2px solid transparent;
  padding-block-end: 2px;
  transition: border-color .2s, color .2s;
}
.ways-card__cta:hover {
  color: var(--ae-brand-navy);
  border-block-end-color: var(--ae-gold-400);
}

/* «المركز الإعلامي» — one lead story beside three routes to published
   material. A 2:1 split rather than the four equal columns Al Ihsan uses,
   because there is one real story to lead with and inventing three more is
   not on the table. */
.media-block { padding-block: clamp(48px, 6vw, 80px); background: #ffffff; }
.media-block .section-inner { max-width: 1180px; margin-inline: auto; padding-inline: clamp(20px, 5vw, 56px); }
.media-block .section-heading { max-width: 62ch; margin-block-end: clamp(28px, 4vw, 44px); }
.media-grid { display: grid; gap: var(--ae-space-6); grid-template-columns: 1fr; }
@media (min-width: 900px) { .media-grid { grid-template-columns: 1.4fr 1fr; align-items: start; } }
.media-side { display: grid; gap: var(--ae-space-6); }
.media-lead { justify-content: space-between; }
.media-lead h3 {
  font-size: clamp(1.25rem, 2.2vw, var(--ae-text-h4)) !important;
  font-family: var(--ae-font-heading);
  font-weight: 700;
  color: var(--ae-brand-navy);
  line-height: 1.35;
  margin: .5rem 0 .75rem;
}
.media-tag {
  font-size: var(--ae-text-xs) !important;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--ae-gold-700);      /* 6.03:1 — gold as text, the readable step */
  margin: 0;
}
.media-side .aegov-card h3 {
  font-size: var(--ae-text-lg) !important;
  font-family: var(--ae-font-heading);
  font-weight: 700;
  color: var(--ae-brand-navy);
  margin: 0 0 .4rem;
}
.media-block .aegov-card p { font-size: var(--ae-text-base) !important; line-height: 1.75; color: var(--ae-black-700); margin: 0; }
.media-block .aegov-card { transition: border-color .25s, box-shadow .25s, transform .25s; }
.media-block .aegov-card:hover {
  border-color: var(--ae-brand-teal);
  transform: translateY(-2px);
  box-shadow: 0 1px 2px rgba(10,42,61,.05), 0 16px 36px -22px rgba(10,42,61,.22);
}

/* ============================================================================
   THE HERO, IN TWO COLUMNS.
   ==========================================================================

   Everything used to stack in one column — logo, eyebrow, title, copy,
   buttons, a pull-quote and the quick-donation card — 1339px of it. The card
   that takes the money was therefore below the fold on a laptop and about two
   screens down on a phone.

   Now: intro right, donation card left. Source order does it, because in RTL
   the FIRST grid column paints on the RIGHT. No `order`, no `direction`
   override — those are how RTL layouts end up mirrored and looking correct
   only in a flipped preview.

   Mobile first, per the rule: one column below 900px with the card FIRST, so
   a phone shows the donation panel without a scroll, then the intro. The
   two-column arrangement starts where there is width for it.
   ========================================================================== */
.hero-split {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(28px, 4vw, 56px);
  align-items: center;
  max-width: 1180px;
  margin-inline: auto;
  width: 100%;
}
@media (min-width: 900px) {
  .hero-split {
    /* 1.05fr / 0.95fr, not 1fr / 1fr: the intro carries a 3-line paragraph and
       the card is a fixed-width control panel, so an even split leaves the
       text cramped and the card stretched. */
    grid-template-columns: 1.05fr 0.95fr;
    align-items: center;
  }
}

.hero-col--intro { display: flex; flex-direction: column; align-items: flex-start; text-align: start; }
.hero-col--intro .hero-copy { max-width: 46ch; margin-block: 0 1.75rem; }
.hero-col--intro .eyebrow { margin-block-end: .5rem; }
.hero-col--intro h1 { margin-block: 0 1rem; }
.hero-col--intro .mbn-logo { margin-block-end: 1.25rem; }
.hero-actions { display: flex; flex-wrap: wrap; gap: .75rem; }

/* On a phone the card comes first: it is the thing a donor came to use, and
   burying it under a logo, a title and a paragraph is a decision nobody would
   make deliberately. */
.hero-col--action { order: -1; }
@media (min-width: 900px) { .hero-col--action { order: 0; } }
.hero-col--action .hero-donation-card { width: 100%; max-width: 30rem; margin-inline: auto; }

/* The card's own components, spaced on the DLS scale instead of by accident. */
.hero-donation-card { display: flex; flex-direction: column; gap: 1rem; padding: clamp(18px, 2.5vw, 24px); }
.hero-donation-card .quick-donation-head {
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  padding: .75rem 1rem; border-radius: var(--ae-radius); border: 1px solid rgba(10,42,61,.10);
}
.hero-chips, .hero-amounts { display: flex; flex-wrap: wrap; gap: .5rem; }
/* Four amounts in one even row: they are a comparison, and an uneven wrap
   makes 500 look like a different kind of thing from 50. */
.hero-amounts { display: grid; grid-template-columns: repeat(4, 1fr); gap: .5rem; }
.hero-amounts button {
  min-height: 44px;          /* the 44x44 touch minimum */
  border-radius: var(--ae-radius);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}
.hero-chips button,
.hero-chips a {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  border-radius: var(--ae-radius);
  padding-inline: .875rem;
}

/* ============================================================================
   «استكشف البرامج» — the ghost button, and its states.
   ==========================================================================

   It had one state. No hover that reads as a press, no pressed state at all,
   and a focus ring inherited from whatever matched last. Three rules from the
   UX set apply: a visible focus ring (High), a pressed/active visual change
   (Medium), and do not rely on hover alone for an important action (High) —
   which on a touch screen has no hover at all.

   Colour: teal #12525C on white is 8.80:1. The border is the same teal at
   full strength rather than a 35% tint, so the button has an edge a
   low-vision reader can find — 3:1 against white is the 1.4.11 minimum for a
   UI boundary and a tinted border was under it.
   ========================================================================== */
.hero-actions .ghost-button,
#home .ghost-button {
  background: #ffffff;
  color: var(--ae-brand-teal) !important;
  border: 1.5px solid var(--ae-brand-teal);
  font-weight: 600;
  /* Only the properties that do not trigger layout, so the transition cannot
     cost a frame. */
  transition: background-color .2s ease, color .2s ease, border-color .2s ease,
              transform .12s ease, box-shadow .2s ease;
}
#home .ghost-button:hover {
  background: var(--ae-brand-teal);
  color: #ffffff !important;      /* 8.80:1 the other way round */
  border-color: var(--ae-brand-teal);
  box-shadow: 0 6px 18px -10px rgba(18, 82, 92, .55);
}
/* The pressed state, which is the one a touch user actually gets. */
#home .ghost-button:active {
  background: var(--ae-brand-navy);
  color: #ffffff !important;
  border-color: var(--ae-brand-navy);
  transform: translateY(1px);
  box-shadow: none;
}
#home .ghost-button:focus-visible {
  outline: 2px solid var(--ae-gold-400);
  outline-offset: 3px;
  background: var(--ae-brand-teal-050);
}
@media (prefers-reduced-motion: reduce) {
  #home .ghost-button { transition: background-color .2s ease, color .2s ease; }
  #home .ghost-button:active { transform: none; }
}

/* At 320px the four amount buttons measured 43.6px wide — 0.4px under the
   44x44 touch minimum, found by measuring at every breakpoint the UX rule
   names rather than at the one the pane happened to be. Two per row below
   360px gives about 140px each. The four-across comparison is worth keeping
   wherever it fits and is not worth an under-size tap target. */
@media (max-width: 359px) {
  .hero-amounts { grid-template-columns: repeat(2, 1fr); }
}

/* The ghost button, asserted — the fourth time in this file that a declaration
   lost to an !important I had not looked for.
   Measured on the live element: background computed to rgba(0,0,0,0) and the
   border to 0.8px rgba(255,255,255,0.32), which on the LIGHT hero measures
   1.00:1 against white — an invisible border. The winner is
   `.ghost-button, .btn-secondary, .btn-ghost` earlier in
   v9-design-system.css, with `background: transparent !important` and
   `border: 1px solid rgba(255,255,255,.32) !important`: white at 32%, correct
   for the dark hero this button used to sit on and meaningless now.
   1.4.11 asks 3:1 for a UI boundary; teal on white is 8.80:1. */
#home .ghost-button,
.hero-actions .ghost-button {
  background-color: #ffffff !important;
  border: 1.5px solid var(--ae-brand-teal) !important;
}
#home .ghost-button:hover {
  background-color: var(--ae-brand-teal) !important;
  border-color: var(--ae-brand-teal) !important;
}
#home .ghost-button:active {
  background-color: var(--ae-brand-navy) !important;
  border-color: var(--ae-brand-navy) !important;
}
#home .ghost-button:focus-visible {
  background-color: var(--ae-brand-teal-050) !important;
  border-color: var(--ae-brand-teal) !important;
}

/* The focus ring, corrected. --ae-gold-400 #C9A227 against the #eef3f6 focus
   background measured 2.16:1, and 1.4.11 asks 3:1 of a focus indicator — so
   the one state a keyboard user depends on was the one state that failed.
   --ae-gold-700 #7c5e24 is about 5.5:1 on that ground and still reads as
   gold, which is the point of using the brand colour for focus at all.
   Same trap as everywhere else in this file: gold at 400 is a fill, and only
   600 and up carry meaning against a light surface. */
#home .ghost-button:focus-visible,
#home .primary-button:focus-visible {
  outline: 3px solid var(--ae-gold-700) !important;
  outline-offset: 3px;
}

/* ============================================================================
   THE QUICK-DONATION CARD — selection, weight, order.
   ==========================================================================

   THE SELECTION BUG, WHICH WAS A REAL ONE

   styles.css had, for both groups:

     .hero-amounts button.active,
     .hero-amounts button:hover,
     .hero-amounts button:focus-visible { background: cream; color: teal }

     .hero-chips button:hover,
     .hero-chips button:focus-visible,
     .hero-chips button.active { background: gold; color: ink }

   Selected, hovered and focused were given IDENTICAL styling. So while the
   pointer sat on 100, the 100 looked exactly as chosen as the 50 that
   actually was — and moving the pointer between two amounts made the
   selection appear to follow it. There was no way to read the current choice
   without moving the mouse away. Three different meanings sharing one
   appearance is not a styling preference; it is the control failing to report
   its own state.

   Now three distinct states, and the selected one is the strongest because it
   is the only one that persists:

     selected   solid teal fill, white text, ring    keyed off aria-pressed
     hover      pale teal tint, teal border          clearly weaker
     focus      gold ring, 3px offset                separate from both

   Keyed off [aria-pressed="true"] rather than .active, so the accessible
   state and the visible state cannot disagree — a class tells a screen reader
   nothing.

   THE FONT WEIGHTS

   The card asked for 800 on the cause chips and 900 on the amounts and the
   quick-donation label. Alexandria is self-hosted at 400/500/600/700 and Noto
   Kufi at 400/500/600/700/800 — so every 900 here was SYNTHESISED, the
   browser smearing the 700 outlines, on the smallest text in the card. And
   800/900 on a four-character number is heavier than the h1 above it, which
   inverts the hierarchy.

   Capped at 700, which is real in both families, and the DLS puts buttons at
   500 anyway. The numbers keep tabular figures so 10 and 500 occupy the same
   width and the row reads as a comparison.

   THE ORDER

   Removing the zakat link from the cause row leaves two clean groups, each
   with a visible label: pick the cause, pick the amount, add to the basket,
   or go elsewhere. The two actions at the bottom are ordered primary then
   secondary, and the secondary is a text button so it cannot compete.
   ========================================================================== */

/* ---- the group labels ------------------------------------------------- */
.hero-field-label {
  margin: .25rem 0 0;
  font-family: var(--ae-font-body);
  font-size: var(--ae-text-sm) !important;
  font-weight: 700;
  color: var(--ae-black-700);
  display: flex;
  align-items: baseline;
  gap: .4rem;
}
.hero-field-label__unit {
  font-weight: 500;
  font-size: var(--ae-text-xs);
  color: var(--ae-black-500);
}

/* ---- shared: the resting state of every toggle in the card ----------- */
#home .hero-chips button,
#home .hero-amounts button {
  background: #ffffff !important;
  color: var(--ae-black-700) !important;
  border: 1px solid rgba(10, 42, 61, .18) !important;
  border-radius: var(--ae-radius) !important;
  font-family: var(--ae-font-body) !important;
  font-weight: 600 !important;          /* was 800 and 900 */
  transform: none !important;           /* the old rules nudged on hover */
  transition: background-color .18s ease, color .18s ease,
              border-color .18s ease, box-shadow .18s ease;
}
#home .hero-amounts button {
  font-weight: 700 !important;
  font-variant-numeric: tabular-nums;
  font-size: var(--ae-text-base) !important;
}

/* ---- hover: present, and deliberately weaker than selected ---------- */
#home .hero-chips button:hover:not([aria-pressed="true"]),
#home .hero-amounts button:hover:not([aria-pressed="true"]) {
  background: var(--ae-brand-teal-050) !important;
  border-color: var(--ae-brand-teal) !important;
  color: var(--ae-brand-navy) !important;
}

/* ---- selected: the only persistent state, so the strongest ---------- */
#home .hero-chips button[aria-pressed="true"],
#home .hero-amounts button[aria-pressed="true"],
#home .hero-chips button.active,
#home .hero-amounts button.active {
  background: var(--ae-brand-teal) !important;   /* white on teal, 8.80:1 */
  color: #ffffff !important;
  border-color: var(--ae-brand-teal) !important;
  /* A ring rather than a shadow: it survives a high-contrast mode, which a
     box-shadow does not, and it is what makes the choice readable at a glance
     across a row. */
  box-shadow: 0 0 0 3px rgba(18, 82, 92, .18) !important;
}
#home .hero-chips button[aria-pressed="true"]:hover,
#home .hero-amounts button[aria-pressed="true"]:hover {
  background: var(--ae-brand-navy) !important;   /* white on navy, 14.88:1 */
  border-color: var(--ae-brand-navy) !important;
}

/* ---- focus: distinct from both of the above ------------------------- */
#home .hero-chips button:focus-visible,
#home .hero-amounts button:focus-visible {
  outline: 3px solid var(--ae-gold-700) !important;   /* 5.39:1 */
  outline-offset: 3px;
}

/* ---- the head and the two actions ----------------------------------- */
#home .quick-donation-head span {
  font-weight: 600 !important;      /* was 900 — no such face is loaded */
  font-size: var(--ae-text-sm) !important;
  color: var(--ae-black-500) !important;
}
#home .quick-donation-head strong {
  font-weight: 700 !important;
  font-size: var(--ae-text-lg) !important;
  font-variant-numeric: tabular-nums;
}
#home .hero-donation-card .primary-button { font-weight: 600 !important; }
#home .hero-donation-card .text-button {
  font-weight: 600 !important;
  background: transparent !important;
  color: var(--ae-brand-teal) !important;
  border: 1px solid transparent !important;
}
#home .hero-donation-card .text-button:hover {
  background: var(--ae-brand-teal-050) !important;
  border-color: rgba(18, 82, 92, .28) !important;
}

/* ============================================================================
   MOBILE ORDER — corrected.
   ==========================================================================

   I had set .hero-col--action to order:-1, so on a phone the donation card
   came before the column carrying the logo and the title. The reasoning was
   that a donor arrives to donate and should not have to scroll past a logo.

   Mohamed Fahim tested it on a phone and wants the logo column first. That is
   his call and it is the right one for a licensed charity: the first thing on
   the screen should identify who is asking for the money. A donation panel
   above an unidentified logo is a payment form from nobody.

   The override is removed rather than set to a different order value, so the
   columns follow source order at every width — which is also what makes the
   RTL two-column arrangement above work with no order property at all.
   ========================================================================== */
.hero-col--action { order: 0 !important; }

/* ============================================================================
   THE HERO TITLE, ON ONE LINE.
   ==========================================================================

   Measured at 1280 before this: the title needed 644px to sit on one line and
   the column offers 593, so it wrapped. The largest size that fits is 57px,
   against the 62px the DLS h1 specifies at that width.

   So the size is tied to the viewport rather than fixed, and nowrap is set —
   that combination is what keeps it on one line without ever overflowing.
   Chosen from the measurement, not by eye: the required width scales with the
   font size, so px_needed = 62 x (col / 644), and the column is about 0.46 of
   the viewport at the two-column breakpoint.

   clamp(1.75rem, 4.2vw, 3.4rem)
     375px   28.0px   column ~291, needs <= 28.0   fits
     768px   32.3px   column ~690, needs <= 66     fits easily
     1280px  53.8px   column ~593, needs <= 57     fits
     1440px  54.4px (capped)                       fits

   28px on a phone is smaller than the 32px the DLS would give an h1 there.
   That is the cost of one line and it is a deliberate trade, said out loud
   rather than hidden: a title that wraps mid-phrase reads worse than one that
   is four pixels smaller.
   ========================================================================== */
#home #hero-title,
#home h1 {
  font-size: clamp(1.75rem, 4.2vw, 3.4rem) !important;
  white-space: nowrap;
  line-height: 1.25 !important;
  /* If a future edit lengthens the title past what nowrap can hold, this
     keeps it inside the column instead of pushing the layout sideways. */
  max-width: 100%;
  overflow-wrap: normal;
}

/* ============================================================================
   ONE SET OF BUTTON EFFECTS FOR THE WHOLE HERO.
   ==========================================================================

   Six kinds of button sit in the hero and each behaved differently:

     تبرع الآن            gold fill, no press state, no ring of its own
     استكشف البرامج       outline, hover invert, press, gold ring
     the cause chips      toggle, hover == selected until this session
     the amount chips     toggle, 900 weight, hover == selected
     أضف إلى سلة الخير    gold fill, no press, no ring
     أوجه خير أخرى        text, no press, no ring

   Different durations, different easings, some with a 1px lift and some
   without, and three different focus treatments. A visitor learns an
   interface by its consistency, and six behaviours in one panel is six things
   to learn.

   Unified below, as one contract every hero button obeys:

     transition   .18s ease on colour, .12s on the press — colour and shadow
                  only, never a layout property, so it cannot cost a frame
     hover        a colour shift, always weaker than the selected state
     active       translateY(1px) and the shadow removed — the same press
                  everywhere, and the one state a touch user actually gets
     focus        3px gold-700 ring at 3px offset — 5.39:1, identical on all
     motion       every transform dropped under prefers-reduced-motion

   The colours stay per-role: gold fill for the primary action, teal outline
   for the secondary, teal fill for a selected toggle. Unifying behaviour is
   not flattening hierarchy — the primary action must still look primary.
   ========================================================================== */

#home :is(.primary-button, .ghost-button, .text-button,
          .hero-chips button, .hero-amounts button) {
  border-radius: var(--ae-radius) !important;
  font-family: var(--ae-font-body) !important;
  cursor: pointer;
  transition: background-color .18s ease, color .18s ease, border-color .18s ease,
              box-shadow .18s ease, transform .12s ease !important;
}

/* The press, identical everywhere. */
#home :is(.primary-button, .ghost-button, .text-button,
          .hero-chips button, .hero-amounts button):active {
  transform: translateY(1px) !important;
  box-shadow: none !important;
}

/* The focus ring, identical everywhere. */
#home :is(.primary-button, .ghost-button, .text-button,
          .hero-chips button, .hero-amounts button):focus-visible {
  outline: 3px solid var(--ae-gold-700) !important;
  outline-offset: 3px !important;
}

/* The primary action gained a hover and a press it did not have. Gold-500 is
   the next step down the same ramp, so the change reads as the same colour
   pressed rather than as a different colour. Navy text throughout: 11.3:1 on
   gold-400 and 9.6:1 on gold-500. */
#home .primary-button:hover {
  background-color: var(--ae-gold-500) !important;
  color: var(--ae-brand-navy) !important;
  box-shadow: 0 6px 18px -10px rgba(146, 114, 43, .55) !important;
}
#home .primary-button:active {
  background-color: var(--ae-gold-600) !important;   /* 4.5:1 with white, 5.6:1 with navy */
  color: var(--ae-brand-navy) !important;
}

/* The text button: the weakest of the three actions, and it should stay that
   way — a tint on hover, no fill. */
#home .text-button:hover {
  background-color: var(--ae-brand-teal-050) !important;
  color: var(--ae-brand-navy) !important;
}

@media (prefers-reduced-motion: reduce) {
  #home :is(.primary-button, .ghost-button, .text-button,
            .hero-chips button, .hero-amounts button) {
    transition: background-color .18s ease, color .18s ease, border-color .18s ease !important;
  }
  #home :is(.primary-button, .ghost-button, .text-button,
            .hero-chips button, .hero-amounts button):active {
    transform: none !important;
  }
}

/* The title's size, split at the layout breakpoint — because the width it has
   to fit into changes discontinuously there, and one clamp cannot serve both.
   Measured across every breakpoint the UX rule names, and both problems below
   were found that way rather than by looking at one screen:

     ONE clamp, 4.2vw          size    title   column   verdict
       1440                    54.4     565     590     fits
       1280                    53.8     558     593     fits
       1024                    43.0     447     483     fits
        768                    32.3     335     705     fits, but tiny — the
                                                        column is full width
                                                        here and the title
                                                        uses half of it
        414                    28.0     291     330     fits
        320                    28.0     291     291     ZERO margin

   320px was the real problem. 291 into 291 is not "fits", it is the exact
   limit: any letter-spacing change, a font that fails to load and falls back
   to a wider face, or a longer title in a future edit puts it over and the
   layout scrolls sideways. A measurement that lands exactly on the boundary
   is a warning, not a pass.

   768px was the opposite waste. Below 900px the hero is ONE column, so the
   available width jumps from about 0.46 of the viewport to nearly all of it —
   and a viewport-based clamp tuned for the two-column case leaves a tablet
   title at half the size it could be.

   So: two ranges, each tuned to the width its own layout actually offers. */

/* Two columns: the column is roughly 0.46 of the viewport. */
@media (min-width: 900px) {
  #home #hero-title,
  #home h1 { font-size: clamp(2rem, 4.2vw, 3.4rem) !important; }
}

/* One column: nearly the whole viewport is available, so the title can be
   larger on a tablet and needs real headroom on the narrowest phone.
     320 -> 23.0px, title ~239 in 291   headroom restored
     375 -> 27.0px, title ~280 in 343
     414 -> 29.8px, title ~310 in 330
     768 -> 55.3px, title ~574 in 705   no longer half-size on a tablet */
@media (max-width: 899px) {
  #home #hero-title,
  #home h1 { font-size: clamp(1.4rem, 7.2vw, 3.25rem) !important; }
}

/* ============================================================================
   الصفحات الداكنة: إخفاقات مقيسة في ثيمها الخاص

   هذه ليست من طبقة الهوية — قِيست وطبقة الهوية غير محمَّلة إطلاقاً، والقاعدة
   الفائزة في كل حالة من styles.css التي تضبط ألوان حبر صُمِّمت للثيم الفاتح:

     styles.css  .section-heading h2 … { color: var(--ink-900) }  #131316
                 على أرضية #051114  =  1.03:1   (تحتاج 3 لنصّ 32px)
     styles.css  .aid-panel label      { color: var(--ink-800) }  #1f1f23
                 على أرضية #071619  =  1.21:1   (تحتاج 4.5 لنصّ 16px)

   ولا تُفرَض قاعدة شاملة «نصّ فاتح على صفحة داكنة»: القياس أظهر لوحات فاتحة
   داخل هذه الأرضيات — #fffef9 في شاشة الرصد و#e8f4f8 في غرفة الإغاثة — وقاعدة
   شاملة كانت ستطفئ نصوصها. فتُصلَح العناصر المقيسة وحدها.

   القيم مقيسة على أفتح نقطة في تدرّج كل صفحة، وهي أسوأ حالة لنصّ فاتح:
     #ffffff على #081f23  =  17.2:1
     #e1e3e5 على #081f23  =  14.0:1
   ========================================================================== */
body.dls-dark :is(.section-heading, .donation-copy, .impact-copy, .gift-copy) h2 {
  color: #ffffff !important;
}
/* والفقرة المجاورة لذلك العنوان، وقد فاتتني في المرة الأولى: نفس المجموعة من
   المحدِّدات في styles.css تضبط لها var(--ink-600) = #2f2f33، وهو 1.44:1 على
   تدرّج هذه الصفحات. #e1e3e5 يعطي 14.34:1 على أفتح نقطة في التدرّج، ويبقى
   أهدأ من الأبيض الذي يحمله العنوان — فيُحفَظ التمييز بين العنوان ونصّه. */
body.dls-dark :is(.section-heading, .donation-copy, .impact-copy, .gift-copy) p {
  color: #e1e3e5 !important;
}
body.dls-dark .aid-panel label,
body.dls-dark .aid-panel legend {
  color: #e1e3e5 !important;
}
body.dls-dark main .eyebrow,
body.dls-dark main .section-kicker {
  color: var(--ae-gold-200) !important;
}
