/* ========================================================
   DESIGN TOKENS — SINGLE SOURCE OF TRUTH
   ========================================================
   This file previously defined a --color-* palette while layout/main.css
   defined a parallel --accent-* / --card-* one. They described the SAME
   colours under different names, but only the main.css set had dark-theme
   overrides — so anything styled with --color-* (components/cards.css,
   components/forms.css, the link colour in base/typography.css) silently
   stayed in light-mode colours when dark mode was on.

   There is now ONE layer:

     RAW PALETTE   literal colour values, defined here. Never referenced by
                   a component — exists so a hue can be retuned in one place.
     SEMANTIC      what a colour MEANS (--surface, --brand, --negative).
                   Defined and themed in layout/main.css, next to the
                   dark-theme block that flips them, so light and dark
                   values sit side by side and cannot drift apart.
     LEGACY ALIAS  the old --color-* / --timber-* / --bark-* names, re-pointed
                   at the current tokens (bottom of this file). Every existing
                   rule keeps working; delete the aliases once nothing
                   references them.

   IMPORTANT — FILL vs INK
   Several accents are legible as a background fill but not as text against a
   light surface. Each has an -ink partner for text use:
       --positive        fills, bars, status dots, chart series
       --positive-ink    the same meaning, safe as text on a surface

   THE CLAY & BUTTER REFRESH (v2.3.0)
   The palette before this release was State Timber Corporation orange
   (#A85703) on a warm bone page. It is now CLAY BROWN #6B352A on a SOFT
   BUTTER #FFF1A6 page. Three things follow from that swap and they are the
   reason several tokens below look different from their predecessors:

   1. THE PAGE IS NO LONGER NEAR-WHITE. It is a saturated pale yellow, and a
      yellow page eats yellow accents. The old --amber-500 (#D9A404) sat at
      1.98:1 against it — a "caution" chip that was invisible on the surface
      it was warning about. Caution is now a burnt amber (--amber-500
      #A85B00, 4.42:1 on the page) that cannot be mistaken for the page.
   2. THE BRAND IS DARK, NOT MID-TONED. White on clay is 9.7:1, so the brand
      fill no longer needs a darker sibling to carry white text the way
      --timber-500 did. --clay-600 IS the brand, and it is also legible as
      text on both light surfaces (9.7:1 on white, 8.5:1 on butter).
   3. THERE IS NO LONGER A SEPARATE LOGO COLOUR. The orange plate behind the
      STC mark has been replaced by clay too (--clay-logo), so the browser
      theme-color, the PWA splash and the plate all match the UI.
   ======================================================== */

:root {
  /* ---------- RAW PALETTE ----------
     Light-theme hues. Dark-theme equivalents live in layout/main.css.

     Two families, and nothing else warm competes with them:

       CLAY    #6B352A and its range. Structure — the sidebar, brand fills,
               headings, the first chart series, every border that is meant
               to be seen.
       BUTTER  #FFF1A6 and its range. Ground — the page itself, washes,
               highlights, the active navigation pill.

     They are complements in the practical sense: clay is dark and red-warm,
     butter is light and yellow-warm, and a clay element on a butter page is
     8.5:1 without any third colour being involved. That is what lets the
     rest of the palette (status, charts) stay small. */

  /* ---------- CLAY ----------
     The brand family. --clay-600 is the value the refresh is specified in;
     everything else is a tint or shade of it on the same hue line.

     WHY --clay-600 IS BOTH THE FILL AND THE INK
     The previous brand orange needed two tokens — a mid-tone that was too
     light to be text and a darker one that was. Clay is dark enough at its
     specified value to do both jobs (9.7:1 either way on white), which is
     why --brand and --brand-ink can point at the same shade in light mode
     and no rule has to remember which one it wanted. */
  --clay-50:   #FBF3F0;   /* faintest wash: table zebra stripe, hover rows */
  --clay-100:  #F4E3DC;   /* chips, subtle fills, selected rows */
  --clay-200:  #E7CCC1;
  --clay-300:  #D3AC9C;   /* clay hairline, for rules on a white card */
  --clay-400:  #D6947B;   /* dark-theme brand fill — 7.1:1 with dark ink */
  --clay-500:  #8A4636;   /* lighter brand step: sidebar active, hover fills */
  --clay-600:  #6B352A;   /* THE BRAND. 9.7:1 with white on it. */
  --clay-700:  #54281F;   /* hover — one step down, 12.4:1 */
  --clay-800:  #3D1D16;   /* the sidebar */
  --clay-900:  #2A140F;   /* body text, deepest surfaces */
  --clay-logo: #6B352A;   /* the plate behind the STC mark, and OS chrome.
                             Identical to the brand since v2.3.0 — kept as a
                             separate name because build_app_icons.py and the
                             <meta name="theme-color"> read this one, and the
                             plate may need to diverge again if the artwork
                             is ever re-cut. */

  /* ---------- BUTTER ----------
     The ground family. --butter-300 is the value the refresh is specified in
     and it is the page background itself.

     There is no butter step dark enough to carry text or to be a chart
     series, on purpose. Butter is a SURFACE colour in this system; anything
     that has to be read against it comes out of the clay or status ramps. */
  --butter-50:  #FFFDF2;   /* card tint where pure white is too stark */
  --butter-100: #FFFBE2;   /* raised surfaces sitting on the butter page */
  /* ---------- PARCHMENT (v2.4.0) ----------
     THE CARD. Cards were pure #FFFFFF until this release: correct by the
     numbers and wrong in the room. A sheet of white inside a saturated
     yellow page reads as a hole punched in the design rather than as a
     surface belonging to it, and it is the first thing anyone notices about
     a screenshot of the old dashboard.

     Parchment is #FDF8EE. It is NOT another step of butter: butter's hue is
     51 degrees and parchment's is 38, pulled towards clay. That distinction
     is the whole point. A card tinted along the butter line is the page,
     slightly lighter, and the eye reads it as a wash rather than as an
     object; a card pulled towards clay is a DIFFERENT warm, and the two sit
     next to each other the way paper sits on a desk.

     dE(parchment, white) = 5.9 — unmistakably not white, still nowhere near
     being a colour of its own.
     dE(parchment, page)  = 33.2 — the card/page separation the old white had
     (38.8) is essentially intact.

     What it costs, measured rather than assumed:
        --text        17.42:1 -> 16.46:1
        --text-muted   6.41:1 ->  6.05:1
        --border-strong 3.50:1 -> 3.31:1   (WCAG 1.4.11 floor is 3.0)
     Nothing crosses a threshold. Do not darken it further without re-running
     the sweep in tests/test_v240_surfaces.py: --border-strong is the binding
     constraint and it has 0.31 of headroom, not much. */
  --parchment-100: #FFFDF9;  /* raised: a tile lifted off a parchment card */
  --parchment-200: #FDF8EE;  /* THE CARD. */
  --parchment-300: #F7EFE1;  /* pressed / hovered parchment, table zebra */
  --butter-200: #FFF7C9;   /* hover on a butter surface */
  --butter-300: #FFF1A6;   /* THE PAGE. */
  --butter-400: #F2DE8C;   /* pressed / active on a butter surface */
  --butter-500: #D8C177;   /* hairline against butter and against white */
  --butter-600: #9C8750;   /* input outlines — 3.1:1 against the butter page
                              and 3.5:1 against a white card, which is the
                              WCAG 1.4.11 floor for a control boundary on
                              BOTH surfaces. #A8925A was tried first and is
                              2.7:1 on butter: fine on the card, invisible
                              on the page. Do not lighten this one. */

  /* ---------- STONE ----------
     Warm neutrals, pulled towards clay rather than towards grey so a muted
     label on a butter page does not read as cold. */
  --stone-500: #6F5B4C;    /* muted text — 6.4:1 on white, 5.6:1 on butter */
  --stone-700: #4A3B31;
  --stone-900: #2A140F;

  /* ---------- STATUS ----------
     Deliberately NOT tints of clay or butter: an operator must be able to
     tell "on target" from "brand-coloured" at a glance on a small chip.

     Every one of these is a FILL that carries WHITE text at 4.5:1 or better,
     including caution — which is new. The old amber could not (2.3:1) and
     needed --on-caution to flip to near-black, a rule that was broken twice
     before it was documented. Burning the amber down to #A85B00 removes the
     special case entirely. */
  --green-500: #2E7D32;    /* 5.1:1 with white */
  --green-700: #1B5E20;    /* 7.9:1 — safe as text */
  --red-500:   #B02A2A;    /* 6.5:1 with white */
  --red-700:   #8E1F1F;    /* 8.6:1 — safe as text */
  --amber-500: #A85B00;    /* 5.1:1 with white — burnt, not yellow */
  --amber-700: #854800;    /* 6.9:1 — safe as text */

  /* ---------- LEGACY RAW ALIASES ----------
     The --timber-*, --bark-*, --blue-*, --slate-* and --grey-300 names are
     still referenced by a handful of rules that have not been renamed. They
     now resolve to the clay equivalents so nothing renders in a retired
     brand colour. Do not add new uses; delete these once the last reference
     is gone. */
  --timber-50:   var(--clay-50);
  --timber-100:  var(--clay-100);
  --timber-200:  var(--clay-200);
  --timber-300:  var(--clay-300);
  --timber-400:  var(--clay-400);
  --timber-500:  var(--clay-600);
  --timber-700:  var(--clay-700);
  --timber-logo: var(--clay-logo);
  --bark-800:    var(--clay-800);
  --bark-900:    var(--clay-900);
  --blue-400:    var(--clay-400);
  --blue-500:    var(--clay-600);
  --blue-700:    var(--clay-700);
  --slate-500:   var(--stone-500);
  --slate-900:   var(--stone-900);
  --grey-300:    var(--clay-300);

  /* ---------- SPACING ----------
     4 / 8 / 16 / 24 / 32 / 48 / 64. There is intentionally no 12px step —
     components that want one use --space-2 (8) or --space-3 (16) rather than
     reintroducing eyeballed in-between values.

     These numbers are load-bearing for the radius scale below. Changing one
     changes which radius steps are concentric with which. */
  --space-1: .25rem;   /*  4px */
  --space-2: .5rem;    /*  8px */
  --space-3: 1rem;     /* 16px */
  --space-4: 1.5rem;   /* 24px */
  --space-5: 2rem;     /* 32px */
  --space-6: 3rem;     /* 48px */
  --space-7: 4rem;     /* 64px */

  /* ---------- RADIUS — A CONCENTRIC SCALE (v2.3.0) ----------
     THE RULE: a child whose edge sits P away from its parent's edge takes
     radius (parent radius − P). Anything else and the two curves are not
     parallel — the gap between them pinches at the corner and opens out
     along the straight, which is the specific ugliness that makes a nested
     card look hand-drawn no matter how carefully the colours were picked.

     Each step below IS the step above minus the padding that separates
     them, so the common nestings are concentric by construction and nobody
     has to do the arithmetic at the call site:

        --radius-xl  28px   modals, drawers, the login card
          − --space-2  8    (a panel inset 8px inside a drawer)
        --radius-lg  20px   cards, panels, tiles, the chart frame
          − --space-2  8    (a tile inset 8px inside a card)
        --radius-md  12px   inputs, buttons, inner tiles, table shells
          − --space-1  4    (a chip inset 4px inside a button or field)
        --radius-sm   8px   badges, chips, table controls, progress tracks
          − --space-1  4
        --radius-xs   4px   the innermost thing there is
        --radius-full       pills, avatars, status dots

     NOTE THE INSET IS --space-2, NOT --space-3. A card's CONTENT padding is
     still 16px; the 8px is the inset used where one rounded SURFACE sits
     inside another. Those are different measurements and conflating them is
     why the first attempt at this produced 4px tiles inside 20px cards.

     WHEN THE NESTING IS NOT ONE OF THE PAIRS ABOVE, derive it. Set the two
     inputs on the parent and read --radius-inner on the child:

        .panel        { --r-outer: var(--radius-xl); --r-pad: var(--space-3);
                        border-radius: var(--r-outer); padding: var(--r-pad); }
        .panel > .box { border-radius: var(--radius-inner); }

     max() floors the result at --radius-xs rather than letting it go
     negative, which browsers clamp to 0 silently — a square-cornered child
     inside a round parent is a bug you can see but not find. */
  --radius-xs: 4px;
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 20px;
  --radius-xl: 28px;
  --radius-full: 9999px;
  --radius: var(--radius-md);   /* legacy default used by buttons.css */

  /* The derivation. --r-outer / --r-pad are set by whichever parent is doing
     the nesting; the defaults describe the commonest case (a tile inside a
     card) so a child that reads --radius-inner without a parent opting in
     still gets a sane value rather than nothing. */
  --r-outer: var(--radius-lg);
  --r-pad:   var(--space-2);
  --radius-inner: max(var(--radius-xs), calc(var(--r-outer) - var(--r-pad)));

  /* ---------- ELEVATION ----------
     elev-1 resting cards · elev-2 hover · elev-3 modals and drawers.

     The tint is clay-black, not neutral black. On a butter page a neutral
     shadow reads faintly violet — yellow's complement — which is the same
     class of mistake the old cool-grey shadow made on the bone page.
     Values are deliberately shallow: the design leans on hairline borders
     for separation, with shadow reserved for things that genuinely float. */
  --elev-0: none;
  --elev-1: 0 1px 2px rgba(42, 20, 15, 0.08);
  --elev-2: 0 4px 12px rgba(42, 20, 15, 0.12);
  --elev-3: 0 12px 28px rgba(42, 20, 15, 0.20);
  /* Used only by the motion layer: the lifted state of a hovering button or
     card. Softer and wider than --elev-2 rather than darker, so the hover
     reads as the element rising rather than as the shadow being turned up. */
  --elev-hover: 0 8px 20px rgba(42, 20, 15, 0.14);

  /* ---------- MOTION (extended v2.3.0) ----------
     Four durations and four curves, and every animation in the app is built
     out of them. The point is not tidiness: a mixed set of durations reads
     as jank even when each individual value is defensible, because the eye
     compares two things moving at once and not one thing moving alone.

     --ease-bounce OVERSHOOTS (the y value passes 1 before settling). Use it
     only for something that has just been PRESSED — the overshoot is what
     makes a tap feel acknowledged. Never use it for something entering or
     leaving; an overshooting panel reads as a rendering fault.

     EVERY rule that uses these must be inside, or paired with, the
     prefers-reduced-motion block in components/motion.css. Vestibular
     disorders are not rare, and a mill office screen is often the only
     screen someone looks at all day. */
  --dur-instant:   80ms;                        /* press-down, active states */
  --dur-fast:     120ms;                        /* hover, focus, colour */
  --dur-base:     200ms;                        /* toggles, tabs, toasts */
  --dur-slow:     320ms;                        /* drawers, modals, panels */
  --dur-celebrate: 900ms;                       /* target-met burst, streaks */
  --ease-out:    cubic-bezier(.2, .8, .2, 1);   /* things entering */
  --ease-in-out: cubic-bezier(.4, 0, .2, 1);    /* things moving */
  --ease-bounce: cubic-bezier(.34, 1.56, .64, 1);/* things that were TAPPED */
  --ease-spring: cubic-bezier(.22, 1.2, .36, 1); /* things settling into place */

  /* ---------- TYPE ---------- */
  --base: 16px;
  --font-sans: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto,
               'Helvetica Neue', Arial, sans-serif;

  /* ---------- LAYERS ----------
     Named so a new overlay never has to guess a z-index. Ordered by how
     they actually stack: the skip link must clear the sidebar, and a toast
     must clear everything. */
  --z-bottom-nav:    900;
  --z-mobile-header: 950;
  --z-overlay:       999;
  --z-sidebar:      1000;
  --z-modal:        1050;
  /* The notification panel sits above the sidebar drawer (it can be opened
     from inside it) and above a modal, but BELOW the toasts — a toast
     confirming an action must never be hidden by the panel listing it. */
  --z-notif-overlay:1060;
  --z-notif-panel:  1070;
  --z-skip-link:    1100;
  --z-toast:        1200;
  /* Above everything, including toasts: the celebration burst is purely
     decorative and pointer-events: none, so it can never intercept a tap,
     and it should not be clipped by whatever it is congratulating. */
  --z-celebrate:    1300;
}

/* ========================================================
   LEGACY ALIASES
   ========================================================
   The old names, re-pointed at the semantic tokens defined in
   layout/main.css. CSS custom properties resolve at use time, not at
   definition time, so referencing --surface here before main.css declares
   it is fine — and it means these aliases follow the dark theme correctly,
   which was the whole bug.

   Do not add new rules that use these. They exist so the migration didn't
   need to touch every stylesheet at once.
   ======================================================== */
:root {
  --color-bg:            var(--surface-sunken);
  --color-surface:       var(--surface);
  --color-primary:       var(--brand);
  --color-primary-hover: var(--brand-hover);
  --color-on-primary:    var(--on-brand);
  --color-muted:         var(--text-muted);
  --color-success:       var(--positive);
  --color-warning:       var(--caution);
  --color-error:         var(--negative);

  /* Old shadow names -> the elevation scale. */
  --shadow-sm: var(--elev-1);
  --shadow-md: var(--elev-2);
}

html {
  font-family: var(--font-sans);
  font-size: var(--base);
  background: var(--surface-sunken);
  color: var(--text);
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;  /* stop iOS inflating text on rotation */
}
