/* TOKENS: every value the app's stylesheets share, named once.

   This is the only file that writes a colour, a font stack, a radius step, a shadow, a duration or a rhythm distance.
   The board (styles.css) and the dashboard (ops.css) both take them from here, and the dashboard's stylesheet
   imports it because it also loads on its own (at /ops) and inside a shadow root (in the app), where the board's
   sheets do not reach: hence `:root, :host`. stylelint (npm run lint:css) fails a colour written anywhere else.

   Naming: a material and a step for a palette entry (--faience-300), a role for what is drawn with it
   (--tone-good), and the dashboard's older names as aliases onto the board's (the last section). An alias is
   a name for a token, never a second value.

   Known exceptions, not defects:
   - Native date and number fields show Western digits in the Arabic page. The browser's locale decides that, not
     `lang`, and a custom picker for it is not worth what it would cost.
   - The dashboard's amber, idle grey, manual and auto hues, and the neutral tints of its tracks, have no board
     equivalent yet; they are here, named, so that they are stated once and can be folded into a ramp deliberately. */

:root, :host {
  /* Native widgets (date pickers, selects, scrollbars) render light to match. */
  color-scheme: light;

  /* ---- materials -------------------------------------------------------
     A light theme, shared with the ops dashboard so the two read as one app.
     Each ramp runs by ROLE, not by lightness: 000 is the ground (or, for
     alabaster, the strongest text), 300 is the shade that carries text, 500
     the fill, 700 a muted shade that still carries small text, 900 the soft
     tint behind a badge. The names
     are the dark theme's, kept so every rule that already asked for "the text
     shade of carnelian" still gets it.

     Every text shade is measured, not judged: at least 4.5:1 (WCAG AA) on
     white, on the paper ground and on the deep panel -- see DESIGN.md and the
     contrast audit in a11y.spec.js. */

  /* Obsidian, now paper: the grounds and edges. */
  --obsidian-000: #F6F4EF;
  --obsidian-050: #F1EEE7;
  --obsidian-100: #FFFFFF;
  --obsidian-200: #FBFAF7;
  --obsidian-300: #E6E1D6;
  --obsidian-400: #D4CDBE;
  --obsidian-500: #B8B09E;

  /* Alabaster, now ink: the text ramp, warmed so type belongs with the gold.
     The dimmest step is 4.70:1 on the deep panel -- a quieter voice, never an
     inaudible one. */
  --alabaster-000: #1D2320;
  --alabaster-100: #2E3531;
  --alabaster-300: #414A45;
  --alabaster-500: #585E58;
  --alabaster-700: #666B65;

  /* Nub — Egyptian gold. 500 carries white button text at 4.96:1. */
  --gold-100: #5A4205;
  --gold-300: #7D5C07;
  --gold-500: #8F6A0E;
  --gold-700: #806626;
  --gold-900: #FBF1D6;

  /* Khesbed — lapis lazuli. */
  --lapis-300: #2B4F96;
  --lapis-500: #3C66B8;
  --lapis-700: #A9C0EA;
  --lapis-900: #E6EDFA;

  /* Mefkat — turquoise faience. */
  --faience-300: #0F6456;
  --faience-500: #1A7A6C;
  --faience-700: #A9DCD2;
  --faience-900: #E3F4F0;

  /* Herset — carnelian. */
  --carnelian-300: #962F10;
  --carnelian-500: #B04722;
  --carnelian-700: #F2BCA6;
  --carnelian-900: #FCEBE4;

  /* Reserved for emergencies, and used nowhere else. */
  --flame-300: #A8251A;
  --flame-500: #C93C2F;
  --flame-700: #F4B3AA;
  --flame-900: #FDE8E5;

  /* ---- surfaces --------------------------------------------------------- */
  --bg: var(--obsidian-000);
  --panel: var(--obsidian-100);
  --panel-raised: var(--obsidian-200);
  --panel-deep: var(--obsidian-050);
  --card-bg: rgba(255, 255, 255, 0.97);
  /* On paper a card is an object because of its edge and a soft shadow, not
     a gold rim: the edge is the line colour, warmed a step toward gold. */
  --card-border: color-mix(in srgb, var(--gold-700) 14%, var(--obsidian-300));
  --line: var(--obsidian-300);
  --line-soft: rgba(29, 35, 32, 0.08);
  /* The edge of a control that is found by its edge: a field, a select, a quiet or icon-only button. WCAG 2.2 SC 1.4.11
     asks 3:1 of it against what it sits on; --obsidian-400 was 1.58:1 on white. This is 3.77:1 on white, 3.43:1 on the
     paper ground, 3.08:1 on the track (tests/edge-audit.js measures it). Decorative edges (a card, a divider) stay
     --line: they identify nothing. */
  --field-edge: #8A8372;
  --field-border: var(--field-edge);
  --field-border-hover: var(--alabaster-700);

  /* ---- type roles -------------------------------------------------------
     'Tempo Arabic' leads every stack. It covers the Arabic ranges only, so
     Latin falls straight through to the Latin face behind it -- Manrope for UI,
     Playfair for display, DM Mono for figures -- while Arabic is the bundled
     IBM Plex Sans Arabic on every device, which is the point: nothing here is
     borrowed from the reader's machine any more, so the phone in the server
     room and the screen on the desk render the same page in the same face. */
  --font-sans: 'Tempo Arabic', 'Manrope', 'IBM Plex Sans Arabic', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-serif: 'Tempo Arabic', 'Playfair Display', 'IBM Plex Sans Arabic', Georgia, serif;
  --font-mono: 'Tempo Arabic', 'DM Mono', 'IBM Plex Sans Arabic', ui-monospace, SFMono-Regular, Menlo, monospace;
  --font-quran: 'Tempo Arabic', 'IBM Plex Sans Arabic', serif;

  /* ---- accent ----------------------------------------------------------- */
  --gold: var(--gold-500);
  --gold-hover: var(--gold-300);
  --gold-bright: var(--gold-100);
  --gold-dim: var(--gold-700);
  --gold-deep: var(--gold-900);
  --gold-edge: color-mix(in srgb, var(--gold-500) 40%, transparent);
  --on-gold: var(--obsidian-100);

  /* ---- text ------------------------------------------------------------- */
  --ink: var(--alabaster-000);
  --ink-strong: var(--alabaster-000);
  --ink-soft: var(--alabaster-100);
  --sage: var(--alabaster-300);
  --sage-dim: var(--alabaster-500);
  --sage-mute: var(--alabaster-700);

  --danger: var(--flame-300);

  /* ---- meaning ----------------------------------------------------------
     One hue per meaning, each drawn from a material above, so a colour says the
     same thing wherever it appears — a bar, a badge, a table cell, a KPI rail. */
  --tone-good: var(--faience-300);
  --tone-warn: var(--gold-300);
  --tone-bad: var(--flame-300);
  --tone-info: var(--lapis-300);

  /* The gold standard.
     Gold is the rhythm a day is meant to have; colour measures distance from it
     in both directions rather than climbing a ladder. Warm below, cool above,
     and the same four materials the rest of the app is built from -- carnelian
     and flame going down, lapis coming up. Deliberately not a ladder: a day run
     at 140% of its own plan is not a high score, and an app whose argument is
     steady execution should not paint overwork as winning. */
  /* The two far steps are written as plain sRGB rather than derived with
     color-mix. Both need to be checkable against the panel for contrast, and a
     mixed colour resolves to oklab(), which neither getComputedStyle nor a
     canvas will hand back as sRGB -- so the one property that matters here
     could not be measured. Stated outright, they can be. flame-300 also sat
     almost on top of carnelian-300, so the far step read as no step at all. */
  --std-under-far: #C2291A;
  --std-under: var(--carnelian-300);
  --std-on: var(--gold-300);
  --std-over: var(--lapis-300);
  --std-over-far: #172F5E;
  --tone-flat: var(--alabaster-500);

  /* One value per place, and one place it lands: the accent bar at the row's
     edge, plus the badge that names it in words.

     The full-row wash that used to sit beside these is gone again. Where a job
     happens is a *stable* fact -- it does not change while the operator watches
     the board -- and painting the whole row with it spends the strongest signal
     on the least urgent question. What changes, and what the board is actually
     scanned for, is a task's state. That is what the row surface now carries. */
  /* M-13, one meaning per colour. Green, amber and red are status (good, warning, problem) and are never a place:
     field was the very red of "problem" and office the teal of "good", so a field task inside a shift the system
     ended read as two alarms. Places take the hues status does not use, and differ in lightness as well as hue,
     which is what a reader with a colour-vision deficiency still sees. Measured with the dataviz validator on the
     white chart and the #F6F4EF board: lightness band, chroma >= 0.1, normal-vision dE >= 18.7 between places and
     >= 18.9 from every status colour, CVD dE >= 8.7, and >= 3:1 on both grounds (WCAG 1.4.11). Emergency stays in
     the red family on purpose: it is the alarm. Type takes the -text step (>= 5.5:1). */
  --loc-office: #5A3FA8;
  --loc-field: #D05AAE;
  --loc-home: #5585E2;
  --loc-office-text: #4B2F96;
  --loc-field-text: #9A2F7C;
  --loc-home-text: #2F5FB8;
  --loc-emergency: var(--flame-500);

  --status-active: var(--gold-300);
  --status-paused: var(--carnelian-300);
  --status-queued: var(--lapis-300);
  --status-done: var(--faience-300);
  --status-pending: var(--alabaster-500);
  /* Cancelled is not a failure state; it is settled. It recedes rather than
     alarms — the alarm colour is reserved for emergencies. */
  --status-cancelled: var(--alabaster-700);

  /* Radii — one consistent scale, replaces the ad-hoc 4px/5px mix */
  --r-sm: 6px;
  --r-md: 9px;
  --r-lg: 14px;
  --r-pill: 999px;

  /* Elevation */
  --shadow-1: 0 1px 2px rgba(29, 35, 32, 0.05), 0 4px 16px rgba(29, 35, 32, 0.05);
  --shadow-2: 0 2px 6px rgba(29, 35, 32, 0.06), 0 12px 32px rgba(29, 35, 32, 0.10);
  --shadow-tomb: 0 24px 60px rgba(29, 35, 32, 0.22);

  /* Motion */
  --t-fast: 120ms;
  --t-med: 200ms;
  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);

  /* Rhythm. Two distances between blocks, and no third: a section is the gap between the big parts of a page (a
     card and the next card, a column and the next), a tile the gap between the small things inside one (a card of
     a row of cards, a chip and the next chip). tests/design-scale.json holds the same two numbers. */
  --space-section: 24px;
  --space-tile: 12px;
  /* One height for the controls in a row: a button, a field, a select, a switch. 44px is what a finger needs, so it is the
     height of all of them. Rule R6b holds it. */
  --control-h: 44px;
  --gutter: clamp(1rem, 4vw, 2rem);
  --stack: var(--space-section);

  /* ---- the dashboard's own materials --------------------------------------------------------------------------
     No board ramp holds these. They were literals in ops.css; they are named here, with the same values. */
  --warn: #B27A1C;
  --warn-strong: #85550C;
  --warn-soft: #FDF3DF;
  --warn-line: #F0D19A;
  --gold-line: #EBCF86;
  --gold-tint: #FFF7E3;
  --idle: #848982;
  /* A shift is the frame the tasks sit in, so it is quiet (Few's bullet graph: the ranges behind the bar are greys, the
     measure is the strong mark). Ended by the person is a pale grey fill with a 1px edge of --manual, which carries the
     3:1; the place colours on the tasks are then the only strong colours in the chart. */
  --manual: #848982;
  --manual-tint: var(--obsidian-300);
  --auto: #D2693F;
  /* Ended by the system is drawn as an --auto outline on this pale fill (not a pattern). */
  --auto-tint: var(--carnelian-900);
  --open: var(--ink-2); /* M-13: running is a state, not a warning and not "press this" (both gold): neutral, with the hatch saying "live" */
  /* A track behind a bar, a step under the card's paper. */
  --track: #ECE8DF;
  /* The brand mark's gradient. */
  --mark-from: #E5C158;
  --mark-to: #9C7C24;
  /* Text on the dark tooltip (which is --alabaster-000): the paper, two greys, and one light of each meaning. */
  --on-dark: #F3F1EC;
  --on-dark-soft: #C9CCC6;
  --on-dark-mute: #A9AEA7;
  --on-dark-gold: var(--mark-from);
  --on-dark-ok: #7FDCCB;
  --on-dark-warn: #F5C872;
  --on-dark-bad: #F59F7E;
  /* Washes over the paper: a hovered row, a hovered day in a chart, the scrim behind a drawer. */
  --wash-hover: rgba(29, 35, 32, 0.035);
  --wash-chart: rgba(29, 35, 32, 0.05);
  --scrim: rgba(29, 35, 32, 0.28);
  /* Shadows the dashboard draws that are not on the board's scale (--shadow-1, --shadow-2, --shadow-tomb) yet. */
  --shadow-mark: inset 0 -2px 0 rgba(0, 0, 0, 0.12);
  --shadow-tip: 0 10px 30px rgba(0, 0, 0, 0.22);
  --shadow-drawer: -12px 0 40px rgba(0, 0, 0, 0.18);
  --shadow-drawer-rtl: 12px 0 40px rgba(0, 0, 0, 0.18);
  --shadow-savebar: 0 6px 24px rgba(29, 35, 32, 0.1);

  /* ---- the dashboard's names for the board's tokens ------------------------------------------------------------
     Aliases: the same value, under the name ops.css has always used. Where the dashboard's own value was a shade off
     the board's for the same meaning, it now takes the board's (recorded in the pull request that made it). */
  --paper: var(--obsidian-000);
  --card: var(--obsidian-100);
  --card-soft: var(--obsidian-200);
  --line-strong: var(--obsidian-400);
  --ink-2: var(--alabaster-300);
  --muted: var(--alabaster-700);
  --quiet: var(--alabaster-700);
  --gold-strong: var(--gold-300);
  --gold-soft: var(--gold-900);
  --act: var(--gold-500);
  --ok: var(--faience-500);
  --ok-strong: var(--faience-300);
  --ok-soft: var(--faience-900);
  --ok-line: var(--faience-700);
  --bad: var(--carnelian-500);
  --bad-strong: var(--carnelian-300);
  --bad-soft: var(--carnelian-900);
  --bad-line: var(--carnelian-700);
  /* Time on tasks is ink, not a hue: blue is home (--loc-home), and the places are the only hues in a chart. */
  --work: var(--ink);
  --work-soft: var(--lapis-900);
}
