/* @gyrum-labs/tokens — canonical CSS custom properties for the
 * gyrum design system.
 *
 * Source of truth for colour (5-mode palettes per ADR-058), status,
 * spacing, typography, radius, shadow, z-index and transition timings.
 *
 * Consumer usage:
 *   @import "@gyrum-labs/tokens/tokens.css";
 *   <html data-mode="ship"> rebinds the generic names (--accent, etc.)
 *   to the ship-mode palette. See ADR-062 §Layer 1.
 *
 * Extracted from:
 *   - ai-frontend/src/lib/styles/mode-tokens.css (5-mode palettes)
 *   - ai-frontend/src/app.css (status, font stacks)
 *   - Inline <style> blocks in ai-frontend/src/lib/homes/OperateHome.svelte
 *     and siblings that promoted --ok / --warn / --bad / --never as
 *     de-facto status tokens.
 *
 * Changes here are design-system changes — review accordingly.
 */

:root {
  /* ── Colour — per-mode palettes (ADR-058) ─────────────────────── */

  /* Home — calm slate, near-white surfaces; restrained identity page. */
  --home-accent: #334155;
  --home-accent-hover: #1e293b;
  --home-accent-soft: #f1f5f9;
  --home-bg: #ffffff;
  --home-surface: #f8fafc;
  --home-text: #0f172a;
  --home-text-muted: #475569;
  --home-border: #e2e8f0;
  --home-radius: 8px;

  /* Ship — greenish product accent, moderate density. */
  --ship-accent: #15803d;
  --ship-accent-hover: #166534;
  --ship-accent-soft: #dcfce7;
  --ship-bg: #ffffff;
  --ship-surface: #f8fafc;
  --ship-text: #0f172a;
  /* Bumped to slate-600 (refined-calm, warp#8209): the prior slate-500
   * (#64748b) cleared AA against white but dropped to ~4.55:1 on the
   * tinted --ship-surface where KPI labels + table-header bands sit.
   * Slate-600 joins the other four modes at ~7:1 so secondary text reads
   * crisply without louder accents. */
  --ship-text-muted: #475569;
  --ship-border: #e2e8f0;
  --ship-radius: 8px;

  /* Operate — blue/amber, high contrast for alerts. */
  --operate-accent: #1d4ed8;
  --operate-accent-hover: #1e40af;
  --operate-accent-soft: #dbeafe;
  --operate-bg: #ffffff;
  --operate-surface: #f1f5f9;
  --operate-text: #0f172a;
  --operate-text-muted: #475569;
  --operate-border: #cbd5e1;
  --operate-radius: 6px;

  /* Infra — technical blue-grey, sibling of Operate but calmer. */
  --infra-accent: #475569;
  --infra-accent-hover: #334155;
  --infra-accent-soft: #e2e8f0;
  --infra-bg: #ffffff;
  --infra-surface: #f1f5f9;
  --infra-text: #0f172a;
  --infra-text-muted: #475569;
  --infra-border: #cbd5e1;
  --infra-radius: 4px;

  /* Experiment — warm neutral, emphasis on charts. */
  --experiment-accent: #b45309;
  --experiment-accent-hover: #92400e;
  --experiment-accent-soft: #fef3c7;
  --experiment-bg: #fafaf9;
  --experiment-surface: #f5f5f4;
  --experiment-text: #1c1917;
  --experiment-text-muted: #44403c;
  --experiment-border: #d6d3d1;
  --experiment-radius: 10px;

  /* ── Status colours — mode-invariant.
   * Promoted from inline <style> blocks in ai-frontend
   * (OperateHome.svelte, FleetDonut.svelte, DeployTimeline.svelte)
   * where these names had already stabilised. Also aliased to the
   * legacy --success / --error / --running names app.css ships. */
  --ok: #15803d;
  --ok-soft: #dcfce7;
  --warn: #b45309;
  --warn-hover: #92400e;
  --warn-soft: #fef3c7;
  --bad: #b91c1c;
  --bad-hover: #991b1b;
  --bad-soft: #fee2e2;
  --never: #94a3b8;
  --never-soft: #f1f5f9;
  --success: var(--ok);
  --error: var(--bad);
  --running: #3b82f6;

  /* Foreground colour to use ON TOP OF an accent or bad surface — stable
   * WCAG-AA white across every mode (the accent + bad palettes are deep
   * enough that the same #ffffff foreground reads correctly on all five).
   * Promoted from button.ts where they had leaked as raw hex (warp#681).
   * If a future mode introduces a light-accent variant, override
   * --text-on-accent inside that mode block. */
  --text-on-accent: #ffffff;
  --text-on-bad: #ffffff;
  --warn-fg: #ffffff;

  /* ── Spacing — 4px base, t-0 through t-6 (ADR-062 §Layer 1). */
  --space-0: 0;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  /* warp 4233 / ADR-190 — canon grows to a sufficient superset so apps
     consume the canon scale instead of forking their own. Continues the
     progression (32 → 48 → 64 → 96 → 128) to cover the larger layout
     gaps apps previously hand-rolled (`--space-8..16`). */
  --space-8: 48px;
  --space-10: 64px;
  --space-12: 96px;
  --space-16: 128px;

  /* ── Typography. */
  --font:
    system-ui, -apple-system, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
    'Open Sans', 'Helvetica Neue', sans-serif;
  --font-mono:
    ui-monospace, 'SF Mono', Menlo, Monaco, Consolas, monospace;
  --font-size-2xs: 0.6875rem;
  --font-size-xs: 0.7rem;
  --font-size-sm: 0.8125rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-h2: 1.25rem;
  --font-size-h1: 1.5rem;
  /* warp 4272 / ADR-190 — large end of the t-shirt SIZE scale
     (…lg → xl → 2xl → 3xl, monotonic ascending), completing the canon
     superset so apps stop forking it. This size scale is a SEPARATE
     axis from the semantic heading tokens (--font-size-h1/h2): a
     heading level picks h1/h2; a raw size picks the t-shirt scale.
     xl is intentionally < h1 — they are not the same axis. */
  --font-size-xl: 1.375rem;
  --font-size-2xl: 1.75rem;
  --font-size-3xl: 2.25rem;
  /* warp 4233 / ADR-190 — DEPRECATED migration aliases. Apps that forked
     a px-named `--text-*` scale map onto the canon rem `--font-size-*`
     scale here so they can adopt canon incrementally without undefined
     tokens. These are a migration bridge ONLY — removed once the fleet
     canon-drift sweep (warp 4241) reports zero `--text-*` consumers.
     New code uses `--font-size-*` directly. The no-token-fork gate
     (warp 4239) refuses NEW `--text-*` definitions in app CSS. */
  --text-2xs: var(--font-size-2xs);
  --text-xs: var(--font-size-xs);
  --text-sm: var(--font-size-sm);
  --text-base: var(--font-size-base);
  --text-md: var(--font-size-lg);
  --text-lg: var(--font-size-h2);
  --text-xl: var(--font-size-xl);
  --text-2xl: var(--font-size-2xl);
  --text-3xl: var(--font-size-3xl);
  --font-weight-regular: 400;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  --line-height-tight: 1.1;
  --line-height-base: 1.5;

  /* ── Layout. The narrow/wide trio matches ADR-058 §page grammar;
   * values match ai-frontend's current +layout.svelte conventions. */
  --page-max-narrow: 720px;
  --page-max: 1080px;
  --page-max-wide: 1440px;
  /* The typographic prose measure — ~60 characters per line, the classic
   * readability target. Distinct from the --page-max* page/layout widths
   * above: those bound a whole surface, this bounds a column of prose. Use
   * it for body text on reading-first surfaces (preface, chapter bodies)
   * instead of hardcoding `max-width: 60ch`. */
  --measure: 60ch;
  --page-gutter: 24px;

  /* ── Radius (mode overrides radius via --radius binding below). */
  --radius-none: 0;
  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;
  --radius-xl: 10px;
  /* Fully-rounded "pill" radius — used for badge[pill], chip-style
   * status indicators, and any other "the corners are gone" surface.
   * 9999px is the conventional sentinel; any value larger than half
   * the element's height collapses to a full semicircle. */
  --radius-pill: 9999px;

  /* ── Shadow. */
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.05);
  --shadow-md: 0 2px 8px rgba(15, 23, 42, 0.08);
  --shadow-lg: 0 8px 24px rgba(15, 23, 42, 0.12);

  /* ── Z-index — explicit layers per ADR-062 "no random z-index: 99999". */
  --z-base: 0;
  --z-header: 100;
  --z-drawer: 200;
  --z-scrim: 300;
  --z-modal: 400;
  --z-toast: 500;

  /* ── Transitions (legacy names — kept for existing consumers). */
  --transition-fast: 120ms;
  --transition-base: 180ms;
  --transition-slow: 240ms;
  --easing-standard: cubic-bezier(0.2, 0, 0, 1);

  /* ── Motion — durations + easings used by every component animation,
   * keyframe, or `transition:` rule across the design system.
   *
   * The canonical contract lives in `docs/motion-guideline.md` (warp#1849):
   * which token is appropriate for which affordance, what may be animated,
   * what may not, and the reduced-motion override below.
   *
   * Durations are pinned in ms so consumers can multiply / interpolate.
   * Authors MUST consume these via `var(--motion-*)` rather than baking
   * literal `0.15s ease` strings into component CSS — that is the drift
   * the motion guideline exists to prevent. */
  --motion-fast: 80ms;             /* hover/focus state changes */
  --motion-base: 150ms;            /* default microanimation */
  --motion-slow: 300ms;            /* entrance fade-up, expand/collapse */
  --motion-extra-slow: 600ms;      /* emphasis only — celebratory feedback */

  /* Easings. Names match Material's "natural motion" vocabulary so the
   * intent reads on inspection: ease-out for entrances (decelerate as
   * the element settles), ease-in-out for state transitions (smooth
   * on both ends), spring for delight moments (subtle overshoot).
   * `--easing-standard` above is retained as a legacy alias of
   * `--motion-ease-in-out` for the existing button transitions. */
  --motion-ease-out: cubic-bezier(0.2, 0, 0, 1);
  --motion-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --motion-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* ── Reduced-motion contract (WCAG 2.3.3, warp#1849).
 *
 * Users who opt into `prefers-reduced-motion: reduce` get instant state
 * changes — every duration token collapses to 0ms. Component CSS that
 * consumes `--motion-*` therefore needs ZERO extra `@media` blocks to
 * honour the OS preference; the override propagates through the
 * cascade automatically.
 *
 * Easings are also flattened to the identity curve (`steps(1, end)`)
 * so any consumer reading `--motion-ease-*` separately still produces
 * an instant transition rather than a 0ms-but-eased animation. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-fast: 0ms;
    --motion-base: 0ms;
    --motion-slow: 0ms;
    --motion-extra-slow: 0ms;
    --motion-ease-out: steps(1, end);
    --motion-ease-in-out: steps(1, end);
    --motion-ease-spring: steps(1, end);
    /* Legacy transition tokens follow the same contract — components
     * still on the old names also collapse to instant under reduce. */
    --transition-fast: 0ms;
    --transition-base: 0ms;
    --transition-slow: 0ms;
  }
}

/* Home is the default. Pages rendered before the mode store publishes
 * (SSR first paint) stay on the calm Home palette. Legacy aliases
 * (--fg / --fg-muted / --bg-subtle) are retained so ai-frontend's
 * current selectors keep working across the rename window. */
:root,
:root[data-mode='home'] {
  --accent: var(--home-accent);
  --accent-hover: var(--home-accent-hover);
  --accent-soft: var(--home-accent-soft);
  --bg: var(--home-bg);
  --surface: var(--home-surface);
  --text: var(--home-text);
  --text-muted: var(--home-text-muted);
  --border: var(--home-border);
  --radius: var(--home-radius);
  --fg: var(--home-text);
  --fg-muted: var(--home-text-muted);
  --bg-subtle: var(--home-surface);
}

:root[data-mode='ship'] {
  --accent: var(--ship-accent);
  --accent-hover: var(--ship-accent-hover);
  --accent-soft: var(--ship-accent-soft);
  --bg: var(--ship-bg);
  --surface: var(--ship-surface);
  --text: var(--ship-text);
  --text-muted: var(--ship-text-muted);
  --border: var(--ship-border);
  --radius: var(--ship-radius);
  --fg: var(--ship-text);
  --fg-muted: var(--ship-text-muted);
  --bg-subtle: var(--ship-surface);
}

:root[data-mode='operate'] {
  --accent: var(--operate-accent);
  --accent-hover: var(--operate-accent-hover);
  --accent-soft: var(--operate-accent-soft);
  --bg: var(--operate-bg);
  --surface: var(--operate-surface);
  --text: var(--operate-text);
  --text-muted: var(--operate-text-muted);
  --border: var(--operate-border);
  --radius: var(--operate-radius);
  --fg: var(--operate-text);
  --fg-muted: var(--operate-text-muted);
  --bg-subtle: var(--operate-surface);
}

:root[data-mode='infra'] {
  --accent: var(--infra-accent);
  --accent-hover: var(--infra-accent-hover);
  --accent-soft: var(--infra-accent-soft);
  --bg: var(--infra-bg);
  --surface: var(--infra-surface);
  --text: var(--infra-text);
  --text-muted: var(--infra-text-muted);
  --border: var(--infra-border);
  --radius: var(--infra-radius);
  --fg: var(--infra-text);
  --fg-muted: var(--infra-text-muted);
  --bg-subtle: var(--infra-surface);
}

:root[data-mode='experiment'] {
  --accent: var(--experiment-accent);
  --accent-hover: var(--experiment-accent-hover);
  --accent-soft: var(--experiment-accent-soft);
  --bg: var(--experiment-bg);
  --surface: var(--experiment-surface);
  --text: var(--experiment-text);
  --text-muted: var(--experiment-text-muted);
  --border: var(--experiment-border);
  --radius: var(--experiment-radius);
  --fg: var(--experiment-text);
  --fg-muted: var(--experiment-text-muted);
  --bg-subtle: var(--experiment-surface);
}

/* Apply the canonical font + colour + surface to the document body so
 * every consumer (Storybook, factory routes post-Phase-3, any host
 * page that imports tokens.css) inherits the design-system typography
 * baseline. Without this rule the --font / --text / --bg tokens are
 * defined at :root but never consumed, and the user-agent default
 * (serif on most browsers) leaks through onto every text surface. */
body {
  font-family: var(--font);
  color: var(--text);
  background: var(--bg);
}
