/* Longview design tokens.
 *
 * The light palette is defined on bare :root so a browser with no explicit
 * choice and no dark preference gets a complete, valid palette. Dark is applied
 * twice: once under prefers-color-scheme for the "system" default, guarded so an
 * explicit light choice still wins, and once under [data-theme="dark"] so the
 * in-app toggle beats the OS in both directions.
 *
 * No component defines a raw colour. If a value is needed that is not here, the
 * token set is what changes - not the component.
 *
 * Contrast is enforced by tools/contrast_check.py, which runs in the test suite.
 * Read the note there before changing any colour: several of these values are
 * pinned to a WCAG threshold and are not free to taste.
 */

:root {
  /* Surfaces */
  /* A ledger is paper, not screen-grey. The old --bg (#f6f8f7) sat a hair off
   * --panel (#ffffff), so cards floated invisibly and every surface read as one
   * flat sheet. Warming and deepening the ground is what makes a white panel
   * legible AS a panel.
   *
   * How deep is not free: --text gains contrast as the ground darkens, but the
   * MID-tone inks (--accent, --gold, --text-faint) lose it. This value is the
   * deepest ground on which --accent still clears 4.5:1 unchanged; the other
   * two are nudged a shade darker to follow it. Solved numerically, not by eye. */
  --bg: #f1eee7;
  --bg-raised: #ffffff;
  --panel: #ffffff;
  --panel-edge: #ffffff;
  --line: #dcd6c9;
  /* --line is decorative (dividers, table rules). --line-strong is the visible
   * boundary of interactive controls and must hold 3:1 against the surface
   * behind it - WCAG 2.1 SC 1.4.11. In light mode --field-fill equals --panel,
   * so this border is the ONLY thing that makes an input findable. */
  --line-strong: #837c6d;

  /* Text */
  --text: #0d1b18;
  --text-muted: #55665f;
  --text-faint: #606f6a;

  /* Accents */
  --accent: #0f7a5c;
  --accent-ink: #ffffff;
  --accent-quiet: #e3f2ec;
  --gold: #84681d;
  --gold-quiet: #f6efdc;
  --danger: #b3261e;
  --danger-quiet: #fbe6e4;
  --violet: #5b4bb8;
  --violet-quiet: #eae7f8;

  /* Category hues.
   *
   * Six, not eight: green is deliberately absent because --accent already means
   * "money in", and green against orange or pink is the one pairing that cannot
   * be made colourblind-safe. Validated with the dataviz palette checker in both
   * themes - all checks pass, with one WARN (cyan/purple, deutan dE 7.8) that is
   * legal because every use carries a text label beside the colour.
   *
   * Order is fixed. A seventh category takes --cat-none, never a new hue. */
  --cat-1: #0b6fb8;  --cat-1-quiet: #e2eef7;
  --cat-2: #c1560f;  --cat-2-quiet: #faeade;
  --cat-3: #a337b0;  --cat-3-quiet: #f6e6f8;
  --cat-4: #0a8f9e;  --cat-4-quiet: #dcf0f2;
  --cat-5: #c02a5f;  --cat-5-quiet: #fbe3ec;
  --cat-6: #6b4fd8;  --cat-6-quiet: #e9e4fa;
  --cat-none: #5f6459; --cat-none-quiet: #e4dfd3;

  /* Space */
  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-5: 24px; --space-6: 32px; --space-7: 48px; --space-8: 64px;

  /* Shape */
  --radius-sm: 6px; --radius-md: 9px; --radius-lg: 18px; --radius-xl: 22px; --radius-pill: 999px;

  /* Type */
  /* Vendored under static/vendor/fonts and declared with @font-face in app.css,
   * because the CSP allows font-src 'self' only — this deployment has no public
   * egress, so hosted fonts would never arrive. Both are variable, one file each.
   *
   * Sora (display, money) is a warm geometric sans with strong personality at
   * display sizes. IBM Plex Sans (UI) provides clarity and reliability for
   * interface labels and small text. */
  --font-display: "Sora Variable", "Sora", ui-sans-serif, system-ui, sans-serif;
  --font-money: "Sora Variable", "Sora", ui-sans-serif, system-ui, sans-serif;
  --font-ui: "IBM Plex Sans Variable", "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, monospace;
  --size-xs: 11px; --size-sm: 12px; --size-base: 15px; --size-lg: 18px;
  --size-xl: 22px; --size-2xl: 28px; --size-3xl: 40px; --size-4xl: 56px;

  /* Depth and motion */
  --shadow-sm: 0 2px 8px rgb(13 27 24 / 8%);
  --shadow-md: 0 10px 28px rgb(13 27 24 / 10%);
  --ring: 0 0 0 3px color-mix(in srgb, var(--accent) 40%, transparent);
  --motion-fast: 120ms;
  --motion-base: 220ms;

  /* Composed backgrounds, redefined per theme so components stay theme-agnostic */
  --app-backdrop: var(--bg);
  --panel-fill: var(--panel);
  --sidebar-fill: #e7e2d7;
  --sidebar-link: #43483f;
  --sidebar-label: #5f6459;
  --field-fill: #ffffff;

  /* A QR code must be scanned against white. This is the only token whose value
   * is identical in both themes: theming it would break enrollment. */
  --qr-paper: #ffffff;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #07110f;
    --bg-raised: #0d1b18;
    --panel: #14241f;
    --panel-edge: #1a2f28;
    --line: #24382f;
    --line-strong: #5d766e;

    --text: #e9f2ef;
    --text-muted: #a6bcb5;
    --text-faint: #7d9b92;

    --accent: #4fd6b4;
    --accent-ink: #06110e;
    --accent-quiet: #143329;
    --gold: #d7b76a;
    --gold-quiet: #342d18;
    --danger: #ef8d83;
    --danger-quiet: #3a201e;
    --violet: #b9a9ff;
    --violet-quiet: #292348;

    --shadow-sm: 0 2px 10px rgb(0 0 0 / 45%);
    --shadow-md: 0 12px 34px rgb(0 0 0 / 50%);

    --app-backdrop:
      radial-gradient(1200px 600px at 15% -10%, #10241e 0%, transparent 60%),
      var(--bg);
    --panel-fill: linear-gradient(145deg, #10201c, #0b1815);
    --cat-1: #63b3ea;  --cat-1-quiet: #16303f;
    --cat-2: #f0894a;  --cat-2-quiet: #3a2416;
    --cat-3: #dd86e6;  --cat-3-quiet: #33203a;
    --cat-4: #4ec5d2;  --cat-4-quiet: #123033;
    --cat-5: #f0759b;  --cat-5-quiet: #3a1c28;
    --cat-6: #a894ff;  --cat-6-quiet: #262244;
    --cat-none: #8c9a92; --cat-none-quiet: #1d2b26;

    --sidebar-fill: #081410;
    --sidebar-link: #b9cbc6;
    --sidebar-label: #7d9b92;
    --field-fill: #07110f;
  }
}

:root[data-theme="dark"] {
  --bg: #07110f;
  --bg-raised: #0d1b18;
  --panel: #14241f;
  --panel-edge: #1a2f28;
  --line: #24382f;
  --line-strong: #5d766e;

  --text: #e9f2ef;
  --text-muted: #a6bcb5;
  --text-faint: #7d9b92;

  --accent: #4fd6b4;
  --accent-ink: #06110e;
  --accent-quiet: #143329;
  --gold: #d7b76a;
  --gold-quiet: #342d18;
  --danger: #ef8d83;
  --danger-quiet: #3a201e;
  --violet: #b9a9ff;
  --violet-quiet: #292348;

  --shadow-sm: 0 2px 10px rgb(0 0 0 / 45%);
  --shadow-md: 0 12px 34px rgb(0 0 0 / 50%);

  --app-backdrop:
    radial-gradient(1200px 600px at 15% -10%, #10241e 0%, transparent 60%),
    var(--bg);
  --panel-fill: linear-gradient(145deg, #10201c, #0b1815);
  --cat-1: #63b3ea;  --cat-1-quiet: #16303f;
    --cat-2: #f0894a;  --cat-2-quiet: #3a2416;
    --cat-3: #dd86e6;  --cat-3-quiet: #33203a;
    --cat-4: #4ec5d2;  --cat-4-quiet: #123033;
    --cat-5: #f0759b;  --cat-5-quiet: #3a1c28;
    --cat-6: #a894ff;  --cat-6-quiet: #262244;
    --cat-none: #8c9a92; --cat-none-quiet: #1d2b26;

    --sidebar-fill: #081410;
  --sidebar-link: #b9cbc6;
  --sidebar-label: #7d9b92;
  --field-fill: #07110f;
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-fast: 0ms;
    --motion-base: 0ms;
  }
}
