/*
 * tokens.css — THE canonical design tokens for this project.
 *
 * ⚠ THIS FILE IS THE SOURCE OF TRUTH. Edit colours and scales HERE, never in a
 *   component. `npm run sync-starter` never overwrites this file — the moment you
 *   set a palette it becomes the most project-specific file in the repo.
 *
 * TWO LAYERS, and the split is the whole point:
 *
 *   Layer 1 — YOURS.     --brand-* and the scales. This is what you change.
 *   Layer 2 — shadcn's.  The semantic tokens shadcn/ui components consume,
 *                        mapped ONTO layer 1. You rarely touch these.
 *
 * Change a --brand-* value and every shadcn component follows, because nothing in
 * layer 2 hardcodes a colour. That is what keeps "restyle the app" a one-file edit.
 *
 * Ships NEUTRAL on purpose — a working greyscale, not a brand. Run /design-explore
 * to pick a real direction before you start hand-picking hexes per component.
 */

:root {
  /* ══ LAYER 1 — YOURS ═══════════════════════════════════════════════════════ */

  /* — Palette (semantic names, not colour names) —
     Name by ROLE. `--brand-accent` survives a rebrand; `--brand-blue` does not. */
  --brand-ground:   oklch(0.995 0 0);      /* page background */
  --brand-surface:  oklch(1 0 0);          /* cards, sheets, raised chrome */
  --brand-sunken:   oklch(0.97 0 0);       /* wells, insets, code blocks */
  --brand-ink:      oklch(0.18 0 0);       /* primary text */
  --brand-muted:    oklch(0.52 0 0);       /* secondary text */
  --brand-dim:      oklch(0.66 0 0);       /* tertiary text, captions, placeholders */
  --brand-hair:     oklch(0.91 0 0);       /* hairlines, borders, dividers */
  --brand-accent:   oklch(0.55 0.02 264);  /* THE accent — primary CTAs only */
  --brand-accent-hot: oklch(0.48 0.02 264);/* accent hover / active */
  --brand-on-accent: oklch(0.99 0 0);      /* text ON the accent */
  --brand-danger:   oklch(0.58 0.21 27);   /* destructive */
  --brand-warning:  oklch(0.75 0.16 70);
  --brand-success:  oklch(0.60 0.13 155);

  /* — Radius — ONE knob for every rectangle, plus pill for round things.
     Resist re-adding sm/md/lg tiers: three radii read as three design systems. */
  --radius: 8px;
  --radius-pill: 999px;

  /* — Spacing scale (base-4) — */
  --space-1: 4px;   --space-2: 8px;   --space-3: 12px;  --space-4: 16px;
  --space-5: 20px;  --space-6: 24px;  --space-8: 32px;  --space-10: 40px;  --space-12: 48px;

  /* — Semantic rhythm — reach for these in forms before the raw scale.
     They keep every form in the app breathing the same way. */
  --space-label: 8px;     /* label → its input */
  --space-field: 24px;    /* field → next field */
  --space-section: 48px;  /* group → group */

  /* — Controls — inputs AND buttons share ONE height scale.
     An input and the button beside it are never different heights. */
  --control-h-sm: 32px;   /* toolbars, tabs, dense actions */
  --control-h: 40px;      /* DEFAULT — inputs and md buttons */
  --control-h-lg: 48px;   /* standalone CTAs */
  --control-px: 16px;     /* input side padding — text never touches an edge */
  --btn-px: 20px;         /* button side padding */
  --touch-target: 44px;   /* ⚠ minimum tap target on any touch surface. Not negotiable. */

  /* — Typefaces — */
  --font-display: system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-body: system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono: ui-monospace, 'SF Mono', Menlo, monospace;

  /* — Type scale (base-4) —
     ⚠ If you adopt a heavy display face, set a size floor for it. A poster grotesk
       below ~28px closes its counters and reads as a smudge. Put the floor in a
       comment here so the next session does not "fix" it. */
  --text-display-xl: 36px;
  --text-display-lg: 28px;
  --text-title: 24px;
  --text-heading: 20px;
  --text-body: 16px;      /* ⚠ never below 16px on a form input — iOS zooms on focus */
  --text-ui: 14px;
  --text-caption: 12px;
  --leading-tight: 1.15;
  --leading-body: 1.55;

  /* — Elevation — */
  --shadow-sm: 0 1px 2px oklch(0 0 0 / 0.06);
  --shadow: 0 2px 8px oklch(0 0 0 / 0.08);
  --shadow-lg: 0 8px 28px oklch(0 0 0 / 0.12);

  /* — Motion — durations short enough to feel instant, easing that decelerates.
     See /impeccable and the emil-design-eng pack before inventing new curves. */
  --ease-out: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --dur-fast: 120ms;
  --dur: 200ms;
  --dur-slow: 320ms;

  /* ══ LAYER 2 — shadcn/ui semantic tokens ═══════════════════════════════════
     Mapped onto layer 1. Do not hardcode colours here; point at a --brand-*. */

  --background: var(--brand-ground);
  --foreground: var(--brand-ink);
  --card: var(--brand-surface);
  --card-foreground: var(--brand-ink);
  --popover: var(--brand-surface);
  --popover-foreground: var(--brand-ink);
  --primary: var(--brand-accent);
  --primary-foreground: var(--brand-on-accent);
  --secondary: var(--brand-sunken);
  --secondary-foreground: var(--brand-ink);
  --muted: var(--brand-sunken);
  --muted-foreground: var(--brand-muted);
  --accent: var(--brand-sunken);
  --accent-foreground: var(--brand-ink);
  --destructive: var(--brand-danger);
  --destructive-foreground: var(--brand-on-accent);
  --border: var(--brand-hair);
  --input: var(--brand-hair);
  --ring: var(--brand-accent);
}

/* — Dark mode —
   Redefine LAYER 1 ONLY. Layer 2 points at layer 1, so it inverts for free.
   If you find yourself redefining a layer-2 token here, the mapping above is wrong. */
.dark {
  --brand-ground:   oklch(0.15 0 0);
  --brand-surface:  oklch(0.20 0 0);
  --brand-sunken:   oklch(0.24 0 0);
  --brand-ink:      oklch(0.97 0 0);
  --brand-muted:    oklch(0.70 0 0);
  --brand-dim:      oklch(0.55 0 0);
  --brand-hair:     oklch(0.30 0 0);
  --brand-accent:   oklch(0.75 0.02 264);
  --brand-accent-hot: oklch(0.82 0.02 264);
  --brand-on-accent: oklch(0.17 0 0);

  --shadow-sm: 0 1px 2px oklch(0 0 0 / 0.4);
  --shadow: 0 2px 8px oklch(0 0 0 / 0.5);
  --shadow-lg: 0 8px 28px oklch(0 0 0 / 0.6);
}

/* Respect the user's setting. Every transition above should collapse, not just shrink. */
@media (prefers-reduced-motion: reduce) {
  :root { --dur-fast: 0ms; --dur: 0ms; --dur-slow: 0ms; }
}
