/* Canonical theme palette — the single source of truth for every page (SPA and the standalone
   server-rendered pages: /features, /invoices, /payroll, /audit, /changelog, sign-in).
   Keyed on html[data-theme] so the app's own toggle governs, NOT the OS preference.
   Per-instance brand overrides are injected after this (see branding.theme_head / applyBrand). */
:root {
      /* Tells the browser which way to render the controls IT draws — the date picker's glyph and panel,
         the number spinner, an unstyled checkbox, native scrollbars. CSS can paint an input's box but not
         those, so without this a dark page gets light native chrome sitting inside dark fields.
         Set here, on the same selectors the palette is keyed to, so it flips with the app's own toggle
         rather than with the OS. Individual `color-scheme: dark` rules elsewhere predate this and are now
         redundant; they are left alone because they are harmless and removing them is churn. */
      color-scheme: light;
      --brand: #45235f; --brand-deep: #2f1640; --brand-bright: #7a4bb0;
      --bg: #f4f1f8; --panel: #ffffff; --panel-2: #f2edf8; --line: #e4dcef;
      --text: #251b33; --muted: #635b72; --accent: #5a2d8a; --accent-press: #43206a;
      /* The accent when it is TEXT or a border on a surface, as opposed to a fill with white on it.
         Two tokens because one cannot serve both: the two uses move in exact opposition, and walking the
         dark accent's lightness (hue 262deg, sat 56% fixed, as 6.70.1 did for --ok/--warn) they only cross
         at 4.50/4.50 — no margin on either side. Measured on the dark palette: at L58 white-on-accent is
         4.93 and accent-as-text on --panel-2 is 3.20; at L66 they are 3.46 and 4.55.
         Light needs no adjustment (this palette had zero contrast failures), so it is the accent itself. */
      --accent-text: var(--accent);
      /* Text that sits ON --brand-bright. It flips by theme because --brand-bright itself does: it is the
         dark-on-light brand color in this palette and the light-on-dark one in the other, so a single
         foreground cannot serve both. White on the light-theme #7a4bb0 measures 6.07; white on the
         dark-theme #c7a9f0 measures 2.03, which is what the rail's count badge was doing. */
      --on-brand-bright: #ffffff;
      /* A toast floats over the page in the corner, in both themes (7.459.0): the value it has always had. */
      --shadow-toast: 0 8px 24px rgba(0,0,0,.28);
      /* Text ON a filled tone: a solid ok, warn or err pill, and the neutral solid (7.308.0). The tones are
         dark in this palette and light in the other, the --on-brand-bright problem again, so one foreground
         cannot serve both. White here measures 5.49 on --ok, 5.54 on --warn, 5.44 on --err, 6.42 on --muted. */
      --on-tone: #ffffff;
      /* Text that sits ON --accent, i.e. the ink of a filled accent button or a selected segment.
         Defined once rather than per theme, because --accent is a fill in both palettes and white is
         the foreground in both: measured 4.98 on the dark --accent #8257cf, and the light palette had
         zero contrast failures at all (see --accent-text above, which is the token for the OPPOSITE
         use — the accent as ink on a surface).
         It exists because 25 rules across the six stylesheet parts spell this `#fff` inline, which is
         a literal that cannot follow a per-instance brand override. Those are left alone; this is what
         a new component uses so the count stops growing. */
      --on-accent: #ffffff;
      /* --ok and --warn were darkened in 6.70.1: at #2f9e6b and #b5790a they measured 3.37:1 and
         3.68:1 on white, failing WCAG AA for normal text, and both are used as TEXT in ~30 places.
         Hue and saturation are unchanged (152deg / 39deg) — only lightness moved, by the smallest step
         that clears 4.5:1 on the tightest surface they sit on, --panel-2 (#f2edf8), not just on white.
         Measured: --ok 5.49:1 on white / 4.77:1 on --panel-2; --warn 5.54:1 / 4.81:1.
         The dark values were already fine (7.84:1 and 9.44:1) and are untouched. */
      --ok: #237750; --warn: #8e5f08; --err: #c0392b;

      /* NO COLOR REACHES 4.5:1 ON BOTH THE LIGHT AND THE DARK SURFACES (measured 7.203.0). It would
         need luminance <= 0.1833 against #ffffff AND >= 0.2501 against dark --panel-2 (#271f35); that
         window is negative, so this is arithmetic rather than a search anyone can win. 3:1 IS
         reachable — the window is 0.150-0.300, and the three light values above already clear it on
         all four surfaces: --ok 5.49/4.91/3.18/3.41, --warn 5.54/4.96/3.15/3.38, --err
         5.44/4.86/3.21/3.45 (light --panel / light --bg / dark --panel / dark --bg).

         So: an artifact that must work in both themes with ONE palette — a standalone SVG under a
         sandbox CSP, a diagram that gets mailed, anything that cannot read [data-theme] — may carry
         status as a SHAPE but never as colored TEXT. The better move is usually to remove the
         constraint rather than satisfy it: give the artifact its own background and only one surface
         exists, where these values work as text at ~5.5:1. `.ui-figure` exists for that case.

         `@media (prefers-color-scheme)` is NOT the escape hatch. The dark block below is guarded by
         :root:not([data-theme="light"]) precisely so an explicit app setting beats the OS, and a
         standalone document cannot see that attribute — it would track the OS against the user's
         stated choice. */
      --link: #2f5fd0;
      /* Outlook availability, for the calendar's event bars and dots. Categorical rather than semantic —
         "tentative" is not a warning and "free" is not a success — so these are their own tokens instead
         of being bent into --ok/--warn. Hue is fixed per state and only lightness differs by theme.
         Light values clear 4:1 on --panel, comfortably over the 3:1 a non-text indicator needs; the old
         hardcoded values turned out to BE the dark values in three of four cases, which is what the
         audit meant by "chosen for a dark ground". Measured light: 4.16 / 4.08 / 4.53 / 4.09. */
      --cal-tentative: #a4731d; --cal-free: #428c5f; --cal-oof: #b0559e; --cal-elsewhere: #328a8a;
      /* Severity and priority, one scale (7.606.0). Categorical, not semantic — a priority of 2 is not a
         "success" and an 8 is not an "error" — so these are their own tokens, the same argument the
         --cal-* availability colors are here for. A card's priority band, a ticket's priority and a
         detection's severity all paint from this one set. They were two sets, --prio-* and --sev-*, holding
         the same four colors one step apart, so a MEDIUM ticket was orange and a MEDIUM detection yellow.
         The ticket colors are the standard (decided 2026-10-16): low yellow, medium orange, high red, with a
         deeper red for critical, which only detections have, so it stays distinct from high. Informational
         and "none" are gray: neither is actionable, and the pill carries the word, so color reinforces
         rather than carries.

         Defined ONCE rather than per theme, and deliberately: each is a fill carrying its own foreground,
         so the pair's contrast does not depend on the page behind it. Measured ink-on-fill: none 4.83,
         low 8.09, medium 5.54, high 4.83, critical 8.31 — all clear 4.5:1 in both themes because neither
         value moves. Yellow and orange take dark ink for that reason; gray and the reds take white.

         --prio-ring is the white border the card badge is specified to have. It is what separates the badge
         from a dark card; against a light card white-on-white would vanish, so the badge also carries a
         hairline shadow (see .prio-badge) which is what gives it an edge in the light theme. */
      --severity-none: #6b7280;     --severity-none-ink: #ffffff;
      --severity-low: #eab308;      --severity-low-ink: #1f2430;
      --severity-medium: #f97316;   --severity-medium-ink: #1f2430;
      --severity-high: #dc2626;     --severity-high-ink: #ffffff;
      --severity-critical: #991b1b; --severity-critical-ink: #ffffff;
      --prio-ring: #ffffff;
      --scroll: #cabbe3;
      --shadow: 0 1px 2px rgba(47,22,64,.06), 0 4px 14px rgba(47,22,64,.05);
      /* A card's shadow (7.590.0): the panel shadow in light. The dark theme adds a 1px lighter top edge, because a
         dark shadow on a near-black page does not show and the edge is what makes a dark card read as raised. */
      --shadow-card: var(--shadow);
      /* The dim behind a dialog (7.255.0). One value for both themes, like the `.overlay` modals have always
         used: it darkens whatever is behind, and a lighter dim in the dark theme would lift the page instead. */
      --scrim: rgba(0,0,0,.45);
      --watermark-opacity: .5;   /* the corner mark (7.588.0): present, never louder than the page */
    }
html[data-theme="dark"] {
      color-scheme: dark;
      --watermark-opacity: .6;
      --brand: #c3a9ec; --brand-deep: #d6c7f4; --brand-bright: #c7a9f0;
      --bg: #14101c; --panel: #1d1727; --panel-2: #271f35; --line: #362c49;
      --text: #ece8f3; --muted: #a79fb8; --accent: #8257cf; --accent-press: #6f44bb;
      /* Overridden below where color-mix is available; this is the no-op fallback, i.e. today's color. */
      --accent-text: var(--accent);
      /* --brand-bright is the light color in this palette, so what sits on it has to be dark.
         Measured: --bg on #c7a9f0 is 9.25 against the 2.03 white was giving. */
      --on-brand-bright: var(--bg);
      /* White on these tones was 2.22 (--ok), 1.85 (--warn), 2.27 (--err) and 2.53 (--muted), all under the 3:1
         floor; --bg measures 8.42, 10.14, 8.26 and 7.40 (7.308.0). */
      --on-tone: var(--bg);
      --ok: #4fc28e; --warn: #e6b85a; --err: #ff8a8a;
      --link: #9ecbff;
      /* Measured on --panel #1d1727: 7.15 / 5.25 / 4.57 / 5.58. */
      --cal-tentative: #d99a2b; --cal-free: #4a9d6b; --cal-oof: #b866a8; --cal-elsewhere: #3aa0a0;
      --scroll: #4a3d63;
      --shadow: 0 1px 2px rgba(0,0,0,.45), 0 4px 16px rgba(0,0,0,.35);
      --shadow-card: inset 0 1px 0 rgba(255,255,255,.07), var(--shadow);
    }

/* Derived rather than a second hex, so a per-instance brand override of --accent carries through: the
   overlay is injected after this file, and --accent-text resolves at use time. 70% accent + 30% white
   measures 6.05 on --panel, 5.46 on --panel-2 (the tightest surface it sits on) and 6.50 on --bg, while
   --accent itself is untouched so white-on-accent fills stay at 4.98. @supports rather than a bare
   declaration because a custom property accepts almost any value at parse time — an unsupported
   color-mix() would be substituted and then fail at use, taking the color with it. */
@supports (color: color-mix(in srgb, red 50%, white)) {
  html[data-theme="dark"] { --accent-text: color-mix(in srgb, var(--accent) 70%, white); }
}

/* The layering ladder, in order, in one place (6.70.3). The values are unchanged — this is naming,
   not reordering — but they were previously twelve numbers scattered across the file, each chosen
   against whatever it happened to collide with. Making the top bar sticky in 6.69.0 meant reading all
   twelve to pick one, and then lifting the drawer and its scrim so the bar wouldn't overtake them.
   Reach for a name; if none fits, add one here rather than inventing a number at the call site.
   Two values are deliberately absent: .ui-tabs (2) and .pm-ms-list (5) sit inside their own
   stacking contexts, competing only with siblings, so a page-level token would misrepresent them.
   It lives here, not in base.css where it began, because every page links this file and only the SPA links base.css:
   the standalone pages (/audit, /changelog, /features, sign-in) use components that layer by these names, and with the
   ladder undefined there every one computed `z-index: auto` (a dialog on /audit opened under its sticky bar at 390).
   It is theme-independent, so it is its own `:root` block, after the palettes, which are read by their first match. */
:root {
  --z-watermark: -1;    /* the instance's corner mark: behind the page content, above only the canvas */
  --z-watermark-over: 30; /* the same mark when it is set over the content: above it, below every bar and menu */
  --z-sticky-bar: 40;   /* a bar that stays put while page content scrolls under it */
  --z-menu: 50;         /* a menu opened from page content, e.g. the card row's ⋯ */
  --z-header-pop: 60;   /* a popover hanging off the top bar — above page menus */
  --z-crumb: 120;       /* the breadcrumb menu — above both of the above */
  --z-topbar: 130;      /* the sticky top bar — above every page-level menu */
  --z-scrim: 140;       /* the nav drawer's dim — covers the bar, as it did before the bar had a z-index */
  --z-drawer: 150;      /* the nav drawer itself */
  --z-skip: 160;        /* the skip link — the first tab stop, so nothing may cover it while focused */
  --z-overlay: 1000;    /* modals */
  --z-top: 1100;        /* the update banner, and a stacked .ui-dialog */
  --z-toast: 1200;      /* toasts and the busy popover: above every dialog, so a message raised from one is seen */
}
