/* =========================================================================
 * Yachti Design System — tokens (v2 "Regatta" — Phase 3 premium re-skin)
 *
 * Premium, photography-led visual language in the spirit of consumer travel
 * products: deep-green brand + warm-grey neutrals + a warm ORANGE accent
 * reserved for CTAs/highlights. Card-based, generous whitespace, rounded
 * corners, soft shadows. Deliberately NOT clip-art nautical.
 *
 * HSL brand primitives drive everything — re-theming / white-labeling is a
 * handful of primitive edits. Fonts: Archivo (display), Inter (body),
 * IBM Plex Mono. Light + night (watchkeeper) themes.
 * ========================================================================= */

:root {
  /* --- Brand primitives (edit these to re-theme everything) --- */
  --brand-ink-h: 160;              /* deep green-tinged charcoal ink */
  --brand-ink-s: 10%;
  --brand-ink-l: 11%;
  --brand-primary-h: 152;          /* deep sea-green */
  --brand-primary-s: 40%;
  --brand-primary-l: 27%;
  --brand-neutral-h: 40;           /* warm grey (approachable, not beige) */
  --brand-neutral-s: 6%;
  --brand-cta-h: 24;               /* warm orange — CTAs + highlights ONLY */
  --brand-cta-s: 88%;
  --brand-cta-l: 53%;
  --brand-elevation-strength: 1;

  /* --- Primary (green) ramp — derived --- */
  --primary-50: hsl(var(--brand-primary-h) 38% 96%);
  --primary-100: hsl(var(--brand-primary-h) 36% 91%);
  --primary-200: hsl(var(--brand-primary-h) 34% 82%);
  --primary-300: hsl(var(--brand-primary-h) 32% 66%);
  --primary-400: hsl(var(--brand-primary-h) 36% 44%);
  --primary-500: hsl(var(--brand-primary-h) var(--brand-primary-s) var(--brand-primary-l));
  --primary-600: hsl(var(--brand-primary-h) calc(var(--brand-primary-s) + 2%) calc(var(--brand-primary-l) - 5%));
  --primary-700: hsl(var(--brand-primary-h) calc(var(--brand-primary-s) + 4%) calc(var(--brand-primary-l) - 9%));
  --primary-800: hsl(var(--brand-primary-h) 42% 14%);
  --primary-900: hsl(var(--brand-primary-h) 40% 10%);

  /* --- CTA (orange) ramp — derived --- */
  --cta-50: hsl(var(--brand-cta-h) 90% 96%);
  --cta-100: hsl(var(--brand-cta-h) 92% 91%);
  --cta-200: hsl(var(--brand-cta-h) 92% 82%);
  --cta-300: hsl(var(--brand-cta-h) 90% 70%);
  --cta-400: hsl(var(--brand-cta-h) 89% 60%);
  --cta-500: hsl(var(--brand-cta-h) var(--brand-cta-s) var(--brand-cta-l));
  --cta-600: hsl(var(--brand-cta-h) 80% 46%);
  --cta-700: hsl(var(--brand-cta-h) 78% 39%);

  /* --- Neutral ramp (warm grey, derived) --- */
  --neutral-0: #ffffff;
  --neutral-25: hsl(var(--brand-neutral-h) 25% 98.5%);
  --neutral-50: hsl(var(--brand-neutral-h) 18% 97%);
  --neutral-100: hsl(var(--brand-neutral-h) 14% 94%);
  --neutral-200: hsl(var(--brand-neutral-h) 10% 89%);
  --neutral-300: hsl(var(--brand-neutral-h) 8% 80%);
  --neutral-400: hsl(var(--brand-neutral-h) 6% 62%);
  --neutral-500: hsl(var(--brand-neutral-h) 6% 46%);
  --neutral-600: hsl(var(--brand-neutral-h) 7% 36%);
  --neutral-700: hsl(var(--brand-neutral-h) 8% 26%);
  --neutral-800: hsl(var(--brand-neutral-h) 9% 16%);
  --neutral-900: hsl(var(--brand-ink-h) var(--brand-ink-s) var(--brand-ink-l));

  /* --- Status --- */
  --status-ok: #178a52;
  --status-ok-bg: hsl(150 50% 94%);
  --status-warn: #b7791f;
  --status-warn-bg: hsl(41 78% 93%);
  --status-danger: #d6493f;
  --status-danger-bg: hsl(5 78% 95%);
  --status-info: #2e7fb8;
  --status-info-bg: hsl(203 70% 94%);

  /* --- Semantic surfaces (light) --- */
  --bg: var(--neutral-50);
  --bg-elevated: var(--neutral-0);
  --bg-sunken: var(--neutral-100);
  --surface: var(--neutral-0);
  --surface-hover: var(--neutral-25);
  --surface-glass: hsl(var(--brand-neutral-h) 25% 99% / 0.78);
  --border: var(--neutral-200);
  --border-strong: var(--neutral-300);

  --text: var(--neutral-900);
  --text-muted: var(--neutral-500);
  --text-inverse: var(--neutral-0);

  /* Brand = deep green (identity: nav, links, data-viz, headers). */
  --brand: var(--primary-600);
  --brand-emphasis: var(--primary-700);
  --brand-contrast: #ffffff;
  --brand-soft: var(--primary-50);

  /* CTA = warm orange (primary action buttons + highlights ONLY). */
  --cta: var(--cta-500);
  --cta-emphasis: var(--cta-600);
  --cta-contrast: #ffffff;
  --cta-soft: var(--cta-50);
  /* Favourites tab-zone highlight — a soft CTA-tinted gradient behind the first-N favourites that become
     tabs (brief 0017). References --cta-soft, so it adapts to light/dark automatically (one definition). */
  --fav-tab-zone: linear-gradient(180deg, var(--cta-soft), transparent);

  /* Accent — the highlight colour. Points at the CTA orange so eyebrows,
     meters, focus rings and small emphases pick up the warm highlight. */
  --accent: var(--cta-500);
  --accent-emphasis: var(--cta-600);
  --focus-ring: color-mix(in srgb, var(--cta-500) 45%, transparent);

  /* Image scrims (photography-led cards/heroes need legible text overlays). */
  --scrim-bottom: linear-gradient(180deg, hsl(0 0% 0% / 0) 30%, hsl(var(--brand-ink-h) 30% 6% / 0.72) 100%);
  --scrim-full: hsl(var(--brand-ink-h) 30% 8% / 0.42);
  --scrim: hsl(0 0% 0% / 0.4);              /* modal / bottom-sheet backdrop */
  --scrim-strong: hsl(0 0% 0% / 0.88);      /* full-bleed media viewer (lightbox) backdrop — dark in both themes */
  --hairline-on-media: hsl(0 0% 100% / 0.5); /* thin white rule/border over photography */
  --on-media: hsl(0 0% 100%);                /* solid text/icon colour over a dark scrim/media (both themes) */

  /* --- Typography --- */
  --font-sans: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-display: 'Archivo', 'Helvetica Neue', system-ui, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, monospace;

  --text-2xs: 11px;
  --text-xs: 12px;
  --text-sm: 13px;
  --text-base: 15px;
  --text-md: 17px;
  --text-lg: 20px;
  --text-xl: 24px;
  --text-2xl: 30px;
  --text-3xl: 38px;
  --text-4xl: 48px;
  --text-5xl: 60px;

  --leading-tight: 1.15;
  --leading-normal: 1.5;
  --leading-relaxed: 1.65;
  --tracking-tight: -0.012em;
  --tracking-display: -0.022em;
  --tracking-caps: 0.1em;
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;

  /* --- Spacing (2px base) --- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;

  /* --- Radius (rounder — card-led premium feel) --- */
  --radius-sm: 10px;
  --radius-md: 14px;
  --radius-lg: 18px;
  --radius-xl: 24px;
  --radius-2xl: 32px;
  --radius-full: 999px;

  /* --- Shadows (soft, warm-ink tinted; card-led elevation) --- */
  --shadow-color: var(--brand-ink-h) 20% 18%;
  --e: var(--brand-elevation-strength);
  --shadow-sm: 0 1px 2px hsl(var(--shadow-color) / calc(0.05 * var(--e))),
    0 3px 8px hsl(var(--shadow-color) / calc(0.05 * var(--e)));
  --shadow-md: 0 2px 4px hsl(var(--shadow-color) / calc(0.05 * var(--e))),
    0 10px 24px hsl(var(--shadow-color) / calc(0.08 * var(--e)));
  --shadow-lg: 0 6px 12px hsl(var(--shadow-color) / calc(0.06 * var(--e))),
    0 24px 56px hsl(var(--shadow-color) / calc(0.12 * var(--e)));
  --shadow-cta: 0 4px 14px color-mix(in srgb, var(--cta-500) 35%, transparent);

  /* --- Touch (wet hands / gloves) --- */
  --touch-target: 48px;

  --z-header: 100;
  --z-modal: 400;
  --z-toast: 500;
}

/* --- Night mode (watchkeepers): deep green-charcoal, muted glare --- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --bg: hsl(var(--brand-ink-h) var(--brand-ink-s) 7%);
    --bg-elevated: hsl(var(--brand-ink-h) var(--brand-ink-s) 11%);
    --bg-sunken: hsl(var(--brand-ink-h) var(--brand-ink-s) 5%);
    --surface: hsl(var(--brand-ink-h) var(--brand-ink-s) 11%);
    --surface-hover: hsl(var(--brand-ink-h) var(--brand-ink-s) 15%);
    --surface-glass: hsl(var(--brand-ink-h) var(--brand-ink-s) 11% / 0.78);
    --border: hsl(var(--brand-ink-h) var(--brand-ink-s) 20%);
    --border-strong: hsl(var(--brand-ink-h) var(--brand-ink-s) 28%);

    --text: var(--neutral-25);
    --text-muted: var(--neutral-400);
    --text-inverse: var(--neutral-900);

    --brand: var(--primary-300);
    --brand-emphasis: var(--primary-200);
    --brand-contrast: hsl(var(--brand-ink-h) var(--brand-ink-s) 9%);
    --brand-soft: hsl(var(--brand-primary-h) 30% 16% / 0.6);

    --cta: hsl(var(--brand-cta-h) 86% 58%);
    --cta-emphasis: hsl(var(--brand-cta-h) 88% 64%);
    --cta-contrast: hsl(var(--brand-ink-h) 30% 8%);
    --cta-soft: hsl(var(--brand-cta-h) 60% 18% / 0.5);

    --accent: hsl(var(--brand-cta-h) 86% 58%);
    --accent-emphasis: hsl(var(--brand-cta-h) 88% 64%);

    --status-ok-bg: hsl(150 40% 15% / 0.5);
    --status-warn-bg: hsl(41 50% 18% / 0.5);
    --status-danger-bg: hsl(5 50% 20% / 0.5);
    --status-info-bg: hsl(203 50% 18% / 0.5);
  }
}

:root[data-theme='dark'] {
  --bg: hsl(var(--brand-ink-h) var(--brand-ink-s) 7%);
  --bg-elevated: hsl(var(--brand-ink-h) var(--brand-ink-s) 11%);
  --bg-sunken: hsl(var(--brand-ink-h) var(--brand-ink-s) 5%);
  --surface: hsl(var(--brand-ink-h) var(--brand-ink-s) 11%);
  --surface-hover: hsl(var(--brand-ink-h) var(--brand-ink-s) 15%);
  --surface-glass: hsl(var(--brand-ink-h) var(--brand-ink-s) 11% / 0.78);
  --border: hsl(var(--brand-ink-h) var(--brand-ink-s) 20%);
  --border-strong: hsl(var(--brand-ink-h) var(--brand-ink-s) 28%);

  --text: var(--neutral-25);
  --text-muted: var(--neutral-400);
  --text-inverse: var(--neutral-900);

  --brand: var(--primary-300);
  --brand-emphasis: var(--primary-200);
  --brand-contrast: hsl(var(--brand-ink-h) var(--brand-ink-s) 9%);
  --brand-soft: hsl(var(--brand-primary-h) 30% 16% / 0.6);

  --cta: hsl(var(--brand-cta-h) 86% 58%);
  --cta-emphasis: hsl(var(--brand-cta-h) 88% 64%);
  --cta-contrast: hsl(var(--brand-ink-h) 30% 8%);
  --cta-soft: hsl(var(--brand-cta-h) 60% 18% / 0.5);

  --accent: hsl(var(--brand-cta-h) 86% 58%);
  --accent-emphasis: hsl(var(--brand-cta-h) 88% 64%);

  --status-ok-bg: hsl(150 40% 15% / 0.5);
  --status-warn-bg: hsl(41 50% 18% / 0.5);
  --status-danger-bg: hsl(5 50% 20% / 0.5);
  --status-info-bg: hsl(203 50% 18% / 0.5);
}

/* --- Base --- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  /* Stop iOS Safari auto-adjusting text size (font-boosting) so type stays consistent
     across pages on mobile — platform-wide (the spine owns the base reset). */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  /* Break long unbreakable tokens (file paths, identifiers, version slugs) instead of overflowing —
     otherwise they force horizontal overflow on a phone and iOS shrinks the whole page to fit.
     `anywhere` (NOT break-word) so the break counts toward MIN-CONTENT sizing — otherwise a long token
     inside a grid/flex track keeps the track wide and it still overflows. Inherited → platform-wide. */
  overflow-wrap: anywhere;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

:where(a) {
  color: var(--brand);
}
:where(:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* =========================================================================
 * Components — all reference tokens (no raw hex).
 * ========================================================================= */

.ds-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: -0.006em;
  line-height: 1;
  min-height: 44px;
  padding: 0.75rem 1.25rem;
  border-radius: var(--radius-full);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 0.16s ease, border-color 0.16s ease, box-shadow 0.16s ease,
    transform 0.08s ease;
  text-decoration: none;
}
.ds-btn:active { transform: translateY(1px); }
.ds-btn[disabled] { opacity: 0.5; cursor: not-allowed; }
/* Primary = the CTA: warm orange, soft glow on hover. */
.ds-btn--primary { background: var(--cta); color: var(--cta-contrast); }
.ds-btn--primary:hover { background: var(--cta-emphasis); box-shadow: var(--shadow-cta); }
/* Accent = brand green (secondary emphasis). */
.ds-btn--accent { background: var(--brand); color: var(--brand-contrast); }
.ds-btn--accent:hover { background: var(--brand-emphasis); }
.ds-btn--ghost { background: transparent; color: var(--text); border-color: var(--border-strong); }
.ds-btn--ghost:hover { background: var(--surface-hover); }
.ds-btn--sm { min-height: 36px; padding: 0.5rem 0.9rem; font-size: var(--text-xs); }

.ds-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-sm);
  padding: var(--space-5);
}
.ds-card--pad-lg { padding: var(--space-6); }
.ds-card__title { font-weight: var(--weight-semibold); font-size: var(--text-lg); margin: 0 0 var(--space-2); font-family: var(--font-display); letter-spacing: var(--tracking-tight); }
.ds-card__subtitle { color: var(--text-muted); font-size: var(--text-sm); margin: 0; }

.ds-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  padding: 0.3rem 0.65rem;
  border-radius: var(--radius-full);
  line-height: 1.4;
}
.ds-pill::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.ds-pill--ok { color: var(--status-ok); background: var(--status-ok-bg); }
.ds-pill--warn { color: var(--status-warn); background: var(--status-warn-bg); }
.ds-pill--danger { color: var(--status-danger); background: var(--status-danger-bg); }
.ds-pill--info { color: var(--status-info); background: var(--status-info-bg); }
.ds-pill--neutral { color: var(--text-muted); background: var(--bg-sunken); }

.ds-stat__label { color: var(--text-muted); font-size: var(--text-sm); margin: 0 0 var(--space-1); }
.ds-stat__value { font-family: var(--font-display); font-size: var(--text-2xl); font-weight: var(--weight-semibold); line-height: 1; letter-spacing: var(--tracking-display); }
.ds-stat__delta { font-size: var(--text-xs); color: var(--text-muted); margin-top: var(--space-2); }

.ds-page-header { margin-bottom: var(--space-6); }
.ds-page-header__eyebrow { text-transform: uppercase; letter-spacing: var(--tracking-caps); font-size: var(--text-2xs); font-weight: var(--weight-semibold); color: var(--accent-emphasis); margin: 0 0 var(--space-2); }
.ds-page-header__title { font-family: var(--font-display); font-size: var(--text-3xl); font-weight: var(--weight-semibold); letter-spacing: var(--tracking-display); margin: 0; line-height: 1.1; }
.ds-page-header__lede { color: var(--text-muted); font-size: var(--text-md); margin: var(--space-3) 0 0; max-width: 62ch; line-height: var(--leading-relaxed); }

.ds-meter { height: 8px; border-radius: var(--radius-full); background: var(--bg-sunken); overflow: hidden; }
.ds-meter__fill { height: 100%; border-radius: var(--radius-full); background: var(--brand); transition: width 0.3s ease; }
.ds-meter__fill--warn { background: var(--status-warn); }
.ds-meter__fill--danger { background: var(--status-danger); }

/* --- States (A2): spinner, skeleton, status dot (reduced-motion neutralised above) --- */
@keyframes ds-spin { to { transform: rotate(360deg); } }
.ds-spinner {
  width: 22px;
  height: 22px;
  border-radius: var(--radius-full);
  border: 2px solid var(--border);
  border-top-color: var(--brand);
  animation: ds-spin 0.7s linear infinite;
}
@keyframes ds-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
.ds-skeleton { background: var(--bg-sunken); border-radius: var(--radius-sm); animation: ds-pulse 1.4s ease-in-out infinite; }
.ds-status-dot { display: inline-block; width: 10px; height: 10px; border-radius: var(--radius-full); background: var(--text-muted); }
.ds-status-dot--ok { background: var(--status-ok); }
.ds-status-dot--warn { background: var(--status-warn); }
.ds-status-dot--danger { background: var(--status-danger); }

/* Branded loader — the Y holds upright, does two fast spins, holds "a while", spins again. */
@keyframes ds-ylogo-spin {
  0%, 18% { transform: rotate(0deg); }
  38% { transform: rotate(720deg); }
  62% { transform: rotate(720deg); }
  82% { transform: rotate(1440deg); }
  100% { transform: rotate(1440deg); }
}
.ds-ylogo-spin { display: inline-flex; transform-origin: 50% 50%; animation: ds-ylogo-spin 3.2s ease-in-out infinite; }

/* Nav loading overlay (R4) — blurs the CURRENT screen in place; enlarged spinning-Y; fades in fast,
   auto-removed on route commit. `position` + `backdrop-filter` are set inline (fixed vs contained). */
@keyframes ds-nav-overlay-in { from { opacity: 0; } to { opacity: 1; } }
.ds-nav-overlay {
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--surface) 55%, transparent);
  animation: ds-nav-overlay-in 160ms ease-out both;
}

/* Trend indicator (▲/▼ delta) */
.ds-trend { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--text-sm); font-weight: var(--weight-semibold); line-height: 1; }
.ds-trend--up { color: var(--status-ok); }
.ds-trend--down { color: var(--status-danger); }
.ds-trend--flat { color: var(--text-muted); }

/* Urgent-attention pulse — red flash + breathe (reduced-motion neutralised above) */
@keyframes ds-urgent-pulse {
  0%, 100% { filter: drop-shadow(0 0 0 transparent); transform: scale(1); }
  50% { filter: drop-shadow(0 0 5px var(--status-danger)); transform: scale(1.08); }
}
.ds-urgent { display: inline-flex; transform-origin: center; animation: ds-urgent-pulse 1.4s ease-in-out infinite; }

/* =========================================================================
 * Regatta Light 2.0 — EXPRESSIVE TIER (brief 0028, session 36f)
 * Tokens + component classes for the delight layer: motion tokens, the ink
 * (charcoal-pill) tier, a COMPUTED pastel tint ladder, an ordered data-viz
 * scale, display numerals, and the 9 expressive primitives. All colours are
 * tokens (grow-by-config: a new tint/viz colour = one line here, never a raw
 * hex in a surface). Motion stays bound to meaning; the global
 * prefers-reduced-motion rule above neutralises all of it.
 * ========================================================================= */
:root {
  /* Motion tokens — one easing family, three durations. Lists never animate. */
  --motion-fast: 120ms;
  --motion-regular: 250ms;
  --motion-slow: 400ms;
  --ease-out: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* Ink tier — the charcoal pill anchor (owner taste: dark pills grounding light canvases).
     Secondary-action tier; the warm-orange CTA stays THE one accent. */
  --ink: var(--neutral-900);
  --ink-hover: var(--neutral-800);
  --ink-contrast: var(--neutral-0);

  /* Pastel tint ladder — COMPUTED from a small base-hue set against the live surface, so tints
     adapt to light/dark automatically and adding a colour is adding ONE base line. */
  --tint-mint-base: hsl(160 45% 48%);
  --tint-lavender-base: hsl(252 55% 60%);
  --tint-peach-base: hsl(24 82% 58%);
  --tint-sky-base: hsl(203 65% 50%);
  --tint-sand-base: hsl(40 50% 50%);
  --tint-mint: color-mix(in srgb, var(--tint-mint-base) 14%, var(--surface));
  --tint-lavender: color-mix(in srgb, var(--tint-lavender-base) 14%, var(--surface));
  --tint-peach: color-mix(in srgb, var(--tint-peach-base) 14%, var(--surface));
  --tint-sky: color-mix(in srgb, var(--tint-sky-base) 14%, var(--surface));
  --tint-sand: color-mix(in srgb, var(--tint-sand-base) 16%, var(--surface));
  --tint-mint-fg: color-mix(in srgb, var(--tint-mint-base) 70%, var(--text));
  --tint-lavender-fg: color-mix(in srgb, var(--tint-lavender-base) 70%, var(--text));
  --tint-peach-fg: color-mix(in srgb, var(--tint-peach-base) 70%, var(--text));
  --tint-sky-fg: color-mix(in srgb, var(--tint-sky-base) 70%, var(--text));
  --tint-sand-fg: color-mix(in srgb, var(--tint-sand-base) 70%, var(--text));

  /* Ordered data-viz scale (charts, HoR grids, dials). Brand green leads; the CTA-orange hue sits
     mid-scale so it never reads as "the accent" inside a chart. */
  --viz-1: var(--primary-500);
  --viz-2: hsl(203 60% 46%);
  --viz-3: hsl(252 45% 58%);
  --viz-4: hsl(24 80% 55%);
  --viz-5: hsl(160 38% 40%);
  --viz-6: hsl(330 45% 55%);
  --viz-7: hsl(40 62% 46%);
  --viz-8: var(--neutral-500);

  /* Display numerals — the number IS the UI (tabular so values change without layout twitch). */
  --text-num-md: 32px;
  --text-num-lg: 40px;
  --text-num-xl: 56px;
}

/* --- Display numerals --- */
.ds-numeral { font-family: var(--font-display); font-variant-numeric: tabular-nums lining-nums; font-weight: var(--weight-bold); letter-spacing: var(--tracking-display); line-height: 1; font-size: var(--text-num-md); }
.ds-numeral--lg { font-size: var(--text-num-lg); }
.ds-numeral--xl { font-size: var(--text-num-xl); }
.ds-numeral__unit { font-size: 0.45em; font-weight: var(--weight-semibold); color: var(--text-muted); margin-left: 0.15em; letter-spacing: 0; }
.ds-numeral-context { color: var(--text-muted); font-size: var(--text-sm); margin-top: var(--space-2); }

/* --- Ink pill button (secondary anchor; CTA orange stays the one accent) --- */
.ds-btn--ink { background: var(--ink); color: var(--ink-contrast); }
.ds-btn--ink:hover { background: var(--ink-hover); }

/* --- Expressive DEFAULTS on existing components (opt-out via ds-card--static) --- */
.ds-btn { transition: background var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out), box-shadow var(--motion-fast) var(--ease-out), transform var(--motion-fast) var(--ease-spring); }
.ds-btn:active { transform: translateY(1px) scale(0.97); }
.ds-card { transition: box-shadow var(--motion-regular) var(--ease-out), transform var(--motion-regular) var(--ease-out); }
.ds-card--interactive { cursor: pointer; }
.ds-card--interactive:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.ds-card--static { transition: none; }

/* --- PhotoChip — round relevant-image lead for rows/cards (owner-loved detail) --- */
.ds-photo-chip { border-radius: var(--radius-full); object-fit: cover; border: 2px solid var(--surface); box-shadow: var(--shadow-sm); display: block; }

/* --- ArcGauge (SVG drawn in React; these style its centre text) --- */
.ds-arc-gauge { display: inline-grid; place-items: center; position: relative; }
.ds-arc-gauge__value { position: absolute; text-align: center; }

/* --- PhotoHero + DataPin — photography with data pinned ON it --- */
.ds-photo-hero { position: relative; border-radius: var(--radius-xl); overflow: hidden; box-shadow: var(--shadow-md); }
.ds-photo-hero__img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ds-photo-hero--scrim::after { content: ''; position: absolute; inset: 0; background: var(--scrim-bottom); pointer-events: none; }
.ds-photo-hero__content { position: absolute; inset: auto 0 0 0; padding: var(--space-5); color: var(--on-media); z-index: 2; }
.ds-data-pin { position: absolute; transform: translate(-50%, -100%); display: flex; flex-direction: column; align-items: center; z-index: 2; }
.ds-data-pin__label { background: var(--surface-glass); backdrop-filter: blur(8px); border: 1px solid var(--hairline-on-media); border-radius: var(--radius-full); padding: 0.3rem 0.7rem; font-size: var(--text-xs); font-weight: var(--weight-semibold); color: var(--text); white-space: nowrap; box-shadow: var(--shadow-sm); }
.ds-data-pin__stem { width: 1.5px; height: 22px; background: var(--hairline-on-media); }
.ds-data-pin__dot { width: 9px; height: 9px; border-radius: var(--radius-full); background: var(--on-media); border: 2px solid var(--accent); box-shadow: var(--shadow-sm); }

/* --- TicketCard — boarding-pass artifact (cert wallet, PSC readiness) --- */
.ds-ticket { position: relative; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); overflow: hidden; }
.ds-ticket__main { padding: var(--space-5); }
.ds-ticket__tear { position: relative; border-top: 2px dashed var(--border-strong); margin: 0 var(--space-4); }
.ds-ticket__tear::before, .ds-ticket__tear::after { content: ''; position: absolute; top: -9px; width: 18px; height: 18px; border-radius: var(--radius-full); background: var(--bg); border: 1px solid var(--border); }
.ds-ticket__tear::before { left: -25px; }
.ds-ticket__tear::after { right: -25px; }
.ds-ticket__stub { padding: var(--space-4) var(--space-5); display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); }
.ds-ticket__barcode { height: 40px; flex: 1; background: repeating-linear-gradient(90deg, var(--text) 0 2px, transparent 2px 4px, var(--text) 4px 7px, transparent 7px 9px); opacity: 0.85; border-radius: 2px; }
.ds-ticket__code { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-muted); letter-spacing: 0.08em; }

/* --- CategoryChip — tinted illustrated category tile --- */
.ds-category-chip { display: inline-flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-radius: var(--radius-lg); border: 1px solid transparent; cursor: pointer; font-weight: var(--weight-semibold); font-size: var(--text-sm); color: var(--text); transition: transform var(--motion-fast) var(--ease-spring), box-shadow var(--motion-fast) var(--ease-out); }
.ds-category-chip:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); }
.ds-category-chip--active { border-color: var(--accent); box-shadow: 0 0 0 2px var(--focus-ring); }
.ds-category-chip__icon { font-size: var(--text-xl); line-height: 1; }

/* --- AnchorNav — dark bar, accent active pill (crew mobile chrome) --- */
.ds-anchor-nav { display: inline-flex; gap: var(--space-1); background: var(--ink); border-radius: var(--radius-full); padding: 6px; box-shadow: var(--shadow-lg); }
.ds-anchor-nav__item { display: inline-flex; align-items: center; gap: var(--space-2); border: 0; background: transparent; color: var(--ink-contrast); opacity: 0.72; font-family: var(--font-sans); font-size: var(--text-sm); font-weight: var(--weight-semibold); padding: 0.6rem 1rem; border-radius: var(--radius-full); cursor: pointer; transition: background var(--motion-fast) var(--ease-out), opacity var(--motion-fast) var(--ease-out); min-height: 40px; }
.ds-anchor-nav__item:hover { opacity: 1; }
.ds-anchor-nav__item--active { background: var(--cta); color: var(--cta-contrast); opacity: 1; }

/* --- FloatingCards — ambient drifting-card composition (landing hero, empty-state ambience) --- */
@keyframes ds-float { from { transform: translateY(0) rotate(var(--float-tilt, 0deg)); } to { transform: translateY(-10px) rotate(var(--float-tilt, 0deg)); } }
/* width:100% is load-bearing: the stage holds ONLY abs-positioned children, so auto width collapses to 0
   inside shrink-to-fit layouts and every card's left:% resolves against nothing (the s36f pile-up bug). */
.ds-floating-cards { position: relative; width: 100%; }
.ds-floating-cards__item { position: absolute; width: max-content; max-width: min(320px, 60%); animation: ds-float 5.5s var(--ease-out) infinite alternate; animation-delay: var(--float-delay, 0s); will-change: transform; }
/* ^ width:max-content is load-bearing: the body-level `overflow-wrap:anywhere` makes an abs-positioned
   element's min-content width collapse to ~one character (the s36f letter-stack bug) — size to content. */

/* --- Celebrate — the success moment (sign-offs, drill pass). Used sparingly = it stays special. --- */
@keyframes ds-celebrate-pop { 0% { transform: scale(0.6); opacity: 0; } 60% { transform: scale(1.06); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
@keyframes ds-celebrate-burst { from { transform: rotate(var(--burst-angle)) translateY(0); opacity: 1; } to { transform: rotate(var(--burst-angle)) translateY(-46px); opacity: 0; } }
.ds-celebrate { position: relative; display: inline-grid; place-items: center; }
.ds-celebrate__content { animation: ds-celebrate-pop var(--motion-slow) var(--ease-spring) both; }
.ds-celebrate__dot { position: absolute; width: 7px; height: 7px; border-radius: var(--radius-full); animation: ds-celebrate-burst 700ms var(--ease-out) both; animation-delay: 120ms; }
