/* ============================================================
   METRIC-MATCHED FALLBACK (2026-08-10)
   Measured: DM Sans renders the same string at 1335px where the
   system fallback renders 1609px — a 20% mismatch. Every page
   therefore reflowed when the webfont swapped in, and the bigger
   Keynote headings made it worse (about.html hit 0.202 CLS).
   Arial is the closest available base (ratio 0.9420), so the
   fallback is size-adjusted to occupy DM Sans' space. The swap is
   now layout-neutral instead of being hidden or accepted.
   ============================================================ */
@font-face {
  font-family: "DM Sans Fallback";
  src: local("Arial"), local("Helvetica"), local("Liberation Sans");
  size-adjust: 94.2%;
  ascent-override: 92%;
  descent-override: 24%;
  line-gap-override: 0%;
}

/* ============================================================
   Alpha — DESIGN TOKENS
   Source of truth for all colors, shape, shadow, motion, type.
   Per Alpha Design System v1 (§03, §04, §05, §15).
   ============================================================ */

:root {
  /* ----- BRAND ----- */
  --color-primary:        #0065C2;
  --color-primary-deep:   #0054A6;
  --color-primary-dark:   #162D4A;
  --color-ink:            #0F172A;

  /* ----- NEUTRALS ----- */
  --color-surface:        #FFFFFF;
  /* Aliased to the Keynote subtle surface: two greys 3 units apart read as
     an inconsistency between the home line-up and the product sections. */
  --color-surface-light:  var(--surface-subtle);
  /* Aliased to the Keynote subtle surface. The site had THREE near-identical
     quiet greys (#EEF2F7, #F5F7FA, #F5F5F7) doing the same job, which read as
     drift between sections. Dark theme still sets its own value below. */
  --color-surface-subtle: var(--surface-subtle);

  /* ----- TEXT ----- */
  --text-primary:         #111827;
  /* RENAMED 2026-08-10 — was --text-body, which collided with the font-size
     token of the same name further down this file. The size declaration comes
     later and shadowed this one, so the colour was DEAD: `color: var(--text-body)`
     resolved to `16px` and fell back to inherited. The dark-mode blocks then
     redefined it back to a colour, which would have broken all 24 font-size
     uses the moment dark mode was enabled. */
  --color-text-body:      #334155;
  --text-muted:           #64748B;
  --text-faint:           #94A3B8;
  --text-on-dark:         rgba(255, 255, 255, 0.92);
  --text-on-dark-em:      rgba(255, 255, 255, 0.85);
  --text-on-dark-sub:     rgba(255, 255, 255, 0.78);
  --text-on-dark-muted:   rgba(255, 255, 255, 0.70);
  --text-on-dark-faint:   rgba(255, 255, 255, 0.55);

  /* ----- SEMANTIC ----- */
  --color-success:        #059669;
  --color-success-deep:   #047857;   /* .btn-buy hover fill */
  --color-warning:        #F59E0B;
  --color-warning-text:   #B45309;
  --color-destructive:    #DC2626;
  --color-success-bg:     rgba(5, 150, 105, 0.10);
  --color-warning-bg:     rgba(245, 158, 11, 0.10);
  --color-destructive-bg: rgba(220, 38, 38, 0.10);

  /* ----- HAIRLINES ----- */
  --hairline:            1px solid rgba(0, 0, 0, 0.06);

  /* ----- GLASS SURFACES (UI layer only) ----- */
  --glass-subtle:        rgba(255, 255, 255, 0.28);
  --glass-regular:       rgba(255, 255, 255, 0.45);
  --glass-strong:        rgba(255, 255, 255, 0.72);
  --glass-hover:         rgba(255, 255, 255, 0.58);
  --glass-tint:          rgba(0, 101, 194, 0.15);
  --glass-hero-pill:     rgba(255, 255, 255, 0.22);
  /* Master: "top bit is frost glass and bottom is see-through". Reproduced -
     the bar was MORE transparent once scrolled (0.72) than at rest (0.86),
     which is backwards: content only slides under it after you scroll. At 0.72
     a large heading passing behind stayed legible through the glass and read
     as a smudge with a hard edge, not as frosting. */
  --glass-nav-scrolled:  rgba(255, 255, 255, 0.92);
  --glass-dark:          rgba(15, 23, 42, 0.85);

  /* White-on-hero glass border + hover states (nav chrome, e.g. .btn-nav-cta;
     CTA buttons no longer use glass — see BUTTON PRIMITIVES). */
  --glass-white-border:       rgba(255, 255, 255, 0.40);
  --glass-white-hover-bg:     rgba(255, 255, 255, 0.32);
  --glass-white-hover-border: rgba(255, 255, 255, 0.60);

  --glass-blur:          blur(18px) saturate(180%) brightness(1.04);
  --glass-blur-nav:      blur(22px) saturate(190%) brightness(1.04);
  --glass-blur-strong:   blur(24px) saturate(200%) brightness(1.04);
  --glass-blur-sm:       blur(12px) saturate(160%);

  /* ----- GLASS EDGES — directional (top-left bright, bottom-right dim) ----- */
  --glass-edge-top:      1px solid rgba(255, 255, 255, 0.65);
  --glass-edge-left:     1px solid rgba(255, 255, 255, 0.45);
  --glass-edge-right:    1px solid rgba(255, 255, 255, 0.25);
  --glass-edge-bottom:   1px solid rgba(255, 255, 255, 0.15);

  /* Brighter edge variant for badges on colored/hero backgrounds */
  --glass-edge-top-bright: 1px solid rgba(255, 255, 255, 0.85);

  /* Color-only variants of the edges, for use with `border-top-color`
     / `border-color` where the shorthand `border` is already set. */
  --glass-edge-color-top-bright: rgba(255, 255, 255, 0.85);
  --glass-edge-color-dim:        rgba(255, 255, 255, 0.12);

  /* ----- SHADOWS ----- */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.03),
              0 4px 12px rgba(0, 0, 0, 0.04);
  --shadow-2: 0 2px 4px rgba(0, 0, 0, 0.04),
              0 8px 20px rgba(0, 0, 0, 0.05);
  --shadow-3: 0 2px 6px rgba(0, 0, 0, 0.05),
              0 12px 28px rgba(0, 0, 0, 0.08),
              0 24px 48px rgba(0, 0, 0, 0.06);
  --shadow-glass:        var(--shadow-2),
                         inset 0 1px 0 rgba(255, 255, 255, 0.45),
                         inset 0 -1px 0 rgba(0, 0, 0, 0.05);
  --shadow-glass-raised: var(--shadow-3),
                         inset 0 1px 0 rgba(255, 255, 255, 0.55),
                         inset 0 -1px 0 rgba(0, 0, 0, 0.06);
  --shadow-primary:      0 2px 6px rgba(0, 101, 194, 0.25),
                         0 8px 20px rgba(0, 101, 194, 0.18);

  /* Component-specific shadows used in liquid-glass.css */
  --shadow-nav-scrolled:   0 2px 8px rgba(0, 0, 0, 0.05),
                           0 8px 24px rgba(0, 0, 0, 0.06);
  --shadow-hero-badge:     0 1px 2px rgba(0, 0, 0, 0.08),
                           0 6px 18px rgba(0, 0, 0, 0.10),
                           inset 0 1px 0 rgba(255, 255, 255, 0.45);

  /* Curved-glass pill — replaces flat borders on hero pills.
     Stack: atmospheric drop + contact shadow + bright top inner highlight
     + dark bottom inner contour. Reads as a beveled glass slab rather
     than an outlined shape. Apply with `border: none`. */
  --shadow-glass-pill:     0 1px 2px rgba(0, 0, 0, 0.10),
                           0 8px 22px -8px rgba(0, 0, 0, 0.28),
                           inset 0 1px 0 rgba(255, 255, 255, 0.55),
                           inset 0 -1px 0 rgba(0, 0, 0, 0.12);
  --shadow-glass-pill-hover:
                           0 2px 4px rgba(0, 0, 0, 0.12),
                           0 14px 32px -10px rgba(0, 0, 0, 0.34),
                           inset 0 1px 0 rgba(255, 255, 255, 0.70),
                           inset 0 -1px 0 rgba(0, 0, 0, 0.14);

  /* Solid primary button — same beveled-slab language as the glass pill,
     tuned for the opaque blue fill. Pair with --btn-primary-fill below. */
  --shadow-primary-pill:   0 1px 2px rgba(0, 0, 0, 0.12),
                           0 8px 22px -8px rgba(0, 0, 0, 0.35),
                           inset 0 1px 0 rgba(255, 255, 255, 0.38),
                           inset 0 -1px 0 rgba(0, 0, 0, 0.18);
  --shadow-primary-pill-hover:
                           0 2px 4px rgba(0, 0, 0, 0.14),
                           0 14px 32px -10px rgba(0, 0, 0, 0.42),
                           inset 0 1px 0 rgba(255, 255, 255, 0.48),
                           inset 0 -1px 0 rgba(0, 0, 0, 0.20);
  /* Light-from-above overlay laid over the base color (last layer). */
  --btn-primary-bevel:     linear-gradient(180deg,
                           rgba(255, 255, 255, 0.16) 0%,
                           rgba(255, 255, 255, 0.00) 55%,
                           rgba(0, 0, 0, 0.08) 100%);
  /* WHITE pill — same beveled-slab language tuned for a white fill. A white
     top-highlight is invisible on white, so ALL the perceived curvature must
     come from ink-tinted shading: a clearly visible cool-grey bottom half of
     the gradient plus a soft inset under-curve. Keep these strong enough to
     read on a phone — at ~7% tint the pill looked flat next to the blue
     buttons (user-flagged). */
  --shadow-white-pill:     0 1px 2px rgba(0, 0, 0, 0.10),
                           0 8px 22px -8px rgba(0, 0, 0, 0.30),
                           inset 0 1.5px 0 rgba(255, 255, 255, 1),
                           inset 0 -3px 6px rgba(30, 58, 95, 0.12),
                           inset 0 -1px 0 rgba(30, 58, 95, 0.22);
  --shadow-white-pill-hover:
                           0 2px 4px rgba(0, 0, 0, 0.12),
                           0 14px 32px -10px rgba(0, 0, 0, 0.36),
                           inset 0 1.5px 0 rgba(255, 255, 255, 1),
                           inset 0 -3px 6px rgba(30, 58, 95, 0.14),
                           inset 0 -1px 0 rgba(30, 58, 95, 0.26);
  /* Shading confined to the bottom third: enough tint for the 3D curve to
     read on a phone, but the pill's body stays pure white — with the tint
     starting at 40% the whole button read "faded" against bright-blue
     surrounds (user-flagged), even though pixels matched the CTA button. */
  --btn-white-bevel:       linear-gradient(180deg,
                           rgba(255, 255, 255, 1) 0%,
                           rgba(255, 255, 255, 0) 62%,
                           rgba(30, 58, 95, 0.15) 100%);
  /* BUY pill (.btn-buy) — the third semantic button: purchase/checkout
     actions (Square payment links). Same beveled-slab language, tuned for
     the emerald fill so commerce CTAs read instantly distinct from the
     blue action / white contact pair. */
  --btn-buy-fill:          var(--color-success);
  --shadow-buy-pill:       0 1px 2px rgba(0, 0, 0, 0.12),
                           0 8px 22px -8px rgba(4, 90, 63, 0.45),
                           inset 0 1px 0 rgba(255, 255, 255, 0.38),
                           inset 0 -1px 0 rgba(0, 0, 0, 0.18);
  --shadow-buy-pill-hover:
                           0 2px 4px rgba(0, 0, 0, 0.14),
                           0 14px 32px -10px rgba(4, 90, 63, 0.52),
                           inset 0 1px 0 rgba(255, 255, 255, 0.48),
                           inset 0 -1px 0 rgba(0, 0, 0, 0.20);
  --btn-buy-bevel:         linear-gradient(180deg,
                           rgba(255, 255, 255, 0.18) 0%,
                           rgba(255, 255, 255, 0.00) 55%,
                           rgba(0, 0, 0, 0.10) 100%);
  --shadow-mobile-drawer:  0 2px 6px rgba(0, 0, 0, 0.06),
                           0 16px 40px rgba(0, 0, 0, 0.14),
                           0 24px 64px rgba(0, 0, 0, 0.08),
                           inset 0 1px 0 rgba(255, 255, 255, 0.75);

  /* Hover text-shadow glows */
  --glow-white:   0 0 8px  rgba(255, 255, 255, 0.70),
                  0 0 16px rgba(255, 255, 255, 0.45);
  --glow-primary: 0 0 10px rgba(0, 101, 194, 0.55),
                  0 0 20px rgba(0, 101, 194, 0.30);

  /* Primary color tints — named by role rather than opacity. */
  --color-primary-tint-soft:    rgba(0, 101, 194, 0.08);  /* subtle hover bg */
  --color-primary-tint-bg:      rgba(0, 101, 194, 0.10);  /* badge background */
  --color-primary-ring-subtle:  rgba(0, 101, 194, 0.15);  /* input focus ring */
  --color-primary-border-soft:  rgba(0, 101, 194, 0.20);  /* outlined buttons */
  --color-primary-border-med:   rgba(0, 101, 194, 0.22);  /* secondary button */
  --color-primary-shadow-hover: rgba(0, 101, 194, 0.25);  /* primary btn hover extra shadow */
  --color-primary-border-strong:rgba(0, 101, 194, 0.40);  /* secondary button hover */

  /* Form input box-shadows (inset top shadow + bottom highlight). */
  --input-shadow:         inset 0 1px 3px rgba(0, 0, 0, 0.03),
                                  0 1px 0 rgba(255, 255, 255, 0.50);
  --input-shadow-focus:   inset 0 1px 3px rgba(0, 0, 0, 0.03),
                                  0 0 0 3px var(--color-primary-ring-subtle);

  /* Extra primary-color shadow stacked on top of --shadow-2 on btn-primary:hover. */
  --shadow-primary-hover: var(--shadow-2),
                          0 4px 14px var(--color-primary-shadow-hover);

  /* Near-solid white used for .btn-white hover bg — not a glass value. */
  --color-white-95:      rgba(255, 255, 255, 0.95);

  /* Glass fallbacks — for browsers without backdrop-filter, or users who
     set prefers-reduced-transparency. Each value is the theme-appropriate
     opaque substitute for the corresponding translucent surface. */
  --glass-fallback:            rgba(255, 255, 255, 0.92);
  --glass-fallback-strong:     rgba(255, 255, 255, 0.96);
  --glass-fallback-nav:        rgba(255, 255, 255, 0.95);
  --glass-fallback-hero:       rgba(255, 255, 255, 0.40);
  --glass-fallback-dark:       rgba(15, 23, 42, 0.96);
  --glass-fallback-reduced:    rgba(255, 255, 255, 0.94);

  /* Panel glass surfaces (tooltip / modal / dropdown / pagination / lightbox) */
  --glass-panel-soft:          rgba(255, 255, 255, 0.82);
  --glass-panel-medium:        rgba(255, 255, 255, 0.85);
  --glass-panel-strong:        rgba(255, 255, 255, 0.90);
  --glass-panel-opaque:        rgba(255, 255, 255, 0.92);
  --glass-panel-input:         rgba(255, 255, 255, 0.70);

  /* Scrims for modal backdrops */
  --scrim-modal:               rgba(0, 0, 0, 0.4);
  --scrim-lightbox:            rgba(0, 0, 0, 0.75);

  /* Hover tint — black over light surfaces, semantic opacities. */
  --hover-ink-soft:            rgba(0, 0, 0, 0.04);
  --hover-ink-medium:          rgba(0, 0, 0, 0.08);
  --hover-ink-strong:          rgba(0, 0, 0, 0.15);

  /* Semantic color 12% backgrounds (for toasts / subtle alerts) */
  --color-success-bg-solid:    rgba(5, 150, 105, 0.12);
  --color-warning-bg-solid:    rgba(245, 158, 11, 0.12);
  --color-destructive-bg-solid:rgba(220, 38, 38, 0.12);
  --color-primary-bg-solid:    rgba(0, 101, 194, 0.12);

  /* Semantic 25% for solid-border accents on colored cards */
  --color-success-border:      rgba(5, 150, 105, 0.25);

  /* Border-gray on glass panels (dropdowns, menus) */
  --border-on-glass:           rgba(0, 0, 0, 0.12);

  /* Hero-badge directional edges — tighter opacities than standard glass */
  --hero-badge-edge-left:   rgba(255, 255, 255, 0.30);
  --hero-badge-edge-right:  rgba(255, 255, 255, 0.20);
  --hero-badge-edge-bottom: rgba(255, 255, 255, 0.15);

  /* Specular highlight gradient stops */
  --specular-hotspot:    rgba(255, 255, 255, 0.22);
  --specular-falloff:    rgba(255, 255, 255, 0.06);

  /* ----- RADII ----- */
  --r-hairline: 2px;    /* micro rounding on hairline bars (nav lines, dividers) */
  --r-xs:     6px;    /* skeletons, checkboxes */
  --r-sm:     8px;    /* chips, small tags */
  --r-input:  12px;   /* inputs, selects */
  --r-md:     16px;   /* small panels */
  --r-card:   20px;   /* cards (workhorse) */
  --r-sheet:  28px;   /* modals, feature heros */
  --r-pill:   999px;  /* pills */

  /* ----- SPACING ----- */
  --space-xs:   0.25rem;
  --space-sm:   0.5rem;
  --space-md:   1rem;
  --space-lg:   1.5rem;
  --space-xl:   2rem;
  --space-2xl:  3rem;
  --space-3xl:  4.5rem;
  --page-x:     2rem;
  --page-x-m:   1.25rem;

  /* ----- TYPE FAMILIES ----- */
  --font-sans: 'DM Sans', 'DM Sans Fallback', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  /* ----- TYPE SCALE —
     display = home hero only (large)
     h1      = all other page hero titles
     h2      = section titles
     h3      = sub-section / card titles ----- */
  --text-display:  clamp(2.4rem, 5.5vw, 3.8rem);
  --text-h1:       clamp(2rem, 4.5vw, 3rem);
  --text-h2:       clamp(1.8rem, 3.5vw, 2.6rem);
  --text-h3:       clamp(1.2rem, 2vw, 1.5rem);
  --text-body-lg:  18px;
  --text-body:     16px;
  --text-body-sm:  14px;
  --text-caption:  12px;
  --text-eyebrow:  11px;
  --text-micro:    10px;    /* badge--new monospace label */

  /* ----- MOTION ----- */
  --ease:        cubic-bezier(0.4, 0, 0.2, 1);
  --ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
  --dur-fast:    150ms;
  --dur:         300ms;
  --dur-slow:    500ms;
  --dur-hero:    800ms;

  /* Named animation durations — used for decorative / continuous loops. */
  --anim-spin:       1s;
  --anim-shimmer:    1.4s;
  --anim-ring-pulse: 5s;
  --anim-wave-short: 8s;
  --anim-wave-med:   10s;
  --anim-wave-long:  12s;
  --anim-ripple:     12s;

  /* ----- LINE HEIGHT ----- */
  --lh-display-tight: 1.08; /* pd-hero display title */
  --lh-hero:    1.1;   /* hero heading tight */
  --lh-tight:   1.12;  /* h1 display */
  --lh-h2:      1.15;  /* h2 headings */
  --lh-snug:    1.2;
  --lh-h3:      1.25;  /* h3 */
  --lh-h4:      1.3;
  --lh-normal:  1.4;
  --lh-normal-5:1.5;   /* inline UI text, captions */
  --lh-feature: 1.55;  /* pd feature text */
  --lh-body:    1.6;   /* paragraphs */
  --lh-prose:   1.65;  /* long-form prose (about, blog, legal) */
  --lh-loose:   1.7;   /* promo detail description */
  --lh-reading: 1.75;  /* blog post body */

  /* ----- Z-INDEX SCALE — layered stacking context ----- */
  --z-base:         1;
  --z-raised:       2;
  --z-fab:          80;    /* scroll-to-top FAB */
  --z-sticky:       90;
  --z-scroll-top:   99;
  --z-sticky-high:  100;   /* sticky filter bars above stacking */
  --z-nav:          200;   /* see also --nav-z below for legacy name */
  --z-dropdown:     1000;
  --z-modal-scrim:  7000;
  --z-tooltip:      8000;
  --z-modal:        8500;
  --z-toast:        9000;
  --z-skip:         9999;  /* skip-to-content link */
  --z-lightbox:     10000;

  /* ----- HERO ----- */
  --hero-gradient:        linear-gradient(180deg, var(--color-primary) 0%, var(--color-primary-deep) 100%);
  --hero-pad-top:         140px;
  --hero-pad-bottom:      80px;
  --hero-pad-top-m:       110px;
  --hero-pad-bottom-m:    60px;
  --hero-min-height:      440px;
  --hero-min-height-m:    280px;

  /* ----- NAV ----- */
  /* Raised for the Keynote redesign (Master, 2026-08-09: "navigation bar looks
     too tiny"). The concept file used a 48px bar, which is Apple's own height
     and reads cramped here. Mobile 56→64, desktop 68→80 (bumped below); the
     logo keeps its ~47% ratio to the bar so it never looks stranded. */
  --nav-inset:      14px;
  --nav-inset-m:    8px;
  --nav-max:        1280px;
  --nav-height:     64px;     /* mobile baseline — desktop bumped below */
  --nav-logo-h:     30px;
  --nav-link-size:  16px;
  --nav-z:          200;
  /* Keynote flush bar */
  --nav-hairline:        1px;
  --nav-border:          rgba(0, 0, 0, 0.08);
  --nav-border-strong:   rgba(0, 0, 0, 0.12);
  --nav-bg-invert:       rgba(0, 0, 0, 0.90);
  --nav-border-invert:   rgba(255, 255, 255, 0.12);

  /* ----- FOCUS ----- */
  --focus-ring:     0 0 0 3px rgba(0, 101, 194, 0.35);
  --focus-outline:  3px solid rgba(0, 101, 194, 0.35);
  --focus-offset:   2px;


  /* ============================================================
     KEYNOTE — the Apple-register redesign layer (2026-08-09).
     Every value the redesign needs lives here so no component
     rule ever hardcodes one. Naming: --kn-* for things that only
     exist for this design language; anything reusable is promoted
     into the semantic groups above instead.
     ============================================================ */

  /* Surfaces. NOTE: the black stage is a SURFACE, not dark mode.
     Dark mode is dormant on this site (every page hard-sets
     data-theme="light") — implementing these by flipping the theme
     would collide with the unverified [data-theme=dark] variants. */
  --surface-invert:          #000000;
  --surface-subtle:          #F5F5F7;   /* the quiet grey between white sections */
  --text-on-invert:          #F5F5F7;
  --text-on-invert-muted:    #A1A1A6;

  /* Link colour. The concept used #0071E3 — that is literally Apple's
     brand blue. Ours is the existing brand primary. */
  --color-link:              var(--color-primary);

  /* Type — larger and tighter than the standard scale, which is what
     gives the register its confidence. */
  --text-kn-display:         clamp(2.6rem, 7.4vw, 6rem);
  --text-kn-h2:              clamp(2rem, 5.2vw, 4rem);
  --text-kn-sub:             clamp(1.0625rem, 1.8vw, 1.4375rem);
  --tracking-kn-display:     -0.035em;
  --tracking-kn-h2:          -0.032em;
  --lh-kn-display:           1.04;
  --lh-kn-h2:                1.06;

  /* Pinned-scroll stage geometry. Each track is the TOTAL scroll
     length of a pinned section; the sticky child is always 100vh. */
  --kn-hero-track:           230vh;
  --kn-chapters-track:       340vh;
  --kn-runway-track:         300vh;
  --kn-hero-unit-h:          58vh;   /* product height inside the hero */
  --kn-chapter-unit-h:       57vh;
  --kn-frame-dur:            0.55s;  /* angle swap between beats */
  --kn-scent-field-h:        62vh;   /* how far up the stage the field reaches */
  --kn-scent-fade:           52%;    /* where the field becomes fully opaque */
  --kn-scent-unit-h:         min(40vh, 340px);   /* the closing product frame */
  --kn-scent-unit-top:       62%;    /* centred in the space below the copy */
  --kn-scent-unit-top-m:     72%;
  --kn-scent-unit-top-short: 74%;
  --kn-scent-unit-h-short:   min(30vh, 260px);
  --kn-hero-still-y:         calc(var(--nav-height) + var(--space-3xl));
  /* Product sizing. Every one of these is a min() against a ceiling: sizing a
     product in vh alone looked right at 900px tall and became enormous on a
     1200px iPad (Master, 2026-08-10: "product image sizes ... too big"). */
  --kn-hero-still-y-end:     var(--space-2xl);
  --kn-hero-still-w:         min(46vh, 420px);
  --kn-emerge-unit-w:        min(52vh, 460px);
  --kn-emerge-from:          1.07;
  /* The resting floor is what you see while scrolling TOWARD the section,
     before the reveal fires - so it is read as 'dark', not as anticipation.
     Lifted so the product is clearly present, and the blur carries the
     reveal instead. */
  --kn-emerge-dark:          0.78;
  --kn-emerge-dur:           1.1s;
  /* Ease-OUT, not ease-in-out. The in-out curve held near the start value
     for the first ~40% of the duration, which is the 'dark too long' Master
     reported: at 0.45s of 1.8s the brightness had moved 0.62 -> 0.63. This
     moves immediately and settles slowly. */
  --kn-emerge-ease:          cubic-bezier(0.22, 1, 0.36, 1);
  --kn-emerge-blur:          9px;
  --kn-emerge-lift:          1.5%;

  /* Contact form (Master, 2026-08-10: "contact page still needs more work on the
     design implementation, especially the contact form"). */
  --field-h:                 3.5rem;   /* 56px - Apple-scale target */
  --field-radius:            var(--radius-card);
  --field-border:            rgba(17, 24, 39, 0.14);
  --field-border-focus:      var(--color-link);
  --field-bg:                var(--color-surface);
  --field-fs:                var(--text-body);
  --field-pad-x:             var(--space-md);
  --label-fs:                var(--text-caption);
  --label-color:             var(--text-muted);
  --label-tracking:          var(--tracking-eyebrow);
  --form-gap:                var(--space-lg);
  --form-card-pad:           var(--space-3xl);
  --form-card-pad-m:         var(--space-lg);
  --field-textarea-h:        9rem;
  --field-textarea-h-short:  7rem;
  --contact-form-max:        1080px;
  --contact-form-split:      1.9fr 1fr;
  --contact-preview-h:       17rem;
  --field-ring:              rgba(0, 101, 194, 0.16);
  --field-ring-w:            3px;
  --contact-map-h:           26rem;
  --kn-hero-copy-top:        13vh;
  /* Nav-aware: a flat 11vh left only ~52px between an 80px bar and the
     headline on a tall viewport, which read as crowded (Master, 2026-08-10). */
  --kn-beat-top:             calc(var(--nav-height) + 7vh);

  /* Chapter glows — one per filtration stage. */
  --kn-glow-1:               rgba(0, 140, 255, 0.22);
  --kn-glow-2:               rgba(0, 200, 190, 0.20);
  --kn-glow-3:               rgba(150, 110, 255, 0.20);
  --kn-glow-4:               rgba(0, 140, 255, 0.16);
  --kn-glow-size:            66vh;

  /* Layout */
  --kn-measure:              1120px;   /* text column for Keynote sections */
  --kn-section-y:            7.5rem;   /* 120px — Apple-scale breathing room */
  /* A section directly after a hero needs only half a beat: the hero has
     already supplied the air, and two full beats measured 240px of blank. */
  --kn-section-y-tight:      var(--space-3xl);
  --kn-cta-y-top:            var(--space-3xl);
  --kn-cta-y-bottom:         var(--space-2xl);
  /* A filter bar belongs to the grid it drives, not to the hero it sits in.
     Measured 176px between the two before this existed, which read as a
     blank screen on blog and products. */
  --kn-filterbar-y:          var(--space-lg);
  --kn-filterbar-y-after:    var(--space-2xl);
  --kn-beat-measure:         30ch;

  /* Hero geometry (--kn-hero-scale-* are also read by keynote.js) */
  --kn-hero-unit-bottom:     -3vh;
  --kn-hero-scale-from:      0.94;
  --kn-hero-scale-gain:      0.16;
  --kn-hero-copy-lift:       90;       /* px, unitless for JS */
  --kn-hero-track-m:         190vh;

  /* Chapter geometry */
  --kn-chapter-unit-bottom:  7vh;
  --kn-chapters-track-m:     300vh;
  --kn-glow-bottom:          4vh;
  --kn-glow-dur:             0.7s;
  --kn-dot-size:             7px;
  --kn-dot-size-on:          22px;
  --kn-dot-off:              rgba(255, 255, 255, 0.28);
  --kn-dot-off-light:        rgba(0, 0, 0, 0.18);   /* dots on a light stage */
  --kn-rule-invert:          rgba(255, 255, 255, 0.16);
  --kn-link-on-invert:       #6FC3FF;
  --kn-badge-bg:             var(--color-primary-tint-bg);
  --kn-badge-text:           var(--color-primary);
  --promo-detail-reserve:    620px;   /* holds layout while ?id= content renders */
  /* One gap between a section's TITLE and the description under it, so the
     three product sections agree (Master, 2026-08-10). */
  /* The lead paragraph under a title - one size site-wide. */
  --text-page-title:         clamp(2rem, 4.4vw, 3rem);   /* one tier for every page title */
  --text-lead:               1.4375rem;   /* 23px */
  --lh-lead:                 1.42;
  --kn-title-gap:            var(--space-md);
  --kn-sub-measure:          56ch;
  /* Filter chips — light ground */
  --filter-fg:               var(--text-muted);
  --filter-fg-hover:         var(--text-primary);
  --filter-bg-hover:         var(--color-surface-subtle);
  --filter-fg-active:        var(--color-surface);
  --filter-bg-active:        var(--text-primary);
  --filter-bar-bg:           var(--color-surface-subtle);
  --filter-bar-border:       rgba(0, 0, 0, 0.06);
  /* One inset + gap for EVERY horizontal runway, so home and the product
     pages read as the same component. */
  --kn-runway-inset:         max(var(--space-page-x), calc((100% - var(--nav-max)) / 2));
  --kn-runway-gap:           var(--space-lg);
  --kn-section-y-m:          var(--space-2xl);

  /* Cards / tiles */
  /* Marquee: one full pass of the duplicated card set. Speed is a duration
     rather than a px/s rate because the row width is content-driven. */
  --kn-marquee-dur:          60s;
  --kn-dots-bottom:          var(--space-3xl);
  --kn-dots-bottom-m:        7rem;    /* the stage link wraps to two lines on mobile */
  --kn-dots-bottom-scent-m:  var(--space-xl);   /* clear of the product on the scent stage */
  --kn-spec-min:             200px;
  --kn-tile-min:             260px;
  --kn-tile-max:             1fr;
  --kn-card-w:               340px;
  --kn-card-w-m:             74vw;
  --kn-card-fig-h:           300px;
  --card-media-h:            260px;   /* .product-card media area, matching .kn-card */
  /* A card's edge must survive a bright screen: shadow alone vanished on the
     near-white listing grounds. */
  --card-edge:               rgba(17, 24, 39, 0.10);
  --card-edge-hover:         rgba(17, 24, 39, 0.18);
  /* TAGS - one language across the site (Master, 2026-08-10). The reference is
     the promotions hero's "Limited Time Offers" pill. Status badges on cards
     keep their own colour, because the colour is the signal, but they take the
     same geometry and typography at the small size. */
  --tag-size:                var(--text-sm-plus);
  --tag-size-sm:             var(--text-caption);
  --tag-weight:              500;
  --tag-tracking:            0.03em;
  --tag-pad:                 0.5rem 1rem;
  --tag-pad-sm:              0.25rem 0.625rem;
  --tag-radius:              var(--r-pill);
  --tag-bg:                  var(--surface-subtle);
  --tag-fg:                  var(--text-primary);
  --tag-border:              rgba(0, 0, 0, 0.08);
  --tag-icon:                1rem;
  --kn-tile-fig-h:           220px;
  --kn-step-rule:            2px;

  /* Product drop shadows */
  --kn-unit-shadow:          0 40px 60px rgba(0, 0, 0, 0.16);
  --kn-unit-shadow-dark:     0 40px 70px rgba(0, 0, 0, 0.70);
  --kn-unit-shadow-sm:       0 16px 26px rgba(0, 0, 0, 0.14);

  /* Type extras */
  --text-kn-figure:          clamp(2.125rem, 4.4vw, 3.5rem);
  --tracking-tight-sm:       -0.02em;
  --tracking-eyebrow:        0.14em;

  /* Motion */
  --kn-ease:                 cubic-bezier(0.2, 0.7, 0.2, 1);
  --kn-reveal-dur:           0.9s;
  --kn-reveal-shift:         38px;
  --kn-beat-dur:             0.55s;


  /* ============================================================
     LEGACY ALIASES — map v2 token names to new design-system
     names so existing page CSS keeps working during migration.
     Eventually retire each of these as files are refactored.
     ============================================================ */

  /* Color + text legacy */
  --color-white:              #FFFFFF;
  --color-text:               var(--text-primary);
  --color-text-secondary:     var(--text-body);
  --color-text-muted:         var(--text-muted);
  --color-bg:                 var(--color-surface);
  --color-bg-pool:            var(--color-surface-light);
  --color-bg-lighter:         var(--color-surface-light);
  --color-bg-medium:          var(--color-surface-subtle);
  /* NOTE: despite the name this is a LIGHT surface in the light theme, and
     .pd-features / .pd-video rely on that. Do not "fix" it to a dark value -
     it would turn several product sections dark. The signature stage, which
     genuinely is dark, uses --pd-stage-bg below. */
  --color-bg-dark:            var(--color-surface-light);
  /* The pinned signature scene's base. Its sticky child has a nav-height top
     padding, so whatever sits behind shows as a band above the scene canvas -
     that band was the light grey Master reported on the WHP-3000 page. */
  --pd-stage-bg:              var(--color-bg-dark);
  /* Only the WHP-3000 spotlight scene paints itself dark (its .sig-stage sits
     inside the canvas and so cannot cover the sticky's nav-height padding -
     that gap was the grey band). Darkening the section for ALL products was
     wrong: every other signature scene is designed on the light ground. */
  --pd-stage-bg-dark:         #0A1020;
  --color-deep:               var(--color-primary-deep);
  /* Keynote: the footer is now the quiet grey ground, not dark navy.
     Token names are unchanged so every existing .footer rule keeps working. */
  /* Master (2026-08-10) asked for a different footer ground. Dark closes the
     page as one deliberate block with the black CTA above it; the hairline in
     global.css keeps the two readable as separate bands. Every footer colour
     below is answered for the dark ground - a light-ground value here would go
     invisible, which is how the contrast bugs on this site have started. */
  /* The footer mark is a STACKED lockup (logo above the name), so it needs
     real height - at the old 28px its 'WATER PURIFIERS' line was ~3px tall. */
  --footer-logo-h:            88px;
  --color-footer:             var(--surface-invert);
  /* Contrast is measured against --surface-subtle (#F5F5F7), NOT white — the
     old --text-muted lands at 4.37:1 there, just under AA. These are picked to
     clear 4.5:1 on that exact ground. */
  --footer-text:              var(--text-on-invert-muted);
  --footer-heading:           var(--text-on-invert);
  --footer-link:              var(--text-on-invert-muted);
  --text-muted-aa:            #5A6577;                   /*  5.3:1 — AA-safe muted on --surface-subtle */

  /* Hero legacy */
  /* Keynote: inner-page heroes move from the blue gradient to white, so the
     whole site reads in the same register as the home page. One token change
     converts all seven page stylesheets that consume it. */
  --lg-hero-bg:               var(--color-surface);
  --home-hero-gradient:       var(--hero-gradient);
  --home-products-gradient:   var(--color-surface);
  --home-shower-gradient:     var(--color-surface-light);
  --home-why-gradient:        var(--color-surface);
  --home-trust-gradient:      var(--color-surface-light);

  /* Type + font legacy */
  --font-family:              var(--font-sans);
  --text-md:                  1.1rem;
  --text-lg:                  1.2rem;
  --text-2xs:                 11px;
  --text-xs:                  12px;
  --text-xs-plus:             13px;
  --text-sm:                  13px;
  --text-sm-plus:             14px;
  --text-sm-lg:               14px;

  /* Layout legacy */
  /* --nav-height already defined above (line 297); duplicate removed. */
  --space-page-x:             var(--page-x);
  --space-page-x-m:           var(--page-x-m);
  --space-page-x-sm:          1.2rem;
  --space-section-y:          var(--space-3xl);
  --gap-card:                 var(--space-lg);
  --gap-section:              var(--space-xl);

  /* Buy modal (package picker — .buym-*) */
  --modal-scrim:              rgba(15, 23, 42, 0.48);
  --modal-sheet-w:            440px;
  --modal-sheet-max-h:        86vh;
  --modal-pad:                1.25rem;
  --modal-rise:               24px;    /* sheet slide-up distance */
  --modal-close-size:         34px;
  --modal-border-w:           1.5px;   /* option/chip selection borders */
  --modal-row-pad:            0.85rem 1.15rem;
  --modal-chip-pad:           0.45rem 0.9rem;
  --modal-badge-pad:          0.14rem 0.5rem;
  --modal-gap:                0.55rem;
  --modal-gap-sm:             0.45rem;
  --modal-gap-lg:             0.9rem;

  /* Brand logos in products-listing headings */
  --brand-logo-h:             2.2rem;
  --brand-logo-h-m:           1.75rem;

  /* Extra clearance under the floating nav for in-page anchor landings */
  --anchor-clearance:         12px;
  --gap-lg:                   var(--space-2xl);
  --gap-xl:                   var(--space-3xl);
  --gap-btn:                  0.6rem;
  --gap-filter:               0.35rem;

  /* Radii legacy */
  --radius-sm:                var(--r-input);
  --radius-md:                var(--r-md);
  --radius-card:              var(--r-card);
  --radius-button:            var(--r-pill);

  /* Border legacy */
  --border-light:             rgba(17, 24, 39, 0.06);
  --border-medium:            rgba(17, 24, 39, 0.12);
  --border-heavy:             rgba(17, 24, 39, 0.20);
  --color-border:             #D1D5DB;

  /* ----- CARD SURFACE — unified liquid-glass content card.
     A refined hairline edge (clearly defined, unlike the near-invisible
     6% --border-light it replaces on cards) paired with the glass shadow
     stack: a layered drop shadow plus beveled inset highlights (bright
     top lip + dim bottom contour). Reads as a glass slab, not a flat
     outlined box. Applied to every solid content card site-wide. */
  --card-border:        rgba(17, 24, 39, 0.10);
  --card-border-hover:  rgba(17, 24, 39, 0.18);
  --card-shadow:        var(--shadow-glass);
  --card-shadow-hover:  var(--shadow-glass-raised);

  /* ----- HORIZONTAL-SCROLL EDGE FADE — width of the soft mask applied to
     the scroll wrappers so the pinned card rows dissolve into the section
     at the clipped left/right edges instead of looking hard-cut.

     Only the WIDTH is a token. The mask gradient itself lives on the
     shared .hscroll-wrapper primitive (primitives.css) — it must be on
     the wrapper, because it references the wrapper-local --fade-l /
     --fade-r multipliers, and var() inside a :root-level custom property
     would resolve against :root (where those are undefined). ----- */
  --scroll-edge-fade:   2.25rem;

  /* Ease legacy */
  --ease-fast:                var(--dur-fast) var(--ease);
  --ease-normal:              var(--dur) var(--ease);
  --ease-slow:                var(--dur-slow) var(--ease);
  --ease-slower:              var(--dur-slow) var(--ease);
  --ease-reveal:              var(--dur-slow) var(--ease);
  --ease-reveal-long:         var(--dur-hero) var(--ease);
  --ease-glass:               var(--dur) var(--ease);

  /* Shadow legacy */
  --shadow-xs:                0 2px 12px rgba(17, 24, 39, 0.04);
  --shadow-sm:                var(--shadow-1);
  --shadow-md:                var(--shadow-2);
  --shadow-lg:                var(--shadow-3);
  --shadow-button:            0 4px 15px rgba(30, 58, 95, 0.30);
  --shadow-focus:             var(--focus-ring);
  --shadow-error:             0 0 0 3px rgba(220, 38, 38, 0.10);
  --shadow-drop-image:        drop-shadow(0 20px 40px rgba(17, 24, 39, 0.12));

  /* Nav legacy (for old pre-pill-nav rules) */
  --nav-bg:                   rgba(255, 255, 255, 0.86);   /* less show-through: at 0.75 the bar looked different on every page */
  --nav-bg-scrolled:          var(--glass-nav-scrolled);
  --nav-mobile-bg:            rgba(255, 255, 255, 0.97);

  /* Badge/icon legacy */
  --badge-bg:                 rgba(30, 58, 95, 0.10);
  --badge-border:             rgba(30, 58, 95, 0.20);
  --icon-bg:                  rgba(30, 58, 95, 0.12);
  --scrollbar-color:          rgba(30, 58, 95, 0.30);

  /* Warm theme legacy (product detail barista) */
  --warm-accent:              #B8875B;
  --warm-deep:                #806E2C;
  --warm-gradient:            linear-gradient(135deg, var(--warm-accent), var(--warm-deep));
  --warm-badge-bg:            rgba(184, 135, 91, 0.10);
  --warm-badge-border:        rgba(184, 135, 91, 0.25);
  --warm-icon-bg:             rgba(184, 135, 91, 0.12);

  /* Overlays legacy */
  --overlay-primary-faint:    rgba(30, 58, 95, 0.03);
  --overlay-primary-light:    rgba(30, 58, 95, 0.04);
  --overlay-primary-soft:     rgba(30, 58, 95, 0.08);
  --overlay-primary-bold:     rgba(30, 58, 95, 0.20);
  --overlay-silver-faint:     rgba(203, 213, 225, 0.06);
  --overlay-silver-light:     rgba(203, 213, 225, 0.08);
  --overlay-accent-faint:     rgba(0, 122, 255, 0.04);
  --overlay-accent-soft:      rgba(0, 90, 200, 0.05);

  /* White tint scale (decorative) */
  --glass-white-10:           rgba(255, 255, 255, 0.10);
  --glass-white-15:           rgba(255, 255, 255, 0.15);
  --glass-white-25:           rgba(255, 255, 255, 0.25);
  --glass-white-50:           rgba(255, 255, 255, 0.50);
  --glass-white-55:           rgba(255, 255, 255, 0.55);
  --glass-white-60:           rgba(255, 255, 255, 0.60);
  --glass-white-70:           rgba(255, 255, 255, 0.70);
  --glass-white-80:           rgba(255, 255, 255, 0.80);

  /* Shadow tints (decorative) */
  --shadow-tint-04:           rgba(0, 0, 0, 0.04);
  --shadow-tint-06:           rgba(0, 0, 0, 0.06);

  /* Spacing legacy (sub-rem values) */
  --space-3xs:                0.2rem;
  --space-2xs:                0.3rem;
  --space-1:                  1rem;
  --space-1-4:                1.4rem;
  --space-1-5:                1.5rem;
  --space-1-8:                1.8rem;
  --space-3:                  3rem;
  --space-4:                  4rem;
  --space-6:                  6rem;

  /* Card padding legacy */
  --padding-card:             2rem 1.6rem;
  --padding-card-lg:          2.2rem 1.8rem;
  --padding-card-sm:          1rem 1.2rem;
  --padding-filter-btn:       0.55rem 1.5rem;
  --padding-filter-bar:       0.3rem;
  --padding-btn:              0.85rem 2rem;
  --padding-btn-nav:          0.6rem 1.4rem;
  --padding-badge:            0.45rem 1.2rem;
  --padding-tag:              0.25rem 0.75rem;

  /* Hero legacy (px anchoring) */
  --hero-pad-bottom-sm:       50px;
  --hero-pad-bottom-xs:       40px;
  --lg-hero-pad-top:          var(--hero-pad-top);
  --lg-hero-pad-bottom:       var(--hero-pad-bottom);
  --lg-hero-pad-top-m:        var(--hero-pad-top-m);
  --lg-hero-pad-bottom-m:     var(--hero-pad-bottom-m);
  --lg-hero-pad-x:            var(--page-x);
  --lg-hero-pad-x-m:          var(--page-x-m);
  --lg-hero-text:             var(--text-primary);
  --lg-hero-text-sub:         var(--text-muted);
  --lg-bg:                    var(--color-surface);
  --lg-section-bg:            var(--color-surface);
  --lg-nav-mobile:            rgba(255, 255, 255, 0.92);
  --lg-blur:                  var(--glass-blur);
  --lg-border:                1px solid rgba(255, 255, 255, 0.55);
  --lg-surface:               var(--glass-regular);
  --lg-shadow:                var(--shadow-glass);
  --lg-hero-badge-bg:         rgba(255, 255, 255, 0.12);
  --lg-hero-badge-border:     rgba(255, 255, 255, 0.20);
  --lg-r-lg:                  var(--r-card);

  /* Section subtitle text */

  /* Footer legacy */
  --footer-border:            var(--kn-rule-invert);
  --footer-text-faint:        var(--text-on-invert-muted);

  /* Ambient + semantic helpers */
  --pd-image-glass-1:         rgba(200, 210, 225, 0.30);
  --pd-image-glass-2:         rgba(180, 195, 215, 0.20);
  /* --color-primary-dark already defined above (line 11); duplicate removed. */
  --color-error:              var(--color-destructive);
  --text-on-dark-ghost:       rgba(255, 255, 255, 0.50);

  /* Decorative rings */

  /* Icon sizes */
  --icon-xs:                  14px;   /* inline with body-sm text */
  --icon-sm:                  20px;
  --icon-md:                  26px;
  --icon-inline:              18px;   /* inline icons in headings / info rows */
  --icon-box-sm:              44px;
  --icon-box-md:              52px;
  --icon-box-lg:              56px;

  /* Responsive filter */
  --padding-filter-btn-m:     0.42rem 0.9rem;
  --padding-filter-btn-sm:    0.38rem 0.75rem;
  --gap-filter-m:             0.25rem;
  --gap-filter-sm:            0.2rem;
}

/* ============================================================
   DESKTOP NAV SCALE — the floating pill reads undersized on
   large screens (logo + links especially). Mobile keeps the
   tighter 56px/26px baseline; the drawer offset also depends
   on --nav-height, so this must stay scoped to ≥769px.
   ============================================================ */
@media (min-width: 769px) {
  :root {
    --nav-height:    80px;
    --nav-logo-h:    38px;
    --nav-link-size: 16px;
  }
}


/* ============================================================
   DARK MODE — Apple Liquid Glass adapts automatically L↔D.
   Surfaces invert to ink-based; glass stays "light-over-dark"
   (low-α white film), so the material still reads as glass
   rather than a flat dark panel.

   Activates in two cases (both selectors apply the same vars):
     1. <html data-theme="dark">              — forced dark (toggle)
     2. (prefers-color-scheme: dark) AND
        <html> has no data-theme="light"      — follows OS
   ============================================================ */

/* Reusable dark-mode vars — referenced by both forced-dark and
   system-dark selectors below to avoid divergence. */
:root[data-theme="dark"] {
  /* Surfaces */
  --color-surface:        #0F172A;
  --color-surface-light:  #111B30;
  --color-surface-subtle: #162338;
  --surface-subtle:        #162338;   /* Keynote quiet grey, dark variant */
  --color-ink:            #E2E8F0;

  /* Text inverts */
  --text-primary:         #E8EDF5;
  --color-text-body:      #CBD5E1;
  --text-muted:           #94A3B8;
  --text-faint:           #64748B;

  /* Hairlines — now white-tinted */
  --hairline:            1px solid rgba(255, 255, 255, 0.06);

  /* Glass: light film over dark bg (α drops; tint stays white) */
  --glass-subtle:        rgba(255, 255, 255, 0.06);
  --glass-regular:       rgba(255, 255, 255, 0.10);
  --glass-strong:        rgba(255, 255, 255, 0.18);
  --glass-hover:         rgba(255, 255, 255, 0.14);
  --glass-hero-pill:     rgba(255, 255, 255, 0.14);
  --glass-nav-scrolled:  rgba(15, 23, 42, 0.72);
  --glass-tint:          rgba(0, 101, 194, 0.22);

  /* Edges — softer top highlight on dark */
  --glass-edge-top:        1px solid rgba(255, 255, 255, 0.28);
  --glass-edge-left:       1px solid rgba(255, 255, 255, 0.18);
  --glass-edge-right:      1px solid rgba(255, 255, 255, 0.10);
  --glass-edge-bottom:     1px solid rgba(0, 0, 0, 0.20);
  --glass-edge-top-bright: 1px solid rgba(255, 255, 255, 0.40);

  /* Shadows — dark bg absorbs light shadows; deepen + soften */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.30),
              0 4px 12px rgba(0, 0, 0, 0.25);
  --shadow-2: 0 2px 4px rgba(0, 0, 0, 0.35),
              0 8px 20px rgba(0, 0, 0, 0.30);
  --shadow-3: 0 2px 6px rgba(0, 0, 0, 0.40),
              0 12px 28px rgba(0, 0, 0, 0.35),
              0 24px 48px rgba(0, 0, 0, 0.25);
  --shadow-glass:        var(--shadow-2),
                         inset 0 1px 0 rgba(255, 255, 255, 0.12),
                         inset 0 -1px 0 rgba(0, 0, 0, 0.25);
  --shadow-glass-raised: var(--shadow-3),
                         inset 0 1px 0 rgba(255, 255, 255, 0.18),
                         inset 0 -1px 0 rgba(0, 0, 0, 0.30);

  /* Dark-mode glass fallbacks */
  --glass-fallback:         rgba(30, 41, 59, 0.92);
  --glass-fallback-strong:  rgba(30, 41, 59, 0.96);
  --glass-fallback-nav:     rgba(15, 23, 42, 0.95);
  --glass-fallback-hero:    rgba(30, 41, 59, 0.55);
  --glass-fallback-dark:    rgba(15, 23, 42, 0.96);
  --glass-fallback-reduced: rgba(15, 23, 42, 0.96);

  /* Glass pill — top highlight slightly softer on dark to avoid a stripe. */
  --shadow-glass-pill:      0 1px 2px rgba(0, 0, 0, 0.30),
                            0 8px 22px -8px rgba(0, 0, 0, 0.55),
                            inset 0 1px 0 rgba(255, 255, 255, 0.32),
                            inset 0 -1px 0 rgba(0, 0, 0, 0.30);
  --shadow-glass-pill-hover:
                            0 2px 4px rgba(0, 0, 0, 0.35),
                            0 14px 32px -10px rgba(0, 0, 0, 0.60),
                            inset 0 1px 0 rgba(255, 255, 255, 0.40),
                            inset 0 -1px 0 rgba(0, 0, 0, 0.35);

  /* Solid primary button bevel — highlights softened like the glass pill. */
  --shadow-primary-pill:    0 1px 2px rgba(0, 0, 0, 0.30),
                            0 8px 22px -8px rgba(0, 0, 0, 0.55),
                            inset 0 1px 0 rgba(255, 255, 255, 0.26),
                            inset 0 -1px 0 rgba(0, 0, 0, 0.30);
  --shadow-primary-pill-hover:
                            0 2px 4px rgba(0, 0, 0, 0.35),
                            0 14px 32px -10px rgba(0, 0, 0, 0.60),
                            inset 0 1px 0 rgba(255, 255, 255, 0.34),
                            inset 0 -1px 0 rgba(0, 0, 0, 0.35);
  /* Buy pill on dark — deeper drops, same construction. */
  --shadow-buy-pill:        0 1px 2px rgba(0, 0, 0, 0.30),
                            0 8px 22px -8px rgba(0, 0, 0, 0.55),
                            inset 0 1px 0 rgba(255, 255, 255, 0.26),
                            inset 0 -1px 0 rgba(0, 0, 0, 0.30);
  --shadow-buy-pill-hover:
                            0 2px 4px rgba(0, 0, 0, 0.35),
                            0 14px 32px -10px rgba(0, 0, 0, 0.60),
                            inset 0 1px 0 rgba(255, 255, 255, 0.34),
                            inset 0 -1px 0 rgba(0, 0, 0, 0.35);
  /* White pill on dark — deeper drops, same construction. */
  --shadow-white-pill:      0 1px 2px rgba(0, 0, 0, 0.30),
                            0 8px 22px -8px rgba(0, 0, 0, 0.55),
                            inset 0 1.5px 0 rgba(255, 255, 255, 1),
                            inset 0 -3px 6px rgba(30, 58, 95, 0.14),
                            inset 0 -1px 0 rgba(30, 58, 95, 0.26);
  --shadow-white-pill-hover:
                            0 2px 4px rgba(0, 0, 0, 0.35),
                            0 14px 32px -10px rgba(0, 0, 0, 0.60),
                            inset 0 1.5px 0 rgba(255, 255, 255, 1),
                            inset 0 -3px 6px rgba(30, 58, 95, 0.16),
                            inset 0 -1px 0 rgba(30, 58, 95, 0.30);

  /* Solid panel surfaces (modals, form panels, dropdowns) — flip to ink. */
  --glass-panel-soft:       rgba(17, 27, 48, 0.82);
  --glass-panel-medium:     rgba(17, 27, 48, 0.86);
  --glass-panel-strong:     rgba(17, 27, 48, 0.92);
  --glass-panel-opaque:     rgba(17, 27, 48, 0.96);
  --glass-panel-input:      rgba(255, 255, 255, 0.06);

  /* Image placeholder gradient — slate frame on dark. */
  --pd-image-glass-1:       rgba(255, 255, 255, 0.04);
  --pd-image-glass-2:       rgba(255, 255, 255, 0.02);

  /* Legacy aliases that hold raw color values.
     NOTE: --color-white deliberately stays #FFFFFF in both modes — every
     existing usage means "literal white" (button bg, outline, text on
     colored surface). Use --color-bg if you want the adaptive page surface. */
  --color-text:           var(--text-primary);
  --color-text-secondary: var(--text-body);
  --color-bg:             var(--color-surface);
  --color-bg-pool:        var(--color-surface-light);
  --color-bg-lighter:     var(--color-surface-light);
  --color-bg-medium:      var(--color-surface-subtle);
  --color-bg-dark:        #0A1020;
  --color-footer:         #070B16;
  --color-border:         #334155;

  --home-products-gradient: var(--color-surface);
  --home-shower-gradient:   var(--color-surface-light);
  --home-why-gradient:      var(--color-surface);
  --home-trust-gradient:    var(--color-surface-light);

  --lg-bg:                var(--color-surface);
  --lg-section-bg:        var(--color-surface);
  --lg-surface:           var(--glass-regular);
  --lg-nav-mobile:        rgba(15, 23, 42, 0.92);
  --lg-border:            1px solid rgba(255, 255, 255, 0.18);

  --border-light:         rgba(255, 255, 255, 0.08);
  --border-medium:        rgba(255, 255, 255, 0.14);
  --border-heavy:         rgba(255, 255, 255, 0.22);

  /* Card edge — white-tinted on dark. --card-shadow/-hover inherit from
     --shadow-glass/-raised, which are already redefined for dark above. */
  --card-border:          rgba(255, 255, 255, 0.12);
  --card-border-hover:    rgba(255, 255, 255, 0.22);

  --badge-bg:             rgba(255, 255, 255, 0.08);
  --badge-border:         rgba(255, 255, 255, 0.14);
  --icon-bg:              rgba(255, 255, 255, 0.10);
  --scrollbar-color:      rgba(255, 255, 255, 0.25);

  --nav-bg:               rgba(15, 23, 42, 0.75);
  --nav-mobile-bg:        rgba(15, 23, 42, 0.96);
}

/* System dark mode: same vars as above, gated by media query. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-surface:        #0F172A;
    --color-surface-light:  #111B30;
    --color-surface-subtle: #162338;
    --surface-subtle:        #162338;   /* Keynote quiet grey, dark variant */
    --color-ink:            #E2E8F0;
    --text-primary:         #E8EDF5;
    --color-text-body:      #CBD5E1;
    --text-muted:           #94A3B8;
    --text-faint:           #64748B;
    --hairline:            1px solid rgba(255, 255, 255, 0.06);
    --glass-subtle:        rgba(255, 255, 255, 0.06);
    --glass-regular:       rgba(255, 255, 255, 0.10);
    --glass-strong:        rgba(255, 255, 255, 0.18);
    --glass-hover:         rgba(255, 255, 255, 0.14);
    --glass-hero-pill:     rgba(255, 255, 255, 0.14);
    --glass-nav-scrolled:  rgba(15, 23, 42, 0.72);
    --glass-tint:          rgba(0, 101, 194, 0.22);
    --glass-edge-top:        1px solid rgba(255, 255, 255, 0.28);
    --glass-edge-left:       1px solid rgba(255, 255, 255, 0.18);
    --glass-edge-right:      1px solid rgba(255, 255, 255, 0.10);
    --glass-edge-bottom:     1px solid rgba(0, 0, 0, 0.20);
    --glass-edge-top-bright: 1px solid rgba(255, 255, 255, 0.40);
    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.30), 0 4px 12px rgba(0, 0, 0, 0.25);
    --shadow-2: 0 2px 4px rgba(0, 0, 0, 0.35), 0 8px 20px rgba(0, 0, 0, 0.30);
    --shadow-3: 0 2px 6px rgba(0, 0, 0, 0.40), 0 12px 28px rgba(0, 0, 0, 0.35), 0 24px 48px rgba(0, 0, 0, 0.25);
    --shadow-glass:        var(--shadow-2), inset 0 1px 0 rgba(255, 255, 255, 0.12), inset 0 -1px 0 rgba(0, 0, 0, 0.25);
    --shadow-glass-raised: var(--shadow-3), inset 0 1px 0 rgba(255, 255, 255, 0.18), inset 0 -1px 0 rgba(0, 0, 0, 0.30);
    --glass-fallback:         rgba(30, 41, 59, 0.92);
    --glass-fallback-strong:  rgba(30, 41, 59, 0.96);
    --glass-fallback-nav:     rgba(15, 23, 42, 0.95);
    --glass-fallback-hero:    rgba(30, 41, 59, 0.55);
    --glass-fallback-dark:    rgba(15, 23, 42, 0.96);
    --glass-fallback-reduced: rgba(15, 23, 42, 0.96);
    --shadow-glass-pill:      0 1px 2px rgba(0, 0, 0, 0.30),
                              0 8px 22px -8px rgba(0, 0, 0, 0.55),
                              inset 0 1px 0 rgba(255, 255, 255, 0.32),
                              inset 0 -1px 0 rgba(0, 0, 0, 0.30);
    --shadow-glass-pill-hover:
                              0 2px 4px rgba(0, 0, 0, 0.35),
                              0 14px 32px -10px rgba(0, 0, 0, 0.60),
                              inset 0 1px 0 rgba(255, 255, 255, 0.40),
                              inset 0 -1px 0 rgba(0, 0, 0, 0.35);
    --glass-panel-soft:       rgba(17, 27, 48, 0.82);
    --glass-panel-medium:     rgba(17, 27, 48, 0.86);
    --glass-panel-strong:     rgba(17, 27, 48, 0.92);
    --glass-panel-opaque:     rgba(17, 27, 48, 0.96);
    --glass-panel-input:      rgba(255, 255, 255, 0.06);
    --pd-image-glass-1:       rgba(255, 255, 255, 0.04);
    --pd-image-glass-2:       rgba(255, 255, 255, 0.02);
    /* --color-white intentionally stays #FFFFFF — see comment above. */
    --color-text:           var(--text-primary);
    --color-text-secondary: var(--text-body);
    --color-bg:             var(--color-surface);
    --color-bg-pool:        var(--color-surface-light);
    --color-bg-lighter:     var(--color-surface-light);
    --color-bg-medium:      var(--color-surface-subtle);
    --color-bg-dark:        #0A1020;
    --color-footer:         #070B16;
    --color-border:         #334155;
    --home-products-gradient: var(--color-surface);
    --home-shower-gradient:   var(--color-surface-light);
    --home-why-gradient:      var(--color-surface);
    --home-trust-gradient:    var(--color-surface-light);
    --lg-bg:                var(--color-surface);
    --lg-section-bg:        var(--color-surface);
    --lg-surface:           var(--glass-regular);
    --lg-nav-mobile:        rgba(15, 23, 42, 0.92);
    --lg-border:            1px solid rgba(255, 255, 255, 0.18);
    --border-light:         rgba(255, 255, 255, 0.08);
    --border-medium:        rgba(255, 255, 255, 0.14);
    --border-heavy:         rgba(255, 255, 255, 0.22);
    --card-border:          rgba(255, 255, 255, 0.12);
    --card-border-hover:    rgba(255, 255, 255, 0.22);
    --badge-bg:             rgba(255, 255, 255, 0.08);
    --badge-border:         rgba(255, 255, 255, 0.14);
    --icon-bg:              rgba(255, 255, 255, 0.10);
    --scrollbar-color:      rgba(255, 255, 255, 0.25);
    --nav-bg:               rgba(15, 23, 42, 0.75);
    --nav-mobile-bg:        rgba(15, 23, 42, 0.96);
  }
}
