/* ============================================================
   LSANY — Redesign
   Gamified, playful-but-premium, dark+gold
   ============================================================ */

/* <picture> wraps for WebP fallback. display:contents makes the wrapper
   transparent in layout so existing img selectors (percentages, centering,
   filters) keep applying as if the wrapper were not there. */
picture { display: contents; }

/* Self-hosted Arabic fonts. Amiri for hero display, Montserrat Arabic elsewhere. */
@font-face {
  font-family: 'Amiri';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/Amiri-Regular-Arabic.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF;
}
@font-face {
  font-family: 'Amiri';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/Amiri-Bold-Arabic.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF;
}
@font-face {
  font-family: 'Montserrat Arabic';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/MontserratArabic-Regular.woff2') format('woff2'),
       url('fonts/MontserratArabic-Regular.woff') format('woff');
}
@font-face {
  font-family: 'Montserrat Arabic';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/MontserratArabic-Bold.woff2') format('woff2'),
       url('fonts/MontserratArabic-Bold.woff') format('woff');
}
/* Tajawal: clean geometric Arabic for the alphabet trace letters. Montserrat
   Arabic Bold draws sad/dad with a notch in the bowl corner; Tajawal renders
   the full, smooth letter while keeping the same bold modern look. */
@font-face {
  font-family: 'Tajawal';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/Tajawal-Bold.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF;
}

/* Self-hosted Latin fonts. Each family ships as one variable woff2 per
   subset (latin / latin-ext); the same file backs every weight via
   font-weight ranges. font-display: optional avoids the swap-jitter that
   was hurting mobile CLS. */
@font-face {
  font-family: 'Unbounded';
  font-style: normal;
  font-weight: 400 700;
  font-display: optional;
  src: url('fonts/Unbounded-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Unbounded';
  font-style: normal;
  font-weight: 400 700;
  font-display: optional;
  src: url('fonts/Unbounded-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 600;
  font-display: optional;
  src: url('fonts/InstrumentSans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 600;
  font-display: optional;
  src: url('fonts/InstrumentSans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 700;
  font-display: optional;
  src: url('fonts/JetBrainsMono-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 700;
  font-display: optional;
  src: url('fonts/JetBrainsMono-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* Core palette — deeper, richer, more confident than original */
  --bg: #0B1917;
  --bg-2: #10221F;
  --bg-3: #163029;
  --surface: #1B3831;
  --surface-2: #214339;
  /* Top stop of every card-face gradient. Split out from --surface-2 so the
     Light theme can make card faces flat white while wells, hovers and tracks
     keep the faint grey they need to read as recessed (Ali, 2026-07-29). */
  --card-top: #214339;
  --stroke: rgba(230, 184, 97, 0.14);
  --stroke-strong: rgba(230, 184, 97, 0.32);

  --cream: #FAF5E8;
  --cream-muted: #E8DFC8;
  --secondary: #B8B2A0;
  /* WCAG AA (4.5:1) against the LIGHTEST surface muted text ever sits on, which
     is --card-top, not --bg. Measured 2026-08-02 at the old #7E8981: 4.96 on
     --bg (fine), 3.49 on --surface, 3.00 on --card-top. Every real failure was
     a 9-11px label on a card, which is the worst case twice over -- smallest
     type on the lightest ground. #A1A9A3 is the same hue and saturation lifted
     in lightness only, landing at 4.53 on --card-top.
     Consequence worth knowing before nudging this again: at L*65 it now sits
     close to --secondary (#B8B2A0, L*67), so the gap between the two recessed
     tiers is narrow. --secondary already passes AA at 5.15, so it was left
     alone rather than lifted to re-open the gap -- that is a design call, not
     an accessibility one. */
  --muted: #A1A9A3;

  /* Accents */
  --gold: #E6B861;
  --gold-2: #F5D08C;
  --gold-deep: #B88838;
  --gold-glow: rgba(230, 184, 97, 0.35);
  /* --gold-glow is a HALO value: right for a box-shadow thrown off a gold
     button, wrong as a background under body copy. Four panels were using it
     that way -- .cn-guarantee, .cn-bizfoot, .cn-packs-note and .eb-set--hero --
     and because their radial gradients are centred on an edge, the text starts
     roughly 25px from the hot spot and sits on close to the full 35%. Measured
     2026-08-02 on the resulting ground: --secondary 3.07, --muted 2.70, gold
     3.53, all under the 4.5 AA needs. 0.09 is the most gold that keeps all
     three of those tokens passing on --surface. It cannot be pushed further:
     --muted is calibrated to 4.53 on --card-top, so it has almost no headroom
     for a tint of any kind. Use --gold-glow for shadows, --gold-wash for
     anything that paints behind text. */
  --gold-wash: rgba(230, 184, 97, 0.09);
  /* Gold used as INK rather than as a fill. On the two dark themes that is just
     --gold; on white it cannot be, because --gold there is #A87B2E and measures
     3.79:1, under the 4.5 body copy needs. --gold-deep is 6.24 on white.

     This exists because eight footer brand marks and the cookie bar's links set
     their colour in an inline style attribute or in a stylesheet injected by
     cookie-consent.js, and neither can be reached by a
     html[data-theme="light"] selector. A token is the only mechanism that
     works in both places, so it is the mechanism new gold TEXT should use.

     The retrofit for gold text that IS reachable by a selector lives in
     courses/preview/design-1.css under "LIGHT THEME - gold that has to be
     read"; those rules do the same job by overriding the declaration instead.
     Do not remove one in favour of the other without re-measuring both. */
  --gold-ink: var(--gold);
  /* THREE fill stops, THREE ink stops. --gold / --gold-2 / --gold-deep are the
     stops of a gold GRADIENT and are read by roughly 150 fills; --gold-ink /
     --gold-ink-2 / --gold-ink-deep are the same three roles used as TEXT.

     On the two dark themes the two sets are identical, so those themes cannot
     move when a fill value changes -- that is why the ink tokens are declared
     as var() of their fill rather than as literals. Light is the theme where
     the two genuinely diverge, because a gold bright enough to be a pretty
     button fill is nowhere near readable as text on white, and a gold dark
     enough to read on white makes a muddy, olive button. Trying to serve both
     with one value is what made light mode look the way Ali described it.

     Which one to reach for: painting a surface -> the fill set. Setting
     `color:` -> the ink set. Third case, settled 2026-08-02: a FOCUS RING takes
     the ink set too. WCAG 1.4.11 asks a focus indicator for 3:1 against what it
     is drawn on, an outline-offset ring lands on the page rather than on the
     control, and the fill measures 1.84 on white -- so all 67 gold focus rings
     across the site are on --gold-ink now. Neither dark theme moved, because
     ink and fill are the same value there. */
  --gold-ink-2: var(--gold-2);
  --gold-ink-deep: var(--gold-deep);
  /* The un-gilded half of a .scroll-gold heading, before the scroll fills it in.
     Per theme, because the resting state of a gilded heading is real text that
     has to clear the 3:1 large-text bar on whatever it is sitting on, and one
     value cannot do that on both a near-black green and pure white.
     Dark: 5.47 on --bg, 3.85 on --surface, 3.31 on --card-top. */
  --gild-off: #948D7E;
  /* The ink that sits ON a gold fill. Deliberately NOT re-declared per theme:
     every theme's gold is a light gold, so the ink stays this near-black brown.
     It was retyped as a literal at ~130 call sites, and one of them had drifted
     to #1a1206, which is why it is a token now.

     The trap this token exists to close, found in 18 more places 2026-08-02:
     writing `color: var(--bg)` on a gold-filled control. It reads as "the page
     colour on gold", which is true on a dark theme and inverts on a light one,
     where --bg is white. Every one of them -- the Reference tabs, the Pronounce
     tabs and filters, the Saqr Call mic, the book covers, the combo multiplier,
     the game start button, the mic orbs, the word-forms chips, the tour's Next
     button -- rendered white on gold at 1.47 to 1.84 in light mode. If a control
     is filled with gold, its ink is --on-gold. Never --bg. */
  --on-gold: #1A0F00;

  /* ONE radius scale for the whole site. These lived on .page in courses.css, so
     any page that does not use .page (the Emirati at Work dashboard, the industry
     dictionary) could not reach them and re-invented its own pair, which is how
     the site ended up with radii from 10px to 22px. */
  --r-panel: 22px;   /* big panels: hero, Ramsa, upsell, featured tile */
  --r-card: 16px;    /* inner cards: tool tiles, node-cards, result cards */
  --r-pill: 999px;

  /* subtle chip fill + progress-track fill — darken-on-dark here, overridden
     to a light ink tint on the light/sage themes so chip text stays legible */
  --chip-bg: rgba(0, 0, 0, 0.16);
  --track-bg: rgba(0, 0, 0, 0.25);

  --green: #4DBF8E;
  --green-deep: #2E7D5C;
  /* The ink for anything FILLED with --green, and the one token on this list
     whose light value is white rather than near-black. --gold stays light on
     every theme, so --on-gold is near-black everywhere. --green does not: it is
     #4DBF8E on dark and #D4A03A on desert, both light, but #1F7A52 on light,
     which is dark. Ink that is correct on two themes is therefore wrong on the
     third, and there is no single literal that works.
     Found by the Wordle keyboard: .wd-key.correct was near-black on --green and
     measured 3.40 in light at 15px bold, which needs 4.5 (the 3:1 large-text
     allowance starts at 18.66px for bold). The 30px tiles above it use the same
     pair and pass on that allowance, which is why it only showed on the keys.

     `color: var(--bg)` happens to give the right answer on a green fill in all
     three themes today, because --green flips light-to-dark exactly when --bg
     flips dark-to-light. That is a coincidence of the current palette, not a
     rule, and it is one letter away from the gold trap described under
     --on-gold. Prefer this token. (.ss-word .w-mark on pronounce.html still
     uses --bg deliberately, because the same element also carries a coral
     state; the note there explains it.) */
  --on-green: #0B1917;
  /* Green as INK on a green TINT, the sibling of --coral-ink and the last gap
     in that family. Without it the two auth pages wrote a literal #c8f0dd for
     dark and overrode light to --green-deep, and --green-deep is a FILL colour:
     pixel-sampled on /auth/reset 2026-08-02, the "we sent a new link" message
     measured 3.95 on the rendered 12% green tint, where 13.5px needs 4.5.
     --green (#1F7A52 on light) is no better at 4.19. #1B6845 measures 5.33 on
     the same pixel. Dark and desert keep the mint that already worked. */
  --green-ink: #C8F0DD;

  --coral: #E8614A;
  --coral-deep: #B8442F;
  /* Coral as INK, the same split --gold / --gold-ink makes and for the same
     reason: #E8614A is a good warning FILL and is not readable as small text.
     Pixel-sampled on the dashboard 2026-08-02, the "UNIT TEST" status and the
     "Punch in" badge measured 3.26 and 3.13 against the rendered card, both
     under the 4.5 that 9.5px and 10px need. #F49E8B is the same hue lifted
     until it clears every dark ground the coral text lands on: 5.07 on the
     unit-test card, 4.68 on the desert version of it, 8.67 on plain --bg.
     Light re-declares it downward, because there the problem inverts.
     Untouched: .m-timer b at 26px and .game-clock b at 22px bold. Those are
     large text, the 3:1 bar, and the fill is the design there. */
  --coral-ink: #F49E8B;

  /* a cool turquoise accent for variety (the Tabby installment line). Desert
     theme overrides this to its native coral so it stays warm on brown. */
  --accent-cool: #43CDBD;

  /* Type */
  --f-display: "Unbounded", "Outfit", system-ui, sans-serif;
  --f-body: "Instrument Sans", "DM Sans", system-ui, sans-serif;
  --f-mono: "JetBrains Mono", ui-monospace, monospace;
  --f-arabic: "Montserrat Arabic", "Amiri", "Noto Naskh Arabic", sans-serif;
  --f-arabic-hero: "Amiri", "Montserrat Arabic", "Noto Naskh Arabic", serif;

  /* Motion */
  --ease-bounce: cubic-bezier(.34,1.56,.64,1);
  --ease-smooth: cubic-bezier(.22,.8,.36,1);
  --ease-spring-soft: cubic-bezier(.34,1.28,.64,1); /* gentle settle — restrained, never bouncy */
  --ease-pop: cubic-bezier(.22,1,.36,1); /* fast-start, soft-land — the premium "everything reacts" curve (Stripe/Duolingo) */
  --dur-fast: .18s;
  --dur-base: .42s;
  --dur-slow: .62s;

}

/* =========================================================
   LIGHT THEME — clean white. Modern, neutral, a single gold accent
   (not gold-on-cream). Triggered by html[data-theme="light"].
   ========================================================= */
html[data-theme="light"] {
  /* Clean white theme — BOLD neutral near-black ink (no navy/cool cast) and
     pure neutral SOFT shadows (subtle lift). A faint neutral off-white canvas
     lets pure-white surfaces pop. */
  --bg: #FFFFFF;          /* plain white canvas; surfaces read by their shadow and hairline (Ali, 2026-07-29) */
  --bg-2: #F4F4F5;
  --bg-3: #ECECEE;
  --surface: #FFFFFF;
  --surface-2: #F4F4F5;   /* wells, hovers, tracks — NOT card faces */
  --card-top: #FFFFFF;    /* card faces are flat white on the light theme */

  /* The three FILL stops. These were #C99A3F / #A87B2E / #7E5A18 -- text values
     doing a fill's job, and the result was the olive-mud button Ali rejected on
     2026-08-02: "such a dull gold with black text, it's so ugly".

     The old stops also failed on their own terms. Every gold gradient on the
     site runs --gold-2 -> --gold or --gold-2 -> --gold-deep and carries
     --on-gold (#1A0F00) ink, and the old light values measured 7.35 / 4.98 /
     3.02 against that ink -- the bottom of every two-stop gradient was failing
     AA outright. The new stops measure 12.84 / 10.24 / 8.39, so near-black now
     clears 4.5 at EVERY point along EVERY gold gradient in this theme with
     enormous margin, and the buttons read as brand gold instead of olive.

     --gold and --gold-2 are literally the dark theme's brand golds. That is the
     point: gold is gold, and the reason light mode had its own duller pair was
     never a design decision, it was the text-contrast constraint leaking into
     the fill set. With the ink split out below, the constraint is gone and the
     fills can just be the brand. --gold-deep is the one that is NOT shared:
     the dark theme's #B88838 is a shading stop against near-black and reads as
     a dirty bottom edge on white, so this is the same hue kept bright.

     What this costs: a bright fill is only ~2.0:1 against the white page, so
     the button's own edge no longer carries itself. That is paid for below with
     a real light-theme shadow on .btn-primary rather than the gold halo, which
     is invisible on white. A filled pill with 9:1 ink inside it is not
     ambiguous; a 3.79 olive smear with black text was legible and ugly.
     Measured 2026-08-02. */
  --gold: #E6B861;
  --gold-2: #F5D08C;
  --gold-deep: #D9A441;
  --gold-glow: rgba(230, 184, 97, 0.32);
  --gold-wash: rgba(230, 184, 97, 0.10);
  /* The three INK stops. This is the one theme where they diverge from the fill
     set; see the note on --gold-ink-2 in :root.

     --gold-ink      #96650A  5.04 on white, 4.59 on --surface-2
     --gold-ink-2    #8A5A00  5.93 on white, 5.39 on --surface-2
     --gold-ink-deep #7E5A18  6.24 on white, 5.68 on --surface-2

     --gold-ink was var(--gold-deep) (#7E5A18). It passed, but it is a 67%
     saturation brown and it is what Ali meant by "the word Lsany just looks
     dull". #96650A is fully saturated at the same lightness band: still AA on
     both grounds, visibly gold rather than brown.

     --gold-ink-2 is the real bug fix. --gold-2 is text in 110 places -- every
     Arabic line in the course runner, .saqr-ar on the homepage -- and at
     #C99A3F on a white card it measured 3.06, failing AA everywhere it
     appeared. Deeper is more emphatic on white, which is the correct inversion:
     on the dark themes --gold-2 is the BRIGHTER gold, and brighter-than-normal
     on white means darker-than-normal.

     --gold-ink-deep holds #7E5A18, the value --gold-deep used to carry, so the
     11 `color: var(--gold-ink-deep)` sites do not move in any theme. It exists so
     --gold-deep itself was free to become a fill stop. */
  --gold-ink: #96650A;
  --gold-ink-2: #8A5A00;
  --gold-ink-deep: #7E5A18;
  /* The dark themes' #948D7E is only 3.30 on white and 2.97 on --surface-2,
     which is where the gilded headings on the storefront actually land, so it
     missed the 3:1 bar in this theme. #6B655A is the same hue taken down
     instead of up: 5.78 on white, 5.26 on --surface-2. Measured 2026-08-02. */
  --gild-off: #6B655A;

  /* supporting status colors tuned for contrast on white */
  --green: #1F7A52;
  /* White, not the near-black the other two themes use. This is the theme where
     --green is a DARK fill; white on #1F7A52 measures 6.37. See the note on the
     :root declaration for why this token cannot be one literal. */
  --on-green: #FFFFFF;
  /* Green as ink, deeper here rather than lighter, exactly like --coral-ink
     below. On the 12% green tint this theme renders at #DDE7E2, --green-deep is
     3.95 and --green is 4.19; this is 5.33. */
  --green-ink: #1B6845;
  --coral: #C8432B;
  /* Coral as ink, deeper here rather than lighter. The coral text on this theme
     lands on the coral's own 10-14% wash, not on plain white: pixel-sampled at
     #F6E0DC, where the fill measures 3.87 and the 10px badge needs 4.5.
     #B03A24 is 4.78 on that wash and 6.04 on white. */
  --coral-ink: #B03A24;
  /* Was #138B86, under a comment claiming it was "deeper turquoise for contrast
     on the white theme". It was deeper than the dark theme's #43CDBD, but not
     deep enough: 4.15:1 on white, and its only consumer is .pv-tabby at 12.5px,
     which needs 4.5. #0F7A75 is 5.17 on white and 4.70 on --surface-2, the two
     grounds it actually lands on. Measured 2026-08-02. Nothing fills with this
     token -- .pv-tabby is the single use in the whole site -- so deepening it
     cannot darken a background anywhere. */
  --accent-cool: #0F7A75;

  /* neutral ink tints — chips/tracks read clean on white, not gold-muddy */
  --chip-bg: rgba(0, 0, 0, 0.05);
  --track-bg: rgba(0, 0, 0, 0.08);

  /* ---- bold neutral ink (no navy) + neutral hairline strokes ---- */
  --cream: #18181B;
  --cream-muted: #3F3F46;
  --secondary: #52525B;
  /* Calibrated against --surface-2 and --bg-3, not against --bg. The dark theme
     already works this way ("AA against --card-top, not --bg") and light did
     not: #71717A is 4.83 on white but only 4.40 on --surface-2 #F4F4F5 and 4.10
     on --bg-3, so every --muted label standing in a well or on a card face that
     is not pure white was under AA. .pk-meta on the eleven Emirati at Work
     cards is where it was caught, at 10px. #696972 is 5.43 / 4.94 / 4.61 on
     white / --surface-2 / --bg-3. Measured 2026-08-02.
     Safe to darken: --muted is ink everywhere in the site except two 6px
     typing-indicator dots (courses.css 491 and 907), which only gain from it. */
  --muted: #696972;
  --stroke: rgba(0, 0, 0, 0.08);
  --stroke-strong: rgba(0, 0, 0, 0.13);

  /* ---- elevation tokens (Soft — subtle, neutral; the chosen strength) ---- */
  --card-border: rgba(0, 0, 0, 0.07);
  --shadow-pill: 0 1px 2px rgba(0,0,0,0.05);
  --shadow-card: 0 1px 2px rgba(0,0,0,0.05), 0 6px 14px -8px rgba(0,0,0,0.09);
  --shadow-card-hover: 0 2px 4px rgba(0,0,0,0.06), 0 14px 28px -12px rgba(0,0,0,0.14);
  --shadow-hover-lift: 0 16px 32px -14px rgba(0,0,0,0.16);
}

html[data-theme="light"] body {
  background: var(--bg);
}

/* =========================================================
   DESERT DUNES — warm brown. A dark-family theme (dark warm bg,
   cream text, amber gold), ported from the app's desert-dunes
   palette. Inherits only :root (no light base), so it sets the
   full token set itself. Kept on [data-theme="default"] so the
   theme id stays stable across theme.js / sidebar.js.
   ========================================================= */
html[data-theme="default"] {
  --bg: #1F140A;
  --bg-2: #2A1B0F;
  --bg-3: #352314;
  --surface: #3F2B19;
  --surface-2: #4A341F;
  --card-top: #4A341F;
  --stroke: rgba(230, 184, 77, 0.14);
  --stroke-strong: rgba(230, 184, 77, 0.32);

  --cream: #F5E6CC;
  --cream-muted: #D4C094;
  /* --secondary and --muted were #B89E73 and #B19F81, landing on 4.54 and 4.52
     against plain --card-top. Both were calibrated ONTO the 4.5 bar rather than
     past it, which meant any tint at all put them under: on the featured plan
     card, whose gold radial is real and deliberate, a screenshot of the
     rendered pixels under .pv-promise measured grounds from #41311E to #4E3C26
     and the ink fell to 4.08. Desert has the least ink headroom of the three
     themes, so it is the one that has to be calibrated against a TINTED ground,
     not a flat one. On that worst rendered ground these read 4.84 and 4.73, and
     on plain --card-top 5.37 and 5.24. Measured 2026-08-02 from a 390px
     screenshot, not from a model of the gradient. */
  --secondary: #C4AD86;
  --muted: #BCAC91;

  --gold: #E6B84D;
  --gold-2: #F0CA6E;
  --gold-deep: #B88838;
  --gold-glow: rgba(230, 184, 77, 0.40);
  /* 0.06, where dark gets 0.09. Desert is the theme with the least ink headroom,
     and this is the belt to the ink lift's braces: with the OLD ink a 0.10 wash
     put --muted at 4.19, --secondary at 4.20 and --accent-cool at 4.41, all
     under AA. The ink tokens above have since been recalibrated, which alone
     would carry a 0.10 wash on --surface (4.71 / 4.82) -- but only just, and it
     would still fail on --card-top (4.26 / 4.36). Keeping the wash at 0.06 as
     well means a future panel that washes a card face instead of the page
     surface does not quietly reopen this. Measured 2026-08-02. */
  --gold-wash: rgba(230, 184, 77, 0.06);

  --green: #D4A03A;
  /* Desert reads --green as gold, so this is a light fill and takes near-black
     ink, the same as the dark theme. Declared rather than inherited so that all
     three theme blocks state it and none of them can be read as an oversight. */
  --on-green: #0B1917;
  /* Desert's "green" tint is gold, so the ink over it stays the same mint the
     dark theme uses. Declared rather than inherited for the reason above. */
  --green-ink: #C8F0DD;
  --coral: #E8614A;
  /* Same lifted coral the base theme uses as ink; 4.68 on this theme's version
     of the unit-test card. See the note in :root. */
  --coral-ink: #F49E8B;
  /* Desert uses the native coral rather than turquoise, which reads off on warm
     brown. It used to be a bare var(--coral), and --coral is a FILL value:
     #E8614A measures 3.46 on --card-top and 3.97 on --surface, and the only
     thing this token inks is .pv-tabby at 12.5px, which needs 4.5. #F08A72 is
     the same hue lifted until it clears on both (4.76 and 5.46). --coral itself
     is untouched: it is correct as a fill and this was the only place using it
     as text. Measured 2026-08-02, same pass that deepened the light value.
     #F49B85 rather than the #F08A72 that first cleared --card-top: .pv-tabby
     also appears on the featured plan card, where the rendered ground reaches
     #4E3C26 and #F08A72 falls to 4.30. #F49B85 is 4.94 there and 5.48 on plain
     --card-top. */
  --accent-cool: #F49B85;
  /* #948D7E is a cool grey and reads dirty on warm brown. Same lightness,
     warmed to the theme: 3.48 on --card-top, 3.99 on --surface and 5.40 on
     --bg, clearing the 3:1 these 22-27px bold headings need on all three.
     Measured 2026-08-02. */
  --gild-off: #978B77;

  --chip-bg: rgba(230, 184, 77, 0.15);
  --track-bg: rgba(212, 160, 58, 0.18);
}
html[data-theme="default"] body {
  background:
    radial-gradient(ellipse 100% 60% at 50% 0%, rgba(230,184,77,0.10) 0%, transparent 60%),
    radial-gradient(ellipse 80% 50% at 50% 100%, rgba(184,136,56,0.06) 0%, transparent 60%),
    var(--bg);
}

/* Dark-only atmospheric layers — hide in light mode */
html[data-theme="light"] .hero-stars,
html[data-theme="light"] .hero-aura,
html[data-theme="light"] .hero-dunes { display: none; }

/* Hardcoded dark surfaces — flip per theme (the base .nav is the deep-green brand glass) */
html[data-theme="light"] .nav {
  background: rgba(255,255,255,0.78);
  /* Neutral, not gold-tinted: a gold shadow on white reads as a stain. */
  box-shadow: 0 20px 50px -20px rgba(0,0,0,0.16), 0 1px 0 rgba(255,255,255,0.6) inset;
}
/* Desert dunes: warm-brown glass, not the green nav (matches --bg #1F140A) */
html[data-theme="default"] .nav {
  background: rgba(31,20,10,0.78);
  box-shadow: 0 20px 50px -20px rgba(0,0,0,0.6), 0 1px 0 rgba(230,184,77,0.05) inset;
}
/* The phone nav panel is OPAQUE on all three themes. It used to carry
   `rgba(255,255,255,0.92)` here, copied from the .nav glass three rules up --
   but .nav is a 64px strip with a backdrop-filter behind it, and this is a
   432px panel with none. Eight percent of a full-height pricing card read
   straight through it: on /courses the words Home / Course / Kids / E-books
   sat on top of a legible "AED 1,999", the whole feature checklist and the
   six-book cover fan at once. Nothing here fails a contrast ratio -- the panel
   still measures clean, which is exactly why the sweep only caught it once the
   auditor started reporting occlusion -- it is simply unreadable as a menu.
   The base rule's --bg-2 -> --bg gradient is #F4F4F5 -> #FFFFFF on this theme,
   which is the same soft top-to-bottom lift dark and desert already get, so
   there is nothing to replace it with. */
/* Neutral washes. A gold film over white is the exact "gold-on-cream" muddiness
   this theme exists to avoid, and it was still here on every hover. */
html[data-theme="light"] .nav-link:hover,
html[data-theme="light"] .nav-mute:hover,
html[data-theme="light"] .theme-toggle:hover { background: rgba(0,0,0,0.05); }
html[data-theme="light"] .btn-ghost { background: rgba(0,0,0,0.04); }
html[data-theme="light"] .btn-ghost:hover { background: rgba(0,0,0,0.07); }

/* Theme toggle stays visible at all widths — overrides the .nav-cta mobile hide rule */
@media (max-width: 820px) {
  .nav .theme-toggle.nav-cta { display: inline-flex; }
}

/* Light-mode legibility patches — readability fixes Ali flagged on first preview */

/* .btn-primary used to be in this rule taking `color: #FAF5E8`, cream on a
   gradient whose top stop it measured 2.35 against. It then briefly carried a
   light-only narrowed gradient, because with the OLD light fill stops
   (#C99A3F -> #A87B2E -> #7E5A18) no single ink worked end to end: near-black
   ran 7.41 down to 3.03, cream ran 2.35 up to 5.74.

   Both patches are gone because the cause is gone. The light fill stops are now
   11.94 / 9.22 / 6.27 against near-black, so the BASE rule's full-range
   --gold-2 -> --gold-deep gradient clears AA along its whole height and the
   button gets its depth back instead of being flattened to keep it legible.

   What light still needs is an EDGE. A bright gold is only ~2.0:1 against a
   white page, and the base box-shadow is a gold halo -- invisible on white, it
   was only ever doing work on the dark themes. This replaces it with a real
   shadow plus a hairline of the gradient's own bottom stop, so the pill has a
   defined boundary without a bevel. Measured 2026-08-02. */
html[data-theme="light"] .btn-primary {
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.06),
    0 10px 24px -12px rgba(120, 84, 20, 0.55),
    0 0 0 1px rgba(120, 84, 20, 0.22) inset;
}
html[data-theme="light"] .btn-primary:hover {
  box-shadow:
    0 2px 4px rgba(0, 0, 0, 0.07),
    0 18px 34px -14px rgba(120, 84, 20, 0.6),
    0 0 0 1px rgba(120, 84, 20, 0.22) inset;
}
html[data-theme="light"] .btn-primary:active {
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.06),
    0 6px 14px -10px rgba(120, 84, 20, 0.5),
    0 0 0 1px rgba(120, 84, 20, 0.22) inset;
}
/* Dead as of 2026-08-02: `.tier-cta` appears in no HTML and no JS on the site.
   Left in place rather than deleted with the rest of this pass, but do not
   build on it. `.tier-gold .tier-cta` (styles.css, near the tier block) is a
   different component -- a near-black button with gold text. */
html[data-theme="light"] .tier-cta { color: #FAF5E8; }

/* Tracing card — the canvas pad needs a light surface, not the dark rgba(0,0,0,0.2) overlay */
html[data-theme="light"] .trace-demo .trace-letter-pad {
  background:
    linear-gradient(rgba(184,136,56,0.10) 1px, transparent 1px) 0 0 / 25% 25%,
    linear-gradient(90deg, rgba(184,136,56,0.10) 1px, transparent 1px) 0 0 / 25% 25%,
    rgba(184,136,56,0.05);
}
html[data-theme="light"] .trace-letter { color: rgba(140, 100, 41, 0.32); }

/* Demo cards / orbit cards / tier cards — white + the active personality's card elevation */
html[data-theme="light"] .demo-card,
html[data-theme="light"] .orbit-card,
html[data-theme="light"] .tier {
  background: var(--surface);
  border-color: var(--card-border);
  box-shadow: var(--shadow-card);
}

/* Demo inner panels — clean WHITE surface + real shadow (grey tint was unreadable) */
html[data-theme="light"] .lesson-body,
html[data-theme="light"] .chat-input,
html[data-theme="light"] .pron-demo .pron-stage {
  background: var(--surface);
  border: 1px solid var(--card-border);
  box-shadow: var(--shadow-card);
}

/* Flatten the gold atmospheric washes on white (homepage / storefront) — keep them for dark + brown */
html[data-theme="light"] .hero-halo { display: none; }
html[data-theme="light"] .journey::before { background: none; }
html[data-theme="light"] .map-bg { background-image: none; }
html[data-theme="light"] .gold-section,
html[data-theme="light"] .finale-card,
html[data-theme="light"] .legal-page { background: var(--bg); }

/* ============================================================
   LIGHT THEME · storefront contrast pass (Ali, 2026-06-26)
   On white, grey fills (--chip-bg/--surface-2) read muddy, gold prices/
   labels wash out, dark-on-gold text loses contrast on the darker light-gold
   (#A87B2E), and thin checks/crosses vanish. Fix: white surfaces + shadow,
   black prices, cream ink on gold, bold high-contrast marks.
   ============================================================ */

/* Pricing cards → clean white + shadow (kills the grey gradient + gold haze
   that made the "best for most learners" feature card text faint) */
html[data-theme="light"] .pv-card,
html[data-theme="light"] .pv-card.feat {
  background: var(--surface);
  box-shadow: var(--shadow-card);
}

/* Prices → black, not gold (override the feat card's gold gradient text too) */
html[data-theme="light"] .pv-price .now,
html[data-theme="light"] .pv-card.feat .pv-price .now {
  color: var(--cream);
  background: none;
  -webkit-text-fill-color: var(--cream);
}

/* Carousel pills + arrows → white + pill shadow + a real ring, never grey
   (shadow follows the active personality). The Personal/Business toggle track
   used to be in this list; the toggle was deleted 2026-08-02. */
html[data-theme="light"] .cn-show-tab:not(.is-on),
html[data-theme="light"] .cn-show-arrow {
  background: var(--surface);
  border-color: var(--card-border);
  box-shadow: var(--shadow-pill);
}

/* This rule used to force cream #FAF5E8 onto six gold surfaces in light, under
   the header "dark text is unreadable on #A87B2E". That is measurably
   backwards. On the two golds these surfaces are actually filled with, cream
   measures 3.48 (#A87B2E) and 2.36 (#C99A3F); near-black --on-gold measures
   5.00 and 7.41. Cream only works on --gold-deep (5.74), which none of them
   use. Every one of the six was under AA, three of them badly.

   Measured on the storefront and the homepage at 390px, 2026-08-02:
   .pv-ribbon 2.36, .cn-show-tab.is-on 2.36, .chat-send 3.48. The remaining
   three (.lesson-check-btn, .trace-check, .billing-btn.active) live inside the
   course app and the tracing pad, which this sweep could not reach signed out;
   they are given the same ink because they take the same fill from the same
   tokens, and leaving them cream would mean knowingly shipping the one value
   already disproved on their three siblings. Re-measure them in the app.

   .btn-primary was in this family too and is corrected separately above: its
   fill is a gradient wide enough that no single ink works end to end, so the
   gradient was narrowed instead. */
html[data-theme="light"] .lesson-check-btn,
html[data-theme="light"] .chat-send,
html[data-theme="light"] .trace-check,
html[data-theme="light"] .cn-show-tab.is-on,
html[data-theme="light"] .billing-btn.active,
html[data-theme="light"] .pv-ribbon { color: var(--on-gold); }

/* ---- Gilded text: a gold gradient clipped to the glyphs ----------------
   A background clipped to text IS the ink, so the gradient has to clear a text
   contrast bar along its whole length, not just at one stop. On the two dark
   themes it does easily -- pixel-sampled on the homepage hero in dark,
   2026-08-02: ground #1C241C to #242B20, stops measuring 10.03, 7.90 and 4.63
   top to bottom.

   Light is the problem, and now more so than before: the fill stops there are
   deliberately bright (2.05 and 1.58 on white) because they have to look like
   gold buttons. Clipped to text on a white page they would be a pale smear.

   Rather than rewrite fourteen gradient declarations spread over nine files --
   each with its own angle and stop structure -- this re-points the three fill
   tokens to the three ink values ON THE CLIPPED ELEMENT ITSELF. Every existing
   `linear-gradient(..., var(--gold-2), var(--gold-deep))` keeps working
   verbatim and simply resolves to readable ink here. Adding a new gilded
   heading means adding its selector to this list and nothing else.

   The values are LITERALS on purpose, not var(--gold-ink...). On the dark
   themes --gold-ink is declared as var(--gold), so writing --gold: var(--gold-ink)
   would be a custom-property cycle: both sides go invalid, the gradient
   declaration drops, and with -webkit-text-fill-color: transparent still in
   force the heading renders as nothing at all. Literals cannot do that. This
   rule is scoped to light for the same reason.

   Ordering matches the dark themes' lightness order, so gradients written
   --gold-2 -> --gold -> --gold-deep still run light-to-dark:
     --gold-2    #B8801A  3.42 on white
     --gold      #A87400  4.07
     --gold-deep #96650A  5.04

   These are BRIGHTER than the ink tokens on purpose. Every element in the list
   below was measured on 2026-08-02 and is 24-58px, all of it bold: 35.2px for
   the section headings, 37.6px for the hero, 24px for the checkout price. That
   is large text, where the bar is 3:1 rather than 4.5, and the top stop clears
   it by 14 percent. Pinning these to the 4.5-calibrated ink values instead
   would be needlessly dark -- that is what made the light theme's headings read
   brown rather than gold.

   The bar is 3:1 ONLY because of those sizes. Anything added to this list has
   to be re-measured; a gilded heading that turns out to be 14px needs the ink
   tokens, not these. The compare table's "Lsany" is exactly that case: 14px
   bold, so it stays on --gold-ink at 5.04 and is deliberately not here. */
html[data-theme="light"] .hero-title .gold,
html[data-theme="light"] .section-title .gold,
html[data-theme="light"] .is-mastered .ti,
html[data-theme="light"] .m-letters .ml-glyph,
html[data-theme="light"] .price-now,
html[data-theme="light"] .pv-card.feat .pv-price .now,
html[data-theme="light"] .ach-hero h1 .gold,
html[data-theme="light"] .cert-title .gold,
html[data-theme="light"] .lb-hero h1 .gold,
html[data-theme="light"] .wd-title,
html[data-theme="light"] .sd-title,
html[data-theme="light"] .wm-title,
html[data-theme="light"] .ga-title {
  --gold-2: #B8801A;
  --gold: #A87400;
  --gold-deep: #96650A;
}
/* .scroll-gold is the same job done a different way: a horizontal wipe whose
   gilded half is a flat var(--gold-ink) rather than a vertical gradient. Same
   sizes (35.2px bold, measured), so the same 3:1 bar and the same brighter
   gold. Overriding --gold-ink here rather than globally because --gold-ink also
   inks 12-16px body text, which needs the 4.5 value. */
html[data-theme="light"] .scroll-gold { --gold-ink: #B8801A; }
/* segmented-control inactive label → readable dark on the now-white track
   (its base color is hardcoded light cream, invisible on white) */
html[data-theme="light"] .billing-btn { color: var(--secondary); }
/* keep the gold-tier's inverted dark badge — don't let the grey-kill whiten it */
html[data-theme="light"] .tier-gold .tier-label { background: #1A0F00; border-color: transparent; box-shadow: none; }

/* "Lsany vs the usual way" — bold, full-contrast checks + crosses */
html[data-theme="light"] .cn-vs { background: var(--surface); }
html[data-theme="light"] .cn-vs .vs-ic-no { color: var(--coral-ink); opacity: 1; }
html[data-theme="light"] .cn-vs .vs-ic svg { stroke-width: 3.4; }

/* cn-trust green-circle checkmarks → white check (was near-black, invisible on green) */
html[data-theme="light"] .cn-trust li::before {
  background: var(--green) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center/10px no-repeat;
}

/* ============================================================
   LIGHT THEME · kill ALL grey, site-wide (Ali: "grey is shit on white";
   shadows = modern). Every pill / chip / row that used a grey fill
   (--chip-bg / --track-bg / dark translucent) → white + hairline ring + a
   subtle elevation, all driven by the active personality's tokens so the
   Elevation toggle restyles them consistently. Colored BEM variants
   (.hud-chip--live/--new/--rank, .pill.live/.lvl) are left untouched. 2026-06-26
   ============================================================ */
html[data-theme="light"] .tier-label,
html[data-theme="light"] .billing-toggle,
html[data-theme="light"] .pill.soon,
html[data-theme="light"] .unit-prog,
html[data-theme="light"] .cf-tools span,
html[data-theme="light"] .hud-chip:not(.hud-chip--live):not(.hud-chip--new):not(.hud-chip--rank),
html[data-theme="light"] .combo-banner,
html[data-theme="light"] .cn-book-price,
html[data-theme="light"] .cn-work-chips li,
html[data-theme="light"] .stat,
html[data-theme="light"] .build-answer,
html[data-theme="light"] .grammar-ex .row,
html[data-theme="light"] .load-fail,
html[data-theme="light"] .kit-fq {
  background: var(--surface);
  border: 1px solid var(--card-border);
  box-shadow: var(--shadow-pill);
}

/* Hover lift — interactive pills gently rise for a modern, tactile feel; the
   pricing card keeps its loved lift but on the active personality's deeper
   shadow. Gated on real hover + motion-allowed. (Never the loved Library /
   journey-lesson hovers — those are untouched.) */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  html[data-theme="light"] .cn-show-tab:not(.is-on),
  html[data-theme="light"] .pill.soon,
  html[data-theme="light"] .hud-chip:not(.hud-chip--live):not(.hud-chip--new):not(.hud-chip--rank) {
    transition: transform .18s var(--ease-pop), box-shadow .18s var(--ease-pop), color .2s, border-color .16s, background .16s;
  }
  html[data-theme="light"] .cn-show-tab:not(.is-on):hover,
  html[data-theme="light"] .pill.soon:hover,
  html[data-theme="light"] .hud-chip:not(.hud-chip--live):not(.hud-chip--new):not(.hud-chip--rank):hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow-card);
  }
  html[data-theme="light"] .pv-card:hover { box-shadow: var(--shadow-card-hover); }
}

/* Hero stat labels — bump to near-body-text color so they're truly readable, not ghosted */
html[data-theme="light"] .hero-stat-label { color: var(--cream-muted); font-weight: 600; }

/* Smooth theme transition + premium press feedback baseline.
   transform is added to the curve so the snappy press scale eases (research:
   the leaders transition transform broadly on one easeOut). */
html, body, .btn, .nav, .nav-link, .theme-toggle, .nav-mute {
  transition: background-color .35s ease, color .25s ease, border-color .25s ease, transform .16s var(--ease-pop);
}
@media (prefers-reduced-motion: no-preference) {
  .btn:active { transform: scale(.96); }
}

/* Theme toggle button — mirrors .nav-mute so the icon cluster looks unified */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: auto; min-width: 36px; height: 36px;
  padding: 0 9px;
  background: transparent;
  border: 1px solid var(--stroke);
  border-radius: 999px;
  color: var(--secondary);
  cursor: pointer;
  transition: color .2s, background .2s, border-color .2s;
}
.theme-toggle:hover { color: var(--cream); background: rgba(250,245,232,0.04); border-color: var(--stroke-strong); }
/* three themes, three icons: moon = dark green, sand = desert dunes (default), sun = white/light */
.theme-toggle-moon, .theme-toggle-sun, .theme-toggle-sand { display: none; }
html[data-theme="dark"] .theme-toggle-moon { display: block; }
html[data-theme="default"] .theme-toggle-sand { display: block; }
html[data-theme="light"] .theme-toggle-sun { display: block; }
html[data-theme="light"] .theme-toggle:hover { background: rgba(156,111,38,0.10); }

/* ===== Theme picker — caret affordance + popover menu (all 3 themes, labeled) ===== */
.theme-toggle-caret { opacity: .6; transition: transform .2s var(--ease-pop), opacity .2s; }
.theme-toggle:hover .theme-toggle-caret { opacity: 1; }
.theme-toggle[aria-expanded="true"] .theme-toggle-caret { transform: rotate(180deg); }

.tp-wrap { position: relative; display: inline-flex; }
.tp-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 200;
  min-width: 178px;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--stroke-strong);
  border-radius: 14px;
  box-shadow: var(--shadow-card, 0 18px 44px -16px rgba(0,0,0,0.55), 0 2px 8px -3px rgba(0,0,0,0.4));
  opacity: 0;
  transform: translateY(-6px) scale(.97);
  transform-origin: top right;
  pointer-events: none;
  transition: opacity .16s var(--ease-smooth), transform .18s var(--ease-pop);
}
.tp-menu.is-open { opacity: 1; transform: none; pointer-events: auto; }
.tp-head {
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 4px 10px 7px;
}
.tp-opt {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 9px 10px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--cream);
  font-family: var(--f-body);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s var(--ease-smooth);
}
.tp-opt:hover { background: var(--chip-bg); }
.tp-opt:focus-visible { outline: 2px solid var(--gold-ink); outline-offset: -2px; }
.tp-sw {
  flex: none;
  width: 18px; height: 18px;
  border-radius: 999px;
}
.tp-sw--dark   { background: #0B1917; box-shadow: inset 0 0 0 2px #E6B861, 0 0 0 1px var(--stroke-strong); }
/* #C08B2C, the light theme's own deep fill stop, not its bright one. This ring
   is a UI component boundary on white, so the bar is WCAG 1.4.11's 3:1 rather
   than a text bar: the bright stop is 2.05 and would leave the swatch looking
   like a plain white circle, the deep stop is 3.01 and clears it. The other two
   swatches carry their theme's --gold literally because they sit on near-black
   and have contrast to spare. */
.tp-sw--light  { background: #FFFFFF; box-shadow: inset 0 0 0 2px #C08B2C, 0 0 0 1px var(--stroke-strong); }
.tp-sw--desert { background: #1F140A; box-shadow: inset 0 0 0 2px #E6B84D, 0 0 0 1px var(--stroke-strong); }
.tp-name { flex: 1; text-align: left; }
.tp-check { flex: none; color: var(--gold-ink); opacity: 0; transition: opacity .15s; }
html[data-theme="dark"]    .tp-opt[data-theme-id="dark"]    .tp-check,
html[data-theme="light"]   .tp-opt[data-theme-id="light"]   .tp-check,
html[data-theme="default"] .tp-opt[data-theme-id="default"] .tp-check { opacity: 1; }
html[data-theme="light"] .tp-opt:hover { background: rgba(0,0,0,0.05); }

/* ===== Flip vocab cards — the "Flashcards" demo (tap/hover to reveal) ===== */
.flip-demo { padding: 20px; }
.flip-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.flip-card {
  appearance: none; -webkit-appearance: none;
  border: 0; margin: 0; padding: 0;
  background: transparent; cursor: pointer;
  perspective: 1000px; min-height: 156px; border-radius: 16px;
}
.flip-card:focus-visible { outline: 2px solid var(--gold-ink); outline-offset: 3px; }
.flip-inner {
  position: relative; display: block; width: 100%; height: 100%; min-height: inherit;
  transform-style: preserve-3d;
  transition: transform .55s var(--ease-pop);
}
.flip-card.is-flipped .flip-inner { transform: rotateY(180deg); }
@media (hover: hover) and (pointer: fine) {
  .flip-card:hover:not(.is-flipped) .flip-inner { transform: rotateY(180deg); }
}
.flip-face {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; padding: 14px;
  border-radius: 16px; border: 1px solid var(--stroke-strong);
  background: var(--surface);
  box-shadow: var(--shadow-card, 0 14px 30px -18px rgba(0,0,0,0.45));
  -webkit-backface-visibility: hidden; backface-visibility: hidden;
}
.flip-back { transform: rotateY(180deg); background: var(--surface-2); }
.flip-ar { font-family: var(--f-arabic); font-size: 36px; line-height: 1; color: var(--cream); }
.flip-hint { font-family: var(--f-mono); font-size: 9px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.flip-tr { font-family: var(--f-body); font-weight: 700; font-size: 19px; color: var(--gold-ink); }
.flip-en { font-family: var(--f-body); font-size: 13px; color: var(--cream-muted); }
@media (max-width: 520px) { .flip-ar { font-size: 30px; } .flip-card { min-height: 140px; } }

/* ===== Watch it written — ghost-pen draws the real Montserrat-Arabic letterform ===== */
.trace-letter-pad[data-watch-write] { position: relative; }
.ww-svg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; z-index: 4; overflow: visible;
}
.ww-ink {
  fill: none;
  stroke: var(--gold);
  stroke-width: 24;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 2px 6px var(--gold-glow));
}
/* faint guide = the EXACT same outline the pen traces, so the letter you see
   and the letter being written are pixel-identical (no ghosting/size drift) */
.ww-guide { fill: var(--gold); fill-opacity: 0.15; stroke: none; }
.ww-pen { fill: var(--gold-2); stroke: #1A0F00; stroke-width: 4; }
.ww-svg.is-done .ww-ink { fill: var(--gold); fill-opacity: 0.16; transition: fill-opacity .4s ease; }
.ww-btn {
  font-family: var(--f-body); font-weight: 700; font-size: 13px;
  color: var(--gold-ink); background: transparent;
  border: 1px solid var(--stroke-strong); border-radius: 999px;
  padding: 8px 14px; cursor: pointer;
  transition: background .18s var(--ease-pop), color .18s var(--ease-pop), border-color .18s var(--ease-pop), transform .16s var(--ease-pop);
}
.ww-btn:hover { background: var(--gold); color: #1A0F00; border-color: var(--gold); }
.ww-btn:active { transform: scale(.96); }

/* Mid-page Start Journey button container — between hero stats and divider-ornate */
.hero-bridge {
  display: flex;
  justify-content: center;
  padding: 8px 28px 0;
  position: relative;
  z-index: 2;
}

/* In-flow waitlist CTA — fills empty gaps between sections so scrollers get touchpoints */
.cta-bridge {
  display: flex;
  justify-content: center;
  padding: 8px 28px 48px;
  position: relative;
  z-index: 2;
}
.cta-bridge .btn { font-weight: 700; }
@media (max-width: 820px) { .cta-bridge { padding: 30px 20px 32px; } }
/* Collapse the host section's bottom padding when a CTA bridge sits directly after it,
   so the cumulative "section pad-bottom + bridge pad-top" doesn't leave a giant dead zone. */
.journey:has(+ .cta-bridge),
.gold-section:has(+ .cta-bridge) { padding-bottom: 16px; }

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

/* Form-control reset.
   Chrome's default <button> border is `2px outset` -- a hard bevel, which is
   the one look this product has a standing rule against -- and its default font
   is Arial, not the page font. Both only appear when a control's own CSS never
   names them, which happens whenever a class written for an <a> is later put on
   a <button>. That has now happened three times on the account page alone:
   #ac-export (Export), #ac-delete (Delete account) and #ac-confirm-cancel
   (Keep my account, sitting beside a fully styled red Delete forever, so the
   safe choice was the one that looked unfinished).

   Fixing each site is treating the symptom. An element selector is specificity
   0,0,1, so every authored `.thing { border: ... }` and every `font-family`
   already beats this; it can only reach controls that named neither, which is
   exactly the bug set and nothing else. A site-wide scan of 25 pages found the
   three above and no control that wanted a UA bevel.

   `font: inherit` is deliberately not used -- it would also reset font-size and
   weight, which several controls do rely on inheriting from a shorthand
   elsewhere. Family only. Added 2026-08-03. */
button, input, select, textarea, optgroup {
  font-family: inherit;
}
button { border: 0; }
html {
  background: var(--bg);
  color: var(--cream);
  font-family: var(--f-body);
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  scroll-behavior: smooth;
}
body {
  background:
    radial-gradient(ellipse 100% 60% at 50% 0%, rgba(230,184,97,0.08) 0%, transparent 60%),
    radial-gradient(ellipse 80% 50% at 50% 100%, rgba(77,191,142,0.05) 0%, transparent 60%),
    var(--bg);
  min-height: 100vh;
  overflow-x: hidden;
  line-height: 1.55;
}

/* Placeholder ink, site-wide default.

   Nineteen separate rules across the site already say exactly this, one per
   form, which meant the twentieth form shipped without one: the support page's
   subject and message fields were painting Chrome's UA default #757575 on all
   three themes and measured 3.59 / 4.19 / 3.61 where 16px needs 4.5. Nobody
   had looked, because placeholder text lives in an attribute and in a pseudo,
   so a contrast sweep that walks text nodes cannot see it at all -- af.js only
   started measuring them on 2026-08-02 and found this on the first form it hit.

   A bare-element selector is the weakest thing that can carry a default, so
   every existing per-form rule still wins on specificity and nothing moves:
   the kids fields keep --k-dim, the newsletter keeps its own literal, the
   coming-soon form keeps --cs-field-placeholder, and the library's note field
   keeps --secondary. This exists so the NEXT form is right before anyone
   remembers to think about it. */
input::placeholder,
textarea::placeholder { color: var(--muted); opacity: 1; }

/* Scrollbar */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--surface); border-radius: 10px; }
::-webkit-scrollbar-thumb:hover { background: var(--gold-deep); }

/* Utilities */
.wrap { max-width: 1200px; margin: 0 auto; padding: 0 28px; }
.wrap-narrow { max-width: 960px; margin: 0 auto; padding: 0 28px; }
.arabic { font-family: var(--f-arabic); direction: rtl; }
.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; }

/* Section labels — plain text, no pill */
.eyebrow {
  display: inline-block;
  font-family: var(--f-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-ink);
  margin-bottom: 6px;
}

/* Pill button */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 24px;
  border-radius: 999px;
  font-family: var(--f-body);
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -0.01em;
  cursor: pointer;
  border: none;
  text-decoration: none;
  transition: transform .25s var(--ease-bounce), box-shadow .2s ease;
  position: relative;
  white-space: nowrap;
}
.btn:hover, .btn:focus, .btn:focus-visible, .btn:active { text-decoration: none; }
/* keyboard focus reads as clearly as hover does */
.btn:focus-visible, .nav-link:focus-visible, .nav-brand:focus-visible { outline: 2px solid var(--gold-ink); outline-offset: 3px; }
/* footer legal links carry inline muted colors (homepage + storefront), so the
   hover needs !important to win over the style attribute */
.footer-legal a:hover, .cn-footer nav a:hover { color: var(--cream) !important; }
.footer-legal a:focus-visible, .cn-footer nav a:focus-visible { outline: 2px solid var(--gold-ink); outline-offset: 2px; border-radius: 4px; }
/* Homepage footer tap targets. The eight legal links measured 31-49 x 20 and
   the Instagram link 132x21, all under the 24x24 WCAG 2.5.8 asks at AA -- the
   same defect as the storefront's <nav aria-label="Legal"> and the marketing
   .site-footer-links, now closed in all three places. Padding only, so the type
   and the row spacing are untouched. This one is live today. 2026-08-03. */
.footer-legal a, .footer-ig {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 2px 6px;
  margin: 0 -6px;
}
/* No bevel. This carried the full three-part skeuomorphic recipe — a hard white
   inset line along the top, a dark inset line along the bottom and a solid
   0 2px 0 lip underneath — which is the "raised plastic button" look Ali has
   banned outright. What reads premium here is the gold itself and the glow it
   throws, so the surface is a clean two-stop gradient and the only shadow is
   that glow. The lift on hover and the settle on press still give the press
   its feedback; they just do it with movement instead of a moulded edge. */
.btn-primary {
  background: linear-gradient(180deg, var(--gold-2) 0%, var(--gold-deep) 100%);
  color: #1A0F00;
  box-shadow: 0 10px 30px -8px rgba(230,184,97,0.5);
}
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 16px 40px -8px rgba(230,184,97,0.65); }
.btn-primary:active { transform: translateY(0); box-shadow: 0 6px 16px -8px rgba(230,184,97,0.42); }
.btn-ghost {
  background: rgba(250,245,232,0.04);
  color: var(--cream);
  border: 1px solid var(--stroke);
  backdrop-filter: blur(10px);
}
.btn-ghost:hover { background: rgba(250,245,232,0.08); border-color: var(--stroke-strong); }

/* =========================================================
   NAVBAR
   ========================================================= */
.nav {
  position: fixed;
  top: var(--nav-top, 14px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 8px 8px 20px;
  background: rgba(11,25,23,0.72);
  backdrop-filter: blur(20px) saturate(1.4);
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  border: 1px solid var(--stroke);
  border-radius: 999px;
  box-shadow: 0 20px 50px -20px rgba(0,0,0,0.6), 0 1px 0 rgba(255,255,255,0.03) inset;
  transition: top .3s var(--ease-smooth);
}
.nav-brand {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.02em;
  color: var(--cream);
  text-decoration: none;
}
.nav-brand .ar { color: var(--gold-ink); font-family: var(--f-arabic); font-size: 19px; font-weight: 700; }
.nav-links { display: flex; gap: 4px; padding: 0 8px; }
.nav-link {
  color: var(--secondary);
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 500;
  padding: 8px 14px;
  border-radius: 999px;
  transition: color .2s, background .2s;
}
.nav-link:hover { color: var(--cream); background: rgba(250,245,232,0.04); }
.nav-link.gold { color: var(--gold-ink); }
.nav-link.gold:hover { background: rgba(230,184,97,0.1); }

.nav-mute {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  margin-right: 4px;
  background: transparent;
  border: 1px solid var(--stroke);
  border-radius: 999px;
  color: var(--secondary);
  cursor: pointer;
  transition: color .2s, background .2s, border-color .2s;
}
.nav-mute:hover { color: var(--cream); background: rgba(250,245,232,0.04); border-color: var(--stroke-strong); }
.nav-mute .nav-mute-off { display: none; }
.nav-mute.is-muted .nav-mute-on { display: none; }
.nav-mute.is-muted .nav-mute-off { display: inline; color: var(--muted); }

.nav-xp {
  display: flex; align-items: center; gap: 6px;
  padding: 7px 14px 7px 10px;
  background: rgba(230,184,97,0.1);
  border: 1px solid var(--stroke-strong);
  border-radius: 999px;
  font-family: var(--f-mono);
  font-size: 12px;
  font-weight: 600;
  color: var(--gold-ink);
}
.nav-xp svg { filter: drop-shadow(0 0 4px var(--gold-glow)); }

.nav .btn { padding: 10px 18px; font-size: 13.5px; }

@media (max-width: 820px) {
  .nav {
    left: 12px; right: 12px; transform: none;
    padding: 8px 8px 8px 16px;
    justify-content: space-between;
    gap: 12px;
  }
  .nav-links { display: none; }
  .nav-xp { display: none; }
  .nav-mute { margin-left: auto; }
  .nav-burger { margin-left: 4px; }
}

/* =========================================================
   HERO
   ========================================================= */
.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  overflow: hidden;
  padding: 120px 0 60px;
}
.hero-stars {
  position: absolute; inset: 0;
  background-image:
    radial-gradient(1px 1px at 20% 30%, rgba(230,184,97,0.6), transparent),
    radial-gradient(1px 1px at 80% 20%, rgba(255,255,255,0.4), transparent),
    radial-gradient(1.5px 1.5px at 40% 70%, rgba(230,184,97,0.4), transparent),
    radial-gradient(1px 1px at 70% 60%, rgba(255,255,255,0.3), transparent),
    radial-gradient(1px 1px at 15% 85%, rgba(230,184,97,0.5), transparent),
    radial-gradient(1.5px 1.5px at 90% 80%, rgba(255,255,255,0.3), transparent),
    radial-gradient(1px 1px at 55% 15%, rgba(230,184,97,0.4), transparent);
  animation: twinkle 8s ease-in-out infinite;
}
@keyframes twinkle { 0%,100%{opacity:0.7} 50%{opacity:1} }

.hero-aura {
  position: absolute;
  top: -8%; left: 50%; transform: translateX(-50%);
  width: 1200px; height: 880px;
  /* a whisper of warmth, static — no pulsing blob (that read cheap) */
  background: radial-gradient(closest-side, rgba(230,184,97,0.06) 0%, transparent 68%);
  pointer-events: none;
}

.hero-dunes {
  position: absolute; bottom: 0; left: 0; right: 0;
  height: 420px;
  pointer-events: none;
  opacity: 0.38;
  background: radial-gradient(ellipse 110% 90% at 50% 40%, rgba(230,184,97,0.06) 0%, transparent 72%);
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 25%, #000 60%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 25%, #000 60%, transparent 100%);
}

.hero-grid {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 1.2fr 0.8fr;
  gap: 40px;
  align-items: center;
}
@media (max-width: 960px) {
  .hero-grid { grid-template-columns: 1fr; gap: 20px; text-align: center; }
}

.hero-title {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: clamp(2.35rem, 5.1vw, 3.9rem);
  line-height: 1.05;
  letter-spacing: -0.035em;
  color: var(--cream);
  margin: 10px 0 20px;
}
.hero-title .gold {
  background: linear-gradient(180deg, var(--gold-2) 0%, var(--gold) 60%, var(--gold-deep) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  display: inline-block;
  position: relative;
}
.hero-title .gold::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -8px;
  height: 3px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  opacity: 0.6;
}
.hero-title .wiggle {
  display: inline-block;
  animation: wiggle 4s ease-in-out infinite;
  transform-origin: bottom center;
}
@keyframes wiggle { 0%,100%{transform:rotate(0)} 25%{transform:rotate(-3deg)} 75%{transform:rotate(3deg)} }

.hero-sub {
  font-size: 18px;
  line-height: 1.55;
  color: var(--cream-muted);
  max-width: 520px;
  margin: 0 0 32px;
  font-weight: 400;
}
@media (max-width: 960px) { .hero-sub { margin: 0 auto 32px; } }

.hero-ctas { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
.hero-ctas .btn { min-width: 240px; justify-content: center; }
@media (max-width: 960px) { .hero-ctas { align-items: center; } }

.hero-stats {
  display: flex; gap: 28px;
  margin-top: 48px;
  padding-top: 32px;
  border-top: 1px solid var(--stroke);
}
.hero-stat-num {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 28px;
  color: var(--gold-ink);
  letter-spacing: -0.03em;
}
.hero-stat-label {
  font-size: 12px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  margin-top: 2px;
}
@media (max-width: 960px) { .hero-stats { justify-content: center; } }

/* Hero right-side: Saqr + floating flashcard */
.hero-stage {
  position: relative;
  height: 560px;
  display: flex;
  align-items: center;
  justify-content: center;
}
@media (max-width: 960px) { .hero-stage { height: 420px; } }

.hero-saqr {
  position: relative;
  width: min(320px, 80%);
  height: auto;
  z-index: 3;
  filter: drop-shadow(0 30px 50px rgba(0,0,0,0.5)) drop-shadow(0 0 80px rgba(230,184,97,0.25));
  animation: float 5s ease-in-out infinite;
}
@keyframes float { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-14px)} }

.hero-halo {
  position: absolute;
  top: 50%; left: 50%;
  width: 500px; height: 500px;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, rgba(230,184,97,0.22) 0%, rgba(230,184,97,0.08) 40%, transparent 70%);
  border-radius: 50%;
  animation: halo 6s ease-in-out infinite;
  pointer-events: none;
}
@keyframes halo { 0%,100%{transform:translate(-50%,-50%) scale(1); opacity:.8} 50%{transform:translate(-50%,-50%) scale(1.15); opacity:1} }

/* Floating flashcards orbiting Saqr */
.orbit-card {
  position: absolute;
  padding: 12px 18px;
  background: linear-gradient(180deg, var(--card-top, var(--surface-2)) 0%, var(--surface) 100%);
  border: 1px solid var(--stroke-strong);
  border-radius: 14px;
  box-shadow: 0 16px 30px -10px rgba(0,0,0,0.6), 0 1px 0 rgba(255,255,255,0.04) inset;
  z-index: 4;
  /* entrance uses the independent translate/scale props so it composes cleanly
     with the perpetual float (which animates `transform`). They deal in, staggered,
     then breathe together as a calm constellation. */
  opacity: 0; translate: 0 24px; scale: .92;
  animation: orbit-float 8s ease-in-out infinite, orbit-in .8s var(--ease-smooth) both;
}
.orbit-card .ar {
  font-family: var(--f-arabic-hero);
  direction: rtl;
  color: var(--gold-ink);
  font-size: 22px;
  font-weight: 700;
  line-height: 1;
  display: block;
}
.orbit-card .tr {
  font-family: var(--f-mono);
  color: var(--green);
  font-size: 12px;
  font-weight: 500;
  margin-top: 4px;
  display: block;
}
.orbit-card .en {
  color: var(--cream-muted);
  font-size: 11px;
  margin-top: 2px;
  display: block;
}
/* delay list = [float, entrance]: floats run near-unison (gentle drift, calm),
   entrances stagger so the cards deal in one-by-one */
.orbit-card.card-1 { top: 12%; left: -6%; animation-delay: 0s, .12s; transform: rotate(-6deg); }
.orbit-card.card-2 { top: 20%; right: -4%; animation-delay: -1.2s, .26s; transform: rotate(5deg); }
.orbit-card.card-3 { bottom: 18%; left: 2%; animation-delay: -.6s, .40s; transform: rotate(-3deg); }
.orbit-card.card-4 { bottom: 8%; right: 4%; animation-delay: -1.8s, .54s; transform: rotate(7deg); }

@keyframes orbit-float {
  0%,100% { transform: translateY(0) rotate(var(--r, 0deg)); }
  50% { transform: translateY(-9px) rotate(var(--r, 0deg)); }
}
@keyframes orbit-in {
  to { opacity: 1; translate: 0 0; scale: 1; }
}
.orbit-card.card-1 { --r: -6deg; }
.orbit-card.card-2 { --r: 5deg; }
.orbit-card.card-3 { --r: -3deg; }
.orbit-card.card-4 { --r: 7deg; }

/* =========================================================
   SECTION SCAFFOLD
   ========================================================= */
section { position: relative; }
.section-head { text-align: center; margin-bottom: 48px; }
.section-title {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: clamp(2.2rem, 4.8vw, 3.6rem);
  letter-spacing: -0.04em;
  line-height: 1.02;
  color: var(--cream);
  margin: 16px 0 12px;
}
.section-title .gold {
  background: linear-gradient(180deg, var(--gold-2), var(--gold-deep));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.section-sub {
  font-size: 18px; color: var(--cream-muted);
  max-width: 640px; margin: 0 auto;
  line-height: 1.55;
}

/* =========================================================
   JOURNEY MAP
   ========================================================= */
.journey {
  padding: 40px 0 60px;
  position: relative;
  overflow: hidden;
}
.journey::before {
  content: "";
  position: absolute;
  top: -180px; left: 50%; transform: translateX(-50%);
  width: 140%; max-width: 1400px;
  height: 360px;
  pointer-events: none;
  background: radial-gradient(ellipse 80% 100% at 50% 0%, rgba(230,184,97,0.07) 0%, transparent 70%);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 0%, transparent 100%);
  z-index: 0;
}
@media (max-width: 820px) {
  .journey { padding: 36px 0 72px; }
}
.journey-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 40px;
  margin-bottom: 60px;
}
@media (max-width: 820px) {
  .journey-head { flex-direction: column; align-items: start; gap: 18px; margin-bottom: 32px; }
  .journey-hud { align-self: stretch; width: 100%; box-sizing: border-box; }
  .hud-bars { min-width: 0; }
}

.journey-head-left { flex: 1; max-width: 640px; }
.journey-hud {
  display: flex; gap: 16px; align-items: center;
  padding: 14px 18px;
  background: linear-gradient(180deg, var(--card-top, var(--surface-2)), var(--surface));
  border: 1px solid var(--stroke-strong);
  border-radius: 18px;
  box-shadow: 0 20px 40px -16px rgba(0,0,0,0.6), 0 1px 0 rgba(255,255,255,0.04) inset;
}
.hud-avatar {
  flex-shrink: 0;
  width: 44px; height: 44px;
  background: radial-gradient(circle, var(--gold-2), var(--gold-deep));
  border-radius: 50%;
  display: grid; place-items: center;
  box-shadow: 0 4px 14px rgba(230,184,97,0.4);
  position: relative;
}
.hud-avatar img {
  width: 86%; height: 86%;
  object-fit: contain;
  display: block;
  clip-path: circle(50%);
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.25));
}
.hud-bars { flex: 1; min-width: 180px; }
.hud-bar-label { display: flex; justify-content: space-between; font-family: var(--f-mono); font-size: 11px; color: var(--muted); margin-bottom: 4px; }
.hud-bar-label span.gold { color: var(--gold-ink); }
.hud-bar {
  height: 8px; background: rgba(0,0,0,0.3);
  border-radius: 999px; overflow: hidden;
  border: 1px solid var(--stroke);
  position: relative;
}
.hud-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--gold-deep), var(--gold), var(--gold-2));
  border-radius: 999px;
  box-shadow: 0 0 10px var(--gold-glow);
  position: relative;
}
/* the glint sweeps the FULL bar, not just the filled portion */
.hud-bar::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);
  transform: translateX(-100%);
  animation: shimmer 2.5s infinite;
}
@keyframes shimmer { 0%{transform:translateX(-100%)} 100%{transform:translateX(100%)} }

.hud-streak {
  display: flex; align-items: center; gap: 4px;
  flex-shrink: 0;
  margin-left: -4px;
}
.hud-streak .flame { font-size: 18px; animation: flame 1.8s ease-in-out infinite; }
@keyframes flame { 0%,100%{transform:scale(1) rotate(0)} 50%{transform:scale(1.15) rotate(-5deg)} }
.hud-streak-num { font-family: var(--f-display); font-weight: 700; color: var(--coral-ink); font-size: 16px; }

.map {
  position: relative;
  padding: 50px 0;
}
.map-bg {
  position: absolute; inset: 0;
  background-image:
    radial-gradient(circle at 20% 30%, rgba(230,184,97,0.04), transparent 40%),
    radial-gradient(circle at 80% 70%, rgba(230,184,97,0.035), transparent 40%);
  pointer-events: none;
}

.map-nodes {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 56px;
  max-width: 1240px;
  margin: 0 auto;
}
@media (max-width: 820px) {
  .map-nodes { gap: 40px; }
}
.node {
  display: grid;
  grid-template-columns: 1fr 200px 1fr;
  align-items: center;
  gap: 48px;
}
.node:nth-child(even) { direction: rtl; }
.node:nth-child(even) > * { direction: ltr; }

.node-info { text-align: right; }
.node:nth-child(even) .node-info { text-align: left; }
.node-eyebrow {
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold-ink);
  margin-bottom: 6px;
}
.node-title {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 28px;
  letter-spacing: -0.03em;
  color: var(--cream);
  margin: 0 0 8px;
  line-height: 1.1;
}
.node-desc { color: var(--cream-muted); font-size: 15px; line-height: 1.55; max-width: 360px; margin-left: auto; }
.node:nth-child(even) .node-desc { margin-left: 0; margin-right: auto; }

.node-stage {
  display: flex; flex-direction: column; align-items: center;
  position: relative;
}
.node-pin {
  width: 120px; height: 120px;
  border-radius: 50%;
  background: linear-gradient(180deg, var(--card-top, var(--surface-2)), var(--bg-3));
  border: 3px solid var(--gold);
  display: grid; place-items: center;
  position: relative;
  box-shadow:
    0 0 40px var(--gold-glow),
    0 20px 40px -10px rgba(0,0,0,0.6),
    0 0 0 6px rgba(11,25,23,1),
    0 0 0 8px rgba(230,184,97,0.2);
  transition: transform .3s var(--ease-bounce);
  cursor: pointer;
}
.node-pin:hover { transform: scale(1.08) rotate(-3deg); }
.node-pin img { width: 70%; height: 70%; object-fit: contain; }
.node-pin img[src*="burj-khalifa"] {
  max-height: 72%;
  max-width: 40%;
  width: auto;
  height: auto;
  object-position: center top;
  transform: translateY(-14%);
}
.node-pin img[src*="emirates-towers"] {
  transform: translateY(-10%);
}
.node-pin-num {
  position: absolute;
  top: -10px; left: -10px;
  width: 36px; height: 36px;
  background: linear-gradient(180deg, var(--gold-2), var(--gold-deep));
  color: #1A0F00;
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 15px;
  border-radius: 50%;
  display: grid; place-items: center;
  border: 3px solid var(--bg);
  box-shadow: 0 4px 10px rgba(0,0,0,0.5);
}
.node-pin-xp {
  position: absolute;
  bottom: -6px; right: -8px;
  padding: 3px 9px;
  background: var(--coral);
  color: white;
  font-family: var(--f-mono);
  font-weight: 700;
  font-size: 10px;
  border-radius: 999px;
  border: 2px solid var(--bg);
  transform: rotate(6deg) scale(0);
  opacity: 0;
  transition:
    transform 520ms cubic-bezier(0.34, 1.56, 0.64, 1) 220ms,
    opacity 260ms ease-out 220ms;
}
.node.reveal.in .node-pin-xp,
.node-finale.reveal.in .node-pin-xp {
  transform: rotate(6deg) scale(1);
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  .node-pin-xp {
    transition: none;
    transform: rotate(6deg) scale(1);
    opacity: 1;
  }
}
.node-caption {
  margin-top: 14px;
  font-family: var(--f-mono);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.node-demo {
  /* The interactive/demo card on the opposite side of the node */
}
.node:nth-child(even) .node-demo { }

.demo-card {
  background: linear-gradient(180deg, var(--card-top, var(--surface-2)), var(--surface));
  border: 1px solid var(--stroke);
  border-radius: 22px;
  padding: 20px;
  box-shadow: 0 30px 50px -20px rgba(0,0,0,0.6), 0 1px 0 rgba(255,255,255,0.03) inset;
  position: relative;
  overflow: hidden;
}
.demo-card::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--stroke-strong), transparent);
}
.demo-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px dashed var(--stroke);
}
.demo-title {
  font-family: var(--f-mono); font-size: 11px;
  letter-spacing: 0.14em; color: var(--muted);
  text-transform: uppercase;
}
.demo-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 8px;
  background: rgba(230,184,97,0.1);
  color: var(--gold-ink);
  font-family: var(--f-mono);
  font-size: 10px;
  font-weight: 600;
  border-radius: 999px;
  border: 1px solid var(--stroke-strong);
}

@media (max-width: 820px) {
  /* Stack journey nodes vertically: pin on top, title+desc centered, demo full-width */
  .node {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 18px;
    direction: ltr !important;
  }
  .node > * { direction: ltr !important; min-width: 0; }

  .node-stage {
    order: 1;
    align-items: center;
    margin: 0 auto;
  }
  .node-pin {
    width: 104px; height: 104px;
    box-shadow:
      0 0 28px var(--gold-glow),
      0 16px 30px -10px rgba(0,0,0,0.5),
      0 0 0 5px rgba(11,25,23,1),
      0 0 0 7px rgba(230,184,97,0.2);
  }
  .node-pin img { width: 72%; height: 72%; }
  .node-pin-num { width: 30px; height: 30px; font-size: 12px; top: -9px; left: -9px; border-width: 2px; }
  .node-pin-xp { font-size: 10px; padding: 3px 8px; bottom: -4px; right: -8px; }
  .node-caption { margin-top: 10px; font-size: 10.5px; text-align: center; }

  .node-info,
  .node:nth-child(even) .node-info {
    order: 2;
    text-align: center;
    padding: 0 4px;
  }
  .node-title {
    font-size: 22px;
    line-height: 1.2;
    margin: 0 0 8px;
  }
  .node-eyebrow { margin-bottom: 4px; }
  .node-desc,
  .node:nth-child(even) .node-desc {
    margin: 0 auto;
    max-width: 420px;
    font-size: 14.5px;
    line-height: 1.55;
  }
  .node-demo { order: 3; width: 100%; }
  .demo-card {
    padding: 16px;
    border-radius: 18px;
    width: 100%;
  }
  .demo-header { margin-bottom: 12px; padding-bottom: 10px; gap: 8px; }
  .demo-title { font-size: 10.5px; letter-spacing: 0.12em; }
  .demo-badge { font-size: 9.5px; padding: 2px 8px; }

  /* Demo internals — prevent horizontal overflow */
  .chat-input-row { flex-wrap: wrap; gap: 8px; }
  .chat-input { flex: 1 1 160px; min-width: 0; font-size: 13.5px; padding: 9px 12px; }
  .chat-send { padding: 9px 14px; }
  .chat-bubble { max-width: 100%; word-break: break-word; }

  .streak-stats { gap: 8px; }
  .streak-stat { padding: 8px 6px; }
  .streak-stat-num { font-size: 17px; }
  .streak-stat-label { font-size: 9px; letter-spacing: 0.06em; }

  .lesson-demo .lesson-top { gap: 8px; }
  .lesson-word-ar { font-size: 26px !important; }
  .lesson-prompt { font-size: 13px; }
  .lesson-trans { font-size: 13px; }
  .lesson-en { font-size: 12px; }

  .pron-demo .pron-stage { padding: 16px 8px; }
  .pron-demo .pron-score { padding: 5px 12px; font-size: 12px; }
  .pron-demo .pron-mic { width: 54px; height: 54px; margin-top: 20px; }
  .pron-demo .pron-mic svg { width: 20px; height: 20px; }
  .pron-demo .pron-play { width: 28px; height: 28px; }
  .pron-demo .pron-play svg { width: 12px; height: 12px; }
  @keyframes mic-pulse {
    0%,100% { box-shadow: 0 0 0 0 rgba(230,184,97,0.45), 0 6px 16px rgba(230,184,97,0.3); }
    50% { box-shadow: 0 0 0 6px rgba(230,184,97,0), 0 6px 16px rgba(230,184,97,0.45); }
  }

  .shuf-demo .shuf-stage { padding: 14px 0; }
}

/* Lesson demo specifics */
.lesson-demo .lesson-top {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 14px;
}
.lesson-progress {
  flex: 1;
  display: flex; gap: 3px;
  padding: 0 12px;
}
.lesson-seg {
  flex: 1; height: 5px; border-radius: 3px;
  background: rgba(250,245,232,0.08);
}
.lesson-seg.done { background: linear-gradient(90deg, var(--gold-deep), var(--gold)); }
.lesson-seg.current { background: var(--gold); animation: seg-pulse 1.4s ease-in-out infinite; }
@keyframes seg-pulse { 0%,100%{opacity:1} 50%{opacity:0.5} }

.lesson-body {
  background: rgba(0,0,0,0.2);
  border-radius: 14px;
  padding: 22px 16px;
  text-align: center;
}
.lesson-hearts { color: var(--coral-ink); font-size: 16px; }

.lesson-word-ar {
  font-family: var(--f-arabic); direction: rtl;
  font-size: 56px; font-weight: 700;
  color: var(--gold-ink);
  line-height: 1; margin-bottom: 4px;
}
.lesson-trans {
  font-family: var(--f-mono);
  color: var(--green);
  font-size: 16px; font-weight: 500;
}
.lesson-en {
  color: var(--cream-muted);
  font-size: 13px; margin-top: 2px;
}
.lesson-play {
  margin-top: 14px;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px;
  background: rgba(230,184,97,0.1);
  border: 1px solid var(--stroke-strong);
  border-radius: 999px;
  color: var(--gold-ink);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
}
.lesson-play:hover { background: rgba(230,184,97,0.18); }

.lesson-check-btn {
  margin-top: 14px;
  width: 100%;
  padding: 12px;
  border-radius: 12px;
  background: var(--gold);
  color: #1A0F00;
  border: none;
  font-family: inherit; font-weight: 700;
  font-size: 14px;
  cursor: pointer;
  box-shadow: 0 3px 0 var(--gold-deep);
  transition: transform .15s;
}
.lesson-check-btn:active { transform: translateY(3px); box-shadow: 0 0 0 var(--gold-deep); }

/* Ramsa chat */
.chat-bubble {
  padding: 10px 14px;
  border-radius: 14px;
  max-width: 80%;
  font-size: 14px;
  line-height: 1.5;
  margin-bottom: 8px;
}
.chat-user {
  background: rgba(230,184,97,0.1);
  color: var(--cream);
  border: 1px solid var(--stroke-strong);
  margin-left: auto;
  border-bottom-right-radius: 4px;
}
.chat-ai {
  background: linear-gradient(180deg, var(--bg-3), var(--surface));
  color: var(--cream);
  border: 1px solid var(--stroke);
  border-bottom-left-radius: 4px;
}
.chat-ai .ar { font-family: var(--f-arabic); direction: rtl; color: var(--gold-ink); font-size: 22px; font-weight: 700; display: block; margin-bottom: 3px; }
.chat-ai .tr { font-family: var(--f-mono); color: var(--green); font-size: 12px; }

.chat-input-row {
  display: flex; gap: 8px;
  margin-top: 14px;
}
.chat-input {
  flex: 1;
  padding: 10px 14px;
  background: rgba(0,0,0,0.3);
  border: 1px solid var(--stroke);
  border-radius: 10px;
  color: var(--cream);
  font-family: inherit;
  font-size: 14px;
  outline: none;
  transition: border-color .2s;
}
.chat-input:focus { border-color: var(--gold-ink); }
.chat-input[readonly] { cursor: default; caret-color: transparent; user-select: none; }
.chat-input[readonly]:focus { border-color: var(--stroke); }

/* =========================================================
   THE 16px FLOOR ON TOUCH. Read this once; the other sheets
   point back here.

   iOS Safari zooms the whole page in when a text field with a
   font-size under 16px takes focus, and it does not zoom back
   out when the field is left. The page is then wider than the
   screen and everything below the keyboard has to be found by
   pinching. It is not a preference and there is no way to opt
   out: user-scalable=no is ignored by iOS and would break
   pinch-zoom for everyone if it were not.

   So every text-entry field is floored at 16px, and only where
   the bug exists. (pointer: coarse) is the exact condition, not
   a width guess: it is true on the phones and tablets that zoom
   and false on the desktops that do not, so a laptop at a narrow
   window keeps the smaller type the design asked for.

   Fields deliberately set ABOVE 16px are left alone. There are
   six of them (the seat counters, the certificate name, the
   review bar) and flooring everything to exactly 16 would have
   shrunk them, which is why this is a list of the small ones
   rather than one blanket rule on input.

   Checkbox, radio, range and file inputs are not text entry and
   never trigger the zoom, so they are not here.
   ========================================================= */
@media (pointer: coarse) {
  .chat-input { font-size: 16px; }
}
.chat-send {
  padding: 10px 18px;
  background: var(--gold);
  color: #1A0F00;
  border: none;
  border-radius: 10px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 3px 0 var(--gold-deep);
  transition: transform .15s;
  font-family: inherit;
  font-size: 14px;
}
.chat-send:active { transform: translateY(3px); box-shadow: 0 0 0 var(--gold-deep); }

/* Shuf camera */
.shuf-demo .shuf-stage {
  aspect-ratio: 1 / 1.15;
  background: radial-gradient(ellipse at center, rgba(0,0,0,0.4), rgba(0,0,0,0.6)), linear-gradient(180deg, #1a3028, #0c1a17);
  border-radius: 16px;
  position: relative;
  overflow: hidden;
  border: 1px solid var(--stroke);
}
.shuf-corners { position: absolute; inset: 18px; pointer-events: none; }
.shuf-corner {
  position: absolute; width: 24px; height: 24px;
  border: 2px solid var(--gold);
}
.shuf-corner.tl { top: 0; left: 0; border-right: none; border-bottom: none; border-radius: 4px 0 0 0; }
.shuf-corner.tr { top: 0; right: 0; border-left: none; border-bottom: none; border-radius: 0 4px 0 0; }
.shuf-corner.bl { bottom: 0; left: 0; border-right: none; border-top: none; border-radius: 0 0 0 4px; }
.shuf-corner.br { bottom: 0; right: 0; border-left: none; border-top: none; border-radius: 0 0 4px 0; }

.shuf-subject {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -55%);
  width: 70%;
  height: auto;
  object-fit: contain;
  filter: drop-shadow(0 20px 30px rgba(0,0,0,0.5));
}
.shuf-scanline {
  position: absolute;
  left: 8%; right: 8%; top: 20%;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  box-shadow: 0 0 20px var(--gold);
  opacity: 0;
  pointer-events: none;
  transition: opacity 220ms ease;
}
@keyframes scan { 0%,100%{top:20%} 50%{top:70%} }

/* Scanline only runs while actively scanning */
.shuf-demo.scanning .shuf-scanline {
  opacity: 1;
  animation: scan 1.8s ease-in-out infinite;
}

.shuf-status {
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--muted);
  text-transform: none;
  transition: color 280ms ease;
}
.shuf-demo.scanning .shuf-status { color: var(--green); }
.shuf-demo.scanned .shuf-status { color: var(--gold-ink); }
.shuf-demo.can-rescan .shuf-status { color: var(--cream-muted); }

.shuf-label {
  position: absolute;
  left: 16px; right: 16px; bottom: 16px;
  background: rgba(11,25,23,0.8);
  backdrop-filter: blur(12px);
  border: 1px solid var(--stroke-strong);
  border-radius: 14px;
  padding: 12px 14px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
}
/* Stack Arabic + transliteration, each centered in its own column.
   The .tr row is a 3-column grid (1fr / auto / 1fr) so the middle "·"
   lands exactly at horizontal center, which sits under the Arabic word's
   visual center. */
.shuf-label-left {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
}
.shuf-label-left .ar {
  font-family: var(--f-arabic); direction: rtl;
  color: var(--gold-ink); font-size: 22px; font-weight: 700;
  line-height: 1;
}
.shuf-label-left .tr {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  column-gap: 8px;
  margin-top: 4px;
  font-family: var(--f-mono);
  color: var(--green);
  font-size: 12px;
  line-height: 1;
}
.shuf-label-left .tr-word { justify-self: end; }
.shuf-label-left .tr-dot { justify-self: center; opacity: 0.85; }
.shuf-label-left .tr-gloss { justify-self: start; }
.shuf-label-right {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 5px 10px;
  background: rgba(230,184,97,0.14);
  color: var(--gold-ink);
  font-family: var(--f-mono);
  font-size: 11px;
  font-weight: 700;
  border-radius: 999px;
  border: 1px solid var(--stroke-strong);
}

.shuf-actions { display: flex; justify-content: center; margin-top: 14px; }
.shuf-shutter {
  width: 56px; height: 56px;
  border-radius: 50%;
  border: 3px solid var(--gold);
  background: var(--bg-3);
  cursor: pointer;
  position: relative;
  transition: transform .2s;
}
.shuf-shutter::before {
  content: ""; position: absolute; inset: 6px;
  background: var(--gold);
  border-radius: 50%;
  box-shadow: 0 0 16px var(--gold-glow);
}
.shuf-shutter:hover { transform: scale(1.05); }
.shuf-shutter:active { transform: scale(0.95); }

/* Alphabet tracing */
.trace-demo .trace-letter-pad {
  aspect-ratio: 1;
  background:
    linear-gradient(rgba(230,184,97,0.06) 1px, transparent 1px) 0 0 / 25% 25%,
    linear-gradient(90deg, rgba(230,184,97,0.06) 1px, transparent 1px) 0 0 / 25% 25%,
    rgba(0,0,0,0.2);
  border-radius: 16px;
  position: relative;
  overflow: hidden;
  border: 1px solid var(--stroke);
  display: grid; place-items: center;
}
.trace-letter {
  font-family: var(--f-arabic); direction: rtl;
  font-size: 220px;
  color: rgba(230,184,97,0.2);
  line-height: 1;
  pointer-events: none;
}
.trace-letter-pad canvas { position: absolute; inset: 0; width: 100%; height: 100%; cursor: crosshair; }
.trace-info { display: flex; justify-content: space-between; align-items: center; margin-top: 12px; }
.trace-name { font-family: var(--f-display); font-weight: 700; color: var(--cream); font-size: 18px; }
.trace-clear {
  padding: 7px 12px;
  background: transparent;
  border: 1px solid var(--stroke);
  border-radius: 8px;
  color: var(--muted);
  font-family: inherit;
  font-size: 12px;
  cursor: pointer;
}
.trace-clear:hover { color: var(--cream); border-color: var(--stroke-strong); }
.trace-check {
  padding: 8px 16px;
  background: var(--gold);
  color: #1A0F00;
  border: 0;
  border-radius: 10px;
  font-family: var(--f-body);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.02em;
  cursor: pointer;
  box-shadow: 0 3px 0 var(--gold-deep);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.trace-check:hover { transform: translateY(-1px); box-shadow: 0 4px 0 var(--gold-deep); }
.trace-check:active { transform: translateY(1px); box-shadow: 0 1px 0 var(--gold-deep); }
.trace-check.is-shaking { animation: lesson-shake 0.4s var(--ease-smooth); }

/* Pronunciation mic */
.pron-demo .pron-stage {
  position: relative;
  aspect-ratio: 1.1;
  background: radial-gradient(ellipse at center top, rgba(230,184,97,0.1), rgba(0,0,0,0.3));
  border-radius: 16px;
  padding: 22px;
  border: 1px solid var(--stroke);
  display: flex; flex-direction: column; align-items: center; justify-content: space-between;
  text-align: center;
}
.pron-word-ar { font-family: var(--f-arabic); direction: rtl; color: var(--gold-ink); font-size: 44px; font-weight: 700; line-height: 1; }
.pron-tr { font-family: var(--f-mono); color: var(--green); font-size: 15px; margin-top: 6px; }
.pron-en { color: var(--cream-muted); font-size: 13px; margin-top: 2px; }

.pron-play {
  flex: none;
  width: 32px; height: 32px;
  border-radius: 50%;
  border: none;
  background: linear-gradient(180deg, var(--gold-2), var(--gold-deep));
  color: #1A0F00;
  display: grid; place-items: center;
  cursor: pointer;
  box-shadow: 0 3px 8px rgba(230,184,97,0.35), inset 0 1px 0 rgba(255,255,255,0.25);
  transition: transform 0.18s var(--ease-smooth), box-shadow 0.18s var(--ease-smooth);
}
.pron-play:hover {
  transform: translateY(-1px);
  box-shadow: 0 5px 12px rgba(230,184,97,0.5), inset 0 1px 0 rgba(255,255,255,0.3);
}
.pron-play:active { transform: translateY(0); }
.pron-play.is-playing {
  box-shadow: 0 0 0 4px rgba(230,184,97,0.25), 0 3px 8px rgba(230,184,97,0.5);
}

.wave {
  display: flex; align-items: center; gap: 3px;
  height: 50px;
}
.wave span {
  display: block;
  width: 3px;
  background: linear-gradient(180deg, var(--gold-2), var(--green));
  border-radius: 999px;
  animation: wave 1.2s ease-in-out infinite;
  transform-origin: center;
}
.wave span:nth-child(1) { --h: 20%; animation-delay: -0.2s; }
.wave span:nth-child(2) { --h: 60%; animation-delay: -0.4s; }
.wave span:nth-child(3) { --h: 90%; animation-delay: -0.1s; }
.wave span:nth-child(4) { --h: 70%; animation-delay: -0.3s; }
.wave span:nth-child(5) { --h: 100%; animation-delay: 0s; }
.wave span:nth-child(6) { --h: 80%; animation-delay: -0.5s; }
.wave span:nth-child(7) { --h: 50%; animation-delay: -0.2s; }
.wave span:nth-child(8) { --h: 70%; animation-delay: -0.4s; }
.wave span:nth-child(9) { --h: 40%; animation-delay: -0.1s; }
.wave span:nth-child(10) { --h: 90%; animation-delay: -0.3s; }
.wave span:nth-child(11) { --h: 60%; animation-delay: 0s; }
.wave span:nth-child(12) { --h: 30%; animation-delay: -0.2s; }

@keyframes wave {
  0%,100% { height: 10%; }
  50% { height: var(--h, 80%); }
}

.pron-mic {
  width: 68px; height: 68px; border-radius: 50%;
  background: linear-gradient(180deg, var(--gold-2), var(--gold-deep));
  box-shadow: 0 0 0 0 var(--gold-glow), 0 8px 20px rgba(230,184,97,0.4);
  border: none;
  display: grid; place-items: center;
  cursor: pointer;
  animation: mic-pulse 2s ease-in-out infinite;
}
@keyframes mic-pulse {
  0%,100% { box-shadow: 0 0 0 0 rgba(230,184,97,0.5), 0 8px 20px rgba(230,184,97,0.3); }
  50% { box-shadow: 0 0 0 18px rgba(230,184,97,0), 0 8px 20px rgba(230,184,97,0.5); }
}

.pron-score {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 14px;
  background: rgba(77,191,142,0.12);
  border: 1px solid rgba(77,191,142,0.3);
  border-radius: 999px;
  color: var(--green);
  font-family: var(--f-mono);
  font-weight: 700;
  font-size: 13px;
}

/* Streak calendar */
.streak-demo .streak-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 8px;
  margin-bottom: 16px;
}
.streak-cell {
  aspect-ratio: 1;
  border-radius: 10px;
  background: rgba(250,245,232,0.04);
  border: 1px solid var(--stroke);
  display: grid; place-items: center;
  font-family: var(--f-mono);
  font-size: 11px;
  color: var(--muted);
  position: relative;
}
.streak-cell.done {
  background: linear-gradient(180deg, rgba(232,97,74,0.25), rgba(232,97,74,0.1));
  border-color: rgba(232,97,74,0.4);
  color: var(--coral-ink);
}
.streak-cell.done::before { content: "🔥"; font-size: 18px; position: absolute; }
.streak-cell.today {
  background: linear-gradient(180deg, var(--gold-2), var(--gold-deep));
  border-color: var(--gold);
  color: #1A0F00;
  font-weight: 700;
  box-shadow: 0 0 20px var(--gold-glow);
}
.streak-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.streak-stat {
  padding: 10px;
  background: rgba(0,0,0,0.25);
  border: 1px solid var(--stroke);
  border-radius: 10px;
  text-align: center;
}
.streak-stat-num { font-family: var(--f-display); font-weight: 700; font-size: 20px; color: var(--gold-ink); }
.streak-stat-label { font-family: var(--f-mono); font-size: 10px; color: var(--muted); letter-spacing: 0.1em; text-transform: uppercase; margin-top: 2px; }

/* =========================================================
   GOLD TIER
   ========================================================= */
.gold-section {
  padding: 40px 0 100px;
  background:
    radial-gradient(ellipse 80% 60% at 50% 50%, rgba(230,184,97,0.08), transparent 70%),
    var(--bg);
  position: relative;
  overflow: hidden;
}
.gold-grid {
  display: grid;
  grid-template-columns: 0.72fr 1.28fr;
  gap: 30px;
  align-items: center;
  max-width: 1100px;
  margin: 0 auto;
}
@media (max-width: 820px) { .gold-grid { grid-template-columns: 1fr; } }

.tier {
  position: relative;
  padding: 22px 20px 20px;
  background: linear-gradient(180deg, var(--surface), var(--bg-2));
  border: 1px solid var(--stroke);
  border-radius: 20px;
}
.tier:not(.tier-gold) .tier-name { font-size: 26px; }
.tier:not(.tier-gold) .tier-price { font-size: 34px; margin-top: 10px; }
.tier:not(.tier-gold) .tier-list { margin-top: 18px; }
.tier:not(.tier-gold) .tier-list li { padding: 6px 0; font-size: 13.5px; }
.tier-text-link {
  display: inline-block;
  margin-top: 20px;
  color: var(--muted);
  font-family: var(--f-mono);
  font-size: 12.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  transition: color .2s;
}
.tier-text-link:hover { color: var(--cream); }
.tier.tier-gold {
  padding: 36px 32px 32px;
  background: linear-gradient(180deg, var(--gold-2) 0%, var(--gold) 55%, var(--gold-deep) 100%);
  border-color: var(--gold-deep);
  color: #1A0F00;
  box-shadow:
    0 1px 0 rgba(255,255,255,0.45) inset,
    0 -2px 0 rgba(0,0,0,0.12) inset;
}
.tier-gold .tier-label {
  color: var(--gold);
  background: #1A0F00;
  border-color: transparent;
  font-weight: 700;
}
.tier-gold .tier-name {
  background: none;
  -webkit-background-clip: initial; background-clip: initial;
  -webkit-text-fill-color: initial;
  color: #1A0F00;
}
.tier-gold .tier-price { color: #1A0F00; }
.tier-gold .tier-price-unit { color: rgba(26,15,0,0.65); }
.tier-gold .tier-list li { color: rgba(26,15,0,0.85); border-bottom-color: rgba(26,15,0,0.16); }
.tier-gold .tier-list svg { color: #1A0F00; }
.tier-gold .tier-cta {
  background: #1A0F00;
  color: var(--gold);
  box-shadow: 0 12px 28px -10px rgba(0,0,0,0.6), 0 1px 0 rgba(255,255,255,0.05) inset;
}
.tier-gold .tier-cta:hover { background: #2a1e0a; box-shadow: 0 14px 32px -10px rgba(0,0,0,0.7); transform: translateY(-1px); }

/* Basic tier excluded-feature rows */
.tier-list li.tier-off { color: var(--muted); font-style: italic; opacity: 0.75; }
.tier:not(.tier-gold) .tier-list li.tier-off svg { color: var(--coral-ink); opacity: 0.9; }
.tier-label {
  display: inline-flex;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 4px 10px;
  background: rgba(250,245,232,0.04);
  border: 1px solid var(--stroke);
  border-radius: 999px;
}
.tier-name {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 34px;
  letter-spacing: -0.03em;
  color: var(--cream);
  margin: 16px 0 4px;
}
.tier-price {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 44px;
  color: var(--cream);
  letter-spacing: -0.03em;
  line-height: 1;
  margin-top: 14px;
}
.tier-price-unit { font-family: var(--f-body); font-size: 14px; color: var(--muted); font-weight: 500; }
.tier-list { list-style: none; margin: 24px 0 0; padding: 0; }
.tier-list li {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 8px 0;
  color: var(--cream-muted);
  font-size: 14.5px;
  border-bottom: 1px dashed var(--stroke);
}
.tier-list li:last-child { border-bottom: none; }
.tier-list svg { flex-shrink: 0; color: var(--gold-ink); margin-top: 2px; }
.tier:not(.tier-gold) .tier-list svg { color: var(--green); }
.tier-cta { margin-top: 20px; width: 100%; justify-content: center; }

/* =========================================================
   INSTAGRAM MARQUEE
   ========================================================= */
.ig-section { padding: 80px 0 100px; }
.marquee {
  overflow: hidden;
  position: relative;
  mask-image: linear-gradient(90deg, transparent, black 8%, black 92%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, black 8%, black 92%, transparent);
}
.marquee-row {
  display: flex; gap: 18px;
  animation: marquee 60s linear infinite;
  width: max-content;
}
.marquee-row.reverse { animation-direction: reverse; animation-duration: 70s; }
@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
.marquee-item {
  display: block;
  width: 220px; aspect-ratio: 9/16;
  border-radius: 18px;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--stroke);
  flex-shrink: 0;
  transition: transform .3s, border-color .3s, box-shadow .3s;
  text-decoration: none;
  color: inherit;
}
.marquee-item:hover,
.marquee-item:focus-visible {
  transform: scale(1.05);
  border-color: var(--gold-ink);
  box-shadow: 0 10px 30px rgba(230, 184, 97, 0.18);
  outline: none;
}
.marquee-item img, .marquee-item video {
  width: 100%; height: 100%; object-fit: cover; display: block;
}

/* =========================================================
   FAQ
   ========================================================= */
.faq-section { padding: 80px 0; }
.faq {
  max-width: 760px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 12px;
}
.faq-item {
  background: var(--surface);
  border: 1px solid var(--stroke);
  border-radius: 16px;
  overflow: hidden;
  transition: border-color .2s;
}
.faq-item:hover { border-color: var(--stroke-strong); }
.faq-item[open] { border-color: var(--stroke-strong); background: var(--surface-2); }
.faq-q {
  padding: 18px 22px;
  cursor: pointer;
  font-family: var(--f-display);
  font-weight: 600;
  font-size: 16px;
  color: var(--cream);
  letter-spacing: -0.01em;
  list-style: none;
  position: relative;
  padding-right: 56px;
}
.faq-q::-webkit-details-marker { display: none; }
.faq-q::after {
  content: "+";
  position: absolute;
  right: 22px; top: 50%;
  transform: translateY(-50%);
  width: 26px; height: 26px;
  border-radius: 50%;
  background: rgba(230,184,97,0.1);
  color: var(--gold-ink);
  font-size: 16px; font-weight: 400;
  display: grid; place-items: center;
  transition: transform .25s, background .2s;
}
.faq-item[open] .faq-q::after { transform: translateY(-50%) rotate(45deg); background: var(--gold); color: #1A0F00; }
.faq-a {
  padding: 0 22px 20px;
  color: var(--cream-muted);
  font-size: 14.5px;
  line-height: 1.65;
}

/* =========================================================
   FINAL CTA
   ========================================================= */
.final-cta {
  padding: 100px 0 80px;
  position: relative;
  overflow: hidden;
}
.final-cta-inner {
  position: relative;
  background: linear-gradient(180deg, var(--card-top, var(--surface-2)), var(--bg-2));
  border: 1px solid var(--stroke-strong);
  border-radius: 32px;
  padding: 60px 40px;
  text-align: center;
  overflow: hidden;
  box-shadow: 0 30px 80px -20px rgba(0,0,0,0.6), 0 1px 0 rgba(255,255,255,0.04) inset;
}
.final-cta-inner::before {
  content: "";
  position: absolute;
  inset: -1px;
  padding: 1px;
  border-radius: 32px;
  background: linear-gradient(135deg, var(--gold), transparent 30%, transparent 70%, var(--gold));
  -webkit-mask:
    linear-gradient(#fff 0 0) content-box,
    linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
  opacity: 0.5;
}
.final-saqr {
  width: 180px;
  height: auto;
  filter: drop-shadow(0 20px 30px rgba(0,0,0,0.4));
  margin: 0 auto 20px;
  display: block;
  animation: float 4s ease-in-out infinite;
}
.waitlist {
  display: flex; gap: 8px;
  max-width: 460px;
  margin: 28px auto 0;
}
.waitlist-email {
  flex: 1;
  padding: 14px 18px;
  background: rgba(0,0,0,0.3);
  border: 1px solid var(--stroke-strong);
  border-radius: 12px;
  color: var(--cream);
  font-family: inherit;
  font-size: 15px;
  outline: none;
  transition: border-color .2s, box-shadow .2s;
}
.waitlist-email:focus { border-color: var(--gold-ink); box-shadow: 0 0 0 4px rgba(230,184,97,0.1); }
.waitlist-email::placeholder { color: var(--muted); }
.waitlist-company {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
@media (max-width: 520px) { .waitlist { flex-direction: column; } }

.waitlist-msg {
  margin-top: 12px;
  font-family: var(--f-mono); font-size: 13px;
  color: var(--green);
  opacity: 0;
  transition: opacity .3s;
}
.waitlist-msg.show { opacity: 1; }

.final-socials { margin-top: 24px; color: var(--cream-muted); font-size: 14px; }
.final-socials a { color: var(--gold-ink); text-decoration: none; font-weight: 600; }
.final-socials a:hover { color: var(--gold-ink-2); }

/* =========================================================
   FOOTER
   ========================================================= */
footer {
  padding: 40px 0 50px;
  border-top: 1px solid var(--stroke);
  color: var(--muted);
}
.footer-row { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 16px; }
.footer-links { display: flex; gap: 22px; font-size: 13.5px; }
.footer-links a { color: var(--muted); text-decoration: none; transition: color .2s; }
.footer-links a:hover { color: var(--cream); }
.footer-bottom {
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px dashed var(--stroke);
  display: flex; justify-content: space-between;
  font-family: var(--f-mono); font-size: 11.5px;
  color: var(--muted);
  letter-spacing: 0.05em;
}

/* =========================================================
   XP BURST (for canvas pops & clicks)
   ========================================================= */
.xp-pop {
  position: fixed;
  z-index: 1000;
  pointer-events: none;
  font-family: var(--f-mono);
  font-weight: 700;
  font-size: 14px;
  color: var(--gold-ink);
  text-shadow: 0 2px 6px rgba(0,0,0,0.6);
  animation: xp-pop 1s var(--ease-smooth) forwards;
}
@keyframes xp-pop {
  0% { opacity: 0; transform: translateY(0) scale(0.8); }
  20% { opacity: 1; transform: translateY(-20px) scale(1.1); }
  80% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-60px) scale(1); }
}

/* Reveal animation baseline */
.reveal { opacity: 0; transform: translateY(24px); transition: opacity .7s var(--ease-smooth), transform .7s var(--ease-smooth); }
.reveal.in { opacity: 1; transform: none; }

/* Staggered child cascade: children of [data-stagger] deal in one-by-one once the
   ancestor .reveal lands. Pure CSS (nth-child delays) so it needs no JS. Uses the
   independent `translate` property so it composes with any `transform` a child
   already carries (e.g. an elevated featured card), instead of overriding it. */
[data-stagger] > * { opacity: 0; translate: 0 14px; }
.reveal.in [data-stagger] > *,
[data-stagger].in > * {
  opacity: 1; translate: 0 0;
  transition: opacity var(--dur-base) var(--ease-smooth), translate var(--dur-base) var(--ease-smooth);
}
.reveal.in [data-stagger] > *:nth-child(1), [data-stagger].in > *:nth-child(1) { transition-delay: 0ms; }
.reveal.in [data-stagger] > *:nth-child(2), [data-stagger].in > *:nth-child(2) { transition-delay: 60ms; }
.reveal.in [data-stagger] > *:nth-child(3), [data-stagger].in > *:nth-child(3) { transition-delay: 120ms; }
.reveal.in [data-stagger] > *:nth-child(4), [data-stagger].in > *:nth-child(4) { transition-delay: 180ms; }
.reveal.in [data-stagger] > *:nth-child(5), [data-stagger].in > *:nth-child(5) { transition-delay: 240ms; }
.reveal.in [data-stagger] > *:nth-child(6), [data-stagger].in > *:nth-child(6) { transition-delay: 300ms; }
.reveal.in [data-stagger] > *:nth-child(7), [data-stagger].in > *:nth-child(7) { transition-delay: 360ms; }
.reveal.in [data-stagger] > *:nth-child(n+8), [data-stagger].in > *:nth-child(n+8) { transition-delay: 420ms; }

/* Whole-page theme morph (View Transitions): a calm crossfade of the root snapshot. */
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .42s; animation-timing-function: var(--ease-smooth); }

/* Gate / section divider */
.divider-ornate {
  display: flex; justify-content: center; align-items: center; gap: 12px;
  padding: 40px 0;
  color: var(--gold-ink);
  opacity: 0.6;
}
@media (max-width: 820px) {
  .divider-ornate { padding: 20px 0; }
}
.divider-ornate .diamond {
  width: 8px; height: 8px; background: var(--gold);
  transform: rotate(45deg);
  box-shadow: 0 0 10px var(--gold-glow);
}
.divider-ornate .line {
  width: 80px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
}

/* Grain */
.grain {
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 300;
  opacity: 0.035;
  mix-blend-mode: overlay;
  background-image: url("images/noise.png");
  background-size: 180px;
}

/* =========================================================
   PHASE 4: Broken-interaction fixes
   ========================================================= */

/* Lesson: tappable word + shake feedback + prompt styling */
.lesson-prompt {
  font-family: var(--f-mono);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-bottom: 12px;
}
button.lesson-word-ar.lesson-choice {
  background: transparent;
  border: 2px solid transparent;
  padding: 6px 14px;
  border-radius: 14px;
  cursor: pointer;
  transition: background .2s, border-color .2s, transform .2s;
  font-family: var(--f-arabic); direction: rtl;
  font-size: 56px; font-weight: 700;
  color: var(--gold-ink);
  line-height: 1;
}
button.lesson-word-ar.lesson-choice:hover {
  background: rgba(230,184,97,0.06);
  border-color: var(--stroke-strong);
}
button.lesson-word-ar.lesson-choice.selected {
  background: rgba(230,184,97,0.12);
  border-color: var(--gold);
  box-shadow: 0 0 0 4px rgba(230,184,97,0.12);
}
@keyframes lesson-shake {
  0%,100% { transform: translateX(0); }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}
.lesson-choice.shake { animation: lesson-shake .4s var(--ease-smooth); }

.lesson-prompt.success {
  color: var(--gold-ink);
  font-size: 13px;
  letter-spacing: 0.16em;
  animation: lesson-success-pop .42s var(--ease-smooth);
}
@keyframes lesson-success-pop {
  0% { opacity: 0; transform: translateY(-3px); }
  100% { opacity: 1; transform: translateY(0); }
}

/* Shuf label: hidden by default, reveal on shutter tap */
.shuf-label {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .45s var(--ease-smooth), transform .45s var(--ease-smooth);
  pointer-events: none;
}
.shuf-label.revealed {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

/* Pronunciation: placeholder when empty */
.pron-score:empty {
  background: transparent;
  border-color: transparent;
  color: var(--muted);
  font-weight: 500;
}
.pron-score:empty::before {
  content: attr(data-placeholder);
}
.pron-score {
  transition: transform .3s var(--ease-bounce), background .3s, border-color .3s, color .3s;
}

/* Alphabet tracing: feedback chip (good / close / off) */
.trace-chip {
  position: absolute;
  top: 14px; right: 14px;
  padding: 6px 12px;
  background: var(--gold);
  color: #1A0F00;
  font-family: var(--f-mono);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.06em;
  border-radius: 999px;
  box-shadow: 0 8px 20px var(--gold-glow);
  animation: trace-chip-in .35s var(--ease-bounce), trace-chip-out .4s ease-in 1.4s forwards;
  pointer-events: none;
}
.trace-chip-close {
  background: rgba(230,184,97,0.14);
  color: var(--gold-ink);
  border: 1px solid rgba(230,184,97,0.4);
  box-shadow: none;
}
.trace-chip-off {
  background: rgba(232,97,74,0.14);
  color: var(--coral-ink);
  border: 1px solid rgba(232,97,74,0.4);
  box-shadow: none;
}
@keyframes trace-chip-in {
  0% { opacity: 0; transform: translateY(-10px) scale(0.85); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes trace-chip-out {
  0% { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-6px); }
}

/* =========================================================
   PHASE 6: Waitlist msg states
   ========================================================= */
.waitlist-msg.error { color: var(--coral-ink); }
.waitlist-msg.success { color: var(--green); }

/* =========================================================
   PHASE 8: Mobile hamburger + slide-down menu
   ========================================================= */
.nav-burger {
  display: none;
  width: 44px; height: 44px;
  background: rgba(230,184,97,0.08);
  border: 1px solid var(--stroke-strong);
  border-radius: 14px;
  padding: 0;
  cursor: pointer;
  position: relative;
  transition: background .2s;
}
.nav-burger:hover { background: rgba(230,184,97,0.14); }
.nav-burger span {
  display: block;
  position: absolute;
  left: 11px; right: 11px;
  height: 2px;
  background: var(--gold);
  border-radius: 2px;
  transition: transform .3s var(--ease-smooth), opacity .2s;
}
.nav-burger span:nth-child(1) { top: 14px; }
.nav-burger span:nth-child(2) { top: 21px; }
.nav-burger span:nth-child(3) { top: 28px; }
.nav-burger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-burger.open span:nth-child(2) { opacity: 0; }
.nav-burger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.mobile-menu {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 95;
  background: linear-gradient(180deg, var(--bg-2) 0%, var(--bg) 100%);
  border-bottom: 1px solid var(--stroke-strong);
  padding: 90px 24px 32px;
  display: flex; flex-direction: column; gap: 6px;
  transform: translateY(-100%);
  transition: transform .4s var(--ease-smooth);
  box-shadow: 0 30px 60px -20px rgba(0,0,0,0.6);
}
.mobile-menu.open { transform: translateY(0); }
.mobile-menu-link {
  display: block;
  padding: 14px 16px;
  color: var(--cream);
  text-decoration: none;
  font-family: var(--f-display);
  font-size: 18px;
  font-weight: 500;
  border-radius: 12px;
  transition: background .2s, color .2s;
}
.mobile-menu-link:hover { background: rgba(250,245,232,0.04); }
.mobile-menu-link.gold { color: var(--gold-ink); }
/* The nav bar keeps its own theme toggle on a phone (see the
   `.nav .theme-toggle.nav-cta { display: inline-flex }` rule in the 820px
   block, which outranks the `.nav .nav-cta { display: none }` beside it), so a
   second one at the foot of this menu is the same control twice on one screen,
   about 700px apart. Nobody had seen the pair because the burger that opens
   this menu was hidden. The one in the bar wins: it is reachable without
   opening anything. Keep the element in the markup so the menu still has more
   than one child and `.mobile-menu:has(> :only-child)` cannot misfire. */
.mobile-menu-cta { display: none; }
.mobile-menu-cta:not(.theme-toggle) { display: flex; margin-top: 16px; justify-content: center; }

body.menu-open { overflow: hidden; }

@media (max-width: 820px) {
  .nav-burger { display: block; }
  .nav .nav-cta { display: none; }
}
@media (min-width: 821px) {
  .mobile-menu { display: none; }
}

/* =========================================================
   PHASE 7: Reduced motion baseline
   ========================================================= */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .hero-stars, .hero-aura, .hero-dunes { animation: none !important; }
  .shuf-scanline { animation: none !important; }
  .pron-mic { animation: none !important; }
  .wiggle { animation: none !important; }
}

/* =========================================================
   PHASE 8: Stop 7 — Saqr finale pin + demo card
   ========================================================= */
/* Give node 7 the same visual distance from node 6 as the rest of the map.
   Node 6 ends with a tall streak demo which visually collapses the gap;
   this restores parity with the 4→5 and 5→6 rhythm. */
.node-finale { margin-top: 96px; }
@media (max-width: 820px) {
  .node-finale { margin-top: 32px; }
}

.node-pin-finale {
  border-color: var(--gold-2);
  box-shadow:
    0 0 60px rgba(230, 184, 97, 0.5),
    0 20px 40px -10px rgba(0, 0, 0, 0.7),
    0 0 0 6px rgba(11, 25, 23, 1),
    0 0 0 9px rgba(230, 184, 97, 0.35);
}
.node-pin-finale .node-pin-xp {
  background: linear-gradient(180deg, var(--gold-2), var(--gold-deep));
  color: #1A0F00;
  font-family: var(--f-display);
  font-weight: 700;
  letter-spacing: 0.04em;
}
.node-pin-finale img {
  width: 78%;
  height: 78%;
  object-fit: contain;
  object-position: center bottom;
  transform: translateX(-2px);
}

.finale-demo {
  min-height: 200px;
}
.finale-card {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 22px;
  background:
    radial-gradient(ellipse 80% 100% at 20% 50%, rgba(230,184,97,0.14) 0%, transparent 70%),
    rgba(230, 184, 97, 0.04);
  border: 1px solid var(--stroke);
  border-radius: 16px;
  margin-top: 8px;
}
.finale-seal {
  flex-shrink: 0;
  width: 72px; height: 72px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, var(--gold-2), var(--gold-deep));
  display: grid; place-items: center;
  box-shadow:
    0 0 30px rgba(230, 184, 97, 0.35),
    inset 0 -4px 8px rgba(0, 0, 0, 0.25),
    inset 0 4px 8px rgba(255, 255, 255, 0.18);
  color: #1A0F00;
}
.finale-seal svg { display: block; }
.finale-copy { min-width: 0; flex: 1; }
.finale-title {
  font-family: var(--f-display);
  font-size: 20px;
  font-weight: 700;
  color: var(--cream);
  letter-spacing: -0.01em;
  line-height: 1.15;
  margin: 0 0 4px;
}
.finale-title .ar {
  font-family: var(--f-arabic-hero);
  font-size: 22px;
  color: var(--gold-ink);
  margin-right: 4px;
}
.finale-sub {
  font-family: var(--f-mono);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* =========================================================
   PHASE 9: Legal pages (privacy / terms)
   ========================================================= */
/* Legal pages are read-through content — no staggered reveal */
.legal-page .reveal,
.legal-page .reveal.in {
  opacity: 1;
  transform: none;
  transition: none;
}

.legal-page {
  padding: 132px 0 80px;
  background:
    radial-gradient(ellipse 100% 60% at 50% 0%, rgba(230,184,97,0.06) 0%, transparent 60%),
    var(--bg);
  min-height: 100vh;
}
.legal-container { position: relative; }

.legal-header { margin-bottom: 44px; }
.legal-header .eyebrow { margin-bottom: 14px; }
.legal-title {
  font-family: var(--f-display);
  font-size: clamp(36px, 5vw, 56px);
  font-weight: 700;
  color: var(--cream);
  margin: 0 0 10px;
  letter-spacing: -0.025em;
  line-height: 1.05;
}
.legal-meta {
  color: var(--muted);
  font-family: var(--f-mono);
  font-size: 13px;
  letter-spacing: 0.04em;
  margin: 0;
}

.legal-intro {
  background: linear-gradient(180deg, var(--card-top, var(--surface-2)), var(--surface));
  border: 1px solid var(--stroke);
  border-radius: 20px;
  padding: 24px 28px;
  margin-bottom: 48px;
  position: relative;
  overflow: hidden;
}
.legal-intro::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--stroke-strong), transparent);
}
.legal-intro p {
  color: var(--cream-muted);
  line-height: 1.7;
  font-size: 15px;
  margin: 0 0 12px;
}
.legal-intro p:last-child { margin-bottom: 0; }

.legal-sections {
  display: flex;
  flex-direction: column;
  gap: 44px;
}
.legal-section-head {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 14px;
}
.legal-section-icon {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: rgba(230, 184, 97, 0.12);
  border: 1px solid var(--stroke);
  display: grid;
  place-items: center;
  color: var(--gold-ink);
  flex-shrink: 0;
}
.legal-section-icon svg { width: 20px; height: 20px; }
.legal-section-title {
  font-family: var(--f-display);
  font-size: 22px;
  font-weight: 600;
  color: var(--cream);
  margin: 0;
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.legal-section-body {
  padding-left: 54px;
  color: var(--cream-muted);
  line-height: 1.7;
  font-size: 15px;
}
.legal-section-body > p { margin: 0 0 14px; }
.legal-section-body strong { color: var(--cream); font-weight: 600; }
.legal-subhead {
  font-family: var(--f-display);
  font-size: 16px;
  font-weight: 600;
  color: var(--cream);
  margin: 18px 0 10px;
  letter-spacing: -0.005em;
}
.legal-section-body a {
  color: var(--gold-ink);
  text-decoration: none;
  border-bottom: 1px solid rgba(230, 184, 97, 0.3);
  transition: border-color 0.15s ease;
}
.legal-section-body a:hover { border-bottom-color: var(--gold); }

.legal-list {
  list-style: none;
  padding: 0;
  margin: 0 0 14px;
}
.legal-list li {
  position: relative;
  padding-left: 18px;
  margin-bottom: 8px;
  color: var(--cream-muted);
}
.legal-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 10px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gold);
  opacity: 0.85;
}

.legal-contact {
  margin-top: 20px;
  padding: 24px 28px;
  background: rgba(230, 184, 97, 0.06);
  border: 1px solid var(--stroke);
  border-radius: 18px;
  display: grid;
  grid-template-columns: 1fr 1px 1fr;
  gap: 24px;
  align-items: center;
}
.legal-contact-col { min-width: 0; }
.legal-contact-divider { background: var(--stroke); height: 48px; width: 1px; }
.legal-contact-email {
  font-family: var(--f-display);
  font-weight: 600;
  color: var(--gold-ink);
  font-size: 15px;
  margin: 0 0 4px;
  word-break: break-word;
}
.legal-contact-email a { color: var(--gold-ink); text-decoration: none; }
.legal-contact-email a:hover { text-decoration: underline; }
.legal-contact-label {
  color: var(--muted);
  font-size: 13px;
  margin: 0;
}

.legal-footer-ack {
  margin-top: 48px;
  padding-top: 24px;
  border-top: 1px solid var(--stroke);
  color: var(--muted);
  font-size: 14px;
  line-height: 1.7;
}

.site-footer {
  border-top: 1px solid var(--stroke);
  padding: 40px 0;
  margin-top: 60px;
}
.site-footer-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
}
.site-footer-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--f-display);
  font-weight: 700;
  color: var(--cream);
  font-size: 18px;
  text-decoration: none;
}
.site-footer-brand .ar {
  font-family: var(--f-arabic-hero);
  color: var(--gold-ink);
}
.site-footer-links {
  display: flex;
  align-items: center;
  gap: 24px;
  font-size: 14px;
}
.site-footer-links a {
  color: var(--cream-muted);
  text-decoration: none;
  transition: color 0.15s ease;
  /* 22px tall before this, on About, Privacy, Terms, Refunds and Business
     Terms -- the marketing twin of the storefront's legal nav below, and two
     pixels under the 24x24 WCAG 2.5.8 asks at AA. Padded, not resized: the
     14px type is unchanged and the row still reads the same. The flex gap is
     24px so the negative margin cannot make neighbours touch. 2026-08-03. */
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 2px 6px;
  margin: 0 -6px;
}
.site-footer-links a:hover { color: var(--cream); }
.site-footer-links a.current { color: var(--gold-ink); }

/* Legal footer tap targets.
   The storefront, books, kids, work and free-ebook pages all carry the same
   hand-written <nav aria-label="Legal"> with its styling inline, and on a phone
   each of those five links measured 37-49 x 20. WCAG 2.5.8 asks 24x24 at AA, so
   About / Privacy / Terms / Refunds / Contact were all four pixels short of the
   floor in the exact places a customer goes looking for the refund policy.

   Padded rather than resized: the type stays 13px, only the box grows, so
   nothing about the footer looks different. The nav's own inline style sets
   `gap: 16px`, which the 8px of side padding eats into visually but not
   physically, so the targets still do not touch. Two of the five pages are
   already live. Measured 2026-08-03. */
nav[aria-label="Legal"] a {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 3px 8px;
  margin: 0 -8px;
}
.site-footer-meta {
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid rgba(230, 184, 97, 0.08);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  color: var(--muted);
  font-size: 13px;
}

@media (max-width: 640px) {
  .legal-page { padding: 100px 0 60px; }
  .legal-header { margin-bottom: 32px; }
  .legal-intro { padding: 20px; margin-bottom: 36px; }
  .legal-sections { gap: 36px; }
  .legal-section-head { gap: 12px; margin-bottom: 12px; }
  .legal-section-icon { width: 36px; height: 36px; border-radius: 10px; }
  .legal-section-icon svg { width: 18px; height: 18px; }
  .legal-section-title { font-size: 19px; }
  .legal-section-body {
    padding-left: 0;
    font-size: 14.5px;
  }
  .legal-contact {
    grid-template-columns: 1fr;
    gap: 16px;
    padding: 20px;
  }
  .legal-contact-divider { display: none; }
  .site-footer-row { justify-content: center; text-align: center; }
  .site-footer-links { flex-wrap: wrap; justify-content: center; gap: 14px 18px; }
  .site-footer-meta { justify-content: center; text-align: center; }
  .finale-card {
    padding: 18px;
    gap: 14px;
  }
  .finale-seal { width: 60px; height: 60px; }
  .finale-seal svg { width: 32px; height: 32px; }
  .finale-title { font-size: 17px; }
}

/* =========================================================
   PHASE 10: Scroll-gold — the word fills in gold left→right as the user
   scrolls it toward the viewport center. Unfills as it moves away.
   Driven by --gild-x (0–100%) set per-element by a rAF loop in script.js.
   ========================================================= */
.scroll-gold,
.section-title .scroll-gold,
.hero-title .scroll-gold,
.node-title .scroll-gold,
.node-eyebrow.scroll-gold {
  --gild-x: 0%;
  /* Both halves are tokens, and both had to become tokens for the same reason.
     These words are 22-27px bold headings, so the bar is the 3:1 large-text
     one, and the ungilded half is the RESTING state of every gilded heading on
     the site -- what a visitor sees before the scroll fills it in, and all they
     ever see if they never scroll it into the middle of the screen.

     It was a literal #8C8577, then a literal #948D7E, and a single literal
     cannot work: the value has to be light enough to clear a near-black green
     and dark enough to clear pure white. #948D7E is 5.47 / 3.85 / 3.31 on the
     dark theme's bg / surface / card-top and only 3.30 on white, 2.97 on the
     light theme's --surface-2, which is the ground the storefront's gilded
     headings actually land on. --gild-off carries the per-theme value; see the
     three declarations in the theme blocks above. Measured 2026-08-02. */
  /* --gold-ink, not --gold. A background clipped to text IS the text, so the
     gilded half has to clear a text bar, and the light theme's --gold is a fill
     stop measuring 2.05 on white -- it would render these headings as a pale
     smear. --gold-ink is the same colour's ink form and is identical to --gold
     on both dark themes, so only light moves. */
  background: linear-gradient(
    90deg,
    var(--gold-ink) 0%,
    var(--gold-ink) calc(var(--gild-x) - 3%),
    /* The fallback is not decoration. An undefined custom property is invalid
       at computed-value time, so a bare var(--gild-off) on a stylesheet that
       did not define it would drop this whole background declaration -- and
       with color:transparent and -webkit-text-fill-color:transparent still in
       force below, the heading would render as nothing at all. */
    var(--gild-off, #948D7E) calc(var(--gild-x) + 3%),
    var(--gild-off, #948D7E) 100%
  );
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  text-shadow: none;
  transition: text-shadow 400ms ease-out;
}
/* Subtle gold glow once mostly filled */
.scroll-gold.is-gilded {
  text-shadow: 0 0 24px rgba(230, 184, 97, 0.22);
}
@media (prefers-reduced-motion: reduce) {
  .scroll-gold { --gild-x: 100%; transition: none; }
}

/* ============================================================
   PHASE 11 — Billing toggle (Monthly / Yearly)
============================================================ */
.billing-toggle-wrap { display: flex; justify-content: center; margin: 0 0 32px; }
.billing-toggle {
  display: inline-flex;
  padding: 4px;
  background: rgba(15, 31, 29, 0.22);
  border: 1px solid rgba(230, 184, 97, 0.18);
  border-radius: 999px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.billing-btn {
  position: relative;
  padding: 10px 22px;
  border: 0;
  background: transparent;
  color: rgba(244, 241, 236, 0.55);
  font-family: var(--f-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  border-radius: 999px;
  cursor: pointer;
  transition: background 240ms ease, color 240ms ease;
}
.billing-btn.active {
  background: var(--gold);
  color: #1A0F00;
  box-shadow: 0 4px 14px rgba(230, 184, 97, 0.28);
}
.billing-btn:focus-visible { outline: 2px solid var(--gold-ink); outline-offset: 2px; }
.billing-save {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 7px;
  background: var(--green);
  color: #F4F1EC;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  border-radius: 999px;
  text-transform: uppercase;
}
.billing-btn.active .billing-save { background: #1A0F00; color: var(--gold); }

.tier-price-strike {
  display: inline-block;
  margin-right: 10px;
  font-size: 0.55em;
  color: rgba(26, 15, 0, 0.45);
  text-decoration: line-through;
  text-decoration-thickness: 2px;
  font-weight: 600;
  vertical-align: middle;
}

/* =========================================================
   Stealth overrides, written when the nav genuinely had no items to surface.

   `.nav-burger { display: none !important }` used to live here and it outlived
   its reason. The nav has carried real items for a while now, and below 820px
   `.nav-links` is hidden and the burger is the only way to open `.mobile-menu`,
   so an unconditional hide left every phone visitor on index, about, contact,
   privacy, terms, refund and the two business policy pages with a wordmark and
   no navigation. Desktop kept its links, so the two widths disagreed, which is
   the tell that it was a leftover and not a decision. Verified on the live site
   at 500px on 2026-08-02: burger display:none, .nav-links display:none, and
   .mobile-menu parked at translateY(-361px) with aria-hidden="true".

   The two rules below stay because they cannot misfire: each one only hides a
   thing that has nothing in it, so they switch themselves off the moment the
   nav has something to say. Do not put an unconditional hide back here.
   ========================================================= */
.nav-links:empty { display: none; }
.mobile-menu:has(> :only-child) { display: none; }

/* Two consequences of the burger being real again, both on the seven pages
   whose nav is a wordmark and a CTA: about, contact, privacy, terms, refund,
   business-terms, business-data-processing. Their `.nav-links` is literally
   `<div class="nav-links"></div>` and their `#mobile-menu` holds exactly one
   link, so the rule directly above hides that menu.

   1. The burger opens a menu that is hidden, so it would be a control that
      does nothing. It is hidden by the same `:only-child` test that hides the
      menu, not by a separate list of pages, so the two can never fall out of
      step: fill one of those menus and the burger comes back on its own.
   2. With no burger and no links, the bar had only the wordmark on a phone,
      because `.nav .nav-cta` is hidden below 820px. That hide exists so the CTA
      does not fight the links for width, and on these pages there are no links
      to fight. So the CTA comes back exactly when `.nav-links` is empty, which
      is the same condition, read from the same element. On index the links are
      real, `:empty` does not match, and nothing changes there. */
body:has(.mobile-menu > :only-child) .nav-burger { display: none; }
@media (max-width: 820px) {
  .nav .nav-links:empty ~ .nav-cta { display: inline-flex; }
}
.footer-ig { display: inline-flex; align-items: center; gap: 8px; }
