/* Design tokens (SPEC §16.1). One file for both origins.
 *
 * R-UI-10: every component references a semantic token and never a literal
 * hex value, so adding light mode later is a change to this file rather than
 * a sweep through components. `tools/lint/no_hex_literals.py` rejects a hex
 * colour anywhere else; A-28 audits the pairs below in `make test`.
 *
 * Dark only at launch; light mode is deferred, not designed out (DECISION-9).
 *
 * R-UI-2 governs the text tokens: body ≥ 7:1 against its surface, secondary
 * ≥ 4.5:1, non-text boundaries of interactive elements ≥ 3:1. `--text-low`
 * and `--line-input` differ from the §16.1 listing for that reason (SC-012):
 * the listed tertiary grey fell under 4.5:1 on every surface but the void,
 * and no listed hairline reached 3:1 as an input border.
 *
 * A-28 reads this file: keep every colour on its own `--name: #hex;` line.
 *
 * ── Themes (D-138, D-139) ─────────────────────────────────────────────────
 * A theme is one block of colour overrides keyed on `[data-theme="<id>"]`.
 * `web/shared/theme.ts` names the themes, the picker builds itself from that
 * list, and A-28 audits every theme's token set against R-UI-2 rather than
 * only the default's.
 *
 * The file is in three parts, and the split is what makes a theme small and
 * a swatch honest:
 *
 *   1. the raw colours, once per theme. The default's block names both
 *      `:root` and `[data-theme='teal']`, so a page that sets no attribute
 *      still has colours (the landing page) *and* an element that asks for
 *      the default by name gets it rather than inheriting the page's theme
 *      (D-139).
 *   2. the derived colours — the gradient, the tints, the glows — on
 *      `:root, [data-theme]`, so they are re-derived on any element that
 *      carries a theme rather than inherited already resolved from the root.
 *      A custom property is substituted where it is *declared*, so this is
 *      the difference between a swatch that shows its own theme and one that
 *      shows the page's.
 *   3. everything that is not colour — type, space, shape, the motion
 *      budget — on `:root` alone. A theme cannot touch these.
 *
 * Together those mean a swatch deep in the page carrying `data-theme="<id>"`
 * renders in that theme's real colours, glow included: the picker's previews
 * are the tokens themselves, not a copy of them, which is why no hex appears
 * outside this file.
 */

/* ── 1. The raw colours: the default (teal, D-099) ───────────────────────── */
:root,
[data-theme='teal'] {
  /* ── Surfaces ── */
  --bg-void: #050b0d;      /* app background */
  --bg-surface: #0a1315;   /* panels */
  --bg-raised: #111b1e;    /* cards, compose, menus */
  --bg-overlay: #182629;   /* modals, popovers */
  --line: #1d2e32;         /* hairlines */
  --line-strong: #2b434a;  /* hairlines on hover / active */
  --line-input: #4f7681;   /* the boundary of an input or a control (≥ 3:1) */
  --ambient: #0f2a2d;      /* the fixed light source behind the list, at 8 % */

  /* ── Text ── */
  --text-hi: #e6f1ef;
  --text-mid: #9db6b2;
  --text-low: #86a29e;     /* tertiary: dates, counts, hints (≥ 4.5:1 everywhere) */
  --text-on-accent: #050b0d;

  /* ── Accent and status ── */
  --accent: #2cd3b3;       /* primary action, focus, active alias */
  --accent-warm: #2f8fff;  /* gradient partner; never text */
  --positive: #5ee27f;
  --warning: #ffb55c;
  --danger: #ff6b6b;
}

/* ── 2. Derived colours (tokens of tokens; no new colour) ─────────────────
 * On `[data-theme]` as well as `:root` so an element wearing a theme
 * re-derives these from *its* raw tokens (D-139). */
:root,
[data-theme] {
  --gradient-accent: linear-gradient(135deg, var(--accent), var(--accent-warm));
  --accent-tint: color-mix(in srgb, var(--accent) 14%, transparent);
  --accent-tint-strong: color-mix(in srgb, var(--accent) 26%, transparent);
  --positive-tint: color-mix(in srgb, var(--positive) 14%, transparent);
  --warning-tint: color-mix(in srgb, var(--warning) 14%, transparent);
  --danger-tint: color-mix(in srgb, var(--danger) 14%, transparent);
  --ambient-glow: color-mix(in srgb, var(--ambient) 8%, transparent);
  --scrim: color-mix(in srgb, var(--bg-void) 72%, transparent);

  /* Glow: a soft neon halo for what is selected or active — subtle, never
   * on body text, never animated in a scroll context (R-UI-5). */
  --glow-accent: 0 0 10px color-mix(in srgb, var(--accent) 55%, transparent), 0 0 2px color-mix(in srgb, var(--accent) 80%, transparent);
  --glow-accent-soft: 0 0 18px color-mix(in srgb, var(--accent) 22%, transparent);
  --glow-positive: 0 0 8px color-mix(in srgb, var(--positive) 60%, transparent);
  --glow-danger: 0 0 10px color-mix(in srgb, var(--danger) 45%, transparent);
  --glow-warm: 0 0 16px color-mix(in srgb, var(--accent-warm) 30%, transparent);
}

/* ── 3. Everything that is not colour. A theme cannot touch these. ──────── */
:root {
  /* R-UI-1: every gradient carries a dithering overlay. This is an SVG
   * `feTurbulence` noise tile; painted at 2–3 % it breaks the 8-bit banding
   * that makes a dark gradient look cheap. */
  --dither: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.6 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  --dither-opacity: 0.03;

  /* ── Type ── */
  --font-ui: 'Geist Variable', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono: 'Geist Mono Variable', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  --fs-xs: 11.5px;
  --fs-sm: 12.5px;
  --fs-md: 14px;
  --fs-body: 15px;
  --fs-lg: 17px;
  --fs-xl: 21px;
  --fs-2xl: 28px;
  --lh: 1.45;

  /* ── Space and shape ── */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-pill: 999px;
  --row-height: 64px;
  --sidebar-width: 232px;
  --list-width: 400px;

  /* ── Motion (R-UI-3, R-UI-4). Nothing in the reading path exceeds 180 ms:
   * a mail client is used thousands of times a week and every animation is
   * paid for on every repetition. ── */
  --motion-transition: 150ms;
  --motion-entrance: 230ms;
  --motion-moment: 450ms;
  --motion-send: 300ms;
  --motion-skeleton: 1400ms;
  --ease-enter: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-exit: cubic-bezier(0.4, 0, 1, 1);
}

/* R-UI-6: reduced motion removes all non-essential motion and collapses
 * durations to ≤ 80 ms opacity fades. Tested by A-26, not merely declared;
 * the rest of the rule is in base.css, where the keyframes are. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-transition: 80ms;
    --motion-entrance: 80ms;
    --motion-moment: 80ms;
    --motion-send: 80ms;
    --motion-skeleton: 80ms;
  }
}

/* ── The themes ─────────────────────────────────────────────────────────────
 *
 * One block each, in the order `theme.ts` offers them. Raw colours only:
 * everything derived from them follows from part 2 above.
 */

/* `lime` — deep navy with a single lime accent, from the page the human
 * named as the reference they love. The surfaces, lines, greys, the lime
 * and its hover, and the danger red are that page's own values; the three
 * this palette does not state — the input boundary, positive and warning —
 * are chosen to sit in the same family and to clear R-UI-2, which the
 * reference's hairline (`#2c3e54`, kept here as `--line-strong`) does not
 * as an input border. A-28 checks every pair below. */
[data-theme='lime'] {
  --bg-void: #0a192f;
  --bg-surface: #0d1f3a;
  --bg-raised: #112240;
  --bg-overlay: #1a2f52;
  --line: #22334b;
  --line-strong: #2c3e54;
  --line-input: #6a86a6;
  --ambient: #173a63;

  --text-hi: #e5e7eb;
  --text-mid: #8b9cb3;
  --text-low: #9ca3af;
  --text-on-accent: #0a192f;

  /* One accent, as the reference has: the gradient partner is the same lime
   * at its hover brightness, so a primary button reads as a sheen on one
   * colour rather than a second hue arriving. */
  --accent: #c3e325;
  --accent-warm: #d4f72e;
  --positive: #4ade80;
  --warning: #fbbf24;
  --danger: #f87171;
}

/* `cyber` — near-black violet, with cyan and magenta. The one theme whose
 * gradient partner is a second hue rather than a brighter shade of the
 * first: cyan against magenta *is* the palette, and the gradient between
 * them is what the genre looks like. The greys are violet-tinted so nothing
 * reads as neutral, and the surfaces stay dark enough that a saturated cyan
 * on them is a light source rather than a colour — §16.1's depth from
 * layered surfaces, not from shadows. */
[data-theme='cyber'] {
  --bg-void: #08050f;
  --bg-surface: #100a1c;
  --bg-raised: #171029;
  --bg-overlay: #221738;
  --line: #2c1f4a;
  --line-strong: #3d2b63;
  --line-input: #8a72c0;
  --ambient: #2a0f45;

  --text-hi: #f0e9ff;
  --text-mid: #b3a3d6;
  --text-low: #a495cc;
  --text-on-accent: #08050f;

  --accent: #2ef2ff;
  --accent-warm: #ff3ec8;
  --positive: #3ef2a3;
  --warning: #ffd23e;
  --danger: #ff4d6d;
}

/* `amber` — warm near-black with an amber accent: the one warm theme, and
 * the counterweight to three cool ones. The gradient partner is a deeper
 * orange, so a primary button is a sunset in one hue.
 *
 * What a warm palette costs, stated: the accent and the warning are
 * neighbours here in a way they are not in the cool themes. They are pulled
 * apart by lightness — the warning is a pale yellow at 14:1 on the void,
 * the accent a mid orange at 10:1 — and by the rule the whole design
 * already follows: the accent marks what is *active*, never what is wrong,
 * and a warning always arrives with its icon and its sentence. */
[data-theme='amber'] {
  --bg-void: #100d0a;
  --bg-surface: #181410;
  --bg-raised: #211c16;
  --bg-overlay: #2e2720;
  --line: #382f26;
  --line-strong: #4a4034;
  --line-input: #8f8070;
  --ambient: #3d2a14;

  --text-hi: #f5ece0;
  --text-mid: #bdab96;
  --text-low: #aea08d;
  --text-on-accent: #100d0a;

  --accent: #ffa73d;
  --accent-warm: #ff7847;
  --positive: #a3d06a;
  --warning: #ffd93d;
  --danger: #ff6161;
}
