/* =====================================================================================================
   The Marketing Cartel · design tokens (E02) — the single source of truth.
   Layers: 1 primitives → 2 semantic roles (light) → 3 dark theme → 4 type → 5 space → 6 shape → 7 motion.
   Components and pages consume ONLY the semantic layer (and type/space/shape/motion); primitives are
   referenced directly only by gradients, which need the raw steps.
   Colour maths: OKLCH (source of each step in the comment) → gamut-clamped sRGB hex. Generator:
   ../verify/palette.py. AA of every text/surface pair is a gate (../verify/check-contrast.mjs).
   ===================================================================================================== */

:root {
  color-scheme: light dark;

  /* ---------- 1 · primitives ---------------------------------------------------------------------- */
  /* violet · OKLCH hue 296 — the logo purple (#3C1468) is hue 299.9; a hair bluer = "royal" */
  --violet-50: #F7F5FF;  /* oklch(0.975 0.013 296) */
  --violet-100: #EEE9FF; /* oklch(0.945 0.030 296) */
  --violet-200: #DED3FF; /* oklch(0.890 0.060 296) */
  --violet-300: #C8B5FF; /* oklch(0.815 0.105 296) */
  --violet-400: #AA88F7; /* oklch(0.705 0.160 296) */
  --violet-500: #8D5AE8; /* oklch(0.595 0.205 296) */
  --violet-600: #7534D3; /* oklch(0.505 0.225 296) */
  --violet-700: #5E1EAE; /* oklch(0.425 0.205 296) */
  --violet-800: #48138A; /* oklch(0.355 0.175 296) — the brand purple */
  --violet-900: #350D67; /* oklch(0.290 0.140 296) */
  --violet-950: #220A44; /* oklch(0.225 0.100 296) */

  /* pink · OKLCH hue 348 — the second colour of the gradient (Arthur: pink, never blue) */
  --pink-50: #FDF4F8;  /* oklch(0.975 0.012 348) */
  --pink-100: #FCE6F0; /* oklch(0.945 0.028 348) */
  --pink-200: #FBCDE3; /* oklch(0.895 0.058 348) */
  --pink-300: #F4ADD1; /* oklch(0.825 0.095 348) */
  --pink-400: #EA84BA; /* oklch(0.740 0.140 348) */
  --pink-500: #DD5CA5; /* oklch(0.660 0.180 348) */
  --pink-600: #C53C8E; /* oklch(0.580 0.190 348) */
  --pink-700: #A32C74; /* oklch(0.500 0.170 348) */
  --pink-800: #7E2159; /* oklch(0.415 0.140 348) */
  --pink-900: #5B1A40; /* oklch(0.335 0.105 348) */
  --pink-950: #3D112A; /* oklch(0.260 0.075 348) */

  /* neutrals · OKLab interpolation between two poles: ink (violet-black) and paper (warm white).
     The poles swap roles between themes; mid-greys come out almost neutral. */
  --neutral-0: #FEFCF9;
  --neutral-25: #F9F5F0;   /* paper · oklch(0.972 0.008 78) */
  --neutral-50: #F2EEE9;
  --neutral-100: #E7E3E0;
  --neutral-150: #DAD6D4;
  --neutral-200: #CAC6C6;
  --neutral-300: #B1ADB0;
  --neutral-400: #949095;
  --neutral-500: #7C7880;
  --neutral-600: #67646D;
  --neutral-700: #56525D;
  --neutral-800: #44414D;
  --neutral-850: #383442;
  --neutral-900: #2C2836;
  --neutral-950: #221E2C;
  --neutral-1000: #14101F; /* ink · oklch(0.185 0.030 296) */
  --ink: var(--neutral-1000);
  --paper: var(--neutral-25);
  --night: #1C1827;        /* ink→paper 4.5% — dark theme page */
  --night-raised: #262231; /* ink→paper 10% */

  /* ---------- 2 · semantic roles — one declaration per role: light-dark(<light>, <dark>) ---------------------
     The used colour scheme decides: `color-scheme: light dark` follows the system; a manual choice pins it with
     :root[data-theme]. Components never branch on the theme. */
  --bg: light-dark(var(--paper), var(--night));                       /* page */
  --bg-raised: light-dark(var(--neutral-0), var(--night-raised));     /* cards, panels, the nav pill base */
  --bg-sunken: light-dark(var(--neutral-50), var(--ink));             /* wells, the nav capsule */
  --bg-inverse: light-dark(var(--ink), var(--paper));
  --fg: light-dark(var(--ink), var(--paper));                         /* 17.2:1 · 16.0:1 */
  --fg-muted: light-dark(var(--neutral-600), var(--neutral-200));     /* 5.3:1 · 10.3:1 */
  --fg-subtle: light-dark(var(--neutral-500), var(--neutral-400));    /* 4.0:1 · 5.5:1 — large text / non-essential */
  --fg-inverse: light-dark(var(--paper), var(--ink));
  --fg-accent: light-dark(var(--violet-700), var(--violet-300));      /* 8.5:1 · 9.5:1 — links, accent text */
  --line: light-dark(var(--neutral-150), var(--neutral-850));         /* decorative dividers */
  --line-strong: light-dark(var(--neutral-500), var(--neutral-500));  /* boundaries that must read, ≥ 3:1 */
  --brand: light-dark(var(--violet-800), var(--violet-300));          /* the purple: 11.2:1 · 9.5:1 */
  --brand-strong: light-dark(var(--violet-900), var(--violet-200));
  --brand-soft: light-dark(var(--violet-100), var(--violet-950));     /* tinted backgrounds */
  --accent: light-dark(var(--pink-600), var(--pink-400));             /* the gradient's second colour, sparingly */
  --focus: light-dark(var(--violet-600), var(--violet-400));          /* focus ring: 6.1:1 · 6.3:1 */
  --on-brand: #FFFFFF;                                                /* label on the brand gradient */
  --logo-ink: light-dark(var(--ink), var(--paper));                   /* symbol lines */
  --logo-brand: light-dark(var(--violet-800), var(--violet-400));     /* circle, hat band, bow tie */
  --logo-smoke: .42;                                                  /* smoke = ink at reduced opacity */
  --selection: light-dark(color-mix(in oklab, var(--violet-300) 55%, transparent),
                          color-mix(in oklab, var(--violet-600) 60%, transparent));

  /* frost (navbar #21): subtle, blur ≤ 8px */
  --frost-bg: light-dark(color-mix(in oklab, var(--neutral-0) 74%, transparent),
                         color-mix(in oklab, var(--night) 62%, transparent));
  --frost-line: light-dark(color-mix(in oklab, var(--ink) 9%, transparent), rgb(255 255 255 / .09));
  --frost-blur: 8px;
  /* overlays that open on top of content (the dropdown) are OPAQUE: tested at 74% and 95%, a 92px H1 still
     ghosts through. The navbar pill keeps the frost because it floats over the blinds, not over text. */
  --panel-bg: light-dark(var(--neutral-0), var(--night-raised));

  /* shadows — ink-tinted and soft in light, deep in dark; the device shadow is the only deep one in light */
  --shadow-1: 0 1px 2px light-dark(rgb(20 16 31 / .06), rgb(0 0 0 / .5)), 0 1px 1px light-dark(rgb(20 16 31 / .04), rgb(0 0 0 / .3));
  --shadow-2: 0 6px 16px -4px light-dark(rgb(20 16 31 / .10), rgb(0 0 0 / .55)), 0 2px 4px -1px light-dark(rgb(20 16 31 / .06), rgb(0 0 0 / .4));
  --shadow-3: 0 18px 40px -12px light-dark(rgb(20 16 31 / .18), rgb(0 0 0 / .7)), 0 6px 12px -4px light-dark(rgb(20 16 31 / .08), rgb(0 0 0 / .45));
  --shadow-device: 0 60px 90px -36px light-dark(rgb(20 16 31 / .38), rgb(0 0 0 / .85)), 0 24px 40px -20px light-dark(rgb(20 16 31 / .22), rgb(0 0 0 / .6));
  --highlight-top: inset 0 1px 0 light-dark(rgb(255 255 255 / .55), rgb(255 255 255 / .07));

  /* the brand gradient (adapted from the #2 sphere): lilac highlight top-left, pink bloom bottom-right,
     deep violet core under the label. Grain is added by the component (components.css .has-grain). */
  --grad-brand:
    radial-gradient(90% 120% at 8% -10%, color-mix(in oklab, var(--violet-400) 85%, transparent) 0%, transparent 52%),
    radial-gradient(80% 140% at 104% 112%, color-mix(in oklab, var(--pink-600) 92%, transparent) 0%, transparent 58%),
    radial-gradient(130% 150% at 42% 60%, var(--violet-700) 0%, var(--violet-800) 55%, var(--violet-900) 100%);
  --grad-brand-hover:
    radial-gradient(90% 120% at 14% -6%, color-mix(in oklab, var(--violet-400) 95%, transparent) 0%, transparent 56%),
    radial-gradient(80% 140% at 98% 108%, color-mix(in oklab, var(--pink-500) 90%, transparent) 0%, transparent 60%),
    radial-gradient(130% 150% at 42% 60%, var(--violet-700) 0%, var(--violet-800) 58%, var(--violet-900) 100%);

  /* hero blinds (#6): colour clouds seen through reeded glass */
  --blinds-a: light-dark(var(--violet-500), var(--violet-600));
  --blinds-b: light-dark(var(--pink-400), var(--pink-600));
  --blinds-c: light-dark(var(--violet-300), var(--violet-400));
  --blinds-reed-light: light-dark(rgb(255 255 255 / .30), rgb(255 255 255 / .06));
  --blinds-reed-dark: light-dark(rgb(20 16 31 / .035), rgb(0 0 0 / .22));
  --grain-opacity: .22;     /* non-colour: overridden for dark below */
  --grain-blend: multiply;

  /* ---------- 4 · type ------------------------------------------------------------------------------ */
  --font-sans: 'Archivo', 'Archivo Fallback', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-sans-heavy: 'Archivo', 'Archivo Heavy Fallback', system-ui, sans-serif;
  --font-serif: 'Newsreader', 'Newsreader Fallback', Georgia, 'Times New Roman', serif;
  --font-statement: 'Roboto Flex', 'Archivo', system-ui, sans-serif;
  --font-mono: ui-monospace, 'Cascadia Mono', 'SFMono-Regular', Consolas, monospace;

  /* fluid scale: mobile end (≈390px) is provisional; desktop end (1280–1440px) is validated */
  --text-display: clamp(2.25rem, 1.35rem + 5.1vw, 5.75rem);   /* hero H1: 92px @1440 · ~40px @360 (E04: min 44 → 36) */
  --text-h1: clamp(2.5rem, 1.45rem + 3.9vw, 4.5rem);          /* page H1: 72px */
  --text-h2: clamp(1.875rem, 1.2rem + 2.75vw, 3.5rem);        /* section titles: 56px · 30px on narrow phones */
  --text-h3: clamp(1.375rem, 1.12rem + .8vw, 1.875rem);       /* 30px */
  --text-h4: clamp(1.125rem, 1.02rem + .35vw, 1.3125rem);     /* 21px */
  --text-lead: clamp(1.1875rem, 1.02rem + .56vw, 1.4375rem);  /* 23px — #3 no-want: never small */
  --text-body: clamp(1rem, .96rem + .14vw, 1.0625rem);        /* 17px */
  --text-sm: .9375rem;                                        /* 15px */
  --text-xs: .8125rem;                                        /* 13px — eyebrows, captions */
  --text-statement: clamp(3rem, 1.2rem + 6.2vw, 7.5rem);

  --lh-display: .98;
  --lh-tight: 1.04;
  --lh-snug: 1.18;
  --lh-lead: 1.45;
  --lh-body: 1.6;

  --track-display: -.036em;
  --track-heading: -.026em;
  --track-tight: -.012em;
  --track-caps: .09em;

  --w-display: 800;
  --w-heading: 780;
  --w-strong: 640;
  --w-ui: 560;
  --w-body: 400;

  /* ---------- 5 · space & layout ------------------------------------------------------------------- */
  --space-1: .25rem;  /* 4 */
  --space-2: .5rem;   /* 8 */
  --space-3: .75rem;  /* 12 */
  --space-4: 1rem;    /* 16 */
  --space-5: 1.25rem; /* 20 */
  --space-6: 1.5rem;  /* 24 */
  --space-7: 2rem;    /* 32 */
  --space-8: 2.5rem;  /* 40 */
  --space-9: 3rem;    /* 48 */
  --space-10: 4rem;   /* 64 */
  --space-11: 5rem;   /* 80 */
  --space-12: 6rem;   /* 96 */
  --space-13: 8rem;   /* 128 */
  --space-14: 10rem;  /* 160 */
  --container: 76rem;       /* 1216 */
  --container-wide: 84rem;  /* 1344 */
  --container-text: 44rem;  /* 704 — lead measure */
  --gutter: clamp(1rem, .2rem + 3.3vw, 2.5rem);
  --section-y: clamp(3.5rem, min(1.5rem + 6vw, 1rem + 12vh), 7.5rem); /* 56 → 120px (E04: phone min 64 → 56); the vh term keeps short screens
                        from 320px gaps (Arthur 28/09: ≈99px each side at 1534×692) */
  --nav-top: 16px;
  --nav-h: 60px;
  /* phone chrome (E04, <1024px): the top bar, the bottom action bar, the iPhone home-indicator inset */
  --topbar-h: 56px;
  --bar-h: 56px;
  --safe-b: env(safe-area-inset-bottom, 0px);

  /* ---------- 6 · shape ----------------------------------------------------------------------------- */
  --r-xs: 6px;    /* tags, small chips inside cards */
  --r-sm: 12px;   /* buttons, inputs */
  --r-md: 18px;   /* cards, dropdown items */
  --r-lg: 24px;   /* the nav pill, dropdown panel, large panels — "not 100% round" (#21) */
  --r-xl: 32px;   /* hero stage panels */
  --r-full: 999px;/* avatars, the proof badge, chips and buttons */
  --r-button: var(--r-full); /* every button: 100% round (Arthur, E03 review 25/09; Gate 2 had 12px) */
  --border: 1px;

  /* ---------- 7 · motion (transform/opacity only) ---------------------------------------------------- */
  --d-micro: 150ms;   /* hover colour, small nudges */
  --d-ui: 240ms;      /* dropdown, toggle, accordion */
  --d-reveal: 480ms;  /* section reveals */
  --d-flip: 600ms;    /* service flip, card swaps */
  --d-spring: 420ms;  /* the sliding nav pill */
  --e-out: cubic-bezier(.22, 1, .36, 1);
  --e-in-out: cubic-bezier(.65, 0, .35, 1);
  --e-in: cubic-bezier(.55, 0, 1, .45);
  /* spring from #20 (stiffness 350, damping 32, mass 1; ζ = .855, 0.55% overshoot), sampled over 420ms */
  --e-spring: linear(0, .0445, .1476, .2758, .408, .5317, .6404, .7317, .8058, .8638, .9081, .9408, .9644,
    .9807, .9916, .9985, 1.0026, 1.0047, 1.0055, 1.0055, 1.0051, 1.0044, 1.0037, 1.003, 1);
  --stagger: 40ms;
  --reveal-distance: 20px;

  /* ---------- z-index ------------------------------------------------------------------------------- */
  --z-base: 1;
  --z-nav: 100;
  --z-dropdown: 110;
  --z-panel: 200;
}

/* ---------- 3 · theme pins. `color-scheme: light dark` on :root follows the system; a manual choice pins it.
   Only non-colour values need a theme branch (grain) — every colour role above is a single light-dark(). ---- */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --grain-opacity: .16; --grain-blend: screen; }
}
:root[data-theme="dark"] { --grain-opacity: .16; --grain-blend: screen; }

/* reduced motion: durations collapse; transforms are removed by components, opacity crossfades stay short */
@media (prefers-reduced-motion: reduce) {
  :root {
    --d-micro: 1ms;
    --d-ui: 120ms;
    --d-reveal: 150ms;
    --d-flip: 150ms;
    --d-spring: 1ms;
    --reveal-distance: 0px;
  }
}



/* phones (<1024px, E04): the accent serif comes from the lighter static cut (fonts.css) */
@media (max-width: 1023.98px) {
  :root { --font-serif: 'Newsreader Phone', 'Newsreader Fallback', Georgia, 'Times New Roman', serif; }
}
