/* ═══════════════════════════════════════════════════════════════════════
   Bingqilin design tokens — the single source of truth for colour, type,
   shape, elevation, motion, state layers and stacking.

   This file used to be ~100 lines of palette pasted into the <style> block
   of all ten pages. It was byte-identical by luck, not by mechanism, and
   everything built on top of it had already drifted. One file now, loaded
   first on every page, before shared/chrome.css and shared/ui.css.

   Nothing in here selects an element — it only declares custom properties.
   Anything that paints lives in ui.css (components) or chrome.css (the
   top app bar and bottom navigation).
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  color-scheme: light dark;

  /* ── Typeface ───────────────────────────────────────────────────────
     Google Sans Flex, rounded, is the site's only font — body and display
     alike. The @font-face rule that loads it lives in chrome.css (it
     needs to sit next to the /shared/fonts/ file it references). */
  --font-sans: 'Google Sans Flex', system-ui, sans-serif;
  --font-mono: ui-monospace, 'SF Mono', Menlo, monospace;

  /* ── Type scale ─────────────────────────────────────────────────────
     One role per job, replacing the 48 distinct ad-hoc font-sizes the
     pages had grown. The *sizes are the site's own*, not M3's nominal
     rem values — the point of the scale here is that one job has one
     size everywhere, not that the numbers match the spec sheet. Declared
     as `font` shorthands so a component sets its type in one line:
     `font: var(--type-body-medium);`. Letter-spacing is not part of the
     shorthand, so each role carries a matching --track-* token. */
  --type-display-large:   600 3.5rem/1.1     var(--font-sans);
  --type-display-medium:  600 2.6rem/1.15    var(--font-sans);
  --type-display-small:   600 2rem/1.2       var(--font-sans);

  --type-headline-large:  600 1.9rem/1.2     var(--font-sans);
  --type-headline-medium: 600 1.6rem/1.25    var(--font-sans);
  --type-headline-small:  600 1.5rem/1.3     var(--font-sans);  /* .hero__title */

  --type-title-large:     600 1.25rem/1.4    var(--font-sans);  /* wordmark, sheet title */
  --type-title-medium:    600 1.05rem/1.4    var(--font-sans);  /* section h2, dialog title */
  --type-title-small:     500 0.88rem/1.35   var(--font-sans);  /* card + row titles */

  --type-body-large:      400 1rem/1.5       var(--font-sans);  /* search input */
  --type-body-medium:     400 0.85rem/1.5    var(--font-sans);  /* body copy */
  --type-body-small:      400 0.78rem/1.5    var(--font-sans);  /* hints, notes, field labels */

  --type-label-large:     500 0.9rem/1.25    var(--font-sans);  /* buttons */
  --type-label-medium:    500 0.8rem/1.2     var(--font-sans);  /* small buttons, chips */
  --type-label-small:     600 0.7rem/1.3     var(--font-sans);  /* eyebrows, badges */

  /* The text inside a text field. Kept as its own role because it is the
     one size a browser will zoom the page for if it drops below 16px on
     iOS — worth being able to see and change in one place. */
  --type-field:           400 0.88rem/1.4    var(--font-sans);

  /* Tracking is left at the typeface's own metrics everywhere except the
     display sizes, which need tightening, and the all-caps eyebrow
     labels, which need opening up. Google Sans Flex is already spaced for UI
     at these sizes; M3's nominal tracking made it look loose. */
  --track-title-large:    -0.01em;
  --track-title-medium:   0;
  --track-title-small:    0;
  --track-body-large:     0;
  --track-body-medium:    0;
  --track-body-small:     0;
  --track-label-large:    0.01em;
  --track-label-medium:   0.01em;
  --track-label-small:    0.04em;
  --track-headline:       -0.01em;
  --track-display:        -0.02em;
  --track-eyebrow:        0.07em;

  /* Line-height for prose that wraps to several lines. The type scale's
     own line-heights are tuned for one- and two-line UI labels and read
     too tight in a paragraph. */
  --leading-prose: 1.55;

  /* ── App-shell metrics ──────────────────────────────────────────────
     The bars are deliberately compact. These live here rather than in
     chrome.css because the scrolling content has to reserve exactly the
     bottom bar's height — hard-coding that in two files is how content
     ends up sliding under the nav. */
  --topbar-h: 56px;
  --bottomnav-h: 58px;
  /* What a scroll container pads at the bottom so its last element clears
     the fixed nav instead of hiding behind it. */
  --content-bottom: calc(var(--bottomnav-h) + 1rem + env(safe-area-inset-bottom));

  /* ── M3 shape scale ─────────────────────────────────────────────────
     Seven steps, replacing the 18 distinct border-radius values. */
  --shape-none: 0;
  --shape-xs:   4px;
  --shape-s:    8px;
  --shape-m:    12px;
  --shape-l:    16px;
  --shape-xl:   28px;
  --shape-full: 999px;

  /* ── M3 tonal palette (warm terracotta seed), light ──────────────── */
  --md-primary: #7e4b22;              --md-on-primary: #fffaf6;
  --md-primary-container: #f8dac1;    --md-on-primary-container: #2d1906;
  --md-secondary: #77584a;            --md-on-secondary: #fffaf6;
  --md-secondary-container: #f9d9c8;  --md-on-secondary-container: #2c1910;
  --md-tertiary: #6b6330;             --md-on-tertiary: #fffaf6;
  --md-tertiary-container: #ded7b0;   --md-on-tertiary-container: #1f1c00;
  --md-error: #ba1a1a;                --md-on-error: #fffaf6;
  --md-error-container: #ffdad6;      --md-on-error-container: #410002;

  /* Success is not an M3 baseline role, but five pages had already
     hardcoded the same two greens for "copied" / "done" / seeders — one
     of them (torrents) without a dark-mode value at all, leaving it at
     2.6:1. Promoted to a real role so there is one place to fix. */
  --md-success: #146c2e;              --md-on-success: #fffaf6;
  --md-success-container: #cbe9c9;    --md-on-success-container: #002106;

  /* Surface ladder. Nothing here is pure white — a bright #ffffff panel on
     a warm page reads as a hole punched in it. The lightest step is a soft
     warm off-white, and every step below warms and deepens from there. */
  --md-surface: #fdf6f0;
  --md-surface-container-lowest: #fffaf6;
  --md-surface-container-low: #f9efe6;
  --md-surface-container: #f4e8db;
  --md-surface-container-high: #eee1d3;
  --md-surface-container-highest: #e8dacb;
  /* The surface a raised element sits on (buttons, chips, the selected
     segment, a settings section). In light mode that is the lightest
     step; in dark mode elevation means *lighter*, so it is a step above
     the containers rather than below them. */
  --surface-raised: #fffaf6;
  --md-on-surface: #22190f;           --md-on-surface-variant: #52443a;
  --md-outline: #837366;              --md-outline-variant: #d6c5b5;
  --md-inverse-surface: #392e24;      --md-inverse-on-surface: #fdede1;
  --md-scrim: #000000;
  /* For text and icons drawn over photography, where no surface token
     applies. Soft warm white rather than #fff, same as everywhere else. */
  --on-media: #f7f1ec;

  /* ── Elevation (M3 shadow tokens) ── */
  --el0: none;
  --el1: 0 1px 2px rgba(34,20,5,0.30), 0 1px 3px 1px rgba(34,20,5,0.15);
  --el2: 0 1px 2px rgba(34,20,5,0.30), 0 2px 6px 2px rgba(34,20,5,0.15);
  --el3: 0 1px 3px rgba(34,20,5,0.30), 0 4px 8px 3px rgba(34,20,5,0.15);

  /* ── State layers (M3) ──────────────────────────────────────────────
     The opacity a component overlays in its own content colour to signal
     hover / focus / press. Buttons used to fake this with
     `filter: brightness()`, which tints the label along with the
     container and does nothing at all for a transparent background —
     while .icon-btn right next to them already did it properly. */
  --state-hover: 0.08;
  --state-focus: 0.10;
  --state-press: 0.10;
  --state-drag:  0.16;

  /* Disabled content: M3 is 38% opacity on the label and a 12% on-surface
     container. Pages had four different values (.38 / .45 / .55 / .6). */
  --disabled-content: 0.38;
  --disabled-container: 0.12;

  /* ── Motion ─────────────────────────────────────────────────────────
     M3 easing. --t is kept as the short alias every page already uses. */
  --ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
  --ease-standard:   cubic-bezier(0.2, 0, 0, 1);
  --dur-short:  0.1s;
  --dur-medium: 0.2s;
  --dur-long:   0.4s;
  --t: var(--dur-medium) var(--ease-emphasized);

  /* ── Stacking ───────────────────────────────────────────────────────
     One scale. index.html ran 20–40, live.html 20–110 and the tools
     20–40, so "above the settings sheet" meant a different number
     depending on which page you were reading. */
  --z-base:       0;
  --z-sticky:     20;   /* top app bar */
  --z-dock:       25;   /* bottom navigation */
  --z-menu:       30;   /* dropdown menus anchored to the bar */
  --z-scrim:      40;   /* dialog + bottom-sheet backdrop */
  --z-dialog:     41;
  --z-snackbar:   50;

  /* ── Legacy aliases ─────────────────────────────────────────────────
     Names the page stylesheets already use everywhere. Kept so component
     rules read the same as before, all resolving to the M3 roles above. */
  --bg: var(--md-surface);
  --bg2: var(--md-surface-container-high);
  --surface: var(--md-surface-container-low);
  --surface2: var(--md-surface-container);
  --primary: var(--md-primary);
  --primary-dark: #704621;
  --on-primary: var(--md-on-primary);
  --text: var(--md-on-surface);
  --text-muted: var(--md-on-surface-variant);
  /* #8a7a6d scored 3.2–4.1:1 against these surfaces — below AA on every
     one of them, and it is the colour of every hint, note and empty
     state on the site. Darkened to clear 4.5:1 on the worst case
     (--md-surface-container-highest, 4.60:1). */
  --text-faint: #67584d;
  --border: color-mix(in srgb, var(--md-outline-variant) 75%, transparent);
  --radius: var(--shape-m);

  /* Scrim behind dialogs and bottom sheets. Pages had four different
     values across three components. */
  --scrim: color-mix(in srgb, var(--md-scrim) 40%, transparent);
}

/* ── Dark palette ───────────────────────────────────────────────────────
   Declared once as a custom property list and applied by both the
   system-preference query and the explicit [data-theme="dark"] override,
   so the two can never disagree. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --md-primary: #deb89b;              --md-on-primary: #362517;
    --md-primary-container: #65442c;    --md-on-primary-container: #ffdcbf;
    --md-secondary: #e5bfa9;            --md-on-secondary: #442a1c;
    --md-secondary-container: #594438;  --md-on-secondary-container: #ffdbc7;
    --md-tertiary: #d2c86e;             --md-on-tertiary: #343100;
    --md-tertiary-container: #464226;   --md-on-tertiary-container: #efe58b;
    --md-error: #ffb4ab;                --md-on-error: #690005;
    --md-error-container: #6b2a28;      --md-on-error-container: #ffdad6;
    --md-success: #6fdb8f;              --md-on-success: #00390f;
    --md-success-container: #2f5138;    --md-on-success-container: #b7f2c0;
    /* Warm charcoal, not near-black — a #101010 panel next to warm text
       reads as a hole. Every step keeps the terracotta warmth. */
    --md-surface: #201a15;
    --md-surface-container-lowest: #1a1511;
    --md-surface-container-low: #26201a;
    --md-surface-container: #2c251e;
    --md-surface-container-high: #342c25;
    --md-surface-container-highest: #3f372f;
    --surface-raised: #373029;
    --md-on-surface: #ede0d3;           --md-on-surface-variant: #d5c4b4;
    --md-outline: #9f8d7c;              --md-outline-variant: #52443a;
    --md-inverse-surface: #ede0d3;      --md-inverse-on-surface: #392e24;
    --primary-dark: #e6c6ac;
    /* #a89686 fell to 4.36:1 on --md-surface-container-highest. */
    --text-faint: #b8a696;
    --el1: 0 1px 2px rgba(0,0,0,0.45), 0 1px 3px 1px rgba(0,0,0,0.30);
    --el2: 0 1px 2px rgba(0,0,0,0.45), 0 2px 6px 2px rgba(0,0,0,0.30);
    --el3: 0 1px 3px rgba(0,0,0,0.45), 0 4px 8px 3px rgba(0,0,0,0.30);
  }
}

:root[data-theme="dark"] {
  --md-primary: #deb89b;              --md-on-primary: #362517;
  --md-primary-container: #65442c;    --md-on-primary-container: #ffdcbf;
  --md-secondary: #e5bfa9;            --md-on-secondary: #442a1c;
  --md-secondary-container: #594438;  --md-on-secondary-container: #ffdbc7;
  --md-tertiary: #d2c86e;             --md-on-tertiary: #343100;
  --md-tertiary-container: #464226;   --md-on-tertiary-container: #efe58b;
  --md-error: #ffb4ab;                --md-on-error: #690005;
  --md-error-container: #6b2a28;      --md-on-error-container: #ffdad6;
  --md-success: #6fdb8f;              --md-on-success: #00390f;
  --md-success-container: #2f5138;    --md-on-success-container: #b7f2c0;
  /* Warm charcoal, not near-black — a #101010 panel next to warm text
     reads as a hole. Every step keeps the terracotta warmth. */
  --md-surface: #201a15;
  --md-surface-container-lowest: #1a1511;
  --md-surface-container-low: #26201a;
  --md-surface-container: #2c251e;
  --md-surface-container-high: #342c25;
  --md-surface-container-highest: #3f372f;
  --surface-raised: #373029;
  --md-on-surface: #ede0d3;           --md-on-surface-variant: #d5c4b4;
  --md-outline: #9f8d7c;              --md-outline-variant: #52443a;
  --md-inverse-surface: #ede0d3;      --md-inverse-on-surface: #392e24;
  --primary-dark: #e6c6ac;
  --text-faint: #b8a696;
  --el1: 0 1px 2px rgba(0,0,0,0.45), 0 1px 3px 1px rgba(0,0,0,0.30);
  --el2: 0 1px 2px rgba(0,0,0,0.45), 0 2px 6px 2px rgba(0,0,0,0.30);
  --el3: 0 1px 3px rgba(0,0,0,0.45), 0 4px 8px 3px rgba(0,0,0,0.30);
}

/* Explicit Light wins over a dark system preference. The light values are
   the :root defaults above, so this only needs to restate what the dark
   blocks changed. */
:root[data-theme="light"] {
  --md-primary: #7e4b22;              --md-on-primary: #fffaf6;
  --md-primary-container: #f8dac1;    --md-on-primary-container: #2d1906;
  --md-secondary: #77584a;            --md-on-secondary: #fffaf6;
  --md-secondary-container: #f9d9c8;  --md-on-secondary-container: #2c1910;
  --md-tertiary: #6b6330;             --md-on-tertiary: #fffaf6;
  --md-tertiary-container: #ded7b0;   --md-on-tertiary-container: #1f1c00;
  --md-error: #ba1a1a;                --md-on-error: #fffaf6;
  --md-error-container: #ffdad6;      --md-on-error-container: #410002;
  --md-success: #146c2e;              --md-on-success: #fffaf6;
  --md-success-container: #cbe9c9;    --md-on-success-container: #002106;
  --md-surface: #fdf6f0;
  --md-surface-container-lowest: #fffaf6;
  --md-surface-container-low: #f9efe6;
  --md-surface-container: #f4e8db;
  --md-surface-container-high: #eee1d3;
  --md-surface-container-highest: #e8dacb;
  --surface-raised: #fffaf6;
  --md-on-surface: #22190f;           --md-on-surface-variant: #52443a;
  --md-outline: #837366;              --md-outline-variant: #d6c5b5;
  --md-inverse-surface: #392e24;      --md-inverse-on-surface: #fdede1;
  --primary-dark: #704621;
  --text-faint: #67584d;
  --el1: 0 1px 2px rgba(34,20,5,0.30), 0 1px 3px 1px rgba(34,20,5,0.15);
  --el2: 0 1px 2px rgba(34,20,5,0.30), 0 2px 6px 2px rgba(34,20,5,0.15);
  --el3: 0 1px 3px rgba(34,20,5,0.30), 0 4px 8px 3px rgba(34,20,5,0.15);
}
