/* ---- Design tokens (plan §5 M2 theming layer) ----------------------------
   GENERATED by `docs/design/generate.py` from `docs/design/guide/tokens.py`.
   Edit the table there and regenerate; never edit this CSS by hand. The same
   bytes are written to `docs/design/tokens.css` (the design canvas reads that
   copy) and to `webapp/static/css/tokens.css` (the live file), so the two can
   never drift.

   The whole palette and type/space scale, and nothing else. It was the head of
   `base.css` until dark mode doubled it; splitting on the responsibility line
   ("the theming layer" vs "layout and components") kept both files inside the
   ceilings. Every template that links `base.css` links this right after
   `fonts.css` (the three faces) and before `base.css`; the offline audit pack
   (`reports/services.STYLESHEETS`) links it first, since it ships no fonts.

   Components style through tokens only. Per-tenant branding overrides tokens
   (Organization.config.theme -> the one sanctioned inline style in base.html),
   never components.

   Three rules this block exists to hold:

   1. Every colour is defined in full on bare `:root`. The two dark blocks
      below redefine token VALUES and nothing else, so no colour has its only
      definition inside a media query or a `[data-theme]` block.
   2. Blue is chrome, never a status. `--accent` carries the interface;
      `--warn` (amber) is the one that means "waiting on you". A status is
      never signalled with the accent, not least because a tenant may replace
      it.
   3. Several colours carry two names (`--bg`/`--ground`, `--surface`/
      `--panel`, `--text`/`--ink`, `--muted`/`--slate`, `--border`/`--line`).
      The older name is what the existing components reference; the newer one
      is what the application shell reads. They are the same colour and must
      stay in step; never give one a value the other does not have. The alias
      block at the end of `:root` goes when every caller reads the canonical
      name. */

:root {
  /* --- Ground and ink ------------------------------------------------------
     The greys carry almost no hue (chroma under 0.01) so that the accent, which
     a tenant may replace, is the only chrome colour on the page. */
  --bg: #f4f5f8;  /* page ground */
  --surface: #ffffff;  /* panels, tables, the sidebar, inputs */
  --surface-sunk: #eef0f4;  /* a surface below a panel: picker buttons, quiet footers, table heads */
  --paper: #e9ecf2;  /* alternate band on the public pages */
  --ink: #171c2b;  /* body text, titles, 17.0:1 on surface */
  --ink-2: #3a4156;  /* secondary text, nav labels, table cells, 10.1:1 */
  --slate: #5c647a;  /* captions, help, legends, chip text on neutral, 5.9:1 (5.1:1 on --surface-sunk) */
  --placeholder: #6b7388;  /* placeholder text only, 4.7:1 */
  --line: #d9dde6;  /* panel and table borders (decorative), 1.4:1 */
  --line-strong: #7c8499;  /* the border of a control, the outline of an empty cell: anything that must be seen to be used, 3.7:1 on surface, 3.3:1 on --surface-sunk (3.4:1 dark) */
  --line-soft: #e8ebf1;  /* hairlines inside a component */
  --rule: #c3c9d6;  /* structural hairline: the ledger line, table head rule (decorative), 1.7:1 */

  /* --- Accent: chrome, and never a status ----------------------------------
     Default EU reflex blue. A tenant replaces `--accent` on `<html>` and the
     other four are mixed from it there, so a tenant sets one value. If a
     tenant sets it to red, nothing in the interface changes meaning. */
  --accent: #003399;  /* links, primary button, active nav, focus ring, selected tab underline */
  --accent-deep: #002266;  /* pressed state, emphatic link text */
  --accent-lift: #1a4ad1;  /* hover fill */
  --accent-soft: #e8eefb;  /* active nav ground, hover rows, selected chips */
  --on-accent: #ffffff;  /* text on a filled accent ground */

  /* --- Status: never chrome ------------------------------------------------
     Each status has a text colour, a soft ground, and (where it is ever filled)
     a text colour for the filled form. Measured on white: ok 5.7:1, warn
     5.1:1, crit 6.5:1, waived 6.5:1; on their soft grounds 5.0, 4.6, 5.5 and
     5.3. `--neutral` is a FILL and has no text contrast against
     `--neutral-soft`: words on that ground use `--slate`. */
  --ok: #167543;  /* satisfied, released, acknowledged in time, 5.7:1 on surface, 5.0:1 on --ok-soft */
  --ok-soft: #e3f4ea;  /* the ground under ok text */
  --on-ok: #ffffff;  /* text on a filled ok ground */
  --warn: #9a6200;  /* waiting on you: new, awaiting info, due soon, expiring, unreviewed, 5.1:1 on surface, 4.6:1 on --warn-soft */
  --warn-soft: #fff3d1;  /* the ground under warn text */
  --on-warn: #ffffff;  /* text on a filled warn ground */
  --crit: #b3261e;  /* wrong now: gap, expired, overdue, refused, 6.5:1 on surface, 5.5:1 on --crit-soft */
  --crit-soft: #fbe6e4;  /* the ground under crit text */
  --on-crit: #ffffff;  /* text on a filled crit ground */
  --waived: #6b4fa0;  /* waived, with an expiry, 6.5:1 on surface, 5.3:1 on --waived-soft */
  --waived-soft: #ede7f7;  /* the ground under waived text */
  --on-waived: #ffffff;  /* text on a filled waived ground */
  --neutral: #8089a1;  /* not started, not applicable, closed, unknown; a fill, not a text colour, 3.5:1 */
  --neutral-soft: #eceff4;  /* the quiet chip and table ground */

  /* --- The pre-login dark band, dark in BOTH themes ------------------------
     A designed band, not a surface that follows the reader's preference, so
     nothing in the dark blocks redefines it. */
  --band: #0d1a3d;  /* the band ground */
  --band-raised: #17285a;  /* a card on the band */
  --band-text: #e7edf8;  /* text on the band */
  --band-muted: #9fb0d0;  /* secondary text on the band */
  --band-line: #27376b;  /* hairlines on the band */
  --accent-on-band: #9cc4ff;  /* a link on the band */

  /* --- Marks: the shield, and Auray's logo ---------------------------------
     The logo, not the interface. `--brand-cut` is the GROUND the mark sits on,
     because the pulse line is cut out of the mark rather than painted white;
     a component that places the mark on another surface re-points it. The
     two Auray yellows are somebody else's brand and never take the theme. */
  --brand-orange: #f9a825;  /* the lit upper field of the shield */
  --brand-slate: #5b5b5d;  /* the shield body */
  --brand-slate-on-band: #9a9ca3;  /* the shield body on the dark band */
  --brand-cut: var(--bg);  /* the cut-out colour inside the mark */
  --auray-yellow: #f9bf3d;  /* Auray's logo, never interface */
  --auray-yellow-2: #fcd13e;  /* Auray's logo, never interface */

  /* The one token whose value changes with the theme: a slate stroke
     disappears against a dark control. */
  --icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none' stroke='%235c647a' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E");

  --shadow-pop: 0 8px 24px -12px rgb(23 28 43 / 0.35);  /* menus, popovers, toasts */
  --shadow-drawer: 0 16px 48px -16px rgb(23 28 43 / 0.5);  /* the phone drawer, the side drawer */
  --shadow-sm: 0 1px 2px rgb(23 28 43 / 0.06);  /* LEGACY: panels are border and fill (spec 5.4); callers migrate to no shadow */

  /* --- Type ------------------------------------------------------------
     Two families, eight sizes, three weights, and nothing in between.
     Source Sans 3 is the Latin companion of Source Han Sans, so English
     and CJK share an x-height and a stroke weight on the same line. */
  --font-sans: "Source Sans 3", "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", "Noto Sans CJK TC", system-ui, sans-serif;
  --font-mono: "Source Code Pro", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

  --fs-micro: 0.75rem;  /* 12px, legends, table meta, chip text, timestamps */
  --fs-small: 0.8125rem;  /* 13px, table cells, help text, captions, secondary rows */
  --fs-ui: 0.875rem;  /* 14px, controls, buttons, nav, dense panels */
  --fs-body: 1rem;  /* 16px, prose, guidance, requirement text */
  --fs-h3: 1.125rem;  /* 18px, panel titles, card titles */
  --fs-h2: 1.375rem;  /* 22px, page sections, the auth card title */
  --fs-h1: 1.75rem;  /* 28px, page title, one per page */
  --fs-display: clamp(2.25rem, 1.6rem + 2.2vw, 3.25rem);  /* 52px, public pages only */

  --lh-micro: 1.4;
  --lh-small: 1.45;
  --lh-ui: 1.5;
  --lh-body: 1.6;
  --lh-h3: 1.35;
  --lh-h2: 1.3;
  --lh-h1: 1.2;
  --lh-display: 1.08;
  /* The two older line-height names, the same two values under the names
     the current CSS calls them by. They are line heights, not aliases of
     a colour, so they live here beside the scale they belong to. */
  --lh-snug: 1.35;  /* = --lh-h3 */
  --lh-tight: 1.2;  /* = --lh-h1 */

  --fw-regular: 400;  /* body, table cells, prose */
  --fw-medium: 500;  /* labels, buttons, tabs, legends, chip text */
  --fw-semibold: 600;  /* headings only */
  /* Nothing else is tracked, and nothing is uppercased: Chinese has no
     capitals and takes no letter-spacing. */
  --tracking-display: -0.015em;

  /* --- Space: a 4px base -----------------------------------------------
     A value between two steps is a design error, not a new token. */
  --sp-4: 0.25rem;  /* 4px, between a glyph and its word */
  --sp-8: 0.5rem;  /* 8px, between chips, inside a chip, control gap */
  --sp-12: 0.75rem;  /* 12px, inside a control, between rows of a list */
  --sp-16: 1rem;  /* 16px, between fields, panel padding on a phone */
  --sp-20: 1.25rem;  /* 20px, panel padding, between panel sections */
  --sp-24: 1.5rem;  /* 24px, page padding, between panels */
  --sp-32: 2rem;  /* 32px, between page sections, page padding at 64rem and up */
  --sp-48: 3rem;  /* 48px, above a page section title */
  --sp-64: 4rem;  /* 64px, public page bands */
  --sp-96: 6rem;  /* 96px, public page bands at 64rem and up */

  /* --- Radius, line, elevation ------------------------------------------
     Panels are a 1px line on a white surface; shadow is only for things
     that float. Hover is a ground change, never a lift. */
  --radius-sm: 4px;  /* chips, ID tags, table-cell buttons */
  --radius-md: 6px;  /* controls, buttons, menus */
  --radius-lg: 10px;  /* panels, cards, dialogs, the auth card */
  --radius-pill: 999px;  /* status chips, counts in tabs */
  --radius-cell: 2px;  /* the 10px cell, the product's signature */

  /* --- Motion: one curve, three durations -------------------------------
     One global prefers-reduced-motion block in base.css sets every
     duration to 1ms; no other file writes one. */
  --dur-1: 120ms;  /* hover, focus, colour */
  --dur-2: 200ms;  /* expand a row, switch a tab, open a menu */
  --dur-3: 320ms;  /* drawer, dialog, the sidebar collapse */
  --dur-wait: 300ms;  /* the wait before an indicator shows, so a fast answer never flashes */
  --ease: cubic-bezier(0.22, 0.8, 0.28, 1);  /* everything; there is one curve */

  /* --- Layers -----------------------------------------------------------
     Breakpoints cannot be custom properties; they are written the same
     way in every file as max-width queries: 40/48/64/80rem. */
  --z-sticky: 5;  /* topbar, sticky table head */
  --z-drawer: 40;  /* sidebar drawer, side drawer */
  --z-popover: 50;  /* menus, pickers */
  --z-dialog: 60;  /* dialog */
  --z-toast: 70;  /* toasts */

  /* --- Controls and measure ---------------------------------------------
     The control scale lives here rather than in forms.css: a button
     standing beside a select has to be the same height as the select,
     and buttons and forms are two files. */
  --control-h: 2.375rem;  /* every single-line control and every button: 38px */
  --control-pad-y: 0.45rem;  /* what centres a control's text at --control-h */
  --control-pad-x: 0.7rem;  /* inside a control, and the inset the chevron sits against */
  --form-measure: 40rem;  /* a column of labelled fields */
  --measure-prose: 70ch;  /* running prose; Chinese prose is 40 characters */
  --page-max: 72rem;  /* the page column */
  --gutter: 0rem;  /* horizontal inset for a full-bleed shell; the workspace pads its body */

  /* --- Derived, so that no component mixes its own ----------------------- */
  --ring: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent);
  --ring-crit: 0 0 0 2px var(--surface), 0 0 0 4px var(--crit);
  --ok-hatch: repeating-linear-gradient(135deg, var(--ok) 0 2px, transparent 2px 5px);

  /* --- Aliases: the older names, kept until every caller is migrated -----
     They are the SAME colour and must stay in step; never give one a
     value the other does not have. Delete this block at the end of the
     migration, not before. */
  --ground: var(--bg);
  --panel: var(--surface);
  --panel-sunk: var(--surface-sunk);
  --text: var(--ink);
  --muted: var(--slate);
  --border: var(--line);
  --space-1: var(--sp-4);
  --space-2: var(--sp-8);
  --space-3: var(--sp-12);
  --space-4: var(--sp-20);
  --space-5: var(--sp-32);
  --space-6: var(--sp-48);
  --space-7: 4.5rem;  /* 72px, no step of its own */
  --space-8: var(--sp-96);
  --fs-eyebrow: var(--fs-micro);
  --fs-lede: var(--fs-body);
  --measure: var(--form-measure);
  --shadow-md: var(--shadow-pop);
  /* Tracking is forbidden by spec 5.2: Chinese has no capitals and takes
     no letter-spacing. The name survives so the old callers keep
     rendering, untracked, until step 1 deletes them. */
  --tracking-eyebrow: 0;
  /* The loud "waiting on you" badge is now the filled warn chip, so the
     brighter amber is gone and the name points at the status it meant.
     Words on it use --on-warn. */
  --warn-bright: var(--warn);
}

/* ---- Dark -----------------------------------------------------------------
   Two blocks, byte-identical bodies, because they answer two different
   questions and CSS cannot share a declaration list between them:

   - the media query answers "the reader's system prefers dark, and this page
     has not been told otherwise";
   - the attribute selector answers "this page was explicitly set to dark",
     and it must win over a system preference of light.

   Both redefine token VALUES only. Nothing here introduces a colour, so a
   token can never exist in dark and be missing in light. A test diffs the two
   bodies; the generator writes them from one function so they cannot differ.

   The band tokens are absent on purpose: that band is dark in both themes.
   -------------------------------------------------------------------------- */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* --- Ground and ink ----------------------------------------------------
       Values only; the light block above says what each one is for. */
    --bg: #0c111c;
    --surface: #131a29;
    --surface-sunk: #0f1522;
    --paper: #10172a;
    --ink: #e6eaf2;
    --ink-2: #b8c0d2;
    --slate: #8a93a8;
    --placeholder: #7c85a0;
    --line: #273043;
    --line-strong: #5c6d94;
    --line-soft: #1c2434;
    --rule: #34405a;

    /* --- Accent: chrome, and never a status --------------------------------
       Values only; the light block above says what each one is for. */
    --accent: #7fb0ff;
    --accent-deep: #a9c8ff;
    --accent-lift: #a9c8ff;
    --accent-soft: #172642;
    --on-accent: #0a1630;

    /* --- Status: never chrome ----------------------------------------------
       Values only; the light block above says what each one is for. */
    --ok: #4cc98a;
    --ok-soft: #103021;
    --on-ok: #08210f;
    --warn: #f0b429;
    --warn-soft: #332708;
    --on-warn: #2a1f00;
    --crit: #ff8a80;
    --crit-soft: #3a1719;
    --on-crit: #3a1719;
    --waived: #b8a0e6;
    --waived-soft: #261b3b;
    --on-waived: #1f1633;
    --neutral: #5b6883;
    --neutral-soft: #1a2336;

    /* --- Marks: the shield, and Auray's logo -------------------------------
       Values only; the light block above says what each one is for. */
    --brand-slate: #9a9ca3;

    /* The one token whose value changes with the theme: a slate stroke
       disappears against a dark control. */
    --icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none' stroke='%238a93a8' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E");

    --shadow-pop: 0 8px 24px -12px rgb(0 0 0 / 0.8);
    --shadow-drawer: 0 16px 48px -16px rgb(0 0 0 / 0.9);
    --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.5);
  }
}

:root[data-theme="dark"] {
  /* --- Ground and ink ----------------------------------------------------
     Values only; the light block above says what each one is for. */
  --bg: #0c111c;
  --surface: #131a29;
  --surface-sunk: #0f1522;
  --paper: #10172a;
  --ink: #e6eaf2;
  --ink-2: #b8c0d2;
  --slate: #8a93a8;
  --placeholder: #7c85a0;
  --line: #273043;
  --line-strong: #5c6d94;
  --line-soft: #1c2434;
  --rule: #34405a;

  /* --- Accent: chrome, and never a status --------------------------------
     Values only; the light block above says what each one is for. */
  --accent: #7fb0ff;
  --accent-deep: #a9c8ff;
  --accent-lift: #a9c8ff;
  --accent-soft: #172642;
  --on-accent: #0a1630;

  /* --- Status: never chrome ----------------------------------------------
     Values only; the light block above says what each one is for. */
  --ok: #4cc98a;
  --ok-soft: #103021;
  --on-ok: #08210f;
  --warn: #f0b429;
  --warn-soft: #332708;
  --on-warn: #2a1f00;
  --crit: #ff8a80;
  --crit-soft: #3a1719;
  --on-crit: #3a1719;
  --waived: #b8a0e6;
  --waived-soft: #261b3b;
  --on-waived: #1f1633;
  --neutral: #5b6883;
  --neutral-soft: #1a2336;

  /* --- Marks: the shield, and Auray's logo -------------------------------
     Values only; the light block above says what each one is for. */
  --brand-slate: #9a9ca3;

  /* The one token whose value changes with the theme: a slate stroke
     disappears against a dark control. */
  --icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none' stroke='%238a93a8' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E");

  --shadow-pop: 0 8px 24px -12px rgb(0 0 0 / 0.8);
  --shadow-drawer: 0 16px 48px -16px rgb(0 0 0 / 0.9);
  --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.5);
}

/* ---- Traditional Chinese --------------------------------------------------
   Chinese sets tighter than Latin at the same size, wants more leading in
   running text, and takes no negative tracking at display sizes. It has no
   capitals either, which is why nothing in this system is uppercased.
   -------------------------------------------------------------------------- */

html[lang^="zh"] {
  --lh-body: 1.75;
  --lh-display: 1.2;
  --tracking-display: 0;
}
