/*
 * ==================================================================
 * Sealion Remote — design tokens
 * ==================================================================
 *
 * Hallmark redesign · genre: modern-minimal × atmospheric
 * Voice: "Precision Instrument" — a car's own control surface, not a
 * dashboard template. Everything here answers to one idea: the interface
 * is the white studio card BYD photographs its cars on, and the controls
 * are milled into it.
 *
 * ------------------------------------------------------------------
 * Pre-emit self-critique (6 axes)
 * ------------------------------------------------------------------
 * 1. Typography — Inter is gone. Cabinet Grotesk (display) against Geist
 *    (body) is a 300-unit weight gap and two different skeletons, so the
 *    hierarchy is carried by the faces, not by font-size steps. Geist Mono
 *    tags exactly two roles: machine identifiers (VIN) and live telemetry
 *    (%, km, °C). Japanese gets Zen Kaku Gothic New rather than whatever
 *    the OS happens to ship, so the kana finally match the latin weight.
 * 2. Colour — one accent (BYD's own blue), held under 3% of any viewport:
 *    focus rings, the active level, the charge arc. Neutrals are tinted
 *    cool toward the same hue so nothing reads as dead grey. Pure #ffffff
 *    survives ONLY where a photo is multiply-blended over it (see below);
 *    every other surface carries a trace of chroma.
 * 3. Layout — the control grid is 12 columns with deliberately unequal
 *    spans, so the tiles stop reading as an auto-fill template. Section
 *    heads are stacked (never eyebrow-left / heading-right).
 * 4. Depth — two shadows only: whisper and hairline. Elevation is carried
 *    by weight and scale instead, which is also the only option available
 *    on a white page without going grubby.
 * 5. Motion — 180ms/240ms, one easing curve, and every animation has a
 *    reduced-motion answer. The car's drive-past is the single piece of
 *    decorative motion and it stops entirely when asked.
 * 6. Restraint — no gradient text, no glassmorphism beyond the one frosted
 *    bar the sticky header genuinely needs, no third accent, no icon-above-
 *    heading-above-copy card triplet.
 *
 * ------------------------------------------------------------------
 * ⚠️ THE PURE-WHITE CONSTRAINT — do not "improve" this
 * ------------------------------------------------------------------
 * BYD's Japanese configurator shoots the Sealion 7 on a mathematically
 * pure (255,255,255) card. The UI composites those photos with
 * `mix-blend-mode: multiply`, which dissolves the card into the page and
 * leaves only the bodywork. That only works if the surface underneath is
 * EXACTLY #ffffff.
 *
 *   - Put any tint behind a multiply-blended photo and the photo's white
 *     renders LIGHTER than its surround, i.e. a visible rectangle.
 *   - `drop-shadow` is equally forbidden on those photos: the source is an
 *     opaque rectangle, not an alpha cut-out, so the shadow traces the
 *     photo's edge and draws exactly the box being hidden.
 *
 * Hence `--paper-pure`, which is the one place in this file that breaks
 * the "never pure white" rule, and breaks it on purpose.
 */

:root {
  /* ---------------------------------------------------------------- */
  /* Anchor                                                           */
  /* ---------------------------------------------------------------- */

  /* Every neutral in this file is tinted toward this hue, so the greys
     agree with the accent instead of fighting it. */
  --hue: 255;

  /* ---------------------------------------------------------------- */
  /* Surfaces                                                         */
  /* ---------------------------------------------------------------- */

  /*
   * The ONE pure white in the system. Reserved for surfaces that carry a
   * multiply-blended photo. See the warning above before touching it.
   */
  --paper-pure: #ffffff;

  --bg: oklch(98.6% 0.003 var(--hue));
  --surface: oklch(97.2% 0.005 var(--hue));
  --surface-2: oklch(99.2% 0.002 var(--hue));
  --surface-3: oklch(94.8% 0.007 var(--hue));
  --line: oklch(89% 0.008 var(--hue));
  --line-soft: oklch(93% 0.006 var(--hue));

  /* ---------------------------------------------------------------- */
  /* Ink                                                              */
  /* ---------------------------------------------------------------- */

  --text: oklch(21% 0.014 var(--hue));
  --text-dim: oklch(46% 0.014 var(--hue));
  --text-faint: oklch(62% 0.012 var(--hue));
  --platinum: oklch(30% 0.014 var(--hue));
  --graphite: oklch(91% 0.007 var(--hue));

  /* ---------------------------------------------------------------- */
  /* Accent — exactly one, kept under 3% of any viewport              */
  /* ---------------------------------------------------------------- */

  --accent: oklch(52% 0.168 255);
  --accent-hi: oklch(60% 0.16 255);
  --accent-soft: oklch(94.5% 0.032 255);

  /* Functional colours. Cool = cooling, warm = heating; each one keeps a
     soft companion for fills so we never tint a whole panel. */
  --cool: oklch(52% 0.168 255);
  --cool-soft: oklch(94.5% 0.032 255);
  --heat: oklch(58% 0.152 52);
  --heat-soft: oklch(95% 0.036 62);
  --ok: oklch(56% 0.128 158);
  --ok-soft: oklch(95% 0.036 158);
  --warn: oklch(60% 0.118 78);
  --danger: oklch(56% 0.185 22);
  --danger-soft: oklch(94.5% 0.038 22);

  /* ---------------------------------------------------------------- */
  /* Legacy role tokens — NAMES kept, ROLES inverted                  */
  /* ---------------------------------------------------------------- */

  /*
   * `--white` and friends kept their NAMES so ~40 existing call sites
   * still resolve, but their ROLE inverted when the theme went white. On
   * a white page the precious accent can no longer BE white — it is ink:
   * reserved for brand marks, active controls and primary actions.
   *
   * Do NOT "fix" this by renaming. The names are load-bearing.
   */
  --white: oklch(21% 0.014 var(--hue));
  --white-12: oklch(21% 0.014 var(--hue) / 0.12);
  --white-20: oklch(21% 0.014 var(--hue) / 0.22);
  --white-06: oklch(21% 0.014 var(--hue) / 0.05);

  /* Genuine pure white, for type that sits ON an ink-filled control. */
  --on-ink: #ffffff;

  /* ---------------------------------------------------------------- */
  /* Type                                                             */
  /* ---------------------------------------------------------------- */

  /*
   * Three families, which is the ceiling: a display grotesque, a body
   * grotesque, and a mono outlier. The Japanese face is a *script*
   * extension of the body face, not a fourth family — it only ever
   * renders glyphs the latin faces do not cover.
   */
  --font-display: 'Cabinet Grotesk', 'Zen Kaku Gothic New', system-ui, sans-serif;
  --font-body: 'Geist', 'Zen Kaku Gothic New', -apple-system, BlinkMacSystemFont,
    'Hiragino Kaku Gothic ProN', sans-serif;
  --font-mono: 'Geist Mono', ui-monospace, 'SFMono-Regular', monospace;

  /* Kept for compatibility with rules that still say `var(--font)`. */
  --font: var(--font-body);

  /* Major-third scale (1.25) from a 16px body. */
  --text-2xs: 0.6875rem; /* 11px   — labels, legal */
  --text-xs: 0.8125rem; /*  13px   — captions, notes */
  --text-sm: 0.875rem; /*   14px   — dense UI */
  --text-base: 1rem; /*      16px   — body */
  --text-md: 1.25rem; /*     20px   — card titles */
  --text-lg: 1.5625rem; /*   25px   — section leads */
  --text-xl: 1.9531rem; /*   31px   — vehicle name */
  --text-2xl: 2.4414rem; /*  39px   — telemetry */
  --text-3xl: 3.0518rem; /*  49px   — hero figure */
  --text-display: clamp(2.5rem, 4vw + 0.75rem, 4.25rem);
  --text-display-s: clamp(2rem, 2.6vw + 0.75rem, 3rem);

  /* ---------------------------------------------------------------- */
  /* Space — 4pt base, named by role                                  */
  /* ---------------------------------------------------------------- */

  --space-3xs: 0.125rem; /*  2px */
  --space-2xs: 0.25rem; /*   4px */
  --space-xs: 0.5rem; /*     8px */
  --space-sm: 0.75rem; /*   12px */
  --space-md: 1rem; /*      16px */
  --space-lg: 1.5rem; /*    24px */
  --space-xl: 2.5rem; /*    40px */
  --space-2xl: 4rem; /*     64px */
  --space-3xl: 6rem; /*     96px */

  /* ---------------------------------------------------------------- */
  /* Form                                                             */
  /* ---------------------------------------------------------------- */

  --radius: 14px;
  --radius-sm: 10px;
  --radius-lg: 22px;
  --radius-pill: 999px;

  /*
   * Two shadows, never stacked. On a white page anything heavier turns
   * into a grey smear, so elevation is carried by weight and scale and
   * these only ever confirm it.
   */
  --shadow-whisper: 0 1px 2px oklch(21% 0.014 var(--hue) / 0.06),
    0 8px 24px oklch(21% 0.014 var(--hue) / 0.05);
  --shadow-hairline: 0 0 0 1px oklch(30% 0.012 var(--hue) / 0.07);

  /* Kept for compatibility with existing `var(--shadow)` call sites. */
  --shadow: var(--shadow-whisper);

  --ring: 0 0 0 3px oklch(52% 0.168 255 / 0.2);

  /* ---------------------------------------------------------------- */
  /* Motion — one curve, two durations                                */
  /* ---------------------------------------------------------------- */

  --ease: cubic-bezier(0.22, 0.72, 0.24, 1);
  --dur-fast: 140ms;
  --dur: 200ms;
  --dur-slow: 380ms;

  /* ---------------------------------------------------------------- */
  /* Elevation order — six named levels, never freestyle numbers      */
  /* ---------------------------------------------------------------- */

  --z-base: 1;
  --z-raised: 10;
  --z-dropdown: 100;
  --z-sticky: 200;
  --z-modal: 400;
  --z-toast: 500;
  --z-splash: 600;
}
