/* ==========================================================================
   Little Ummah — design system
   Cream tonal palette + navy. Two colour families only.

   RTL readiness: all directional spacing/alignment uses CSS logical
   properties (inline-start/end, padding-inline, text-align: start), so adding
   dir="rtl" for Arabic in a later phase flips the layout without any
   component-level rewrites.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Fonts
   Self-hosted. The CSP allows no external origins, and the project ships no
   third-party runtime dependencies — so no Google Fonts <link>, no extra DNS
   and TLS handshake on shared hosting, and nothing leaves the visitor's
   browser to a third party.

   Only the play theme uses this family, and browsers fetch a font file only
   when rendered text actually needs it — so visitors on the default or
   festive theme never download these 30KB.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Fredoka";
  src: url("../fonts/fredoka-v17-latin-var.woff2") format("woff2-variations"),
       url("../fonts/fredoka-v17-latin-var.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
  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;
}

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Cream — tonal scale built around the brand base #F9F4EA */
  --cream-50:  #FDFCF8;
  --cream-100: #F9F4EA;
  --cream-200: #F3ECDE;
  --cream-300: #E9DECA;
  --cream-400: #DACAAE;
  --cream-500: #C4AE8C;

  /* Navy — tonal scale built around the brand navy #17223D */
  --navy-900: #0D1424;
  --navy-800: #17223D;
  --navy-700: #22304F;
  --navy-600: #34446A;
  --navy-500: #4C5C82;
  --navy-400: #6E7A99;
  --navy-300: #9AA3BA;
  --navy-200: #C2C8D6;

  /* Semantic */
  --bg:           var(--cream-100);
  --bg-raised:    var(--cream-50);
  --bg-sunk:      var(--cream-200);
  --bg-invert:    var(--navy-800);
  --ink:          var(--navy-800);
  /* navy-400 (#6E7A99) reads beautifully but only reaches 3.64:1 on --bg-sunk,
     failing WCAG AA for the small text that uses it (eyebrows, pills, dates,
     stat labels). navy-450 is the lightest navy that clears 4.5:1 on every
     cream surface with margin to spare, and stays lighter than --ink-soft so
     the type hierarchy still reads. */
  --navy-450:     #5A6789;
  --ink-muted:    var(--navy-450);
  --ink-soft:     var(--navy-500);
  --ink-invert:   var(--cream-100);
  --line:         var(--cream-300);
  --line-strong:  var(--cream-400);
  --line-hover:   var(--cream-500);
  --accent:       var(--navy-800);
  /* cream-500 (#C4AE8C) reached only 1.96:1 behind .stage__num. The ordinal is
     large text, so it needs 3:1 — and while it reads as a watermark it does
     carry the stage number, which rules out treating it as pure decoration.
     cream-600 is the deepest step of the same tan hue that clears the bar on
     both cream surfaces while staying visibly a watermark. */
  --cream-600:    #9B835D;
  --ink-faint:    var(--cream-600);   /* oversized ordinals, watermark numerals */

  /* Component-level semantic tokens. These exist so a theme can be swapped by
     redefining custom properties alone — no component rule ever needs editing.
     Every value below resolves to exactly the colour it replaced, so the
     default theme is unchanged. */
  --header-tint:      var(--cream-100); /* translucent sticky header base */
  --mark:             var(--navy-800);  /* brand glyph, hamburger bars */
  --media-bg:         var(--cream-200); /* letterbox behind images */
  --hero-glow:        var(--cream-200); /* hero radial wash */
  --surface-switch:   var(--cream-50);  /* language pill track */
  --surface-panel:    var(--cream-50);  /* mobile nav dropdown */
  --focus:            var(--navy-700);  /* focus ring */
  --btn-primary-bg:       var(--navy-800);
  --btn-primary-bg-hover: var(--navy-700);
  --btn-primary-ink:      var(--cream-100);
  --btn-ghost-hover:      var(--cream-200);
  --btn-invert-bg:        var(--cream-100);
  --btn-invert-bg-hover:  var(--cream-200);
  --btn-invert-ink:       var(--navy-800);
  --select-bg:        var(--cream-400); /* ::selection */
  --select-ink:       var(--navy-900);
  --link:             var(--navy-700);  /* inline links in prose */

  /* Deep surfaces — the footer and the CTA band. These are already dark in the
     default theme, so they need their own token family rather than reusing the
     light-surface ones; in the festive theme they go deeper still rather than
     flipping to gold. */
  --surface-deep:     var(--navy-800);
  --ink-deep:         var(--cream-200); /* footer body */
  --ink-deep-bright:  var(--cream-100); /* footer name, CTA heading */
  --ink-deep-soft:    var(--cream-300); /* CTA body */
  --ink-deep-muted:   var(--cream-400); /* footer column headings */
  --deep-cool:        var(--navy-200);  /* footer blurb */
  --deep-cool-faint:  var(--navy-300);  /* footer bottom line */
  --line-deep:        var(--navy-600);  /* footer divider */

  /* Text on the inverted band (dark-on-light in default, dark-on-gold festive) */
  --invert-eyebrow:   var(--cream-400);
  --invert-lede:      var(--cream-300);

  /* Type */
  --font-display: ui-serif, Georgia, "Iowan Old Style", "Times New Roman", serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --step--1: clamp(0.82rem, 0.79rem + 0.14vw, 0.89rem);
  --step-0:  clamp(1rem, 0.96rem + 0.19vw, 1.09rem);
  --step-1:  clamp(1.18rem, 1.1rem + 0.38vw, 1.4rem);
  --step-2:  clamp(1.42rem, 1.28rem + 0.68vw, 1.8rem);
  --step-3:  clamp(1.7rem, 1.46rem + 1.15vw, 2.35rem);
  --step-4:  clamp(2.04rem, 1.65rem + 1.87vw, 3.05rem);
  --step-5:  clamp(2.45rem, 1.82rem + 2.98vw, 3.95rem);

  /* Space */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;
  --sp-7: 3rem;
  --sp-8: 4rem;
  --sp-9: 6rem;

  --wrap: 74rem;
  --wrap-narrow: 44rem;

  --radius-sm: 6px;
  --radius:    12px;
  --radius-lg: 20px;
  --radius-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(23, 34, 61, 0.05);
  --shadow:    0 2px 8px rgba(23, 34, 61, 0.06), 0 1px 2px rgba(23, 34, 61, 0.04);
  --shadow-lg: 0 12px 32px rgba(23, 34, 61, 0.10), 0 2px 8px rgba(23, 34, 61, 0.05);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);

  --header-h: 4.5rem;
}

/* ==========================================================================
   1b. Festive theme — "night"
   A second palette the visitor opts into. The default cream/navy theme above
   is untouched and remains the default for every first-time visitor.

   HOW THIS IS SCOPED
   Applied at :root, so it covers the whole site. It began life scoped to a
   selector list (`.site-header, .hero`) as a proof of concept; because every
   component reads semantic tokens rather than palette tokens, widening the
   scope was a one-line change with no component edits.

   COLOUR ROLES
   Gold is a SURFACE and ORNAMENT colour, never body text: #E8B84B on the
   night background measures 9.30:1 but is uncomfortable for sustained
   reading, because at 77% saturation the blue channel is nearly absent and
   the eye gets almost no luminance-only edge to resolve glyphs against. Body
   copy uses the warm parchment scale; gold is for icons, borders, button
   fills and decoration.
   ========================================================================== */
:root[data-theme="festive"] {
  /* Night — the brand navy #17223D deepened in place. Hue is held between
     218.7 and 224.3 across the ramp, with a slight indigo lift in the upper
     decorative steps, so this reads as the same brand after dark. */
  --night-900: #080E1C;
  --night-800: #0F1B33;
  --night-700: #16243E;
  --night-600: #1E2F4E;
  --night-500: #2E3E6B;
  --night-400: #637196;
  --night-300: #8D99B4;
  --night-200: #BFC7D8;

  /* Gold — the cream ramp driven up in saturation (cream-500 sits at hue 36.4;
     these run 38.4-42.1), so the gold feels latent in the existing palette
     rather than imported. */
  --gold-700: #8A6626;
  --gold-600: #A87C2E;
  --gold-500: #C89A3C;
  --gold-400: #D9A441;
  --gold-300: #E8B84B;
  --gold-200: #EFD08F;
  --gold-100: #F7E6BE;

  /* Warm — parchment. warm-100 is the brand cream byte-identical; the ladder
     descends out of the halation band into comfortable body-text territory. */
  --warm-50:  #FEFCF7;
  --warm-100: #F9F4EA;
  --warm-200: #EFE7D6;
  --warm-300: #E5DBC6;
  --warm-400: #D5C9B2;
  --warm-500: #B3A48A;

  /* Semantic — the same names the components already consume.
     --ink is warm-300, NOT the brightest cream. Near-white body text on a
     dark ground causes halation (glyphs bloom and blur), so the brand cream
     is promoted to display sizes only via --ink-display. */
  --bg:           var(--night-800);
  --bg-raised:    var(--night-700);
  --bg-sunk:      var(--night-900);
  --bg-invert:    var(--gold-400);
  --ink:          var(--warm-300);
  --ink-display:  var(--warm-100);
  --ink-soft:     var(--warm-400);
  --ink-muted:    var(--warm-500);
  --ink-invert:   var(--night-900);
  /* The audit designated night-500 for watermark numerals on the condition it
     never carries information. .stage__num does carry information (the stage
     ordinal), and night-500 is 1.65:1 there. gold-700 is the deepest step that
     still clears 3:1 for large text on both the page and the sunk surface,
     so the numeral stays a quiet watermark while remaining legible. */
  --ink-faint:    var(--gold-700);
  --line:         var(--gold-600);
  --line-strong:  var(--gold-500);
  --line-hover:   var(--gold-300);
  --accent:       var(--gold-300);
  --link:         var(--gold-200);

  /* Component tokens. Every one of these must be reassigned — anything left
     out silently inherits the cream/navy value and disappears against the
     night ground. */
  --header-tint:      var(--night-800);
  --mark:             var(--gold-300);
  --mark-ink:         var(--night-900);
  --media-bg:         var(--night-600);
  --hero-glow:        var(--night-600);
  --surface-switch:   var(--night-600);
  --surface-panel:    var(--night-700);
  --focus:            var(--gold-300);
  --focus-on-gold:    var(--night-900);
  --btn-primary-bg:       var(--gold-400);
  --btn-primary-bg-hover: var(--gold-300);
  --btn-primary-ink:      var(--night-900);
  --btn-ghost-hover:      var(--night-600);
  /* .btn--invert is the button for dark bands. In the default theme those
     bands are navy so it is cream-on-navy; here the bands are deep night, so
     a night fill would vanish into the surface (1.00:1). It takes the gold
     fill instead — 8.57:1 against the deep surface. */
  --btn-invert-bg:        var(--gold-400);
  --btn-invert-bg-hover:  var(--gold-300);
  --btn-invert-ink:       var(--night-900);
  --select-bg:        var(--gold-200);
  --select-ink:       var(--night-900);

  /* Deep surfaces. The footer and CTA band go DEEPER at night rather than
     flipping to the gold band — a full-width gold slab at the base of every
     page fights the nighttime register, and dark-on-gold at that scale is
     tiring. The gold band stays reserved for --bg-invert. */
  --surface-deep:     var(--night-900);
  --ink-deep:         var(--warm-300);
  --ink-deep-bright:  var(--warm-100);
  --ink-deep-soft:    var(--warm-400);
  --ink-deep-muted:   var(--warm-500);
  --deep-cool:        var(--night-200);
  --deep-cool-faint:  var(--night-300);
  --line-deep:        var(--gold-600);

  /* On the gold band the polarity inverts: everything on it is night-toned.
     No gold step may appear here — best case is 2.33:1. */
  --invert-eyebrow:   var(--night-700);
  --invert-lede:      var(--night-800);

  /* Ornament colour, consumed by the decorative layer only. */
  --decor-gold:   var(--gold-300);
  --decor-ink:    var(--gold-300);
  --wave-h:       clamp(44px, 7vw, 96px);

  /* Shadows need to read as depth against dark, not as grey haze. */
  --shadow:    0 2px 10px rgba(0, 0, 0, 0.35);
  --shadow-lg: 0 18px 44px rgba(0, 0, 0, 0.45), 0 2px 10px rgba(0, 0, 0, 0.3);

  /* Kept from when this block was scoped to individual sections, and still
     worth knowing: a descendant inherits the COMPUTED colour an ancestor
     already resolved, so redefining --ink on a section does NOT recolour text
     that merely inherits. A section-scoped theme must set `color` too. At
     :root this is redundant — `body { color: var(--ink) }` resolves against
     these values — but it costs nothing and it documents the trap. */
  color: var(--ink);
}

/* The hero paints its own night wash. Everything below it keeps the default
   cream palette for now, which is what makes this a scoped proof of concept
   rather than a site-wide swap. */
[data-theme="festive"] .hero {
  background:
    radial-gradient(70% 90% at 78% 8%, var(--night-600) 0%, transparent 64%),
    var(--night-800);
  /* Reserve the wave band's own height as extra bottom padding, so the waves
     always sit below the last line of copy instead of behind it. Without this
     the stat row and the waves collide at narrow widths. */
  padding-block-end: calc(var(--sp-8) + var(--wave-h));
}

/* Display type takes the brand cream; running copy stays on the slightly
   dimmer --ink. Headings inherit their colour, so they need an explicit rule
   to opt up to the brighter tone. */
[data-theme="festive"] h1,
[data-theme="festive"] h2,
[data-theme="festive"] h3,
[data-theme="festive"] h4,
[data-theme="festive"] .hero__stat-num,
[data-theme="festive"] .brand__name,
[data-theme="festive"] .price,
[data-theme="festive"] .stage__num {
  color: var(--ink-display);
}
[data-theme="festive"] .stage__num { color: var(--ink-faint); }

/* Surfaces that set their own polarity keep it — a display-cream heading on
   the gold band or on a deep surface would be wrong in both directions. */
[data-theme="festive"] .section--invert :is(h1, h2, h3, h4) { color: var(--ink-invert); }
[data-theme="festive"] .cta-band :is(h1, h2, h3) { color: var(--ink-deep-bright); }
[data-theme="festive"] .site-footer :is(h1, h2, h3) { color: var(--ink-deep-muted); }
[data-theme="festive"] .site-footer__name { color: var(--ink-deep-bright); }

/* A gold focus ring on a gold control measures 1.22:1 — effectively invisible.
   Every control whose fill is gold flips its ring to the dark partner. */
[data-theme="festive"] .btn--primary:focus-visible,
[data-theme="festive"] .lang-switch__opt.is-active:focus-visible,
[data-theme="festive"] .skip-link:focus-visible {
  outline-color: var(--focus-on-gold);
}

/* The brand glyph is a filled gold disc in this theme, so its interior mark
   must be the declared dark partner rather than inheriting gold on gold. */
[data-theme="festive"] .brand__mark { color: var(--mark); }

/* ==========================================================================
   1c. Play theme — "kids store"
   A third palette: bright and cheerful, in the register of a colourful
   children's shop. The default and festive blocks above are untouched.

   HOW THIS IS SCOPED
   Applied to `body.page-home`, so it covers the whole homepage and nothing
   else — index.php sets that class. Declaring the tokens on <body> means the
   header inherits them too. To go site-wide, replace the selector with
   `:root[data-theme="play"]` and drop the .page-home requirement; the full
   token set is already defined below.

   THE RULE THAT MAKES BRIGHT SAFE
   Every bright colour here fails as text: coral-500 is 2.86:1 on the page,
   sun-500 is 1.41:1, leaf-500 is 2.61:1. So brightness lives ENTIRELY in
   fills, borders and ornament, and every piece of text is deep slate. That is
   also how premium kids brands read as premium rather than cheap — colour in
   blocks, not smeared over the type. Ratios in the comments are the WORST
   case across --bg, --bg-raised and --bg-sunk.
   ========================================================================== */
[data-theme="play"] body.page-home,
[data-theme="play"] body.page-home .site-header {
  /* Sky — the light grounds. White is a real surface here, used to keep air
     between the colour blocks. */
  --sky-50:  #FFFFFF;
  --sky-100: #EAF3FB;
  --sky-200: #DCEBF7;
  --sky-300: #C7DDF0;
  --sky-400: #A9C9E4;

  /* Slate — every piece of text in this theme */
  --slate-900: #16283A;
  --slate-800: #22384C;
  --slate-700: #35485C;
  --slate-600: #46596C;
  --slate-500: #55697D;
  --slate-400: #7E8FA0;   /* 3.0:1 — ornament only, never text */

  /* Coral — the lead accent */
  --coral-700: #A8331F;
  --coral-600: #C4452F;
  --coral-500: #EE6352;
  --coral-400: #F47C6C;
  --coral-300: #FBB8AE;

  /* Sun — the warm accent */
  --sun-700: #B07908;
  --sun-600: #E0A31A;
  --sun-500: #FFC542;
  --sun-400: #FFD166;
  --sun-300: #FFE3A8;
  --sun-200: #FFF6E2;

  /* Leaf — the cool accent */
  --leaf-700: #14705A;
  --leaf-600: #1E8A70;
  --leaf-500: #2FA98C;
  --leaf-400: #4FC3A1;
  --leaf-300: #9BDDC8;

  /* Semantic */
  --bg:           var(--sky-100);
  --bg-raised:    var(--sky-50);
  --bg-sunk:      var(--sky-200);
  --bg-invert:    var(--coral-600);
  --ink:          var(--slate-800);   /*  9.94:1 */
  --ink-display:  var(--slate-900);   /* 12.35:1 — headings */
  --ink-soft:     var(--slate-700);   /*  7.73:1 */
  --ink-muted:    var(--slate-500);   /*  4.66:1 — the lightest slate that
                                         clears AA on the sunk surface */
  --ink-invert:   var(--sky-50);      /*  4.95:1 on the coral band */
  --ink-faint:    var(--coral-600);   /*  4.07:1 — large watermark ordinals */
  --line:         var(--sky-300);
  --line-strong:  var(--sky-400);
  --line-hover:   var(--leaf-500);
  --accent:       var(--coral-600);
  --link:         var(--leaf-700);    /*  4.94:1 — the only accent safe as text */

  /* Component tokens */
  --header-tint:      var(--sky-100);
  --mark:             var(--coral-600);
  --mark-ink:         var(--sky-50);
  --media-bg:         var(--sky-200);
  --hero-glow:        #FFF2D6;        /* a warm sunny wash against the sky */
  --surface-switch:   var(--sky-50);
  --surface-panel:    var(--sky-50);
  --focus:            var(--leaf-700);
  --focus-on-fill:    var(--sky-50);  /* ring for coral-filled controls, 4.95:1 */
  --btn-primary-bg:       var(--coral-600);  /* label 4.95:1, boundary 4.07:1 */
  --btn-primary-bg-hover: var(--coral-700);
  --btn-primary-ink:      var(--sky-50);
  --btn-ghost-hover:      var(--sky-200);
  --btn-invert-bg:        var(--sky-50);
  --btn-invert-bg-hover:  var(--sky-200);
  --btn-invert-ink:       var(--coral-700);
  --select-bg:        var(--sun-300);
  --select-ink:       var(--slate-900);  /* 12.01:1 */

  /* Deep surfaces — defined now so widening the scope needs no new work */
  --surface-deep:     var(--slate-900);
  --ink-deep:         var(--sky-200);   /* 12.35:1 */
  --ink-deep-bright:  var(--sky-50);    /* 15.01:1 */
  --ink-deep-soft:    var(--sky-300);   /* 10.74:1 */
  --ink-deep-muted:   var(--sky-400);   /*  8.69:1 */
  --deep-cool:        var(--leaf-300);  /*  9.70:1 */
  --deep-cool-faint:  var(--sun-300);   /* 12.01:1 */
  --line-deep:        var(--leaf-500);  /*  5.13:1 non-text */

  /* The coral band inverts polarity: light text on coral, never coral on coral */
  --invert-eyebrow:   var(--sun-200);   /*  4.61:1 */
  --invert-lede:      var(--sky-50);    /*  4.95:1 */

  /* Ornament — where all the brightness lives */
  --decor-coral:  var(--coral-500);
  --decor-sun:    var(--sun-500);
  --decor-leaf:   var(--leaf-500);

  /* Rounded, friendly display face. Body copy stays on the system sans so
     long-form text remains as readable as in the other two themes. */
  --font-display: "Fredoka", ui-rounded, "Trebuchet MS", var(--font-body);

  /* Playful shapes: bubblier corners than the other themes */
  --radius-sm: 10px;
  --radius:    18px;
  --radius-lg: 28px;

  --shadow-sm: 0 1px 2px rgba(22, 40, 58, 0.06);
  --shadow:    0 4px 14px rgba(22, 40, 58, 0.09), 0 1px 3px rgba(22, 40, 58, 0.06);
  --shadow-lg: 0 18px 44px rgba(22, 40, 58, 0.14), 0 4px 12px rgba(22, 40, 58, 0.08);

  /* Descendants inherit the computed colour body already resolved against
     :root, so a section-scoped theme must restate `color`. */
  color: var(--ink);
}

[data-theme="play"] .page-home .hero {
  background:
    radial-gradient(70% 86% at 82% 4%, var(--hero-glow) 0%, transparent 60%),
    var(--bg);
}

/* Fredoka is a rounded face with a large x-height; at the display sizes the
   brand serif was tuned for it reads oversized, so the tracking and weight
   are pulled back to keep the headline confident rather than shouty. */
[data-theme="play"] .page-home :is(h1, h2, h3, h4),
[data-theme="play"] .page-home .hero__stat-num,
[data-theme="play"] .page-home .price,
[data-theme="play"] .site-header .brand__name {
  color: var(--ink-display);
  font-weight: 600;
  letter-spacing: -0.005em;
}
[data-theme="play"] .page-home .hero h1 { line-height: 1.08; }

/* A leaf-green ring on a coral fill is muddy; flip it to the light partner. */
[data-theme="play"] .btn--primary:focus-visible,
[data-theme="play"] .lang-switch__opt.is-active:focus-visible,
[data-theme="play"] .theme-switch__opt.is-active:focus-visible,
[data-theme="play"] .skip-link:focus-visible {
  outline-color: var(--focus-on-fill);
}

/* --- Colour-blocked sections --------------------------------------------
   A single background across every section reads monochrome-with-accents,
   however bright the accents are. These bands alternate the ground itself so
   the page has rhythm. The .band-- classes are inert markers in the markup:
   only this theme styles them, so the default and festive themes are
   unaffected by their presence.

   Every band was contrast-checked against --ink, --ink-soft, --ink-muted,
   --link and --ink-faint before being used. */
[data-theme="play"] .page-home .band--cream    { background: #FFF6E8; }
[data-theme="play"] .page-home .band--coral    { background: #FDECE8; }
[data-theme="play"] .page-home .band--sky      { background: var(--sky-100); }
[data-theme="play"] .page-home .band--sky-alt  { background: var(--sky-100); }

/* The CTA keeps the saturated coral — one fully-committed colour block is
   what stops the palette reading as pastel wash. */
[data-theme="play"] .page-home .cta-band {
  background: var(--bg-invert);
  color: var(--ink-invert);
}
[data-theme="play"] .page-home .cta-band :is(h1, h2, h3) { color: var(--ink-invert); }
[data-theme="play"] .page-home .cta-band p { color: var(--invert-eyebrow); }

/* Cards sit on tinted grounds now, so they need a visible edge rather than
   relying on a fill difference of 1.1:1. */
[data-theme="play"] .page-home .card {
  border-color: var(--sky-300);
  border-width: 2px;
}

/* A rounded panel behind the stat row — a colour block behind a content
   group, rather than another full-width band. */
[data-theme="play"] .page-home .hero__meta {
  background: #FFF4DA;
  border-radius: var(--radius-lg);
  padding: var(--sp-5);
  border-block-start: 0;
  margin-block-start: var(--sp-6);
}

/* Chunkier, bubblier buttons — the single clearest signal of the register. */
[data-theme="play"] .page-home .btn,
[data-theme="play"] .site-header .btn {
  border-radius: var(--radius-pill);
  font-weight: 600;
  padding-inline: 1.7rem;
}

/* --------------------------------------------------------------------------
   2. Reset
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1rem);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.015em;
  margin: 0 0 var(--sp-4);
  text-wrap: balance;
}
h1 { font-size: var(--step-5); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-1); }
h4 { font-size: var(--step-0); }

p { margin: 0 0 var(--sp-4); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

a { color: inherit; text-underline-offset: 0.18em; }

img, svg, picture { max-width: 100%; height: auto; display: block; }

ul, ol { margin: 0 0 var(--sp-4); padding-inline-start: 1.15em; }

button { font: inherit; color: inherit; }

hr { border: 0; border-top: 1px solid var(--line); margin: var(--sp-7) 0; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

::selection { background: var(--select-bg); color: var(--select-ink); }

.skip-link {
  position: absolute;
  inset-inline-start: var(--sp-4);
  inset-block-start: -100%;
  z-index: 200;
  background: var(--btn-primary-bg);
  color: var(--btn-primary-ink);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-sm);
  text-decoration: none;
}
.skip-link:focus { inset-block-start: var(--sp-4); }

/* --------------------------------------------------------------------------
   3. Layout primitives
   -------------------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--sp-5);
}
.wrap--narrow { max-width: var(--wrap-narrow); }

.section { padding-block: var(--sp-9); }
.section--tight { padding-block: var(--sp-8); }
.section--sunk { background: var(--bg-sunk); }
.section--invert { background: var(--bg-invert); color: var(--ink-invert); }
.section--invert .eyebrow { color: var(--invert-eyebrow); }
.section--invert .lede { color: var(--invert-lede); }

.section-head { max-width: 46rem; margin-bottom: var(--sp-7); }
.section-head--center { margin-inline: auto; text-align: center; }

.eyebrow {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin: 0 0 var(--sp-3);
}

.lede {
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--ink-soft);
}

/* --------------------------------------------------------------------------
   4. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: 0.8rem 1.5rem;
  min-height: 2.75rem;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-size: var(--step-0);
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.18s var(--ease), color 0.18s var(--ease),
              border-color 0.18s var(--ease), transform 0.18s var(--ease);
}
.btn:active { transform: translateY(1px); }

.btn--primary { background: var(--btn-primary-bg); color: var(--btn-primary-ink); }
.btn--primary:hover { background: var(--btn-primary-bg-hover); }

.btn--ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--line-strong);
}
.btn--ghost:hover { background: var(--btn-ghost-hover); border-color: var(--line-hover); }

.btn--invert { background: var(--btn-invert-bg); color: var(--btn-invert-ink); }
.btn--invert:hover { background: var(--btn-invert-bg-hover); }

.btn--sm { padding: 0.5rem 1rem; min-height: 2.25rem; font-size: var(--step--1); }
.btn--block { display: flex; width: 100%; }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  align-items: center;
}

/* --------------------------------------------------------------------------
   5. Site header + nav
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  inset-block-start: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--header-tint) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(12px);
  border-block-end: 1px solid var(--line);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  min-height: var(--header-h);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  text-decoration: none;
  color: var(--ink);
  flex-shrink: 0;
}
.brand__mark { width: 2rem; height: 2rem; color: var(--mark); flex-shrink: 0; }
.brand__mark svg { width: 100%; height: 100%; }
.brand__text { display: flex; flex-direction: column; line-height: 1.15; }
.brand__name {
  font-family: var(--font-display);
  font-size: 1.16rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.brand__tag {
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--sp-6);
}
.site-nav__list {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  list-style: none;
  margin: 0;
  padding: 0;
}
.site-nav__link {
  display: inline-block;
  padding-block: var(--sp-2);
  font-size: 0.95rem;
  font-weight: 500;
  text-decoration: none;
  color: var(--ink-soft);
  position: relative;
  transition: color 0.18s var(--ease);
}
.site-nav__link:hover { color: var(--ink); }
.site-nav__link.is-current { color: var(--ink); font-weight: 600; }
.site-nav__link.is-current::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  height: 2px;
  background: var(--mark);
  border-radius: 2px;
}

.site-nav__aside {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
}

.lang-switch {
  display: inline-flex;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  padding: 2px;
  background: var(--surface-switch);
}
.lang-switch__opt {
  padding: 0.25rem 0.7rem;
  border-radius: var(--radius-pill);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-decoration: none;
  color: var(--ink-muted);
  transition: background-color 0.18s var(--ease), color 0.18s var(--ease);
}
.lang-switch__opt:hover { color: var(--ink); }
.lang-switch__opt.is-active { background: var(--btn-primary-bg); color: var(--btn-primary-ink); }

/* Theme switcher — the same segmented pill as .lang-switch, so three themes
   read as one control rather than a mystery button. Sized to match that pill's
   height exactly, so adding a third option does not change the header height. */
.theme-switch {
  display: inline-flex;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  padding: 2px;
  background: var(--surface-switch);
  flex-shrink: 0;
}
.theme-switch__opt {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  width: 1.9rem;
  height: 1.75rem;
  border-radius: var(--radius-pill);
  color: var(--ink-muted);
  text-decoration: none;
  transition: background-color 0.18s var(--ease), color 0.18s var(--ease);
}
.theme-switch__opt:hover { color: var(--ink); }
.theme-switch__opt.is-active {
  background: var(--btn-primary-bg);
  color: var(--btn-primary-ink);
}
.theme-switch__icon {
  display: grid;
  place-items: center;
  width: 0.95rem;
  height: 0.95rem;
  flex-shrink: 0;
}
.theme-switch__icon svg { width: 100%; height: 100%; }

/* The icons carry the meaning in the header bar; the accessible name comes
   from each link's title plus aria-current. Labels return in the mobile nav
   panel, where there is room and the tap targets need to be bigger. */
.theme-switch__label { display: none; }

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0 0.6rem;
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.nav-toggle__bar {
  display: block;
  height: 2px;
  width: 100%;
  background: var(--mark);
  border-radius: 2px;
  transition: transform 0.22s var(--ease), opacity 0.16s var(--ease);
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* --------------------------------------------------------------------------
   6. Hero
   -------------------------------------------------------------------------- */
.hero {
  padding-block: var(--sp-9) var(--sp-8);
  background:
    radial-gradient(60% 80% at 82% 12%, var(--hero-glow) 0%, transparent 62%),
    var(--bg);
  overflow: hidden;
}
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: var(--sp-8);
  align-items: center;
}
.hero__title { margin-bottom: var(--sp-5); }
.hero__lede { max-width: 34rem; margin-bottom: var(--sp-6); }

.hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5);
  margin-block-start: var(--sp-7);
  padding-block-start: var(--sp-5);
  border-block-start: 1px solid var(--line);
}
.hero__stat { display: flex; flex-direction: column; gap: 2px; }
.hero__stat-num {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1;
}
.hero__stat-label {
  font-size: var(--step--1);
  color: var(--ink-muted);
  letter-spacing: 0.02em;
}

.hero__art {
  position: relative;
  aspect-ratio: 4 / 3.4;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--media-bg);
  box-shadow: var(--shadow-lg);
}
.hero__art img { width: 100%; height: 100%; object-fit: cover; }

/* --------------------------------------------------------------------------
   7. Cards — shared
   -------------------------------------------------------------------------- */
.card {
  display: flex;
  flex-direction: column;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform 0.22s var(--ease), box-shadow 0.22s var(--ease),
              border-color 0.22s var(--ease);
}
.card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
  border-color: var(--line-strong);
}
.card__media {
  aspect-ratio: 4 / 3;
  background: var(--media-bg);
  overflow: hidden;
  position: relative;
}
.card__media img { width: 100%; height: 100%; object-fit: cover; }
.card__body { padding: var(--sp-5); display: flex; flex-direction: column; flex: 1; }
.card__title { margin-bottom: var(--sp-2); }
.card__title a { text-decoration: none; }
.card__title a:hover { text-decoration: underline; }
.card__text { color: var(--ink-soft); font-size: 0.95rem; margin-bottom: var(--sp-4); }
.card__foot { margin-block-start: auto; padding-block-start: var(--sp-2); }

.badge {
  position: absolute;
  inset-block-start: var(--sp-3);
  inset-inline-start: var(--sp-3);
  background: var(--btn-primary-bg);
  color: var(--btn-primary-ink);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  padding: 0.3rem 0.65rem;
  border-radius: var(--radius-pill);
}

.pill {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-muted);
  background: var(--bg-sunk);
  border: 1px solid var(--line);
  padding: 0.22rem 0.6rem;
  border-radius: var(--radius-pill);
}

/* --------------------------------------------------------------------------
   8. Grids
   -------------------------------------------------------------------------- */
.grid { display: grid; gap: var(--sp-5); }
.grid--products { grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr)); }
.grid--posts    { grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr)); }
.grid--3        { grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); }
.grid--2        { grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }

/* --------------------------------------------------------------------------
   9. Stage cards
   -------------------------------------------------------------------------- */
.stage {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: var(--sp-7);
  align-items: center;
  padding-block: var(--sp-8);
  border-block-start: 1px solid var(--line);
}
.stage:first-of-type { border-block-start: 0; padding-block-start: var(--sp-5); }

/* Alternate sides, but mirror the track sizes too, so the artwork keeps the
   same width on every row instead of swapping between 0.9fr and 1.1fr. */
.stage:nth-child(even) { grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); }
.stage:nth-child(even) .stage__art { order: 2; }

.stage__art {
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--media-bg);
  aspect-ratio: 1 / 1;
  box-shadow: var(--shadow);
}
.stage__art img { width: 100%; height: 100%; object-fit: cover; }

.stage__num {
  font-family: var(--font-display);
  font-size: var(--step-2);
  color: var(--ink-faint);
  line-height: 1;
  margin-bottom: var(--sp-3);
}
.stage__age {
  display: inline-block;
  margin-bottom: var(--sp-3);
}
.stage__title { margin-bottom: var(--sp-4); }

.stage__facts {
  display: grid;
  gap: var(--sp-4);
  margin-block-start: var(--sp-5);
  padding-block-start: var(--sp-5);
  border-block-start: 1px solid var(--line);
}
.stage__fact-label {
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: var(--sp-1);
}
.stage__fact-text { color: var(--ink-soft); font-size: 0.95rem; margin: 0; }

/* Compact stage teaser used on the home page */
.stage-teaser { text-align: start; }
.stage-teaser__art {
  aspect-ratio: 1 / 1;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--media-bg);
  margin-bottom: var(--sp-4);
  border: 1px solid var(--line);
}
.stage-teaser__art img { width: 100%; height: 100%; object-fit: cover; }
.stage-teaser__age {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: var(--sp-2);
}
.stage-teaser__title { font-size: var(--step-1); margin-bottom: var(--sp-2); }
.stage-teaser__text { font-size: 0.92rem; color: var(--ink-soft); margin: 0; }

/* --------------------------------------------------------------------------
   10. Product detail / price
   -------------------------------------------------------------------------- */
.price {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1;
}
.price__note {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 400;
  color: var(--ink-muted);
  margin-inline-start: var(--sp-2);
}

.product-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-bottom: var(--sp-4);
}

.product-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
}

/* --------------------------------------------------------------------------
   11. Prose (blog body, about page)
   -------------------------------------------------------------------------- */
.prose { max-width: 38rem; margin-inline: auto; font-size: 1.06rem; line-height: 1.75; }
.prose > * + * { margin-block-start: var(--sp-5); }
.prose h2 {
  font-size: var(--step-2);
  margin-block-start: var(--sp-7);
  margin-block-end: 0;
}
.prose h3 { font-size: var(--step-1); margin-block-start: var(--sp-6); margin-block-end: 0; }
.prose h2 + p, .prose h3 + p { margin-block-start: var(--sp-3); }
.prose p { margin-block-end: 0; }
.prose ul { padding-inline-start: 1.3em; }
.prose li + li { margin-block-start: var(--sp-2); }
.prose strong { font-weight: 650; }
.prose a { color: var(--link); }

.post-header { max-width: 38rem; margin-inline: auto; }
.post-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  align-items: center;
  font-size: var(--step--1);
  color: var(--ink-muted);
  margin-bottom: var(--sp-4);
}
.post-hero {
  aspect-ratio: 16 / 7;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--media-bg);
  margin-block: var(--sp-7);
}
.post-hero img { width: 100%; height: 100%; object-fit: cover; }

.back-link {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--ink-muted);
  text-decoration: none;
  margin-bottom: var(--sp-5);
}
.back-link:hover { color: var(--ink); }
.back-link::before { content: "←"; }
[dir="rtl"] .back-link::before { content: "→"; }

/* Sidebar that follows a long article down the page. */
.sticky-aside { position: sticky; inset-block-start: calc(var(--header-h) + var(--sp-5)); }

/* --------------------------------------------------------------------------
   12. Callout / CTA band
   -------------------------------------------------------------------------- */
.cta-band {
  background: var(--surface-deep);
  /* Not --ink-invert: that token means "text on the inverted band", which in
     the festive theme is dark-on-gold. This surface is deep night in both
     themes, so it needs the deep-surface ink. */
  color: var(--ink-deep-bright);
  border-radius: var(--radius-lg);
  padding: var(--sp-8) var(--sp-7);
  text-align: center;
}
.cta-band h2 { margin-bottom: var(--sp-3); }
.cta-band p { color: var(--ink-deep-soft); max-width: 38rem; margin-inline: auto; margin-bottom: var(--sp-6); }
.cta-band .btn-row { justify-content: center; }

.note {
  background: var(--bg-sunk);
  border: 1px solid var(--line);
  border-inline-start: 3px solid var(--line-hover);
  border-radius: var(--radius);
  padding: var(--sp-4) var(--sp-5);
  font-size: 0.95rem;
  color: var(--ink-soft);
}

/* --------------------------------------------------------------------------
   13. Footer
   -------------------------------------------------------------------------- */
.site-footer {
  background: var(--surface-deep);
  color: var(--ink-deep);
  padding-block: var(--sp-8) var(--sp-6);
  margin-block-start: var(--sp-9);
}
.site-footer a { color: var(--ink-deep); text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }

.site-footer__top {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: var(--sp-7);
  padding-block-end: var(--sp-6);
  border-block-end: 1px solid var(--line-deep);
}
.site-footer__name {
  font-family: var(--font-display);
  font-size: var(--step-1);
  color: var(--ink-deep-bright);
  margin-bottom: var(--sp-3);
}
.site-footer__blurb { color: var(--deep-cool); max-width: 32rem; font-size: 0.95rem; }

.site-footer__nav { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-5); }
.site-footer__heading {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-deep-muted);
  margin-bottom: var(--sp-3);
}
.site-footer__nav ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.site-footer__nav li { font-size: 0.95rem; }

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--sp-3);
  padding-block-start: var(--sp-5);
  font-size: var(--step--1);
  color: var(--deep-cool-faint);
}
.site-footer__bottom p { margin: 0; }

/* --------------------------------------------------------------------------
   14. Floating WhatsApp button
   -------------------------------------------------------------------------- */
.wa-float {
  position: fixed;
  inset-block-end: var(--sp-5);
  inset-inline-end: var(--sp-5);
  z-index: 90;
  width: 3.25rem;
  height: 3.25rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--btn-primary-bg);
  color: var(--btn-primary-ink);
  box-shadow: var(--shadow-lg);
  transition: transform 0.2s var(--ease), background-color 0.2s var(--ease);
}
.wa-float:hover { transform: scale(1.06); background: var(--btn-primary-bg-hover); }
.wa-float svg { width: 1.6rem; height: 1.6rem; }

/* --------------------------------------------------------------------------
   15. Empty state
   -------------------------------------------------------------------------- */
.empty {
  text-align: center;
  padding: var(--sp-8) var(--sp-5);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-lg);
  color: var(--ink-muted);
  background: var(--bg-raised);
}

/* --------------------------------------------------------------------------
   16. Responsive
   -------------------------------------------------------------------------- */

/* Tablet and below — collapse the nav into a panel */
@media (max-width: 62rem) {
  .nav-toggle { display: flex; }

  .site-nav {
    position: absolute;
    inset-inline: 0;
    inset-block-start: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: var(--sp-4) var(--sp-5) var(--sp-6);
    background: var(--surface-panel);
    border-block-end: 1px solid var(--line);
    box-shadow: var(--shadow-lg);

    /* Collapsed by default; toggled by JS via [data-open] */
    display: none;
  }
  .site-nav[data-open="true"] { display: flex; }

  .site-header__inner { position: relative; flex-wrap: wrap; }

  .site-nav__list { flex-direction: column; align-items: stretch; gap: 0; }
  .site-nav__list li + li { border-block-start: 1px solid var(--line); }
  .site-nav__link {
    display: block;
    padding-block: var(--sp-4);
    font-size: 1.05rem;
  }
  .site-nav__link.is-current::after { display: none; }
  .site-nav__link.is-current { color: var(--ink); }

  .site-nav__aside {
    flex-direction: column;
    align-items: stretch;
    gap: var(--sp-4);
    margin-block-start: var(--sp-5);
    padding-block-start: var(--sp-5);
    border-block-start: 1px solid var(--line);
  }
  .lang-switch { align-self: flex-start; }

  /* Inside the mobile nav panel there is room for labels, and a 44px-tall
     target is easier to hit than a 28px icon. */
  .theme-switch { align-self: flex-start; }
  .theme-switch__opt {
    width: auto;
    min-height: 2.5rem;
    padding-inline: 0.75rem;
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.02em;
  }
  .theme-switch__label { display: inline; }

  .hero__grid { grid-template-columns: 1fr; gap: var(--sp-7); }
  .hero__art { order: -1; aspect-ratio: 16 / 10; }

  .stage { grid-template-columns: 1fr; gap: var(--sp-5); }
  .stage:nth-child(even) .stage__art { order: 0; }
  /* Card artwork is square; 4/3 keeps the crop shallow enough to keep the
     card border in frame. */
  .stage__art { aspect-ratio: 4 / 3; }

  .site-footer__top { grid-template-columns: 1fr; gap: var(--sp-6); }

  /* Once the aside stacks under the article, sticking it would trap it. */
  .sticky-aside { position: static; }
}

/* Phones */
@media (max-width: 40rem) {
  :root { --header-h: 4rem; }

  .wrap { padding-inline: var(--sp-4); }

  .section { padding-block: var(--sp-8); }
  .section--tight { padding-block: var(--sp-7); }

  .brand__tag { display: none; }
  .brand__mark { width: 1.75rem; height: 1.75rem; }

  .hero { padding-block: var(--sp-7) var(--sp-6); }
  .hero__meta { gap: var(--sp-4) var(--sp-6); }
  .hero__art { aspect-ratio: 4 / 3; }

  /* One column, full-bleed-ish cards on small screens */
  .grid { gap: var(--sp-4); }
  .grid--products,
  .grid--posts,
  .grid--3,
  .grid--2 { grid-template-columns: 1fr; }

  .card__body { padding: var(--sp-4); }

  .btn-row .btn { width: 100%; }
  .btn-row { gap: var(--sp-2); }

  .cta-band { padding: var(--sp-7) var(--sp-5); }

  .post-hero { aspect-ratio: 3 / 2; margin-block: var(--sp-5); }
  .prose { font-size: 1.02rem; }

  .site-footer__nav { grid-template-columns: 1fr; gap: var(--sp-5); }
  .site-footer__bottom { flex-direction: column; gap: var(--sp-1); }

  .wa-float {
    inset-block-end: var(--sp-4);
    inset-inline-end: var(--sp-4);
    width: 3rem;
    height: 3rem;
  }
}

/* Two-up product grid on mid-size phones/phablets rather than a long column */
@media (min-width: 30rem) and (max-width: 40rem) {
  .grid--products { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--products .card__body { padding: var(--sp-3); }
  .grid--products .card__title { font-size: var(--step-0); }
}

/* Very small phones */
@media (max-width: 22rem) {
  .grid--products { grid-template-columns: 1fr; }
  .brand__name { font-size: 1rem; }
}

/* ==========================================================================
   18. Decorative layer
   Purely ornamental SVG motifs. Never interactive, never announced to
   assistive tech, never a scroll or hit-test participant.
   ========================================================================== */

/* Every theme's ornament ships on every page so the JS switcher can reveal it
   without a round-trip. Only the layer belonging to the active theme paints;
   the default theme paints none. */
.decor { display: none; }
[data-theme="festive"] .decor[data-decor-theme="festive"] { display: block; }
[data-theme="play"]    .decor[data-decor-theme="play"]    { display: block; }

.decor {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  /* Decoration must never intercept a tap meant for a button beneath it. */
  pointer-events: none;
  /* Motifs bleed to the section edge; they must not widen the page. */
  contain: paint;
}
.decor * { pointer-events: none; }

.decor__item {
  position: absolute;
  display: block;
  color: var(--decor-ink, currentColor);
  will-change: transform;
}
.decor__item svg { width: 100%; height: 100%; display: block; overflow: visible; }

/* Any section hosting decoration needs a stacking context, and its real
   content must sit above the ornament — every child except the layer itself. */
/* Positioning is applied ONLY to a section whose layer the active theme
   actually paints.
   
   The obvious rule — `.has-decor { position: relative }` for every marked
   section — turned out to be a real regression: marking three more sections
   changed sub-pixel rasterisation on card edges in the OTHER themes, because
   promoting a section to positioned changes how it rasterises. Matching on
   the painted layer means a theme only pays for the sections it decorates.

   The ornament sits at z-index -1 rather than lifting every sibling to
   z-index 1, so nothing is applied to the children either. `isolation`
   makes the section a stacking context, which keeps a negative z-index
   painting above the section's own background rather than behind it. */
[data-theme="festive"] .has-decor:has(> .decor[data-decor-theme="festive"]),
[data-theme="play"]    .has-decor:has(> .decor[data-decor-theme="play"]) {
  position: relative;
  isolation: isolate;
}
.has-decor > .decor { z-index: -1; }

/* Browsers without :has() fall back to the broad rule. They lose the
   rasterisation nicety, not the layout. */
@supports not selector(:has(*)) {
  .has-decor { position: relative; isolation: isolate; }
}

/* --- Motion -------------------------------------------------------------
   Deliberately slow and small-amplitude. These run behind body copy, so
   anything faster than ~6s or wider than a few pixels becomes a reading
   distraction rather than atmosphere. */
@keyframes lu-sway {
  0%, 100% { transform: rotate(-1.6deg); }
  50%      { transform: rotate(1.6deg); }
}
@keyframes lu-glow {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 1; }
}
@keyframes lu-twinkle {
  0%, 100% { opacity: 0.25; transform: scale(0.94); }
  50%      { opacity: 0.9;  transform: scale(1); }
}
@keyframes lu-drift {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-8px); }
}

/* Lanterns swing from their suspension point, not their centre. */
.decor__item--lantern {
  transform-origin: 50% 0;
  animation: lu-sway 7s ease-in-out infinite;
}
.decor__item--lantern-alt {
  transform-origin: 50% 0;
  animation: lu-sway 9.5s ease-in-out infinite reverse;
}
.decor__item--lantern .lantern__glow,
.decor__item--lantern-alt .lantern__glow {
  animation: lu-glow 5.5s ease-in-out infinite;
}
.decor__item--stars { animation: lu-twinkle 6.5s ease-in-out infinite; }
.decor__item--moon  { animation: lu-drift 12s ease-in-out infinite; }

/* --- Hero composition ---------------------------------------------------
   Weighted to the trailing half and the top/bottom edges. Nothing sits
   behind the headline or lede: an overlay behind body copy changes the
   effective background and would quietly erode the measured contrast, so
   the leading column is left clean. */
.hero .decor--moon {
  inset-inline-end: 7%;
  inset-block-start: 7%;
  width: clamp(70px, 12vw, 150px);
  aspect-ratio: 1 / 1;
  color: var(--decor-gold, currentColor);
  opacity: 0.9;
}
/* The text column ends at ~50% of the hero width, so the star field is held
   to the trailing 48%. A star drifting behind a paragraph would change the
   effective background under that text and quietly undercut the measured
   contrast — the numbers in the audit assume a flat ground. */
.hero .decor--stars {
  inset-inline-end: 0;
  inset-block-start: 0;
  width: 48%;
  height: 100%;
  color: var(--decor-gold, currentColor);
  opacity: 0.55;
}
.hero .decor--lantern-a {
  inset-inline-start: 53%;
  inset-block-start: 0;
  width: clamp(34px, 4.4vw, 62px);
  color: var(--decor-gold, currentColor);
  opacity: 0.85;
}
.hero .decor--lantern-b {
  inset-inline-start: 65%;
  inset-block-start: 0;
  width: clamp(24px, 3.2vw, 44px);
  color: var(--decor-gold, currentColor);
  opacity: 0.7;
}
/* Held at the motif's own 240:320 so it reads as an arch. Stretching it to the
   hero's height flattens the ogee and it reads as a rectangle instead. */
.hero .decor__item--arch {
  inset-inline-end: -5%;
  inset-block-start: 5%;
  width: clamp(220px, 38vw, 520px);
  aspect-ratio: 240 / 320;
  color: var(--decor-gold, currentColor);
  opacity: 0.16;
}
/* Three separately-classed paths, so the band layers night into gold rather
   than landing as one flat gold slab against the cream section below. */
.hero .decor__item--waves {
  inset-inline: 0;
  inset-block-end: 0;
  width: 100%;
  height: var(--wave-h);
  opacity: 1;
}
/* The motif ships per-path fill-opacity attributes (.28/.55/1) for use as a
   single-colour silhouette. Layering it in three colours means overriding
   fill-opacity too, or the attribute multiplies against these values and the
   band washes out. */
.hero .decor__item--waves .wave--back  { fill: var(--night-600); fill-opacity: 1; }
.hero .decor__item--waves .wave--mid   { fill: var(--gold-700); fill-opacity: 0.55; }
.hero .decor__item--waves .wave--front { fill: var(--gold-500); fill-opacity: 0.5; }
/* The baby motifs live in the gutter between the text column and the artwork —
   the one vertical channel in the hero with neither copy nor imagery. */
.hero .decor--footprints {
  inset-inline-start: 50.5%;
  inset-block-end: 26%;
  width: clamp(26px, 2.8vw, 42px);
  color: var(--decor-gold, currentColor);
  opacity: 0.13;
}
.hero .decor--rattle {
  inset-inline-start: 51%;
  inset-block-end: 40%;
  width: clamp(22px, 2.4vw, 34px);
  color: var(--decor-gold, currentColor);
  opacity: 0.12;
}

/* On phones the hero stacks (art above text) and the horizontal budget is
   gone. Keep the sky and the waves; drop the pieces that would crowd. */
/* Once the hero stacks (artwork above copy) the whole lower half is text, and
   there is no longer a gutter to hide ornament in. Everything that cannot be
   confined to the sky band at the top is dropped rather than laid over copy. */
@media (max-width: 62rem) {
  /* Stacked, the artwork sits flush under the header and hides everything
     behind it. Open a band of clear sky above the card so the moon, a lantern
     and some stars actually have somewhere to be. */
  [data-theme="festive"] .hero { padding-block-start: calc(var(--sp-8) + 4.5rem); }

  .hero .decor--stars {
    width: 100%;
    height: 13%;      /* the sky band only — stops above the artwork */
    opacity: 0.55;
  }
  .hero .decor--lantern-a {
    inset-inline-start: auto;
    inset-inline-end: 30%;
    width: clamp(30px, 9vw, 44px);
  }
  .hero .decor--lantern-b {
    inset-inline-start: auto;
    inset-inline-end: 46%;
    width: clamp(22px, 6.5vw, 32px);
  }
  .hero .decor--moon {
    inset-block-start: 2.5%;
    inset-inline-end: 6%;
    width: clamp(52px, 15vw, 84px);
  }

  /* The arch is full-height by design; stacked, that means it lies across the
     headline, lede and both buttons. It belongs to the wide layout only. */
  .hero .decor__item--arch,
  .hero .decor--footprints,
  .hero .decor--rattle { display: none; }
}
@media (max-width: 40rem) {
  [data-theme="festive"] .hero { padding-block-start: calc(var(--sp-7) + 4rem); }
  .hero .decor--stars { height: 11%; }
  .hero .decor--lantern-b { display: none; }
}

/* --- Play hero composition ----------------------------------------------
   Louder than the other two themes on purpose: these are foreground shapes in
   bright fills, not watermarks. The placement discipline is unchanged — the
   gutter beside the artwork and the band above it, never behind running copy,
   because ornament under text changes the background the contrast figures
   assume. */
.hero .decor--play-star {
  inset-inline-end: 3%;
  inset-block-start: 4%;
  width: clamp(96px, 15vw, 190px);
  aspect-ratio: 1 / 1;
  color: var(--decor-coral, currentColor);
  opacity: 0.9;
}
.hero .decor--play-moon {
  inset-inline-end: 21%;
  inset-block-start: 7%;
  width: clamp(74px, 11vw, 138px);
  aspect-ratio: 1 / 1;
  color: var(--decor-sun, currentColor);
  opacity: 0.95;
}
.hero .decor--play-bubbles {
  inset-inline-end: 0;
  inset-block-start: 0;
  width: 52%;
  height: 26%;
  color: var(--decor-leaf, currentColor);
  opacity: 0.75;
}
.hero .decor--play-rattle {
  inset-inline-start: 49.6%;
  inset-block-end: 14%;
  width: clamp(34px, 3.9vw, 56px);
  aspect-ratio: 140 / 180;
  color: var(--decor-coral, currentColor);
  opacity: 0.85;
}
.hero .decor--play-feet {
  inset-inline-start: 49.4%;
  inset-block-start: 30%;
  width: clamp(32px, 3.7vw, 54px);
  aspect-ratio: 1 / 1;
  color: var(--decor-leaf, currentColor);
  opacity: 0.8;
}

/* Motion stays in the same slow register as the other themes — bright does
   not mean busy. */
.hero .decor--play-moon { animation: lu-drift 14s ease-in-out infinite; }
.hero .decor--play-star { animation: lu-drift 18s ease-in-out infinite reverse; }

@media (max-width: 62rem) {
  /* Stacked, the artwork hides everything behind it, so the band above it is
     opened up and the gutter-dwellers are dropped. */
  [data-theme="play"] .hero { padding-block-start: calc(var(--sp-8) + 4.5rem); }
  .hero .decor--play-bubbles { width: 100%; height: 13%; opacity: 0.7; }
  .hero .decor--play-moon { inset-block-start: 2%; inset-inline-end: 6%; width: clamp(58px, 16vw, 92px); }
  .hero .decor--play-star { inset-block-start: 3%; inset-inline-end: 34%; width: clamp(52px, 14vw, 84px); }
  .hero .decor--play-rattle,
  .hero .decor--play-feet { display: none; }
}
@media (max-width: 40rem) {
  [data-theme="play"] .hero { padding-block-start: calc(var(--sp-7) + 4rem); }
  .hero .decor--play-bubbles { height: 11%; }
  .hero .decor--play-star { display: none; }
}

/* --- Play: ornament for the other homepage sections ---------------------
   All of it lives in section padding and outer margins. Bands are wall-to-wall
   copy in the middle, so nothing is placed there. */

/* Why-staged-cards band */
.band--cream .decor--pw-cloud {
  inset-inline-start: 3%;
  inset-block-start: 8%;
  width: clamp(58px, 7vw, 104px);
  aspect-ratio: 200 / 110;
  color: var(--decor-sun, currentColor);
  opacity: 0.75;
  animation: lu-drift 17s ease-in-out infinite;
}
.band--cream .decor--pw-bubbles {
  inset-inline-end: 0;
  inset-block-start: 0;
  width: 34%;
  height: var(--sp-9);
  color: var(--decor-leaf, currentColor);
  opacity: 0.6;
}
.band--cream .decor--pw-rings {
  inset-inline-end: 3%;
  inset-block-end: 6%;
  width: clamp(46px, 5.5vw, 84px);
  aspect-ratio: 180 / 160;
  color: var(--decor-leaf, currentColor);
  opacity: 0.5;
}

/* Four-stages band — the architectural motifs live here rather than the hero */
.band--sky .decor--ps-mosque {
  inset-inline-end: 2%;
  inset-block-start: 4%;
  width: clamp(78px, 9vw, 148px);
  aspect-ratio: 220 / 180;
  color: var(--decor-coral, currentColor);
  opacity: 0.5;
}
.band--sky .decor--ps-mat {
  inset-inline-start: 2%;
  inset-block-end: 5%;
  width: clamp(42px, 4.6vw, 74px);
  aspect-ratio: 150 / 210;
  color: var(--decor-leaf, currentColor);
  opacity: 0.42;
}
.band--sky .decor--ps-star {
  inset-inline-start: 6%;
  inset-block-start: 3%;
  width: clamp(34px, 3.6vw, 58px);
  aspect-ratio: 1 / 1;
  color: var(--decor-sun, currentColor);
  opacity: 0.72;
}

/* Shop band */
.band--coral .decor--pp-lantern {
  inset-inline-end: 4%;
  inset-block-start: 0;
  width: clamp(38px, 4.4vw, 68px);
  aspect-ratio: 120 / 200;
  color: var(--decor-sun, currentColor);
  opacity: 0.8;
  transform-origin: 50% 0;
  animation: lu-sway 11s ease-in-out infinite;
}
.band--coral .decor--pp-paci {
  inset-inline-start: 3%;
  inset-block-end: 7%;
  width: clamp(42px, 5vw, 78px);
  aspect-ratio: 160 / 140;
  color: var(--decor-leaf, currentColor);
  opacity: 0.45;
}
.band--coral .decor--pp-bubbles {
  inset-inline-start: 0;
  inset-block-start: 0;
  width: 30%;
  height: var(--sp-8);
  color: var(--decor-coral, currentColor);
  opacity: 0.5;
}

/* Journal band */
.band--sky-alt .decor--pj-moon {
  inset-inline-end: 3%;
  inset-block-start: 5%;
  width: clamp(56px, 6.5vw, 104px);
  aspect-ratio: 1 / 1;
  color: var(--decor-sun, currentColor);
  opacity: 0.8;
  animation: lu-drift 15s ease-in-out infinite;
}
.band--sky-alt .decor--pj-cloud {
  inset-inline-start: 2%;
  inset-block-start: 6%;
  width: clamp(52px, 6vw, 96px);
  aspect-ratio: 200 / 110;
  color: var(--decor-coral, currentColor);
  opacity: 0.35;
  animation: lu-drift 19s ease-in-out infinite reverse;
}

/* CTA band — ornament sits in the panel's own corners, which the centred
   copy never reaches. Nothing on the coral may be coral. */
.cta-band .decor--pc-star {
  inset-inline-end: 2%;
  inset-block-start: 6%;
  width: clamp(50px, 6vw, 96px);
  aspect-ratio: 1 / 1;
  color: var(--decor-sun, currentColor);
  opacity: 0.55;
}
.cta-band .decor--pc-rattle {
  inset-inline-start: 3%;
  inset-block-start: 8%;
  width: clamp(32px, 3.6vw, 54px);
  aspect-ratio: 140 / 180;
  color: var(--sky-50, currentColor);
  opacity: 0.4;
}
.cta-band .decor--pc-feet {
  inset-inline-start: 5%;
  inset-block-end: 8%;
  width: clamp(30px, 3.4vw, 50px);
  aspect-ratio: 1 / 1;
  color: var(--sky-50, currentColor);
  opacity: 0.32;
}

/* The side-margin ornaments need horizontal room the layout stops providing
   below ~1200px, where the content column reaches out toward the edges. */
@media (max-width: 75rem) {
  .band--sky .decor--ps-mat,
  .band--coral .decor--pp-paci,
  .band--cream .decor--pw-rings { display: none; }
}

@media (max-width: 62rem) {
  /* Narrow, these bands run wall-to-wall — keep only what fits in padding,
     and keep it clear of the padding's inner edge. */
  .band--sky-alt .decor--pj-cloud,
  .band--sky .decor--ps-star,
  .cta-band .decor--pc-rattle,
  .cta-band .decor--pc-feet { display: none; }
  /* Height stays well inside the section's own top padding so the field
     cannot reach the eyebrow that sits immediately below it. */
  .band--cream .decor--pw-bubbles,
  .band--coral .decor--pp-bubbles {
    width: 100%;
    height: calc(var(--sp-8) - 1.25rem);
    opacity: 0.45;
  }
  .band--sky .decor--ps-mosque { width: clamp(64px, 14vw, 96px); }
}

/* --- Other sections -----------------------------------------------------
   Much quieter than the hero. These bands carry real copy across their full
   width, so ornament is pushed to the margins and kept faint. */

/* Recessed content band — confined to the section's own top padding, the one
   strip guaranteed to be free of copy. The field letterboxes to a cluster
   rather than stretching, which reads as a patch of sky above the band. */
.section--sunk .decor--sunk-stars {
  inset-inline: 0;
  inset-block-start: 0;
  width: 100%;
  height: var(--sp-9);
  color: var(--decor-gold, currentColor);
  opacity: 0.22;
}

/* Call-to-action band. The copy is centred and well short of full width, so
   the two upper corners are genuinely free — the star field is not, and was
   dropped rather than faded until it stopped mattering. */
.cta-band { overflow: hidden; }
.cta-band .decor--band-moon {
  inset-inline-end: 1.5%;
  inset-block-start: 5%;
  width: clamp(56px, 8vw, 104px);
  aspect-ratio: 1 / 1;
  color: var(--decor-gold, currentColor);
  opacity: 0.45;
}
.cta-band .decor--band-star {
  inset-inline-start: 4%;
  inset-block-end: 10%;
  width: clamp(20px, 2.4vw, 34px);
  aspect-ratio: 1 / 1;
  color: var(--decor-gold, currentColor);
  opacity: 0.3;
}

/* Footer: a lantern hanging in the top padding, and a star field held to the
   same strip. Below that the footer is columns of links all the way down. */
.site-footer .decor--foot-stars {
  inset-inline: 0;
  inset-block-start: 0;
  width: 100%;
  height: var(--sp-8);
  color: var(--decor-gold, currentColor);
  opacity: 0.2;
}
.site-footer .decor--foot-lantern {
  inset-inline-end: 6%;
  inset-block-start: 0;
  width: clamp(24px, 2.6vw, 36px);
  color: var(--decor-gold, currentColor);
  opacity: 0.45;
}

@media (max-width: 62rem) {
  /* Narrow, the CTA copy fills the panel and the footer stacks — the corners
     these motifs relied on stop existing. */
  .cta-band .decor--band-moon,
  .cta-band .decor--band-star,
  .site-footer .decor--foot-lantern { display: none; }
  .site-footer .decor--foot-stars { opacity: 0.14; }
  .section--sunk .decor--sunk-stars { height: var(--sp-8); opacity: 0.16; }
}

/* --------------------------------------------------------------------------
   17. Preferences
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .card:hover { transform: none; }

  /* The decorative motifs stay — only their motion stops. The blanket rule
     above already freezes them; this pins them to a sensible resting pose
     rather than whatever frame they halt on. */
  .decor__item--lantern,
  .decor__item--lantern-alt { transform: rotate(0deg) !important; }
  .decor__item--stars { opacity: 0.6 !important; transform: none !important; }
  .decor__item--moon { transform: none !important; }
  .decor__item .lantern__glow { opacity: 0.85 !important; }
}

@media print {
  .site-header, .site-footer, .wa-float, .skip-link, .btn { display: none !important; }
  body { background: #fff; }
}
