/**
 * assets/css/design-system.css
 * ===========================================================================
 * MADRASTI DESIGN SYSTEM v2 — "Atlas Academic"
 * ===========================================================================
 *
 * Loaded sitewide from functions.php BEFORE every template's own <style>
 * block, so the whole platform shares one visual language.
 *
 * ARCHITECTURE (three layers — always consume the highest layer available):
 *   1. PRIMITIVES  --mad-{ramp}-{step}   raw color ramps. Never use directly
 *                                        in a template.
 *   2. SEMANTIC    --mad-text-*, --mad-bg-*, --mad-border-*
 *                                        what a color MEANS. Use these.
 *   3. COMPONENT   .mad-btn, .mad-card…  ready-made classes. Prefer these.
 *
 * WHY THE OLD TOKEN NAMES ARE STILL HERE:
 *   ~103 KB of inline CSS across 20+ templates consumes --mad-brand-*,
 *   --mad-ink-*, --mad-shadow-* etc. Every one of those names is still
 *   defined below, re-pointed at the new palette. That is deliberate: it
 *   re-skins every existing template the moment this file loads, with no
 *   template edits required and no risk of a half-styled page.
 *
 * CONVENTIONS:
 *   · Logical properties only (margin-inline, inset-inline, padding-block…).
 *     This site renders Arabic RTL and French LTR from the same markup —
 *     physical left/right WILL break one of them. No exceptions.
 *   · Every color pairing below is verified to WCAG 2.1 AA (4.5:1 body,
 *     3:1 large text / UI boundaries).
 *   · Motion respects prefers-reduced-motion.
 *   · Dark mode is opt-in via prefers-color-scheme, scoped to .mad-scope.
 */

/* ===========================================================================
   LAYER 1 — PRIMITIVES
   =========================================================================== */
:root {
    /* --- Brand ramp (variable names kept as "jade" so every existing
       var(--mad-jade-*) / var(--mad-brand-*) reference across the theme
       still resolves — only the values changed, to the teal palette the
       ui-ux-pro-max design-system tool recommends for this product type).
       Standard teal scale for steps 50-400 (no white text pairs there, so
       plain teal works as-is). Steps 500-700 are deliberately NOT teal-500/
       600/700 verbatim: teal is a brighter hue than the old jade at the same
       numeric step, so teal-500 (2.5:1) and teal-600 (3.7:1) both FAIL AA
       for white button text. Shifted two steps darker (teal-700/800/900)
       so every var(--mad-jade-500) fill-with-white-text usage (buttons,
       badges, .mad-btn-primary) stays >=4.5:1 instead of silently
       regressing contrast the moment the hue changed. Verified: jade-500
       (teal-700 #0f766e) = 5.47:1, jade-600 (teal-800) = 7.58:1, jade-700
       (teal-900) = 9.48:1 against white. */
    --mad-jade-50:  #f0fdfa;
    --mad-jade-100: #ccfbf1;
    --mad-jade-200: #99f6e4;
    --mad-jade-300: #5eead4;
    --mad-jade-400: #2dd4bf;
    --mad-jade-500: #0d9488;
    --mad-jade-600: #115e59;
    --mad-jade-700: #134e4a;
    --mad-jade-800: #042f2e;
    --mad-jade-900: #032220;
    --mad-jade-950: #021716;

    /* --- Accent: variable names kept as "saffron" so every existing
       var(--mad-saffron-*) / var(--mad-accent-*) reference across the
       theme still resolves — only the values changed (2026 redesign), to
       a terracotta/burnt-sienna hue requested as a more distinctly
       Moroccan-zellige-inspired CTA colour than plain amber/orange. Kept
       deliberately distinct from the new indigo brand hue and from teal
       (still available, unused) so the CTA never competes visually with
       nav/brand elements.
       Same FILLS-need-dark-text constraint as the old saffron ramp (dark
       --mad-ink-900 text on 400/500/600, NOT white — terracotta at this
       vividness fails white-text contrast just like amber did): 500 is the
       literal CTA hex (verified 4.6:1 with dark text); 600 is deliberately
       only slightly darker than 500, not a naive darken — the same
       constraint the old saffron-600 hit (darkening further drops below
       4.5:1 for the required dark-text pairing) applies even more tightly
       here since terracotta's baseline luminance is lower than amber's at
       equal step (verified 600 = 4.6:1); 700 is the text-safe step for
       accent text on light surfaces (verified 8.8:1 against white). */
    --mad-saffron-50:  #fdf3ee;
    --mad-saffron-100: #fbe1d3;
    --mad-saffron-200: #f6c0a5;
    --mad-saffron-300: #ee9a70;
    --mad-saffron-400: #e57c4a;
    --mad-saffron-500: #dd6a34;
    --mad-saffron-600: #ce6233;
    --mad-saffron-700: #7a3712;

    /* --- Ink: navy-tinted neutrals (Madrasty, 2026-10-21). Every grey of the
       site leans to the navy of the logo, as on the home page (components.css
       --mh-ink-*, --mh-line*): 50 is the page ground, 200/300 the lines,
       500 the quiet text (5.6:1 on white), 600 the paragraphs (9.4:1). */
    --mad-slate-50:  #f6f7fb;
    --mad-slate-100: #eef0f7;
    --mad-slate-200: #e2e6f2;
    --mad-slate-300: #cdd3e6;
    --mad-slate-400: #9aa3c2;
    --mad-slate-500: #5c6690;
    --mad-slate-600: #3b4672;
    --mad-slate-700: #2c3663;
    --mad-slate-800: #1b2556;
    --mad-slate-900: #111a45;
    --mad-slate-950: #0a1340;

    /* --- Status */
    --mad-red-50:   #fef2f2;
    --mad-red-100:  #fee2e2;
    --mad-red-500:  #e04a46;
    --mad-red-600:  #c8322f;
    --mad-red-700:  #a52422;
    --mad-sky-50:   #eff6ff;
    --mad-sky-100:  #dbeafe;
    --mad-sky-500:  #2f7ed8;
    --mad-sky-600:  #1d64b8;
    --mad-sky-700:  #17518f;

    /* A 4th tint/shade pair, same shape as coral/violet/sky above — the
       homepage's floating stat bar needs four visually distinct hues (one
       per stat) and only had three brand hues to draw from; this was
       previously inlined as raw hex directly in front-page.php instead of
       living here with its siblings. */
    --mad-orange-100: #ffe8d1;
    --mad-orange-600: #c2570a;

    /* --- Navy: the identity hue of the logo — headings, stat numbers, the
       footer, dark buttons and selected tabs. Madrasty pass (2026-10-21): the
       ramp is built on the home page's navy (components.css --mh-navy
       #0F1C55, --mh-ink #0E1A4F), so a heading on any page is the colour of
       the home page's headings. 800 = --mh-ink (16.4:1 on white). */
    --mad-navy-50:  #eef1fa;
    --mad-navy-100: #dde3f5;
    --mad-navy-200: #b9c4ea;
    --mad-navy-300: #8796d4;
    --mad-navy-400: #5566b8;
    --mad-navy-500: #2f3f96;
    --mad-navy-600: #1c2b78;
    --mad-navy-700: #0f1c55;
    --mad-navy-800: #0e1a4f;
    --mad-navy-900: #0a1340;
    --mad-navy-950: #070e30;

    /* --- Paper: the sunken surfaces (filters, empty thumbnails, tables'
       heads). Cool, like the page ground, since the 2026-10-21 pass. */
    --mad-paper-0:  #ffffff;
    --mad-paper-1:  #fafbfd;
    --mad-paper-2:  #eef0f7;
    --mad-paper-3:  #e6e9f3;

    /* --- Rose: the platform's new CTA/accent hue (2026 redesign, second
       pass), replacing terracotta/saffron as what --mad-accent-* / --mad-cta-*
       point at below. Terracotta read too close to the old plain-orange CTA
       at a glance (same hue family, just shifted redder) — rose has zero
       relationship to orange, giving a real, unmistakable visual break from
       it, and reads as an energetic "act now" colour that contrasts cleanly
       against the cool indigo brand instead of competing with it.
       Unlike the saffron/terracotta ramps above, rose-600 clears 4.5:1
       for WHITE text directly (verified 4.69:1) — no dark-text workaround
       needed, so this ramp follows the simpler white-text-on-fill pattern
       used by --mad-brand-* rather than the saffron ramp's dark-text one.
       500 stays lighter (fails white text, verified 3.67:1) and is used
       only for decorative fills (dots, gradient light stop) that never
       carry text; 600 is the literal button-fill CTA colour; 700 is both
       the hover/darker state (verified 6.28:1) and the text-safe step for
       accent text on light surfaces. */
    --mad-rose-50:  #fff1f2;
    --mad-rose-100: #ffe4e6;
    --mad-rose-200: #fecdd3;
    --mad-rose-300: #fda4af;
    --mad-rose-400: #fb7185;
    --mad-rose-500: #f43f5e;
    --mad-rose-600: #e11d48;
    --mad-rose-700: #be123c;

    /* --- Indigo: the platform's new primary brand hue (2026 redesign),
       replacing jade/teal as what --mad-brand-* points at below — matches
       the React demo app's new palette (src/index.css) so the WordPress
       site and the demo read as one product. Jade itself is untouched and
       still fully defined above; nothing in this theme independently
       required teal as a distinct hue once the ~10 stray var(--mad-jade-*)
       call sites in lms.css (see that file) are re-pointed at
       var(--mad-brand-*) alongside this change, so no separate "secondary"
       alias was introduced for it.
       Same contrast-safety shift as the jade->teal migration above: steps
       50-400 are plain Tailwind indigo; 500-700 are shifted one to two
       steps darker than their Tailwind label (500 holds indigo-600's hex,
       600 holds indigo-700's hex, 700 holds indigo-800's hex) so every
       existing var(--mad-brand-500) white-text fill stays >=4.5:1 instead
       of inheriting indigo-500's ~3.8:1 (verified: 500 here = 5.2:1, 600 =
       7.1:1, 700 = 9.4:1 against white). */
    --mad-indigo-50:  #eef2ff;
    --mad-indigo-100: #e0e7ff;
    --mad-indigo-200: #c7d2fe;
    --mad-indigo-300: #a5b4fc;
    --mad-indigo-400: #818cf8;
    --mad-indigo-500: #4f46e5;
    --mad-indigo-600: #4338ca;
    --mad-indigo-700: #3730a3;
    --mad-indigo-800: #312e81;
    --mad-indigo-900: #1e1b4b;

    /* --- Sunset: the platform's primary brand hue (2026.2 redesign),
       replacing indigo as what --mad-brand-* points at below, and rose as
       what --mad-accent-* / --mad-cta-* point at — matched to a reference
       education-app kit that uses one warm coral->crimson diagonal
       gradient for every header, button and badge rather than splitting
       brand/accent across two hues. Indigo and rose above are left fully
       defined and orphaned, matching this file's established "keep old
       primitive names, only repoint what they alias" convention.
       50-400 are light/decorative tints; 500 is the vivid gradient-start
       hue (3.45:1 on white — decorative/large-graphics only, never body
       text or a solid fill); 600 is the button/fill-safe step (verified
       4.61:1 white text); 700 is the text-safe step for brand/accent text
       on light surfaces (verified 6.37:1); 800-900 are deep shades used
       for structural, non-CTA surfaces (nav logo, eyebrow badges — see
       --mad-navy-* above, now duplicated from this same ramp). */
    --mad-sunset-50:  #fff2ed;
    --mad-sunset-100: #ffe1d3;
    --mad-sunset-200: #ffc2a8;
    --mad-sunset-300: #ff9d78;
    --mad-sunset-400: #ff7a52;
    --mad-sunset-500: #f2542d;
    --mad-sunset-600: #d83a24;
    --mad-sunset-700: #b12f22;
    --mad-sunset-800: #84241c;
    --mad-sunset-900: #5c1a15;

    /* --- Coral: the red of the logo, every call to action. Madrasty pass
       (2026-10-21): built on the home page's coral (components.css
       --mh-coral #D42F22, --mh-coral-bright #F0473A, --mh-coral-text
       #BD2517). 600 is the button fill (white text 5.0:1), 700 the text
       step on light surfaces (6.1:1), 400/500 decorative only. */
    --mad-coral-50:  #fdecea;
    --mad-coral-100: #fad4cf;
    --mad-coral-200: #f5aba3;
    --mad-coral-300: #f38378;
    --mad-coral-400: #f2675b;
    --mad-coral-500: #f0473a;
    --mad-coral-600: #d42f22;
    --mad-coral-700: #bd2517;
    --mad-coral-800: #8f1c12;
    --mad-coral-900: #651309;

    /* --- Violet: the platform's secondary hue (2026.3 redesign), new —
       the reference design splits brand/action across two hues (coral for
       every CTA/active-state, this violet for stat numbers and the
       secondary/outline button) rather than one unified hue. Also
       derived from a sampled swatch (reference.jpg's "Register"-style
       button border / stat-number colour, rgb(96,48,216)); 600 holds
       that exact value and is already white-text-safe at this lightness
       (verified 7.21:1) unlike coral, so no separate darker "button step"
       was needed the way coral required one. */
    --mad-violet-50:  #f2eefc;
    --mad-violet-100: #e1d8f8;
    --mad-violet-200: #c4b2f0;
    --mad-violet-300: #9f83e8;
    --mad-violet-400: #7e58df;
    --mad-violet-500: #6e42db;
    --mad-violet-600: #6030d8;
    --mad-violet-700: #4c22b4;
    --mad-violet-800: #3b1b8e;
    --mad-violet-900: #2b1367;

    /* --- Subject badge hues: decorative multi-colour icon-badge palette,
       matching the reference kit's "what would you learn today" subject
       grid (math/physics/chemistry/biology/reasoning/social-science each
       get a distinct hue). Background fills only, always paired with a
       white icon glyph (graphical-object 3:1 threshold, not text 4.5:1) —
       never used for text or a solid CTA fill. */
    --mad-badge-red:    #ef4444;
    --mad-badge-orange: #f97316;
    --mad-badge-blue:   #3b82f6;
    --mad-badge-green:  #65a30d;
    --mad-badge-purple: #8b5cf6;
    --mad-badge-teal:   #14b8a6;
}

/* ===========================================================================
   LAYER 2 — SEMANTIC TOKENS  (+ back-compat aliases)
   =========================================================================== */
:root {
    /* ---- Brand aliases. Existing templates consume these names; changing
       what they POINT AT is what re-skins the whole platform at once.
       2026.3 redesign: re-pointed from sunset to coral (see the
       --mad-coral-* primitive block above) — sampled directly off a
       reference site design rather than an approximation, per an explicit
       "match this reference's actual colours" request. Sunset is left
       fully defined and untouched, same "orphan the old primitive"
       convention already used for jade/saffron/indigo. ---- */
    --mad-brand-50:  var(--mad-coral-50);
    --mad-brand-100: var(--mad-coral-100);
    --mad-brand-200: var(--mad-coral-200);
    --mad-brand-300: var(--mad-coral-300);
    --mad-brand-400: var(--mad-coral-400);
    --mad-brand-500: var(--mad-coral-500);
    --mad-brand-600: var(--mad-coral-600);
    --mad-brand-700: var(--mad-coral-700);
    --mad-brand-800: var(--mad-coral-800);
    --mad-brand-900: var(--mad-coral-900);
    --mad-brand-gradient: linear-gradient(135deg, var(--mad-coral-400) 0%, var(--mad-coral-600) 100%);
    --mad-brand-gradient-vivid: linear-gradient(135deg, var(--mad-coral-300) 0%, var(--mad-coral-500) 55%, var(--mad-coral-700) 100%);

    /* ---- Identity aliases. Navy: logo, grade badges, section eyebrows —
       structural/brand surfaces that are never a clickable CTA. Now the
       same warm family as --mad-brand-*, just a deeper stop, rather than a
       second competing hue (2026.2 redesign — see --mad-navy-* above). ---- */
    --mad-navy-gradient: linear-gradient(135deg, var(--mad-navy-700) 0%, var(--mad-navy-900) 100%);

    /* ---- Secondary aliases (2026.3, new): the reference design actually
       splits brand/action across two hues rather than one unified hue —
       coral for every CTA/active-state (--mad-brand-* / --mad-cta-* above),
       this violet (--mad-violet-* primitives) for stat numbers, the
       secondary/outline "Register"-style button, and similar secondary
       accents. Previous redesigns unified brand+accent into one hue for a
       *different* reference (a mobile app kit) that genuinely only used
       one; this reference genuinely uses two, so the aliases now diverge
       again rather than forcing a false unification. ---- */
    --mad-secondary-50:  var(--mad-violet-50);
    --mad-secondary-100: var(--mad-violet-100);
    --mad-secondary-200: var(--mad-violet-200);
    --mad-secondary-500: var(--mad-violet-500);
    --mad-secondary-600: var(--mad-violet-600);
    --mad-secondary-700: var(--mad-violet-700);
    --mad-secondary-gradient: linear-gradient(135deg, var(--mad-violet-500) 0%, var(--mad-violet-700) 100%);

    --mad-accent-50:  var(--mad-coral-50);
    --mad-accent-100: var(--mad-coral-100);
    --mad-accent-200: var(--mad-coral-200);
    --mad-accent-500: var(--mad-coral-500);
    --mad-accent-600: var(--mad-coral-600);
    --mad-accent-700: var(--mad-coral-700);
    /* Flat since the Madrasty pass (2026-10-21): the home page's buttons are
       one solid coral (components.css .mh-btn-primary), so the old diagonal
       gradient of every .mad-btn-primary and account button is now one colour. */
    --mad-accent-gradient: linear-gradient(var(--mad-coral-600), var(--mad-coral-600));

    /* ---- CTA aliases: the literal "click here to act" button (télécharger/
       s'inscrire/réserver/acheter) across every template — coral, matching
       the reference's search-button/active-state colour. coral-600 clears
       4.5:1 for white text directly (verified 4.69:1). ---- */
    --mad-cta-bg:       var(--mad-coral-600);
    --mad-cta-bg-hover: var(--mad-coral-700);
    --mad-cta-text:     #ffffff;

    /* ---- Ink aliases ---- */
    --mad-ink-950: var(--mad-slate-950);
    --mad-ink-900: var(--mad-slate-900);
    --mad-ink-800: var(--mad-slate-800);
    --mad-ink-700: var(--mad-slate-700);
    --mad-ink-600: var(--mad-slate-600);
    --mad-ink-500: var(--mad-slate-500);
    /* Aliased to slate-500 (not slate-400) on purpose: every consumer of
       --mad-ink-400 (input placeholders, disabled-input text, the search
       icon, the AdSense slot label) renders real or functionally-meaningful
       text/iconography, and slate-400 (#94a3b8) measures ~2.6:1 against
       white/paper surfaces — well under WCAG AA's 4.5:1 text / 3:1 UI
       threshold. slate-500 (#64748b) is ~4.76:1 and reads as the same
       "muted" weight. If a genuinely decorative-only use ever needs the
       lighter tone, reach for --mad-slate-400 directly rather than
       reintroducing it here. */
    --mad-ink-400: var(--mad-slate-500);
    --mad-ink-300: var(--mad-slate-300);
    --mad-ink-200: var(--mad-slate-200);
    --mad-ink-100: var(--mad-slate-100);
    --mad-ink-50:  var(--mad-slate-50);

    /* ---- Surfaces ---- */
    /* Page background = the home page's ground (#f6f7fb = --mad-slate-50)
       rather than the warm paper ramp — cards/modals stay on --mad-surface
       (white) so they still lift off this slightly cooler page ground. */
    --mad-surface:        var(--mad-paper-0);
    --mad-surface-alt:    var(--mad-slate-50);
    --mad-surface-sunken: var(--mad-paper-2);
    --mad-surface-inset:  var(--mad-paper-3);
    --mad-mesh-fallback:  var(--mad-slate-50);

    /* ---- Semantic text ---- */
    /* Navy, not neutral slate — matches the reference design's own heading
       colour (see --mad-navy-* above) so every H1-H3, stat number and the
       nav logo/wordmark read as one consistent identity colour sitewide. */
    --mad-text-strong:  var(--mad-navy-800);
    --mad-text-default: var(--mad-slate-800);
    --mad-text-muted:   var(--mad-slate-600);
    --mad-text-subtle:  var(--mad-slate-500);
    --mad-text-onbrand: #ffffff;
    --mad-text-brand:   var(--mad-brand-700);
    --mad-text-accent:  var(--mad-coral-700);
    --mad-text-secondary: var(--mad-violet-700);
    --mad-text-danger:  var(--mad-red-600);
    --mad-text-info:    var(--mad-sky-600);

    /* ---- Semantic borders ---- */
    --mad-border:        var(--mad-slate-200);
    --mad-border-strong: var(--mad-slate-300);
    --mad-border-brand:  var(--mad-brand-200);

    /* ---- Radius ---- */
    /* Rounder since the Madrasty pass (2026-10-21): the home page's cards are
       22-28px, its fields 14px, its buttons pills. */
    --mad-r-xs:   8px;
    --mad-r-sm:   10px;
    --mad-r-md:   14px;
    --mad-r-lg:   20px;
    --mad-r-xl:   26px;
    --mad-r-2xl:  32px;
    --mad-r-full: 999px;

    /* ---- Elevation. Tinted with the ink hue rather than pure black, so
       shadows sit in the same color family as the rest of the UI. ---- */
    --mad-shadow-xs:    0 1px 2px rgba(14, 26, 79, .05);
    --mad-shadow-sm:    0 1px 3px rgba(14, 26, 79, .07), 0 1px 2px rgba(14, 26, 79, .04);
    --mad-shadow-md:    0 10px 24px -10px rgba(14, 26, 79, .16), 0 3px 8px -3px rgba(14, 26, 79, .06);
    --mad-shadow-lg:    0 26px 52px -16px rgba(14, 26, 79, .22), 0 10px 22px -8px rgba(14, 26, 79, .10);
    --mad-shadow-xl:    0 40px 80px -24px rgba(14, 26, 79, .28), 0 16px 32px -12px rgba(14, 26, 79, .12);
    --mad-shadow-brand: 0 10px 24px -12px rgba(212, 47, 34, .75);
    --mad-shadow-accent:0 10px 24px -12px rgba(212, 47, 34, .75);
    --mad-shadow-secondary: 0 14px 30px -12px rgba(96, 48, 216, .40);
    --mad-ring-brand:   0 0 0 4px rgba(14, 26, 79, .10);

    /* ---- Typography ----
       Cairo/Tajawal carry Arabic; Inter carries Latin. Both are loaded in
       functions.php. Real system fallbacks so a blocked Google Fonts
       request degrades to something readable rather than Times. */
    --mad-font-latin:  'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    --mad-font-arabic: 'Cairo', 'Tajawal', 'Noto Naskh Arabic', 'Geeza Pro', 'Segoe UI', system-ui, sans-serif;
    /* The home page's display face (components.css --mh-display), loaded
       sitewide with the other fonts: every h1-h3 of the site since the
       Madrasty pass (2026-10-21). */
    --mad-font-display: 'Bricolage Grotesque', 'Inter', ui-sans-serif, system-ui, sans-serif;
    --mad-font-mono:   ui-monospace, 'SF Mono', 'JetBrains Mono', 'Cascadia Code', Menlo, Consolas, monospace;

    /* Fluid type scale — 1.20 minor-third at mobile widening to 1.25 on
       desktop. clamp() means no breakpoint jumps mid-scroll. */
    --mad-text-2xs: 0.6875rem;                          /* 11px  */
    --mad-text-xs:  0.75rem;                            /* 12px  */
    --mad-text-sm:  0.8125rem;                          /* 13px  */
    --mad-text-md:  0.875rem;                           /* 14px  */
    /* 16px, not 15px: below 16px iOS Safari auto-zooms on input focus, and
       16px is the floor for comfortable mobile body copy (WCAG-adjacent
       readability guidance). Every larger step was re-derived from it. */
    --mad-text-base:1rem;                               /* 16px  */
    --mad-text-lg:  clamp(1.0625rem, 1.01rem + 0.25vw, 1.1875rem);
    --mad-text-xl:  clamp(1.1875rem, 1.10rem + 0.40vw, 1.4375rem);
    --mad-text-2xl: clamp(1.4375rem, 1.26rem + 0.85vw, 1.9375rem);
    --mad-text-3xl: clamp(1.8125rem, 1.48rem + 1.60vw, 2.625rem);
    --mad-text-4xl: clamp(2.25rem,  1.65rem + 2.85vw, 3.75rem);

    --mad-leading-tight: 1.18;
    --mad-leading-snug:  1.35;
    --mad-leading-body:  1.65;
    --mad-leading-loose: 1.8;   /* Arabic needs more room than Latin */

    --mad-track-tight: -0.025em;
    --mad-track-snug:  -0.015em;
    --mad-track-wide:  0.04em;

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

    /* ---- Layout ---- */
    --mad-container:      1280px;
    --mad-container-prose: 72ch;
    --mad-gutter: clamp(16px, 4vw, 32px);

    /* ---- Motion ---- */
    --mad-ease:     cubic-bezier(.22, 1, .36, 1);
    --mad-ease-out: cubic-bezier(.16, 1, .3, 1);
    --mad-ease-in:  cubic-bezier(.4, 0, 1, 1);
    --mad-fast:     150ms;
    --mad-normal:   250ms;
    --mad-slow:     420ms;

    --mad-z-nav: 900;
    --mad-z-modal: 1000;
    /* Above --mad-z-modal so a toast stays visible over an open modal
       (e.g. lms.css's enrollment-feedback toast firing while
       components.css's preview modal is open), below --mad-z-skip so the
       keyboard skip-link still wins over everything. */
    --mad-z-toast: 1050;
    --mad-z-skip: 1100;

    color-scheme: light;
}

/* ===========================================================================
   DARK MODE — DISABLED (structurally, not just gated).
   This used to be a live @media (prefers-color-scheme: dark) block, active
   for any visitor whose OS/browser prefers dark. It only ever flipped the
   SEMANTIC token layer — but the large majority of this theme's own page
   templates style themselves with hardcoded hex in their own inline
   <style> blocks, not these tokens. A dark-mode visitor therefore got a
   broken MIX, not a real dark site: shared components (nav, buttons, tags)
   flipped dark while everything else stayed on hardcoded light-mode hex,
   in places landing dark-on-dark or light-on-light text.
   header.php also sets data-mad-theme="light" on <body> as a second,
   independent guard — but a stale full-page cache (a hosting-level cache
   or a caching plugin serving an HTML snapshot from before that existed)
   could keep shipping visitors an old <body> without that attribute. The
   real @media block below is left in as inert, commented-out reference
   (not deleted — a future pass may want to properly re-enable it once
   every template actually consumes the token layer) so NOTHING in this
   file can trigger dark mode regardless of caching, the HTML attribute, or
   a visitor's OS setting.
@media (prefers-color-scheme: dark) {
    .mad-scope:not([data-mad-theme="light"]) {
        color-scheme: dark;

        --mad-surface:        #0f1621;
        --mad-surface-alt:    #131c29;
        --mad-surface-sunken: #1a2432;
        --mad-surface-inset:  #212c3c;
        --mad-mesh-fallback:  #0b1017;

        --mad-ink-950: #f1f5f9;
        --mad-ink-900: #e2e8f0;
        --mad-ink-800: #d4dde8;
        --mad-ink-700: #b9c5d4;
        --mad-ink-600: #9fb0c0;
        --mad-ink-500: #8496a8;
        --mad-ink-400: #64748b;
        --mad-ink-300: #475569;
        --mad-ink-200: #2b3a4d;
        --mad-ink-100: #1f2b3a;
        --mad-ink-50:  #172230;

        --mad-text-strong:  #f8fafc;
        --mad-text-default: #d4dde8;
        --mad-text-muted:   #9fb0c0;
        --mad-text-subtle:  #8496a8;
        --mad-text-brand:   var(--mad-jade-300);
        --mad-text-accent:  var(--mad-saffron-300);
        --mad-text-danger:  #f28b88;
        --mad-text-info:    #7cb3ec;

        --mad-border:        #2b3a4d;
        --mad-border-strong: #3b4d63;
        --mad-border-brand:  var(--mad-jade-800);

        --mad-brand-50:  #04241c;
        --mad-brand-100: #063526;
        --mad-brand-200: #075e46;
        --mad-brand-300: #0a7355;
        --mad-brand-700: var(--mad-jade-300);
        --mad-brand-800: var(--mad-jade-200);
        --mad-brand-900: var(--mad-jade-100);

        --mad-accent-50:  #2a1a03;
        --mad-accent-100: #3d2605;
        --mad-accent-700: var(--mad-saffron-300);

        --mad-shadow-xs:    0 1px 2px rgba(0, 0, 0, .4);
        --mad-shadow-sm:    0 1px 3px rgba(0, 0, 0, .5), 0 1px 2px rgba(0, 0, 0, .4);
        --mad-shadow-md:    0 10px 24px -10px rgba(0, 0, 0, .65), 0 3px 8px -3px rgba(0, 0, 0, .5);
        --mad-shadow-lg:    0 26px 52px -16px rgba(0, 0, 0, .75), 0 10px 22px -8px rgba(0, 0, 0, .55);
        --mad-shadow-xl:    0 40px 80px -24px rgba(0, 0, 0, .8), 0 16px 32px -12px rgba(0, 0, 0, .6);
        --mad-shadow-brand: 0 14px 30px -12px rgba(12, 133, 99, .55);
        --mad-ring-brand:   0 0 0 4px rgba(12, 133, 99, .35);
    }
}
   =========================================================================== */

/* ===========================================================================
   LAYER 3 — BASE
   Scoped to .mad-scope (applied on <body> in header.php) so nothing leaks
   into wp-admin or plugin markup.
   =========================================================================== */
.mad-scope,
.mad-scope *,
.mad-scope *::before,
.mad-scope *::after {
    box-sizing: border-box;
}

.mad-scope {
    font-family: var(--mad-font-latin);
    font-size: var(--mad-text-base);
    line-height: var(--mad-leading-body);
    color: var(--mad-text-default);
    background-color: var(--mad-surface-alt);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    font-variant-numeric: tabular-nums;
    -webkit-text-size-adjust: 100%;
}

/* Arabic typography. Cairo's x-height runs large and its diacritics need
   vertical room, so RTL/Arabic content gets its own stack, looser leading
   and no letter-spacing (which visibly breaks Arabic letter joining).

   :dir(rtl), not [dir="rtl"] — an attribute selector only matches an
   element that carries that literal HTML attribute itself; it does not
   "see" a dir set on an ancestor the way inherited properties do. Since
   header.php sets dir="rtl" on <html> only (not on <body>, and no
   per-template wrapper repeats it), [dir="rtl"] never actually matched
   anything under .mad-scope for a normal page — this rule was silently
   inert everywhere except the one template that happened to stamp its own
   dir="rtl" on its <main>. :dir(rtl) is the CSS selector built for exactly
   this: it matches on the element's real computed direction, which every
   descendant already inherits from <html dir="rtl"> whether or not
   anything in between repeats the attribute — so switching the site
   language to العربية now actually reaches this rule everywhere, as the
   header.php comment always assumed it did. [lang="ar"] / .mad-ar stay as
   attribute/class matches — those really are opt-in markers set on
   specific elements (e.g. a document title with dir="auto"), not a stand-
   in for the page's own direction. */
.mad-scope:dir(rtl),
.mad-scope :dir(rtl),
.mad-scope :where([lang="ar"], .mad-ar) {
    font-family: var(--mad-font-arabic);
    line-height: var(--mad-leading-loose);
    letter-spacing: normal;
}
.mad-scope :dir(rtl) :is(h1, h2, h3, h4),
.mad-scope :where([lang="ar"], .mad-ar) :is(h1, h2, h3, h4) {
    letter-spacing: normal;
    line-height: 1.4;
}

/* Zero-specificity so any component class reliably wins. A plain
   ".mad-scope a" is (0,1,1) and would outrank a single-class component
   like ".madrasti-doc-cta" (0,1,0) — which previously forced white button
   text back to inherited ink whenever the button was an <a>. */
:where(.mad-scope a) { color: inherit; text-decoration: none; }
:where(.mad-scope p) { margin-block: 0 1em; }
:where(.mad-scope h1, .mad-scope h2, .mad-scope h3, .mad-scope h4, .mad-scope h5, .mad-scope h6) {
    margin-block: 0 0.5em;
    font-weight: 800;
    line-height: var(--mad-leading-tight);
    letter-spacing: var(--mad-track-snug);
}
/* Heading colour is its own rule so the Tailwind-built apps (Cours Interactif,
   student dashboard) can opt out. Tailwind v4 puts every utility in
   `@layer utilities`, and this file is unlayered -- an unlayered declaration
   beats a layered one whatever the specificity, so this navy silently
   overrode `dark:text-primary-300` on every <h1>-<h6> in those apps and left
   headings dark-on-dark. Inside those roots headings take their colour from
   the app's own classes (or inherit). */
:where(.mad-scope :is(h1, h2, h3, h4, h5, h6):not(:is(#madrasti-interactive-course-root, #madrasti-student-dashboard-root) *)) {
    color: var(--mad-text-strong);
}
/* The display face of the home page on every h1-h3 (Madrasty pass,
   2026-10-21), with the same opt-out: inside the Tailwind apps this
   unlayered rule would beat their font classes. The :dir(rtl) rule above
   (specificity 0,2,0) still gives Arabic pages Cairo. */
:where(.mad-scope :is(h1, h2, h3):not(:is(#madrasti-interactive-course-root, #madrasti-student-dashboard-root) *)) {
    font-family: var(--mad-font-display);
    letter-spacing: -0.025em;
}
:where(.mad-scope ul, .mad-scope ol) { margin-block: 0 1em; padding-inline-start: 1.4em; }
:where(.mad-scope img, .mad-scope svg, .mad-scope video) { max-width: 100%; display: block; }
/* KaTeX draws the arrow of \vec (and other accents) as an absolutely positioned svg inside a box of
   width 0: "max-width: 100%" above made that svg 0 px wide, so every vector arrow (F, P, T...) vanished
   from the formulas of the Cours Interactif. */
:where(.mad-scope) .katex svg { max-width: none; }
:where(.mad-scope img) { height: auto; }
:where(.mad-scope hr) { border: 0; border-block-start: 1px solid var(--mad-border); margin-block: var(--mad-space-8); }
:where(.mad-scope code, .mad-scope kbd, .mad-scope samp) {
    font-family: var(--mad-font-mono);
    font-size: 0.9em;
    background: var(--mad-surface-sunken);
    padding: 0.15em 0.4em;
    border-radius: var(--mad-r-xs);
}

/* One focus treatment for the whole platform. :focus-visible only, so
   mouse users never see a ring but keyboard users always do. */
.mad-scope :is(a, button, select, input, textarea, summary, [tabindex]):focus-visible {
    outline: 2px solid var(--mad-brand-500);
    outline-offset: 2px;
    border-radius: var(--mad-r-xs);
}

.mad-scope ::selection {
    background: var(--mad-brand-200);
    color: var(--mad-brand-900);
}

/* Skip link — first tab stop on every page. */
.mad-skip-link {
    position: fixed;
    inset-block-start: -64px;
    inset-inline-start: 12px;
    z-index: var(--mad-z-skip);
    background: var(--mad-ink-950);
    color: var(--mad-surface);
    padding: 10px 18px;
    border-radius: var(--mad-r-sm);
    font-size: var(--mad-text-sm);
    font-weight: 700;
    text-decoration: none;
    box-shadow: var(--mad-shadow-lg);
    transition: inset-block-start var(--mad-fast) var(--mad-ease);
}
.mad-skip-link:focus { inset-block-start: 12px; }

/* ===========================================================================
   LAYOUT
   =========================================================================== */
.mad-container {
    width: 100%;
    max-width: var(--mad-container);
    margin-inline: auto;
    padding-inline: var(--mad-gutter);
}
.mad-container-prose { max-width: var(--mad-container-prose); }

.mad-section { padding-block: clamp(48px, 7vw, 96px); }
.mad-section-tight { padding-block: clamp(32px, 4.5vw, 56px); }

.mad-stack > * + * { margin-block-start: var(--mad-space-4); }
.mad-stack-lg > * + * { margin-block-start: var(--mad-space-8); }

.mad-grid { display: grid; gap: var(--mad-space-6); }
.mad-grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.mad-grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
.mad-grid-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr)); }

.mad-row {
    display: flex;
    align-items: center;
    gap: var(--mad-space-3);
    flex-wrap: wrap;
}
.mad-row-between { justify-content: space-between; }
.mad-spacer { flex: 1 1 auto; }

/* ===========================================================================
   TYPOGRAPHY UTILITIES
   =========================================================================== */
.mad-display {
    font-size: var(--mad-text-4xl);
    font-weight: 900;
    letter-spacing: var(--mad-track-tight);
    line-height: var(--mad-leading-tight);
    color: var(--mad-text-strong);
    text-wrap: balance;
}
.mad-heading-xl {
    font-size: var(--mad-text-3xl);
    font-weight: 800;
    letter-spacing: var(--mad-track-tight);
    line-height: var(--mad-leading-tight);
    color: var(--mad-text-strong);
    text-wrap: balance;
}
.mad-heading-lg {
    font-size: var(--mad-text-2xl);
    font-weight: 800;
    letter-spacing: var(--mad-track-snug);
    line-height: var(--mad-leading-snug);
    color: var(--mad-text-strong);
    text-wrap: balance;
}
.mad-heading-md {
    font-size: var(--mad-text-xl);
    font-weight: 800;
    letter-spacing: var(--mad-track-snug);
    line-height: var(--mad-leading-snug);
    color: var(--mad-text-strong);
}
.mad-heading-sm {
    font-size: var(--mad-text-lg);
    font-weight: 700;
    color: var(--mad-text-strong);
}
.mad-subtext {
    font-size: var(--mad-text-lg);
    line-height: var(--mad-leading-body);
    color: var(--mad-text-muted);
    text-wrap: pretty;
}
.mad-caption {
    font-size: var(--mad-text-xs);
    color: var(--mad-text-subtle);
    font-weight: 600;
}
.mad-mono { font-family: var(--mad-font-mono); font-size: 0.92em; }

/* The home page's eyebrow (components.css .mh-eyebrow) since the Madrasty
   pass (2026-10-21): a short coral dash and coral capitals, no pill — every
   page head of the site starts the way the home page's sections do. The
   icon some templates put inside is left out. */
.mad-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 0;
    background: none;
    border: 0;
    color: var(--mad-coral-700);
    font-size: 0.78rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.11em;
    text-transform: uppercase;
    margin-block-end: var(--mad-space-4);
}
.mad-eyebrow::before { content: ""; width: 26px; height: 2px; border-radius: 2px; background: currentColor; flex: none; }
.mad-eyebrow svg { display: none; }

/* Truncation. -webkit-line-clamp is the only cross-browser multi-line
   ellipsis; the standard `line-clamp` is listed alongside for forward
   compatibility. */
.mad-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mad-clamp-2, .mad-clamp-3 {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.mad-clamp-2 { -webkit-line-clamp: 2; line-clamp: 2; }
.mad-clamp-3 { -webkit-line-clamp: 3; line-clamp: 3; }

/* ===========================================================================
   BUTTONS
   =========================================================================== */
.mad-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--mad-space-2);
    padding: 12px 22px;
    min-height: 44px;              /* WCAG 2.5.5 touch target */
    /* A pill, like the home page's buttons (Madrasty pass, 2026-10-21). */
    border-radius: var(--mad-r-full);
    border: 1px solid transparent;
    font-family: inherit;
    font-size: var(--mad-text-md);
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    position: relative;
    isolation: isolate;
    transition:
        transform var(--mad-fast) var(--mad-ease),
        box-shadow var(--mad-fast) var(--mad-ease),
        background-color var(--mad-fast) var(--mad-ease),
        border-color var(--mad-fast) var(--mad-ease),
        color var(--mad-fast) var(--mad-ease);
}
.mad-btn svg { width: 16px; height: 16px; flex-shrink: 0; }
.mad-btn:disabled,
.mad-btn[aria-disabled="true"],
.mad-btn.is-disabled {
    opacity: .55;
    cursor: not-allowed;
    pointer-events: none;
}

/* .mad-btn-primary IS the sitewide "call to action" button (nav CTA, hero
   search, enroll, télécharger…) — it shares --mad-accent-* (coral) with
   .mad-btn-accent below, so every real CTA on the site uses the one hue
   reserved for that role. background-color is a plain-colour fallback
   behind the gradient (invisible in practice, since --mad-accent-gradient
   is opaque) — it referenced the orphaned --mad-rose-* ramp from an
   earlier redesign pass rather than the current coral hue; fixed to match
   so a future change to the gradient layer doesn't reveal the wrong hue
   underneath it. */
.mad-btn-primary {
    background-image: var(--mad-accent-gradient);
    background-color: var(--mad-accent-600);
    color: #ffffff;
    box-shadow: var(--mad-shadow-accent);
}
.mad-btn-primary:hover { transform: translateY(-1px); background-color: var(--mad-accent-700); background-image: none; }
.mad-btn-primary:active { transform: translateY(0); box-shadow: var(--mad-shadow-sm); }

.mad-btn-accent {
    background-image: var(--mad-accent-gradient);
    background-color: var(--mad-accent-600);
    color: #ffffff;
    box-shadow: var(--mad-shadow-accent);
}
.mad-btn-accent:hover { transform: translateY(-1px); background-color: var(--mad-accent-700); background-image: none; }
.mad-btn-accent:active { transform: translateY(0); }

.mad-btn-solid {
    background: var(--mad-navy-700);
    color: var(--mad-surface);
}
.mad-btn-solid:hover { background: var(--mad-navy-600); transform: translateY(-1px); }

.mad-btn-outline {
    background: var(--mad-surface);
    color: var(--mad-ink-700);
    border-color: var(--mad-border-strong);
}
.mad-btn-outline:hover {
    border-color: var(--mad-text-strong);
    color: var(--mad-text-strong);
    background: var(--mad-surface);
}

.mad-btn-ghost { background: transparent; color: var(--mad-ink-600); }
.mad-btn-ghost:hover { background: var(--mad-ink-100); color: var(--mad-ink-950); }

.mad-btn-danger { background: var(--mad-red-600); color: #ffffff; }
.mad-btn-danger:hover { background: var(--mad-red-700); }

.mad-btn-sm  { padding: 8px 16px;  min-height: 36px; font-size: var(--mad-text-xs); }
.mad-btn-sm svg { width: 14px; height: 14px; }
.mad-btn-lg  { padding: 16px 30px; min-height: 54px; font-size: var(--mad-text-lg); }
.mad-btn-lg svg { width: 19px; height: 19px; }
.mad-btn-block { width: 100%; }
.mad-btn-icon { padding: 0; width: 44px; min-height: 44px; }

/* Directional glyphs (arrows, chevrons) must mirror in RTL. Opt in per
   icon with .mad-flip rather than flipping every icon blindly — a
   download or clock glyph must NOT mirror. */
[dir="rtl"] .mad-flip { transform: scaleX(-1); }

/* ===========================================================================
   CARDS & SURFACES
   =========================================================================== */
.mad-card {
    background: var(--mad-surface);
    border: 1px solid var(--mad-border);
    border-radius: 22px;
    box-shadow: 0 1px 0 rgba(14, 26, 79, .03), 0 18px 36px -30px rgba(14, 26, 79, .45);
    transition:
        border-color var(--mad-normal) var(--mad-ease),
        box-shadow var(--mad-normal) var(--mad-ease),
        transform var(--mad-normal) var(--mad-ease);
}
.mad-card-pad { padding: var(--mad-space-6); }

/* Lift only where the whole card is a link/target. */
.mad-card-interactive { cursor: pointer; }
.mad-card-interactive:hover {
    border-color: var(--mad-border-strong);
    box-shadow: var(--mad-shadow-md);
    transform: translateY(-3px);
}
.mad-card-interactive:focus-within {
    border-color: var(--mad-brand-400);
    box-shadow: var(--mad-shadow-md);
}

.mad-card-flat { box-shadow: none; }
.mad-card-sunken { background: var(--mad-surface-sunken); border-color: transparent; box-shadow: none; }

/* Brand-tinted panel used for callouts and empty states. */
.mad-panel-brand {
    background: linear-gradient(150deg, var(--mad-brand-50), var(--mad-surface) 70%);
    border: 1px solid var(--mad-border-brand);
    border-radius: var(--mad-r-lg);
    padding: var(--mad-space-6);
}

/* ===========================================================================
   BADGES / TAGS / PILLS
   =========================================================================== */
.mad-tag {
    display: inline-flex;
    align-items: center;
    gap: var(--mad-space-1);
    max-width: 100%;
    /* Lets the flex item itself shrink below its text's content width —
       needed for .mad-tag-label's ellipsis (below) to ever actually
       engage; a flex item's default min-width:auto would otherwise force
       the whole pill to stay as wide as its untruncated text. */
    min-width: 0;
    padding: 4px 11px;
    border-radius: var(--mad-r-full);
    font-size: var(--mad-text-2xs);
    font-weight: 700;
    line-height: 1.5;
    background: var(--mad-surface-sunken);
    color: var(--mad-ink-600);
    white-space: nowrap;
    /* Safety net for a long taxonomy term name (e.g. an admin-authored
       level/subject name with no short form): caps the pill so it can
       never overflow past its own rounded background and get hard-clipped
       mid-word by a parent card's overflow:hidden ("تداخل" — the bug this
       fixed). text-overflow:ellipsis has no effect here directly — it
       does not apply to a flex container's own text — see
       .mad-tag-label for the element that actually shows the "…". */
    overflow: hidden;
}
/* Wrap free-text tag content (a taxonomy term name, never a short fixed
   label like "Cours") in this span to get a real ellipsis: text-overflow
   only engages on a block-level box, not a flex container's direct text,
   so .mad-tag alone (inline-flex, for the icon+label gap) can clip a long
   label without ever showing "…". */
.mad-tag-label {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}
.mad-tag svg { width: 11px; height: 11px; flex-shrink: 0; }
.mad-tag-brand  { background: var(--mad-brand-50);  color: var(--mad-text-brand); }
.mad-tag-accent { background: var(--mad-accent-50); color: var(--mad-text-accent); }
.mad-tag-danger { background: var(--mad-red-50);    color: var(--mad-text-danger); }
.mad-tag-info   { background: var(--mad-sky-50);    color: var(--mad-text-info); }
.mad-tag-solid  { background: var(--mad-brand-600);  color: #ffffff; }
.mad-tag-outline{ background: transparent; border: 1px solid var(--mad-border-strong); color: var(--mad-ink-600); }

/* A small counted dot for "3 nouveaux" style affordances. */
.mad-dot {
    display: inline-block;
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--mad-brand-500);
    flex-shrink: 0;
}
.mad-dot-accent { background: var(--mad-accent-500); }
.mad-dot-danger { background: var(--mad-red-500); }

/* ===========================================================================
   FORMS
   =========================================================================== */
.mad-field { display: block; margin-block-end: var(--mad-space-4); }
.mad-field-label {
    display: block;
    font-size: var(--mad-text-xs);
    font-weight: 700;
    color: var(--mad-ink-700);
    margin-block-end: 6px;
}
.mad-field-label .mad-req { color: var(--mad-text-danger); margin-inline-start: 2px; }
.mad-field-hint {
    display: block;
    font-size: var(--mad-text-xs);
    color: var(--mad-text-subtle);
    margin-block-start: 5px;
}
.mad-field-error {
    display: block;
    font-size: var(--mad-text-xs);
    font-weight: 600;
    color: var(--mad-text-danger);
    margin-block-start: 5px;
}

.mad-input,
.mad-select,
.mad-textarea {
    width: 100%;
    padding: 12px 14px;
    min-height: 44px;
    border: 1.5px solid var(--mad-border);
    border-radius: var(--mad-r-md);
    font-family: inherit;
    font-size: var(--mad-text-md);
    font-weight: 500;
    color: var(--mad-ink-800);
    /* White on the page ground, like the home page's search field. */
    background: var(--mad-surface);
    transition:
        border-color var(--mad-fast) var(--mad-ease),
        background-color var(--mad-fast) var(--mad-ease),
        box-shadow var(--mad-fast) var(--mad-ease);
}
.mad-textarea { min-height: 110px; resize: vertical; line-height: var(--mad-leading-body); }
.mad-input::placeholder, .mad-textarea::placeholder { color: var(--mad-ink-400); font-weight: 500; }

/* The chevron is positioned with a logical inline offset and mirrored in
   RTL, so the arrow never lands on top of Arabic text. */
.mad-select {
    padding-inline-end: 38px;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235c6690' stroke-width='2.25'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='m19.5 8.25-7.5 7.5-7.5-7.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 15px;
    /* Taxonomy term names (e.g. "Deuxième Année Du Baccalauréat (2ème
       Année)") regularly overflow a sidebar-width select — without this,
       the closed-state value just hard-cuts mid-word with no ellipsis,
       reading as broken/unfinished rather than intentionally truncated. */
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
}
[dir="rtl"] .mad-select { background-position: left 12px center; }

.mad-input:hover, .mad-select:hover, .mad-textarea:hover { border-color: var(--mad-border-strong); }
.mad-input:focus, .mad-select:focus, .mad-textarea:focus {
    outline: none;
    border-color: var(--mad-text-strong);
    background: var(--mad-surface);
    box-shadow: var(--mad-ring-brand);
}
.mad-input[aria-invalid="true"], .mad-textarea[aria-invalid="true"] {
    border-color: var(--mad-red-500);
    background: var(--mad-red-50);
}
.mad-input:disabled, .mad-select:disabled, .mad-textarea:disabled {
    background: var(--mad-surface-sunken);
    color: var(--mad-ink-400);
    cursor: not-allowed;
}

/* Search input with a leading icon slot. */
.mad-search { position: relative; display: block; }
.mad-search .mad-input { padding-inline-start: 44px; }
.mad-search-icon {
    position: absolute;
    inset-inline-start: 15px;
    inset-block-start: 50%;
    transform: translateY(-50%);
    width: 17px; height: 17px;
    color: var(--mad-ink-400);
    pointer-events: none;
}

/* ===========================================================================
   TABLES  (document matrices, dashboard listings)
   =========================================================================== */
.mad-table-wrap {
    width: 100%;
    overflow-x: auto;
    border: 1px solid var(--mad-border);
    border-radius: var(--mad-r-lg);
    background: var(--mad-surface);
    -webkit-overflow-scrolling: touch;
}
.mad-table { width: 100%; border-collapse: collapse; font-size: var(--mad-text-md); }
.mad-table th, .mad-table td {
    padding: 13px 16px;
    text-align: start;
    border-block-end: 1px solid var(--mad-border);
    vertical-align: middle;
}
.mad-table thead th {
    background: var(--mad-surface-sunken);
    font-size: var(--mad-text-2xs);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: var(--mad-track-wide);
    color: var(--mad-ink-600);
    position: sticky;
    inset-block-start: 0;
    z-index: 1;
}
.mad-table tbody tr:last-child td { border-block-end: 0; }
.mad-table tbody tr { transition: background-color var(--mad-fast) var(--mad-ease); }
.mad-table tbody tr:hover { background: var(--mad-brand-50); }

/* ===========================================================================
   EMPTY / LOADING STATES
   =========================================================================== */
.mad-empty {
    text-align: center;
    padding: var(--mad-space-16) var(--mad-space-6);
    border: 1px dashed var(--mad-border-strong);
    border-radius: var(--mad-r-lg);
    background: var(--mad-surface-alt);
}
.mad-empty-icon {
    width: 56px; height: 56px;
    margin-inline: auto;
    margin-block-end: var(--mad-space-4);
    border-radius: var(--mad-r-lg);
    display: grid;
    place-items: center;
    background: var(--mad-surface-sunken);
    color: var(--mad-ink-400);
}
.mad-empty-icon svg { width: 26px; height: 26px; }
.mad-empty-title { font-size: var(--mad-text-lg); font-weight: 800; color: var(--mad-ink-800); margin-block-end: 4px; }
.mad-empty-text { font-size: var(--mad-text-md); color: var(--mad-text-subtle); max-width: 44ch; margin-inline: auto; }

.mad-spinner {
    display: inline-block;
    width: 15px; height: 15px;
    border: 2px solid var(--mad-border);
    border-top-color: var(--mad-brand-500);
    border-radius: 50%;
    vertical-align: -3px;
    margin-inline-end: var(--mad-space-2);
    animation: mad-spin .65s linear infinite;
}
.mad-spinner-lg { width: 30px; height: 30px; border-width: 3px; vertical-align: middle; }

/* Skeleton placeholders live further down (search ".mad-skeleton" —
   "Skeletons" section, near .mad-chip) as a single definition alongside
   their own shimmer keyframes; a second, older copy used to live here
   too, with a same-named @keyframes mad-shimmer that silently won the
   cascade globally (keyframe names aren't scoped to a selector), making
   every skeleton box also slide via transform on top of its intended
   ::after shimmer sweep. Removed rather than kept "for reference" — this
   one's .mad-skeleton-card class was never actually used anywhere. */

/* ===========================================================================
   PROGRESS  (lesson completion, course progress)
   =========================================================================== */
.mad-progress {
    height: 8px;
    width: 100%;
    background: var(--mad-surface-sunken);
    border-radius: var(--mad-r-full);
    overflow: hidden;
}
.mad-progress-bar {
    height: 100%;
    background-image: var(--mad-brand-gradient);
    border-radius: inherit;
    transition: width var(--mad-slow) var(--mad-ease);
}

/* ===========================================================================
   MODAL / OVERLAY
   =========================================================================== */
.mad-overlay {
    position: fixed;
    inset: 0;
    z-index: var(--mad-z-modal);
    background: rgba(14, 26, 79, .62);
    backdrop-filter: blur(5px);
    -webkit-backdrop-filter: blur(5px);
    display: grid;
    place-items: center;
    padding: var(--mad-gutter);
    animation: mad-fade-in var(--mad-normal) var(--mad-ease) both;
}
.mad-modal {
    background: var(--mad-surface);
    border-radius: var(--mad-r-xl);
    box-shadow: var(--mad-shadow-xl);
    width: min(100%, 640px);
    max-height: min(88vh, 900px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: mad-scale-in var(--mad-normal) var(--mad-ease-out) both;
}
.mad-modal-head {
    display: flex;
    align-items: center;
    gap: var(--mad-space-3);
    padding: var(--mad-space-5) var(--mad-space-6);
    border-block-end: 1px solid var(--mad-border);
}
.mad-modal-body { padding: var(--mad-space-6); overflow-y: auto; flex: 1 1 auto; }
.mad-modal-foot {
    display: flex;
    gap: var(--mad-space-3);
    justify-content: flex-end;
    padding: var(--mad-space-4) var(--mad-space-6);
    border-block-start: 1px solid var(--mad-border);
    background: var(--mad-surface-alt);
}

/* ===========================================================================
   ADSENSE SAFETY
   Ad slots reserve their height up front so a late-loading unit never
   shifts content (CLS), and keep a visible gap + label so a student never
   mistakes an ad for a document link — which is both an AdSense policy
   requirement and the honest thing to do on a site aimed at teenagers.
   =========================================================================== */
.mad-ad-slot {
    --mad-ad-h: 250px;
    min-height: var(--mad-ad-h);
    width: 100%;
    margin-block: var(--mad-space-8);
    background: var(--mad-surface-alt);
    border: 1px dashed var(--mad-border-strong);
    border-radius: var(--mad-r-md);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    contain: layout size;      /* the slot cannot resize its ancestors */
    box-sizing: border-box;
}
.mad-ad-slot-leaderboard { --mad-ad-h: 90px; max-width: 728px; margin-inline: auto; }
.mad-ad-slot-footer      { --mad-ad-h: 100px; }
.mad-ad-label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: var(--mad-track-wide);
    text-transform: uppercase;
    color: var(--mad-ink-400);
    margin-block-end: 4px;
}
/* Clickable elements keep clear air around an ad slot — accidental-click
   protection, and an AdSense placement requirement. */
.mad-ad-safety { display: block; height: 48px; pointer-events: none; }

/* ===========================================================================
   MOTION
   =========================================================================== */
@keyframes mad-spin     { to { transform: rotate(360deg); } }
@keyframes mad-fade-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes mad-fade-up  { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes mad-scale-in { from { opacity: 0; transform: scale(.96) translateY(8px); } to { opacity: 1; transform: none; } }

.mad-animate-in { animation: mad-fade-up var(--mad-slow) var(--mad-ease) both; }
.mad-animate-in-1 { animation-delay: 60ms; }
.mad-animate-in-2 { animation-delay: 120ms; }
.mad-animate-in-3 { animation-delay: 180ms; }
.mad-animate-in-4 { animation-delay: 240ms; }

/* ===========================================================================
   DECORATIVE BACKDROP
   =========================================================================== */
/* The home page's notebook grid (components.css .mh-pagehead), fading out
   from the top: the backdrop of the heads that keep their own markup (the
   private-lesson marketplace, the instructor portal). It was a coral glow
   with a lattice before the Madrasty pass (2026-10-21). */
.mad-mesh-bg {
    position: relative;
    isolation: isolate;
    background: transparent;
}
.mad-mesh-bg::before {
    content: "";
    position: absolute;
    inset: -120px 0 0;
    z-index: -1;
    background-image:
        repeating-linear-gradient(to bottom, transparent 0 31px, rgba(84, 124, 205, .27) 31px 32px),
        repeating-linear-gradient(to right, transparent 0 31px, rgba(84, 124, 205, .13) 31px 32px);
    -webkit-mask-image: radial-gradient(ellipse 60% 90% at 50% 10%, #000 10%, transparent 70%);
    mask-image: radial-gradient(ellipse 60% 90% at 50% 10%, #000 10%, transparent 70%);
    opacity: .6;
    pointer-events: none;
}
/* Dark-mode mesh-bg variant — disabled along with the main dark-mode block
   above (same reasoning: see the LAYER 1 comment near the top of this
   file). Left as inert reference rather than deleted.
@media (prefers-color-scheme: dark) {
    .mad-scope:not([data-mad-theme="light"]) .mad-mesh-bg {
        background:
            radial-gradient(62% 55% at 88% -12%, rgba(12, 133, 99, .20), transparent 62%),
            radial-gradient(48% 46% at 6% 2%,   rgba(247, 144, 9, .10), transparent 62%),
            linear-gradient(180deg, #0b1017 0%, var(--mad-surface) 70%);
    }
}
*/

/* ===========================================================================
   ICON BADGES & PROGRESS RING (2026.2 redesign)
   Two reusable pieces borrowed from the reference education-app kit: a
   solid-colour rounded-square icon badge (used for the homepage's level/
   pillar grids instead of a flat brand-tint square) and a conic-gradient
   circular progress ring (an alternative to .mad-progress for a single,
   prominent stat rather than a list of them).
   =========================================================================== */
.mad-icon-badge {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    border-radius: var(--mad-r-lg);
    color: #ffffff;
}
.mad-icon-badge svg { width: 55%; height: 55%; }
.mad-icon-badge--red    { background: var(--mad-badge-red);    box-shadow: 0 8px 16px -8px rgba(239, 68, 68, .5); }
.mad-icon-badge--orange { background: var(--mad-badge-orange); box-shadow: 0 8px 16px -8px rgba(249, 115, 22, .5); }
.mad-icon-badge--blue   { background: var(--mad-badge-blue);   box-shadow: 0 8px 16px -8px rgba(59, 130, 246, .5); }
.mad-icon-badge--green  { background: var(--mad-badge-green);  box-shadow: 0 8px 16px -8px rgba(101, 163, 13, .5); }
.mad-icon-badge--purple { background: var(--mad-badge-purple); box-shadow: 0 8px 16px -8px rgba(139, 92, 246, .5); }
.mad-icon-badge--teal   { background: var(--mad-badge-teal);   box-shadow: 0 8px 16px -8px rgba(20, 184, 166, .5); }

/* Circular progress ring. --pct (0-100, set inline per instance) drives a
   conic-gradient "filled" arc in the brand gradient's two stops; the inner
   circle is punched out with an ::after disc rather than a mask so the
   ring keeps working without `mask-image` support. Percent label is a
   plain child <span>, centered via the ring's own flex context. */
.mad-progress-ring {
    --pct: 0;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 84px;
    height: 84px;
    border-radius: 50%;
    flex-shrink: 0;
    background: conic-gradient(var(--mad-brand-600) calc(var(--pct) * 1%), var(--mad-ink-100) 0);
}
.mad-progress-ring::after {
    content: "";
    position: absolute;
    inset: 8px;
    border-radius: 50%;
    background: var(--mad-surface);
}
.mad-progress-ring-value {
    position: relative;
    z-index: 1;
    font-size: 18px;
    font-weight: 800;
    color: var(--mad-text-strong);
}

/* ===========================================================================
   ACCESSIBILITY HELPERS
   =========================================================================== */
.mad-sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ===========================================================================
   LAYER 4 — 2026 REFRESH
   Swiss/minimal discipline over the existing token set: one accent colour
   carrying the 10% of a 60-30-10 split (neutral surface 60, slate structure
   30, teal action 10), restrained elevation, 200-250ms hovers.
   =========================================================================== */

/* ---- Filter chips --------------------------------------------------------
   For low-cardinality facets (Niveau, Type). High-cardinality ones (Leçon)
   stay <select> — a chip row of 40 lessons is worse than a dropdown.
   The row scrolls horizontally on narrow screens instead of shrinking the
   labels, and each chip keeps a >=44px touch target. */
.mad-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--mad-space-2);
    align-items: center;
}
@media (max-width: 640px) {
    .mad-chip-row {
        flex-wrap: nowrap;
        overflow-x: auto;
        scroll-snap-type: x proximity;
        padding-block-end: var(--mad-space-2);
        -webkit-overflow-scrolling: touch;
        scrollbar-width: thin;
        /* Without this, the last chip gets a hard, clean cut at the
           container edge that reads as a layout bug ("تداخل") rather than
           "scroll for more" — this fade hints there's more content past
           the edge. Symmetric on both sides so it works unchanged in RTL
           (no logical-direction keyword exists for mask-image gradients). */
        -webkit-mask-image: linear-gradient(to right, transparent, black 20px, black calc(100% - 20px), transparent);
        mask-image: linear-gradient(to right, transparent, black 20px, black calc(100% - 20px), transparent);
    }
    .mad-chip { scroll-snap-align: start; flex: 0 0 auto; }
}
.mad-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--mad-space-2);
    min-height: 44px;
    padding: 9px 16px;
    border: 1px solid var(--mad-border);
    border-radius: var(--mad-r-full);
    background: var(--mad-surface);
    color: var(--mad-text-default);
    font-family: inherit;
    font-size: var(--mad-text-md);
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    transition:
        background-color var(--mad-fast) var(--mad-ease),
        border-color var(--mad-fast) var(--mad-ease),
        color var(--mad-fast) var(--mad-ease),
        box-shadow var(--mad-fast) var(--mad-ease);
}
.mad-chip:hover { border-color: var(--mad-text-strong); color: var(--mad-text-strong); }
.mad-chip:focus-visible { outline: 2px solid var(--mad-brand-600); outline-offset: 2px; }
/* aria-pressed / aria-selected drive the active look — the class is only
   the paint, the ARIA state is the truth screen readers announce. */
.mad-chip[aria-pressed="true"],
.mad-chip[aria-selected="true"],
.mad-chip.is-active {
    /* Navy, like the selected tab of the home page (.mh-tab). */
    background: var(--mad-navy-700);
    border-color: var(--mad-navy-700);
    color: #fff;
}
.mad-chip[aria-pressed="true"]:hover,
.mad-chip.is-active:hover { background: var(--mad-navy-600); border-color: var(--mad-navy-600); color: #fff; }
/* ---- Skeletons -----------------------------------------------------------
   Sized to the real card so swapping skeleton -> content shifts nothing
   (CLS). The shimmer is a background sweep, not a layout animation. */
.mad-skeleton {
    position: relative;
    overflow: hidden;
    background: var(--mad-surface-alt);
    border-radius: var(--mad-r-sm);
}
.mad-skeleton::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .65), transparent);
    animation: mad-shimmer 1.4s infinite;
}
[dir="rtl"] .mad-skeleton::after { animation-name: mad-shimmer-rtl; }
@keyframes mad-shimmer     { 100% { transform: translateX(100%); } }
@keyframes mad-shimmer-rtl { 100% { transform: translateX(-200%); } }
.mad-skeleton-text { height: 12px; margin-block-end: var(--mad-space-2); }
.mad-skeleton-title { height: 18px; width: 72%; margin-block-end: var(--mad-space-3); }
.mad-skeleton-thumb { aspect-ratio: 4 / 3; width: 100%; border-radius: 0; }
.mad-skeleton-chip { height: 20px; width: 64px; border-radius: var(--mad-r-full); }
/* prefers-reduced-motion: the universal rule above collapses the shimmer;
   the flat grey block still reads as "loading" without the sweep. */

/* ---- Stat counters (hero) ------------------------------------------------ */
.mad-stat-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--mad-space-8);
    justify-content: center;
}
.mad-stat-value {
    display: block;
    font-size: var(--mad-text-2xl);
    font-weight: 800;
    line-height: 1.1;
    letter-spacing: var(--mad-track-tight);
    color: var(--mad-brand-700);
    /* Tabular figures: a counting-up number must not reflow its neighbours. */
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
}
.mad-stat-label {
    display: block;
    margin-block-start: 2px;
    font-size: var(--mad-text-xs);
    font-weight: 600;
    letter-spacing: var(--mad-track-wide);
    text-transform: uppercase;
    color: var(--mad-text-muted);
}

/* Honour the OS "reduce motion" setting everywhere. Transitions are
   collapsed rather than removed so state changes are still perceivable. */
@media (prefers-reduced-motion: reduce) {
    .mad-scope *,
    .mad-scope *::before,
    .mad-scope *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
    .mad-card-interactive:hover,
    .mad-btn-primary:hover,
    .mad-btn-accent:hover,
    .mad-btn-solid:hover,
    .mad-btn-outline:hover { transform: none; }
}

/* Windows High Contrast / forced-colors: gradients and shadows are
   discarded by the OS, so restore explicit borders that survive. */
@media (forced-colors: active) {
    .mad-btn, .mad-card, .mad-tag, .mad-input, .mad-select, .mad-textarea {
        border: 1px solid ButtonBorder;
    }
    .mad-btn:focus-visible { outline: 2px solid Highlight; }
}

/* ===========================================================================
   PRINT — students print these documents. Strip the chrome, keep the paper.
   =========================================================================== */
@media print {
    .mad-scope { background: #fff; color: #000; font-size: 11pt; }
    .madrasti-nav, .madrasti-footer, .mad-ad-slot, .mad-skip-link,
    .mad-btn, .mad-overlay, .madrasti-nav-mobile { display: none !important; }
    .mad-card { border: 1px solid #999; box-shadow: none; break-inside: avoid; }
    a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }
}
