/* OAR dashboard — design tokens. The one place a colour or a size is named.
 *
 * THE REGISTER IS THE READING ROOM'S, AND IT IS STILL HERE. The first block inside `:root` is
 * `readingroom/ui/static/tokens.css` — the mnem instrument register (round 3e) — copied VERBATIM,
 * and a test holds the two files to the same bytes. It is not edited; it is LAYERED OVER. Copied
 * rather than `@import`ed, because `test_THERE_IS_ONE_PALETTE` refuses a stylesheet that arrives
 * through one line no rule-level guard can inspect.
 *
 * BENEATH IT IS THE OOPS THEME, AND THAT IS THE ONE THE STYLESHEET REACHES FOR. `docs/style-book.html`
 * is its specification and its record — every value below is measured off `docs/oops-open-call.pdf`
 * rather than chosen, and the style book states each one's source and its contrast on the board. The
 * thesis in one line: the open call is a navy sheet with luminous monospace text, and this interface
 * is that sheet DEVELOPED AS A NEGATIVE — the poster's ground `#08152d` becomes the ink, its accents
 * are re-cut in strength for a light ground, and the cream is the poster's own marigold at ~4%.
 *
 * Where a name exists in both — `--ink`, `--line`, `--ok` — the OOPS value is declared SECOND and
 * wins by cascade. That is the layering, and it is deliberate: the register keeps its bytes and the
 * residency keeps its colours. The register's remaining names (`--accent`, `--bg-*`) are simply no
 * longer named by `app.css`; electric blue appears nowhere in the open call.
 *
 * Two rules are enforced by tests rather than by discipline: `--foxing` marks the passage of time and
 * nothing else, and there is exactly ONE block in this file (see the closing note). A token invented
 * in a component file is the thing that erodes a palette; there is nowhere to put one but here.
 */

:root {
  /* ══ the register, verbatim (readingroom/ui/static/tokens.css) ══════════════════════════════ */
  /* desktop */
  --bg-desktop: #0e1417;
  --bg-desktop-glow: #151e21;
  --bg-desktop-edge: #0a0f11;

  /* surfaces */
  --bg-surface: #ffffff;
  --bg-raised: #ffffff;
  --bg-sunken: #f4f7f5;
  --bg-well: #e9eeeb;                 /* inset fields, table heads */
  --bg-hover: rgba(16, 26, 28, 0.045);
  --bg-active: rgba(16, 26, 28, 0.08);

  /* ink */
  --ink: #101a1c;
  --ink-muted: #4d5b56;
  --ink-faint: #8b968f;
  --ink-inverse: #e8efec;
  --ink-inverse-muted: rgba(232, 239, 236, 0.55);
  --ink-inverse-faint: rgba(232, 239, 236, 0.3);

  /* accent */
  --accent: #1717f4;
  --accent-hover: #1111e8;
  --accent-soft: #5d6eff;             /* ONLY on dark grounds */
  --accent-wash: rgba(23, 23, 244, 0.06);
  --accent-wash-strong: rgba(23, 23, 244, 0.14);
  --accent-ink: #f0f2ff;              /* text on accent fills */

  /* status */
  --ok: #3f9a51;
  --warn: #8a6510;
  --danger: #c9564a;
  /* pending = staged locally, not yet pushed — amber, the archive's one working-state colour */
  --pending: #8a6510;
  --pending-strong: #6d4f0b;
  --pending-wash: rgba(138, 101, 16, 0.10);

  /* lines */
  --line: #dfe6e2;
  --line-strong: #cbd5d0;
  --line-ink: rgba(16, 26, 28, 0.9);
  --line-dark: rgba(232, 239, 236, 0.12);

  /* geometry: FLAT */
  --radius: 0;
  --radius-sm: 0;
  --radius-full: 0;

  /* elevation: none — edges are DRAWN */
  --shadow-win: 0 0 0 1px var(--line-ink);
  --shadow-pop: 0 0 0 1px var(--line-ink);
  --shadow-soft: 0 0 0 1px rgba(16, 26, 28, 0.14);

  /* motion */
  --ease: cubic-bezier(0.25, 0.1, 0.25, 1);
  --t-fast: 150ms var(--ease);

  /* type */
  --font-display: "SF Pro Display", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-serif: "Iowan Old Style", Palatino, Georgia, serif;

  /* layout */
  --titlebar-h: 40px;
  --sidebar-w: 196px;

  --focus-ring-color: var(--accent);
  --selection-bg: rgba(23, 23, 244, 0.18);

  /* ══ the OOPS theme — layered over the register, and what app.css names ══════════════════════ *
   *
   * Every value is measured off `docs/oops-open-call.pdf`; `docs/style-book.html` shows each one
   * beside its source and its contrast against the board. Anything at or above 4.5 on the board may
   * set text at any size; anything below it is a fill, a rule, or a ground — never type.
   */

  /* -- ground and ink --
   * `--board` is the paper. It is the poster's marigold at roughly four percent, so the reading
   * surface is the residency's own yellow rather than a warm grey chosen from the air — and the four
   * motifs are BAKED ONTO EXACTLY THIS COLOUR (`ops/motifs.py` composites the wash and discards the
   * alpha), so changing it leaves every motif with a halo of the old one until the script is re-run.
   *
   * Literals rather than `var()` where a guard resolves a colour, because the guards follow ONE hop. */
  --board:        #fdf9ec;   /* the marigold at ~4% — the reading surface everywhere */
  --board-raised: #ffffff;   /* a field a person types into: paper on paper */
  --board-sunken: #f7f2df;   /* the gutter's track, ink 16.20 */
  --board-well:   #f1e9d1;   /* inset blocks — a shell command, a code span; ink 14.99 */

  --ink:       #08152d;   /* THE OPEN CALL'S OWN GROUND, inverted into type. 17.26 */
  --ink-muted: #46516a;   /* secondary prose, captions. 7.54 */
  --ink-faint: #5a6478;   /* the gutter at 11px. 5.65 — deliberately not fainter, because the
                           * gutter is the one thing this design argues you must always read */

  /* -- the accents, re-cut in strength for a light ground --
   * The `-true` pair are the values AS PRINTED. They are kept so nobody has to guess the source when
   * they want the real one behind a heading — and they are FILLS AND RULES ONLY on the board, where
   * they measure 4.22 and 2.66. */
  --key:        #b81c66;   /* from magenta #dd2983 — links, focus, the active state. 5.87 */
  --key-true:   #dd2983;   /* magenta as printed — fills and rules only */
  --key-hover:  #8e1450;   /* the same hue, pressed. 8.43 */
  --key-ink:    #fdf9ec;   /* type on a key fill. 5.87 */
  --key-wash:   rgba(184, 28, 102, 0.07);
  --signal:     #0b7387;   /* from cyan #15a9c4 — structural labels, the system's own voice. 5.22 */
  --signal-true:#15a9c4;   /* cyan as printed — fills, rules, and type on the spine (6.49) */
  --field:      #f6ce3e;   /* the page-1 marigold square. A ground carrying ink at 11.96, never type */
  --ok:         #55700c;   /* from acid green #afff35 — landed, anchored, confirmed. 5.38 */
  --danger:     #bb2018;   /* from the page-5 red — refusals and destructive acts. 5.98 */

  /* -- the two that live only on the dark ground --
   * The open call sets its four keywords in acid green and hot pink. Neither survives a light ground
   * at any strength worth having — on the board they are 1.5 and 1.9 — so both are CONFINED TO THE
   * SPINE, which is the one dark band in the interface and is, in effect, a strip of the open call
   * left in place. */
  --acid:  #afff35;   /* on the spine: 14.87 */
  --bloom: #ff85d8;   /* on the spine: 8.31 */

  /* -- the spine -- */
  --spine:          #08152d;                        /* the poster's ground, kept as a ground */
  --on-spine:       #e8efec;                        /* 15.57 */
  --on-spine-muted: rgba(232, 239, 236, 0.72);      /* 8.43 — a nav link is read, not glanced at */
  --line-spine:     rgba(232, 239, 236, 0.16);

  /* -- time --
   * `--foxing` is the rust bloom on stored paper. In this interface it marks ONLY what time is doing:
   * a deadline nearing, a window closing, an item outstanding. Never a button, never a brand accent,
   * never "look here". It turns out to be the open call's own heading amber, darkened to 5.05 — and
   * `test_FOXING_IS_USED_FOR_TIME_AND_NOTHING_ELSE` is what keeps it that way after the fourth person
   * who just wants a warm accent. */
  --foxing: #8a6510;

  /* -- lines and washes: separation is DRAWN with a 1px edge, never cast with a shadow -- */
  --line:        #e3ddc9;
  --line-strong: #c8c0a8;
  --line-ink:    rgba(8, 21, 45, 0.9);
  --wash:        rgba(8, 21, 45, 0.05);    /* a row under the pointer */
  --select:      rgba(184, 28, 102, 0.18);

  /* -- type: TWO FAMILIES, AND THE SECOND MONO WAS THE BUG --
   * This shipped once with Martian Mono for headings beside DM Mono for identifiers: two monospaces
   * in one eyeline, near enough alike to read as a mistake rather than as a distinction. Both faces
   * loaded; nothing had failed. The inconsistency WAS the system.
   *
   * So there is one mono now, set from 11px to 40px, and `--display` and `--mono` resolve to the same
   * stack DELIBERATELY: the token names record two ROLES, not two faces. The old rule survives,
   * sharpened — SANS IS A PERSON'S PROSE, MONO IS THE SYSTEM'S STRUCTURE — and headings moved from
   * the first to the second, because in a finding aid a heading is structure. The open call is set
   * almost entirely in monospace and has no grotesque at all, so this follows the source for
   * structure and overrules it for prose: mono is not a reading surface, and readability outranks
   * fidelity. Archivo and Martian Mono are both retired; DM Mono is the only family on the wire. */
  --mono:    "DM Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --display: var(--mono);
  --body:    var(--font-body);

  /* ONE SCALE, AND EVERY `font-size` IN THE STYLESHEET COMES OUT OF IT. An ad-hoc 14px on the brand
   * and a bare 11px on two list rules were the other half of "inconsistent": the family was constant
   * and the sizes were not, which the eye reads as the same fault. */
  --t-gutter: 11px;     /* the floor. Nothing in this interface is smaller */
  --t-small:  12.5px;   /* the working size */
  --t-body:   15px;     /* this interface is mostly prose */
  --t-lead:   18px;
  --t-head:   22px;
  --t-title:  28px;
  --t-hero:   clamp(28px, 1.6vw + 18px, 40px);   /* home's one sentence */
  --t-inline: 0.92em;   /* code inside prose: relative, so it tracks the size it sits in, and floored
                         * at --t-gutter where it is used, so it cannot go below 11px */

  --lh-body:  1.55;     /* generous: the column is wide and the ground is warm */
  --lh-tight: 1.15;
  --lh-mono:  1.45;     /* mono at 11-12.5px wants more than tight and less than prose */

  /* -- measure and rhythm --
   * The scale is 1, 2, 3, 4, 6, 8, 12, 16. THERE IS NO `--s5`, and reaching for one is the single
   * most common way to ship a rule that does nothing: `gap: var(--s5)` is not an error, it is a gap
   * of zero. `test_EVERY_TOKEN_THE_STYLESHEET_USES_IS_A_TOKEN_THAT_EXISTS` is what catches it. */
  --measure:  66ch;     /* the content column. There is a great deal of writing here */
  /* **A SHORT ANSWER GETS A SHORT BOX** — checklist item 47's other end. `--measure` is the width a
   * PARAGRAPH is read at, and giving it to a file input, a name field or a picker stretched a
   * one-line answer across 624px with its label marooned 270px away in the gutter track: a reading
   * measure spent rather than a layout gained. Prose keeps `--measure`, because a statement really
   * is read at the width it is typed at. Sized at the longest short answer this form actually takes
   * — an ss58 address at --t-body — rather than at a round number. */
  --measure-field: 30rem;
  /* The staging deck's collapsed bar — checklist item 54. The deck is a SECTION of the page now
   * rather than an overlay, so the workstation (the one surface that asks for a viewport-height
   * box) has to subtract it and the floating windows have to clear it. Declared HERE, in the OOPS
   * layer, and not among the layout sizes twenty lines up: that block is the Reading Room's
   * register copied verbatim and `test_THE_PALETTE_IS_THE_READING_ROOMS_VERBATIM` holds it to the
   * byte — a token added inside it reads as a tidy place to put a layout size and breaks a guard
   * whose whole job is to say the copy is still a copy. */
  --deck-h: 44px;
  --gutter-w: 15.5rem;  /* wide enough for an ss58 address at --t-gutter in two lines, not forty */
  --aid-w:    78rem;    /* the aid's width on a wide screen; beyond it a line is too long to follow */
  --step:     4px;
  --s1: calc(var(--step) * 1);
  --s2: calc(var(--step) * 2);
  --s3: calc(var(--step) * 3);
  --s4: calc(var(--step) * 4);
  --s6: calc(var(--step) * 6);
  --s8: calc(var(--step) * 8);
  --s12: calc(var(--step) * 12);
  --s16: calc(var(--step) * 16);

  /* -- the phone --
   * The hit target on a control somebody taps is not negotiable. The width at which the bar's nine
   * links stop being a disclosure and become a row is NOT a token: a media query cannot read a
   * custom property, so it is written out at `64rem` in `app.css` where it is used, rather than
   * named here and silently ignored there. */
  --touch: 44px;

  /* One half-hour in the week view's hour grid. **A LENGTH THE PAGE CANNOT SET ITSELF**: the CSP
   * admits no inline style, so every box's position is a grid row and this is what a row is worth.
   * The axis labels and the hour rules behind them are both driven by it, which is what keeps them
   * from drifting apart. */
  --slot-h: 1.4rem;
  --slot-h-tight: 1.1rem;   /* the same grid on a phone */

  /* The ground behind a dialog — checklist item 68. **THE INK, NOT BLACK.** Every wash in this file
   * is mixed from `--ink`'s own 16/26/28 (see `--bg-hover`), so a scrim mixed from pure black would
   * be the one dimming on the page that is a different colour from all the others — visible as a
   * faint cast the moment it sits over the cream. */
  --scrim: rgba(16, 26, 28, 0.55);
}

/* -- ONE THEME, DELIBERATELY ------------------------------------------------------------------- *
 *
 * There is no dark palette and no `prefers-color-scheme` block. Operator's decision, and both
 * registers agree with it: the reading surface is light in every theme, and the one dark ground is
 * the spine. So the page declares `color-scheme: light` rather than leaving it to the host, and
 * every token is defined at `:root`, in ONE block — the register first, the residency's own values
 * layered over it. `test_THERE_IS_ONE_PALETTE` is what keeps that true: a
 * `@media (prefers-color-scheme: dark)` block added later would not be a feature half-finished, it
 * would be a second palette nobody maintains, drifting from this one silently because most people
 * never see it.
 *
 * AND THE CREAM IS LOAD-BEARING BEYOND COLOUR. The four motifs in `oar/ui/static/` are exported with
 * the wash composited onto `--board` and the alpha discarded, which is what took `motif-bloom` from
 * 117 KB to 19 KB. Change `--board` and every motif keeps a halo of the old one; re-run
 * `ops/motifs.py` in the same commit.
 */
