/* ============================================================================
 * tokens.css — the RMS bundle's design tokens
 *
 * The only file in web/rms/ besides the face's sheet (web/rms/tokens.css) that
 * may hold a color, a length, a font or a duration. Everything else uses var()
 * (utils/check_rms.py enforces it).
 *
 * Tier 1  the owner's design system ("kyr rms", 2026-10-29): its ramps at their
 *         exact values, then its roles, light and under data-theme="dark";
 *         referenced only in this file.
 * Tier 2  interface roles: grounds and ink bound to the frame's --k-* tokens
 *         (kyr-shell/2 §13), every colour that means something the system's.
 * Tier 3  RMS domain roles: lifecycle families, verification results,
 *         criticality, diff, link state, figure concepts, levels, the view.
 *
 * Lengths are rem; hairlines are px. Every text/background pair here meets
 * WCAG AA on the sheet, the sunken surface and the board, light and dark; the
 * kit (web/tests/kit.html) renders them side by side.
 * ==========================================================================*/

/* --- tier 1 ---------------------------------------------------------------*/

/* The checker's kit (the owner's design system "kyr rms", 2026-10-29): eight ramps built in OKLCH on one lightness scale, every colour one
 * idea. graphite: grounds, hairlines, secondary text (pencil before ink); blueprint: the specification, the ink itself; maya: the accent
 * and the customer; cyanotype: selection, "you are here"; verdigris: proof; highlighter: "look again" (ochre); redline: refused; mauveine:
 * design. Only the steps the roles below use are written, at the system's exact values; the pinned colours keep theirs (blueprint-950,
 * verdigris-300, verdigris-700, maya-300). Any 700-or-darker step is text on light grounds (5.5:1 or better), any 300-or-lighter on dark
 * ones (8.3:1 or better); each role pair below is measured in both themes by the system's ColourAtlas. */
:root {
  --p-graphite-50: #f5f7f9;
  --p-graphite-100: #ebedef;
  --p-graphite-300: #c3c6c9;
  --p-graphite-500: #8c8f93;
  --p-graphite-600: #727578;
  --p-graphite-700: #585b5e;
  --p-graphite-800: #414447;
  --p-graphite-925: #232528;
  --p-blueprint-100: #ebecf8;
  --p-blueprint-400: #a4a8cc;
  --p-blueprint-900: #2a2d46;
  --p-blueprint-950: #1f2041;
  --p-maya-100: #daf1ff;
  --p-maya-200: #b8e3ff;
  --p-maya-400: #3fb7f7;
  --p-maya-800: #00496d;
  --p-maya-900: #183243;
  --p-cyanotype-200: #c7dffa;
  --p-cyanotype-300: #a0caf9;
  --p-cyanotype-600: #4977ae;
  --p-cyanotype-800: #34455c;
  --p-verdigris-50: #e9fcf7;
  --p-verdigris-100: #d5f5ee;
  --p-verdigris-300: #41ead4;
  --p-verdigris-700: #297373;
  --p-verdigris-900: #0c3635;
  --p-highlighter-50: #f7f8e9;
  --p-highlighter-300: #e5c264;
  --p-highlighter-700: #795200;
  --p-highlighter-900: #362d23;
  --p-redline-50: #fff4f1;
  --p-redline-400: #ff815d;
  --p-redline-800: #7c1b00;
  --p-redline-900: #432720;
  --p-mauveine-100: #f7e6fd;
  --p-mauveine-300: #e7abfd;
  --p-mauveine-700: #7a3897;
  --p-mauveine-900: #37283f;
  --p-white: #ffffff;
}

/* The system's roles, light first, then dark: what a component may name (tier 2 and 3 bind to these). */
:root {
  --p-frame: var(--p-graphite-600);       /* an outline that means something: a hovered control, the empty dot */
  --p-ghost: var(--p-graphite-300);       /* switched off, always dashed */
  --p-ink-2: var(--p-graphite-700);
  --p-accent: var(--p-maya-800);          /* item IDs, links, section numbers, the edge being explained */
  --p-accent-tint: var(--p-maya-100);
  --p-select: var(--p-cyanotype-200);     /* "you are here": the current item, tab, pressed toggle, chosen row */
  --p-select-strong: var(--p-cyanotype-600); /* its solid mark: the ring of a pinned node, the current milestone, the past band */
  --p-on-select: var(--p-blueprint-950);
  --p-focus: var(--p-cyanotype-600);
  --p-bar: var(--p-blueprint-950);        /* the one primary button, the tooltip, the toast */
  --p-on-bar: var(--p-white);
  --p-ok: var(--p-verdigris-700);         /* passed, proven, controlled: always with a word */
  --p-ok-tint: var(--p-verdigris-50);
  --p-on-ok: var(--p-white);              /* a word or a mark on the proof's solid (a filled trace cluster's card): 5.5:1 */
  --p-warn: var(--p-highlighter-700);     /* planned, pending, suspect: dashed in drawings, always with a word */
  --p-warn-tint: var(--p-highlighter-50);
  --p-refuse: var(--p-redline-800);       /* refused, forbidden: the checker's red pen */
  --p-refuse-tint: var(--p-redline-50);
  /* the parts of a project's organisation (the owner, 2026-10-30: "no visual identity"), the palette of the criticality page the owner chose
   * on 2026-10-28; a role's tone only, never a state's or a person's */
  --p-fn-blue: #1f6fb2;
  --p-fn-green: #2f8a55;
  --p-fn-teal: #23807f;
  --p-fn-purple: #7a4fb0;
  --p-fn-rose: #b0466f;
  --p-fn-orange: #c0601d;
  --p-fn-slate: #4f5d73;
  /* the health page's two series (views/health.js, 7 Nov): the decisions in the review tone, the work in the engineering tone, each a step
   * the dataviz validator passes on the sheet, light (L 0.43..0.77) and dark (L 0.48..0.67), adjacent CVD ΔE 18 / 16 */
  --p-chart-control: #7a4fb0;
  --p-chart-work: #2f8a55;
  --p-cat-customer: var(--p-maya-800);
  --p-cat-customer-tint: var(--p-maya-100);
  --p-cat-spec: var(--p-blueprint-900);
  --p-cat-spec-tint: var(--p-blueprint-100);
  --p-cat-design: var(--p-mauveine-700);
  --p-cat-design-tint: var(--p-mauveine-100);
  --p-cat-proof: var(--p-verdigris-700);
  --p-cat-proof-tint: var(--p-verdigris-100);
  --p-cat-control-tint: var(--p-graphite-100);
  --p-scrim: rgb(10 12 16 / 0.35);
  --p-shadow-card: 0 1px 2px rgb(20 22 26 / 0.06);   /* a hairline lift */
  --p-shadow-pop: 0 8px 24px rgb(20 22 26 / 0.14);   /* only what floats: menus, the palette, tooltips, the drawer */
}

:root[data-theme="dark"] {
  --p-frame: var(--p-graphite-500);
  --p-ghost: var(--p-graphite-700);
  --p-ink-2: var(--p-graphite-300);
  --p-accent: var(--p-maya-400);
  --p-accent-tint: var(--p-maya-900);
  --p-select: var(--p-cyanotype-800);
  --p-select-strong: var(--p-cyanotype-300);
  --p-on-select: var(--p-graphite-50);
  --p-focus: var(--p-cyanotype-300);
  --p-bar: var(--p-graphite-800);
  --p-on-bar: var(--p-white);
  --p-ok: var(--p-verdigris-300);
  --p-ok-tint: var(--p-verdigris-900);
  --p-on-ok: var(--p-verdigris-900);      /* on verdigris-300: 8.7:1 */
  --p-warn: var(--p-highlighter-300);
  --p-warn-tint: var(--p-highlighter-900);
  --p-refuse: var(--p-redline-400);
  --p-refuse-tint: var(--p-redline-900);
  --p-fn-blue: #6aa9e0;
  --p-fn-green: #6cc28f;
  --p-fn-teal: #5cc4c0;
  --p-fn-purple: #b195e0;
  --p-fn-rose: #e08aaa;
  --p-fn-orange: #f0a060;
  --p-fn-slate: #9fb0c8;
  --p-chart-control: #9a7cd8;
  --p-chart-work: #4aa874;
  --p-cat-customer: var(--p-maya-200);
  --p-cat-customer-tint: var(--p-maya-900);
  --p-cat-spec: var(--p-blueprint-400);
  --p-cat-spec-tint: var(--p-blueprint-900);
  --p-cat-design: var(--p-mauveine-300);
  --p-cat-design-tint: var(--p-mauveine-900);
  --p-cat-proof: var(--p-verdigris-300);
  --p-cat-proof-tint: var(--p-verdigris-900);
  --p-cat-control-tint: var(--p-graphite-925);
  --p-shadow-card: 0 1px 2px rgb(0 0 0 / 0.4);
  --p-shadow-pop: 0 8px 24px rgb(0 0 0 / 0.5);
}

/* --- the file viewer (ui/viewer.js, css/viewer.css) ------------------------------------------------------------------------------
 * A sheet over the window less a gutter (its contents a side column of css/layout.css, its text a sheet's); a source line's height, the same for its number, its text
 * and the band that marks it (em: the source's own size); PlantUML's words in the system's concept colours, each a text colour of both
 * themes; a marked range in the highlighter's tint edged in its ink; a picture on paper in both themes, so a drawing made for white stays
 * legible on a dark screen. */
:root {
  --g-viewer-w: calc(100vw - var(--g-space-6));
  --g-viewer-h: calc(100dvh - var(--g-space-6));
  --g-viewer-outline-h: calc(100dvh - 14rem); /* the contents scroll inside this beside a long document */
  --t-lh-code: 1.5;
  --g-viewer-code-em: 0.9em; /* code inside running text, a little under the text's size */
  --g-code-line: calc(var(--t-lh-code) * 1em);
  --c-code-kw: var(--p-cat-design);
  --c-code-dir: var(--p-accent);
  --c-code-arrow: var(--p-warn);
  --c-code-str: var(--p-ok);
  --c-code-col: var(--p-cat-spec);
  --c-code-com: var(--p-ink-2);
  --c-code-mark: var(--p-warn-tint);
  --c-code-mark-edge: var(--p-warn);
  --c-picture-plate: var(--p-white);
}

/* --- tier 2 ---------------------------------------------------------------*/

/* The grounds and the ink are the frame's (--k-*, kyr-shell/2 §13), so the bundle sits in whichever face the shell wears (rms's own face
 * is the same system, web/rms/tokens.css); every colour that means something is the system's own, the same in every face. */
:root {
  --c-bg: var(--k-bg);
  --c-surface: var(--k-surface);    /* sheet: a card */
  --c-elevated: var(--k-surface-2); /* sunk: table heads, the inspector, grouped regions */
  --c-border: var(--k-line);        /* rule: the hairline between rows and around cards */
  --c-border-strong: var(--k-line); /* one rule: the system draws regions and controls with the same hairline */
  --c-field-edge: color-mix(in srgb, var(--p-frame) 72%, var(--k-surface)); /* a field's boundary: 3:1 on the sheet and sunk, both themes */
  --c-text: var(--k-ink);
  --c-text-muted: var(--k-ink-2);
  --c-accent: var(--p-accent);      /* plain, never a mix: ui/map.js hands it to a canvas as the lit wire */
  --c-accent-tint: var(--p-accent-tint);
  --c-focus: var(--p-focus);
  --c-selection: var(--p-select);
  --c-select-strong: var(--p-select-strong);
  --c-on-select: var(--p-on-select);
  --c-hover: color-mix(in srgb, var(--k-ink) 5%, transparent); /* the ground tinted toward sunk, on any ground */
  --c-pressed: var(--p-select);     /* a toggle that is on, the chosen option */
  --c-bar: var(--p-bar);
  --c-on-bar: var(--p-on-bar);
  --c-hover-frame: var(--p-frame);  /* a control's outline under the pointer */
  --c-ghost: var(--p-ghost);
  --c-ok: var(--p-ok);
  --c-chart-control: var(--p-chart-control); /* the health page: decisions, control's share */
  --c-chart-work: var(--p-chart-work);       /* the health page: work, work's share */
  --c-warn: var(--p-warn);
  --c-err: var(--p-refuse);
  --c-backdrop: var(--p-scrim);
  --c-shadow: color-mix(in srgb, var(--k-ink) 14%, transparent);
  --c-link: var(--p-accent);
  --c-link-line: color-mix(in srgb, var(--p-accent) 40%, transparent);

  /* --- tier 3 ---------------------------------------------------------------*/
  /* A role's tone, the part of the organisation it staffs (core/people.js ROLE_TONE): its mark, and its tint under a chip's words. */
  --c-fn-management: var(--p-fn-blue);
  --c-fn-engineering: var(--p-fn-green);
  --c-fn-configuration: var(--p-fn-teal);
  --c-fn-review: var(--p-fn-purple);
  --c-fn-assurance: var(--p-fn-rose);
  --c-fn-customer: var(--p-fn-orange);
  --c-fn-isvv: var(--p-fn-slate);
  --c-fn-management-tint: color-mix(in srgb, var(--p-fn-blue) 16%, transparent);
  --c-fn-engineering-tint: color-mix(in srgb, var(--p-fn-green) 16%, transparent);
  --c-fn-configuration-tint: color-mix(in srgb, var(--p-fn-teal) 16%, transparent);
  --c-fn-review-tint: color-mix(in srgb, var(--p-fn-purple) 16%, transparent);
  --c-fn-assurance-tint: color-mix(in srgb, var(--p-fn-rose) 16%, transparent);
  --c-fn-customer-tint: color-mix(in srgb, var(--p-fn-orange) 16%, transparent);
  --c-fn-isvv-tint: color-mix(in srgb, var(--p-fn-slate) 16%, transparent);
  /* The role marks (core/role_marks.js, ui/role_icon.js; the owner, 2026-11-07): each mark's badge in the colour of the part of the
   * organisation it stands for, the same as its role's chip, light and dark through the palette above; the person alone in the
   * secondary ink. Marks, not words: each holds 3:1 on the sheet, the sunk ground and the board in both themes, and always carries its
   * name in words. */
  --c-role-person: var(--p-ink-2);
  --c-role-author: var(--c-fn-engineering);
  --c-role-reviewer: var(--c-fn-review);
  --c-role-approver: var(--c-fn-review);
  --c-role-freezer: var(--c-fn-configuration);
  --c-role-admin: var(--c-fn-management);
  --c-role-owner: var(--c-fn-management);
  --c-role-customer: var(--c-fn-customer);
  --c-role-supplier: var(--c-fn-customer);
  --c-role-verifier: var(--c-fn-isvv);
  --c-role-assurance: var(--c-fn-assurance);
  --c-role-safety: var(--c-fn-assurance);

  /* Learn (views/learn.js, views/practice.js, ui/learn_art.js; 7 Nov 2026): a drawing's tones read through the roles above, so light and
   * dark follow the palette; the practice's banner a warm sandbox ground, never the frame's colours (it is not a moment of a project) */
  --c-art-ok: var(--c-ok);
  --c-art-warn: var(--c-link-suspect);
  --c-art-err: var(--c-err);
  --c-art-base: var(--c-view-baseline);
  --c-art-review: var(--c-life-review);
  --c-art-working: var(--c-life-working);
  --c-art-controlled: var(--c-life-controlled);
  --c-art-proven: var(--c-life-proven);
  --c-art-muted: var(--c-text-muted);
  --c-art-accent: var(--c-accent);
  --c-art-person: var(--c-role-author);
  --c-art-c1: var(--c-fn-engineering);
  --c-art-c2: var(--c-fn-review);
  --c-art-c3: var(--c-fn-configuration);
  --c-art-c4: var(--c-fn-customer);
  --c-learn-sandbox: color-mix(in srgb, var(--p-warn) 9%, var(--c-surface));
  --c-learn-sandbox-edge: color-mix(in srgb, var(--p-warn) 55%, var(--c-border));
  --c-learn-why: color-mix(in srgb, var(--p-accent) 6%, var(--c-surface));
  --c-learn-mistake: color-mix(in srgb, var(--p-refuse) 6%, var(--c-surface));
  --c-learn-task: color-mix(in srgb, var(--p-warn) 8%, var(--c-surface));
  --c-learn-done: color-mix(in srgb, var(--p-ok) 9%, var(--c-surface));
  --c-learn-term-line: color-mix(in srgb, var(--p-accent) 55%, transparent);

  /* a lifecycle reads calm: working and controlled in ink, the review loop in the accent, proof in verdigris, out of the lifecycle
   * receding to the frame grey */
  --c-life-working: var(--p-ink-2);
  --c-life-review: var(--p-accent);
  --c-life-controlled: var(--k-ink);
  --c-life-proven: var(--p-ok);
  --c-life-dead: var(--p-frame);

  --c-verif-pass: var(--p-ok);
  --c-verif-fail: var(--p-refuse);
  --c-verif-blocked: var(--p-warn);
  --c-verif-partial: var(--p-warn);
  --c-verif-stale: var(--p-warn);
  --c-verif-none: var(--p-frame);

  --c-crit-none: var(--p-frame);
  --c-crit-low: var(--p-ink-2);
  --c-crit-medium: var(--k-ink);
  --c-crit-high: var(--p-warn);
  --c-crit-safety: var(--p-refuse);

  --c-diff-added: var(--p-ok);
  --c-diff-removed: var(--p-refuse);
  --c-diff-changed: var(--p-warn);

  --c-link-suspect: var(--p-warn);
  --c-link-retired: var(--p-frame);

  /* the trace clusters (ui/clusters.js; the owner, 7 Nov 2026): a neighbour's state, the proof's verdigris when its link holds and is
   * settled, its tint when linked and not settled, the highlighter's when it waits to be confirmed or its result is stale (dashed), the
   * red pen's when its run failed (heavier), the sheet inside the frame's grey when missing (a dotted connector); the item itself in the
   * specification's ink, solid once controlled. Said in words too: the legend, the item's card. */
  --c-tc-settled: var(--p-cat-proof);
  --c-tc-on-settled: var(--p-on-ok);
  --c-tc-open: var(--p-cat-proof-tint);
  --c-tc-open-edge: var(--p-cat-proof);
  --c-tc-suspect: var(--p-warn-tint);
  --c-tc-suspect-edge: var(--p-warn);
  --c-tc-failed: var(--p-refuse-tint);
  --c-tc-failed-edge: var(--p-refuse);
  --c-tc-missing: var(--k-surface);
  --c-tc-missing-edge: var(--p-frame);
  --c-tc-centre: var(--p-cat-spec);
  --c-tc-centre-tint: var(--p-cat-spec-tint);

  /* plain colours, not mixes: ui/map.js hands them to a canvas. A link's colour is its concept's: derives from (structure) the
   * customer's, designed in the design's, verified by the proof's; justified by in ink-2 (dashed by the map); context ghost. */
  --c-wire-verification: var(--p-cat-proof);
  --c-wire-design: var(--p-cat-design);
  --c-wire-reasoning: var(--p-ink-2);
  --c-wire-structure: var(--p-cat-customer);
  --c-wire-context: var(--p-ghost);
  --o-map-wire: 0.6; /* a wire at rest: crossings darken where the links gather; a lit one is whole (ui/map.js reads it) */
  --o-map-dim: 0.1;
  --o-map-dim-node: 0.28; /* the system's focus mode: what is outside the chain fades to 28 % */
  --o-tmod-recede: 0.18; /* the trace model while one level or relation is pointed at: the rest recedes to 18 %, never out */
  --o-history: 0.6;

  /* the concepts of a figure (the system's cat-* pairs) and the levels (aqua, teal, navy; reversed in dark) */
  --c-cat-customer: var(--p-cat-customer);
  --c-cat-customer-tint: var(--p-cat-customer-tint);
  --c-cat-spec: var(--p-cat-spec);
  --c-cat-spec-tint: var(--p-cat-spec-tint);
  --c-cat-design: var(--p-cat-design);
  --c-cat-design-tint: var(--p-cat-design-tint);
  --c-cat-proof: var(--p-cat-proof);
  --c-cat-proof-tint: var(--p-cat-proof-tint);
  --c-cat-control-tint: var(--p-cat-control-tint);

  --c-wf-lane-alt: color-mix(in srgb, var(--k-ink) 2.5%, transparent);
  --c-wf-proposed: var(--k-surface-2); /* a proposed step: sunk, dashed, with its chip */

  /* People never get personal colours, and a window wears no tone: colour is kept for meaning (the system's PersonCard and AppShell).
   * The eight index tones stay as names (the frame's --k-tone-<n> and the screens still read them), all the secondary ink. */
  --c-tone-1: var(--p-ink-2);
  --c-tone-2: var(--p-ink-2);
  --c-tone-3: var(--p-ink-2);
  --c-tone-4: var(--p-ink-2);
  --c-tone-5: var(--p-ink-2);
  --c-tone-6: var(--p-ink-2);
  --c-tone-7: var(--p-ink-2);
  --c-tone-8: var(--p-ink-2);
  --c-shadow-1: var(--p-shadow-card); /* a card on the board */
  --c-shadow-pop: var(--p-shadow-pop); /* what floats: a menu, the palette, a dialog, the drawer, a tooltip */
  --c-canvas: var(--k-bg);            /* the board, behind the cards */
  --c-frame: var(--p-frame);          /* an outline that carries meaning */
  --c-ok-tint: var(--p-ok-tint);      /* a chip that holds */
  --c-warn-tint: var(--p-warn-tint);  /* a chip to look at again */
  --c-bad-tint: var(--p-refuse-tint); /* a chip refused */
  --c-shadow-btn: none;               /* a control rests flat on its card */
  --c-shadow-accent: none;
  --c-mix-faint: 7%;  /* a mark's ground: ink at a whisper */
  --c-mix-wash: 12%;  /* a tone washed into a sheet */
  --c-mix-chip: 14%;  /* a tone's chip behind its icon */
  --c-mix-veil: 62%;  /* the tutorial's veil over the screen */
  --c-mix-halo: 22%;  /* the halo around what a tutorial step points at */
  --c-mix-edge: 45%;  /* a tone mixed into a rule */
  --c-wash-stop: 72%; /* where a wash has faded into the sheet */

  /* a view that is not current truth (a baseline, a branch): the selection's strong blue, the band says which in words */
  --c-view-baseline: var(--p-select-strong);
  --c-view-branch: var(--p-select-strong);

  --c-tint: 10%;
  --c-tint-soft: 6%;
  --c-tint-edge: 45%;   /* a tone's hairline: the tone mixed into the rule */
  --c-tint-mark: 70%;   /* a mark drawn quieter than its tone: the map's lifecycle bar, a lifecycle box's edge */
  --c-tint-press: 86%;  /* the primary button hovered or pressed: the bar with a little sheet */

  /* --- geometry -------------------------------------------------------------*/

  --g-unit: 0.25rem;
  --g-space-1: calc(var(--g-unit) * 1);
  --g-space-2: calc(var(--g-unit) * 2);
  --g-space-3: calc(var(--g-unit) * 3);
  --g-space-4: calc(var(--g-unit) * 4);
  /* the system's 4 px scale: space-1 4 … space-5 20 (a card's padding), space-6 24, then its space-8 32 and space-10 40 */
  --g-space-5: calc(var(--g-unit) * 5);
  --g-space-6: calc(var(--g-unit) * 6);
  --g-space-7: calc(var(--g-unit) * 8);
  --g-space-8: calc(var(--g-unit) * 10);

  /* chips, inputs and drawing boxes; buttons, callouts, stat cards and segmented controls; cards and the header; toggles and dots */
  --g-radius-sm: 0.375rem;
  --g-radius-md: 0.625rem;
  --g-radius-lg: 0.875rem;
  --g-radius-pill: 999px;
  --g-border: 1px;
  --g-border-strong: 2px;
  --g-border-frame: 3px;
  --g-halo: 3px;
  --g-focus-ring: 2px;
  --g-focus-offset: 2px; /* the ring stands clear of the control */

  --g-row-compact: 1.875rem; /* 30 px: the default since 0.63.0 */
  --g-row-normal: 2.5rem; /* a table row: 10 px, a 20 px line, 10 px */
  --g-row-comfy: 2.75rem;
  --g-row-card: 4.75rem; /* a row as a card on a phone: three lines at the interface size */
  --g-row: var(--g-row-normal);

  --g-control-h: 2.25rem; /* a button: 8 px, a 20 px line, 8 px */
  --g-icon-sm: 0.875rem;
  --g-icon-md: 1.125rem;

  --g-topbar-h: 3.5rem;
  --g-statusbar-h: 1.75rem;
  --g-inspector-w: 25rem; /* the details drawer laid over a screen (ui/drawer.js) */
  /* The one layout (css/layout.css "the side column and the sheet", ui/split.js; the owner, 2026-11-07: "enforce the frontend's
   * infrastructure! so we fix the things once forever"): a side column is as wide as its content, its entries on one line, up to a share
   * of what holds it (cqi: of the frame, of a split); a person drags it between the least and the most; a sheet takes the width it is
   * given, its paragraphs alone held to a reading measure (the owner, 2026-11-06: "paragraphs flowing to ~110–130ch"). */
  --g-side-share: 30cqi;
  --g-side-max: 60cqi; /* the widest a person drags a side column (ui/split.js SIDE.MAX_SHARE is the same share) */
  --g-side-min: 10rem; /* the narrowest */
  --g-split-main-min: 24rem; /* the main column's least width beside a side: below it the side goes above it */
  --g-prose-measure: 120ch; /* a paragraph's longest line in a sheet; headings, tables, code and figures take the sheet's width */
  --g-pane-edge-w: 0.375rem; /* the band one drags a side column's edge by */
  --g-pane-reopen-w: 1.25rem; /* the tab on the frame's edge that shows a hidden pane again */
  --g-pane-reopen-h: 3.5rem;
  --g-text-measure: 72ch; /* long prose only (the workflow pages, a diff of a body, a form or a dialog): interface text flows to its box (the owner, 2026-10-31) */
  --g-frame-h: 100dvh; /* the frame fills the shell's content column, top to bottom: the bars stay on the screen's edges */
  --g-frame-h-phone: calc(100dvh - 56px - env(safe-area-inset-top, 0px)); /* under the shell's phone top bar (its 56 px) */
  --g-page-pad: var(--g-space-5); /* a screen's margin: the head band and the sheet share it */
  --g-page-pad-narrow: var(--g-space-4); /* 16 px at the phone's root size */
  --g-facts-key-w: 11rem; /* the key column of an item's facts */
  --g-frame-min-h: 30rem;
  --g-frame-min-w: 22.5rem;
  --g-menu-w: 16rem;
  --g-modal-w: 34rem;
  --g-modal-fit: min(var(--g-modal-w), calc(100vw - var(--g-space-6)));
  --g-modal-wide-fit: calc(100vw - var(--g-space-6)); /* a sheet of rules or a pass (0.64.0): the window less its gutter, as the file viewer */
  --g-palette-w: 40rem;
  --g-palette-fit: min(var(--g-palette-w), calc(100vw - var(--g-space-6)));
  --g-palette-top: 12vh;
  --g-palette-list-h: 50vh;
  --g-select-w: 18rem;
  --g-pick-w: 28rem;
  --g-hairline: 1px;
  --g-clip-all: inset(50%);
  --g-drawer-w: 85%;
  --g-sheet-h: 62%;
  --g-mx-case-max: 34rem; /* a case's id in the matrix: one line, … past this */ /* the details drawer on a narrow frame: a sheet over the lower part, the work still in sight above it */
  --g-col-id: 9rem;
  --g-mono-advance: 0.6; /* a mono character's width in its em (IBM Plex Mono, JetBrains Mono: 600/1000): an ID's column fits it whole */
  --g-col-kind: 9rem;
  --g-col-state: 10.5rem; /* a state chip in mono, "needs-rework" whole */
  --g-col-method: 7rem;
  --g-col-proof: 9rem; /* a proof chip, "no passing run" whole */
  --g-col-fill-min: 12rem; /* the title's least width in a table */
  --g-col-flag: 2rem;
  --g-textarea-max: 70vh; /* a text box grows with its text up to this, then scrolls */
  --g-col-when: 9.5rem; /* a date and time, "2026-10-30 01:47" whole */
  --g-tree-indent: 1rem;
  --g-about-max: 72rem;
  --g-about-measure: 44rem;
  --g-about-point-min: 15rem;
  --g-about-v-min: 36rem; /* the visitor's V never narrower: on a phone it scrolls inside its box */
  --g-about-pad-x: clamp(1rem, 4vw, 3rem);
  --g-about-pad-y: clamp(2.5rem, 7vw, 6rem);
  --g-mark: 1.375rem;
  /* the acting trace graph (docs/VIEWS_PLAN.md V-2): a column's least width, the map's (five columns and their gaps), a link's stroke
   * and the halo under it that keeps it legible across boxes (the design system's TraceMap), a column's swatch */
  --g-tm-col-min: 10rem;
  --g-tm-min: 56rem;
  --g-tm-link: 1.5px;
  --g-tm-halo: 5px;
  --g-tm-swatch: 0.75rem;
  /* the trace clusters (ui/clusters.js): a molecule's least width (the field takes as many across as fit), its strokes in the drawing's
   * own units, a mark's size there, the dashes, the lift under the pointer, a legend's card, a selected item's molecule, the bar */
  --g-tc-cell: 7.5rem;
  --g-tc-cell-max: 9.5rem; /* a molecule no larger than this however few share a row */
  --g-tc-group-h: 40rem; /* a group's height before it is first laid out (out of sight) */
  --g-tc-edge: 1.25px;
  --g-tc-edge-strong: 2.5px;
  --g-tc-wire: 1.5px;
  --g-tc-mark: 10px;
  --g-tc-dash: 3 2;
  --g-tc-dot: 1 2.5;
  --g-tc-lift: 1.05;
  --g-tc-rise: -2px;
  --g-tc-key-w: 1.6rem;
  --g-tc-pick-mol: 3.25rem;
  --g-tc-bar-w: 9rem;
  --g-tc-side-h: calc(100dvh - var(--g-topbar-h) - var(--g-statusbar-h) - var(--g-space-6));
  --g-tc-arrive: 4px;
  --g-tc-slide: 8px;
  /* the cards all around (ui/popup.js): their width, their height before they scroll, how far they grow in */
  --g-pop-w: 26rem;
  --g-pop-max-h: 70vh;
  --g-pop-from: 0.97;
  /* the trace model (ui/trace_model.js): a relation's line as thick as its links are many, by powers of four (weightOf), its dash where
   * the rules allow it and nobody uses it; an item at a glance (ui/quick_info.js): a pip of so many of so many */
  --g-tmod-w0: 1.25px;
  --g-tmod-w1: 2px;
  --g-tmod-w2: 3px;
  --g-tmod-w3: 4.25px;
  --g-tmod-w4: 5.5px;
  --g-tmod-w5: 7px;
  --g-tmod-dash: 4 5;
  --g-tmod-dot: 1 4;
  --g-tmod-ring: 3.5px;
  --g-qi-pip: 0.5rem;
  --g-window-h: 100dvh;
  --g-underline-offset: 0.18em;
  --g-map-min-h: 26rem;
  --g-find-w: 16rem;
  --g-find-min: 10rem; /* the Items search narrows to this before its bar wraps */
  --g-map-head-h: 3.5rem;
  --g-map-view-h: calc(var(--g-window-h) - var(--g-topbar-h) - var(--g-statusbar-h) - var(--g-map-head-h) - var(--g-space-7)); /* the map never shorter than the screen holds under the bars */
  --g-map-wire: 1.25px;
  --g-map-wire-lit: 2.25px;
  --g-map-pulse-w: 4px;
  --g-map-dash: 5 4;
  --g-map-dot: 1.5 3;
  --g-map-swatch-w: 1.75rem;
  --g-map-swatch-h: 3px;
  --g-map-tip-w: 26rem;
  --g-home-card-min: 12rem; /* a head card's least width before the cards wrap */
  --g-wf-link-h: 1.75rem; /* the row of an arrow between two steps */
  --g-wf-link-h-narrow: 0.875rem;
  --g-wf-mark-h: 1.5rem; /* the start and end marks' rows */
  --g-wf-wire: 1.25px;
  --g-wf-step-gap: 0.625rem; /* a step's margin inside its lane */
  --g-wf-swatch-w: 1.5rem;
  --g-wf-term-w: 14rem;
  --g-wf-hit: 12px; /* the clear line over a lifecycle's arrow that takes the pointer (Workflows) */
  /* the check sheet (ui/verdict.js), the workbench's figures (ui/tiles.js), a table's use (ui/gauge.js), the studio's matrix */
  --g-stamp-w: 15rem; /* the verdict's cell, as a title block's check box */
  --g-move-path-w: 15rem;
  --g-move-answer-w: 17rem;
  --g-move-checks-min: 16rem; /* the checks' least width beside the move: narrower, they take their own line under it */
  --g-rules-col-w: 5.5rem; /* a team's column in Who works on what: its name wraps, never wider */
  --g-rules-role-w: 4.25rem; /* a role's column in the rules' grid: its longest word ("assurance") whole, its name wrapping at its spaces */
  --g-table-max-h: 75vh;
  /* a column's width the person sets (ui/colsize.js): the band on a head's right edge one drags, the line it shows, the least width */
  --g-colsize-w: 0.5rem;
  --g-colsize-line: 2px;
  --g-colsize-min: 3rem;
  --g-docs-name-w: 22rem; /* the documents room's name column: its share before the person sets one, its least */
  --g-docs-name-min: 14rem;
  --g-tour-card-w: 24rem; /* the tutorial's card */
  /* Learn: a drawing's height at most (its width is the sheet's), its words in its own units, the demonstration's pointer and its move,
   * the ring a step points with, a lesson's step number */
  --g-art-max-h: 17rem;
  --g-art-font: 13px;
  --g-art-small: 11.5px;
  --g-art-stroke: 2px;
  --g-art-ring: 2.5px;
  --g-show-pointer: 1.375rem;
  --g-show-press: 2.25rem;
  --g-learn-ring-w: 3px;
  --g-learn-step-n: 1.75rem;
  --g-learn-bar-h: 0.375rem;
  --g-learn-bar-w: 4.5rem;
  --g-learn-words-min: 26rem; /* a step's words beside its drawing: below this the drawing goes under them */
  --g-learn-art-min: 24rem;
  --g-learn-term-min: 34rem; /* a term of the glossary: two or three abreast on a wide sheet */
  --g-term-offset: 0.2em;
  --g-motion-show: 420ms; /* the demonstration's pointer crossing the screen: long enough for the eye to follow it */
  --g-flow-doc-w: 15rem; /* a document of the flowdown */
  /* the Log (views/audit.js): a row's room before it is drawn, the timeline's 24 hours, its mark, its column's height under the bars, and
   * two of its marks' shapes */
  --g-log-row: 2.125rem;
  --g-log-tl-strip: 15rem;
  --g-log-tl-mark: 0.625rem;
  --g-log-tl-day: 4.5rem; /* a day of the timeline before it is drawn */
  --g-log-tl-h: calc(var(--g-window-h) - var(--g-topbar-h) - var(--g-statusbar-h) - var(--g-space-8));
  --g-log-tri: polygon(50% 0, 100% 100%, 0 100%);
  --g-log-hex: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
  /* the Activity (views/activity.js): a milestone's time of day, the column of the axis its mark stands on, the mark, the room a day
   * takes before it is drawn, a figure's least width in the status strip */
  --g-act-at: 3.25rem;
  --g-act-axis: 1.75rem;
  --g-act-mark: 0.875rem;
  --g-act-day: 6rem;
  --g-act-st-min: 10rem;
  --g-act-part-min: 18rem; /* a list of a milestone's drop-down: below it the lists stack */
  --t-size-hero: clamp(3.2rem, 10vw, 6.5rem); /* the visitor page's big name */
  --g-about-mark-big: 0.8em; /* the visitor page's mark beside the big name */
  --g-about-node-w: 8rem; /* the programme tree's level names */
  --g-crowd-card-w: 17rem; /* a person's card, people across projects */
  --g-crowd-room-w: 19rem; /* a project's box with its people inside */
  --g-crowd-wire-rest: 0.75;
  --g-crowd-wire-dim: 0.12;
  --g-pmap-max-h: calc(100dvh - 12rem); /* People's map: the window's height less the bars and the page's head */
  --g-pmap-wire-dense: 0.32; /* People's map past its DENSE arrows: the resting ones quiet */
  --g-zp-max-h: calc(100dvh - 12rem); /* a drawing's window (ui/zoom_pan.js): the screen's height less the bars and the page's head */
  --g-zp-min-h: 12rem; /* the least a drawing's window is tall, however short the drawing */
  --g-family-far-key: 30px; /* the projects' Map under FAMILY.FAR, in the drawing's own units: ten pixels and more down to a scale of 0.46 */
  --g-family-far-name: 22px;
  --g-family-far-state: 22px;
  --g-family-far-label: 22px;
  --g-hc-meter-w: 3rem; /* a measure's meter in a table cell */
  --g-hc-meter-h: 0.375rem;
  --g-hc-dot: 0.625rem; /* a dumbbell's dot */
  --g-hc-row-h: 1.5rem;
  --g-hc-label-w: 9rem; /* a dumbbell's row label (a key or a name) */
  --g-health-chart-min: 22rem; /* a week chart's least width before the three wrap */
  --g-shape-min: 15rem; /* a card of Ways to look at this project */
  --g-shape-h: 5.5rem;
  --g-work-head-h: 1.75rem; /* the first head row of Who works on what, where its second sticks */ /* a wide table's own box: its head stays on top inside it */
  --g-rules-dot: 0.625rem; /* the dot of a right a role holds */
  --g-rules-right-w: 1%; /* the rights' column: as narrow as its words let it */
  --g-grant-list-h: 16rem; /* the grant dialog's list of people, scrolled past it */
  --g-grant-role-w: 11rem; /* a role's box in the grant dialog */
  --g-vee-max-w: 58rem; /* the V over the map: as wide as reads, no wider */
  --g-signed-rev-w: 4rem;
  --g-gauge-w: 10rem;
  --g-gap-next-w: 9.5rem;
  --g-chain-card-w: 12.5rem; /* a card of the path's chain (ui/chain.js) */
  --g-chain-link-w: 7.5rem; /* the link between two cards */
  --g-assistant-w: 24rem; /* the set-up's assistant, docked beside the drawing (ui/assistant.js) */
  --g-pieces-max: 52rem; /* the pieces and arrows at their drawn size (ui/pieces.js); the whole window lets them grow */
  /* the hub and the redesign of 2026-10-28 */
  --g-sheet-radius: var(--g-radius-lg);
  --g-tile-h: 8.75rem;   /* a tile's least height */
  --g-tone-chip: 2.25rem; /* a window's icon chip */
  --g-tone-bar: 3px;     /* a window's tone on its edge */
  --g-figure: 2rem;      /* a tile's figure */
  --g-title-xl: 2rem; /* the one title of a screen: display, 32/38 */
  --g-title-xl-narrow: 1.625rem; /* under 720 px: 26/32 */
  --g-pad-chip-y: 0.1875rem; /* 3 px, a chip's */
  --g-pad-btn-x: 0.875rem;  /* 14 px, a button's */
  --g-pad-tab-y: 0.375rem;  /* 6 px, a tab's and a menu row's */
  --g-pad-tab-x: 0.625rem;  /* 10 px, a menu row's */
  --g-stat-min: 11rem;      /* a figure cell's least width: "✓ 39 / 39" whole, two across on a phone */
  --g-meter-h: 0.375rem;
  --g-menu-w-max: 20rem;
  --g-lede: 78ch;
  --g-count: 3.75rem; /* a big number in a side panel */
  --g-dot: 0.875rem; /* a person's dot */
  --g-role-icon: 1.3em; /* a role's mark: the person and its badge, sized to the words it sits among (14 to 17 px) */
  --g-role-icon-tag: 1.45em; /* in a role's chip, whose words are small */
  --g-role-icon-btn: 1.2em; /* inside an action, after its words */
  --g-role-icon-lg: 1.5rem; /* a role's mark heading a column of the rights or the legend */
  --g-role-icon-drop: -0.28em; /* a mark in running text sits on the words' baseline */
  --g-role-stroke: 1.8; /* the person's stroke in the 24-unit drawing */
  --g-role-badge-stroke: 2.1; /* the badge's, a little heavier so it reads at 14 px */
  --g-fchip-w: 24rem; /* a chip's sheet */
  --g-mark-legend-col: 22rem; /* a column of the marks' legend */
  --g-dot-lg: 1.875rem; /* a person's dot with their initial: the system's 30 px avatar */
  --g-eyebrow-track: 0.01em; /* labels are sentence case: the system never sets a label in capitals */
  --g-side-line: 30ch;
  --g-viewpick-w: 26rem; /* the view selector's list */
  --g-recap-base-w: 22rem;
  --g-pm-panel-w: 19rem;
  --g-life-people-w: 14rem; /* who holds a right, under a lifecycle */   /* the project map's panel: what the piece picked is */
  /* a project's lifecycle (ui/spaces.js): a space's node on the spine and its glyph, the spine, the gauge (its width, its bar, a review's
   * diamond, a rung's disc), how far a node grows under the pointer, how quiet the other rows go; the bar's in-work part, ink-2 washed so
   * it stands apart; controlled in the selection's strong blue, proven in verdigris; the ground of the space the project stands in */
  --g-space-node: 2.5rem;
  --g-space-glyph: 1.375rem;
  --g-space-spine: 2px;
  --g-space-gauge-w: clamp(11rem, 16cqi, 20rem); /* of the list's width: wider on a wide window, the bar reading finer */
  --g-full: 100%;
  --g-space-bar-h: 0.5rem;
  --g-space-pip: 0.625rem;
  --g-space-rung: 1.125rem;
  --g-space-lift: 1.08;
  --o-space-quiet: 0.62;
  --c-space-working: color-mix(in srgb, var(--p-ink-2) 38%, transparent);
  --c-space-review: var(--p-accent);
  --c-space-controlled: color-mix(in srgb, var(--p-select-strong) 72%, transparent);
  --c-space-proven: var(--p-ok);
  --c-space-here: color-mix(in srgb, var(--p-select) 40%, transparent);
  --g-col-wide: 30rem;   /* a column of a two-up grid */
  --g-col-board: 44rem;  /* a column of rows beside another (Changes): side by side only where each row's title fits whole */
  --g-col-mid: 26rem;
  --g-col-narrow: 18rem;
  --g-popover-fit: calc(100vw - var(--g-space-6));
  --g-list-max-h: 70vh;
  --g-round: 50%;
  --g-half: 50%; /* the middle of a box: where the timeline's rule meets a dot (ui/review_line.js) */

  --g-z-sticky: 2;
  --g-z-stack: 3;     /* a screen's sticky stack under its tabs (the Activity's bar): over what sticks inside a list (--g-z-sticky) */
  --g-z-stack-top: 4; /* the stack's first, the home's tabs: over the bar that sticks under them */
  --g-zero: 0px;      /* a length of none: a sticky stack's part before it is measured */
  --g-z-drawer: 20;
  --g-z-full: 40; /* over the shell's fixed rail (its 30): the whole window */
  --g-z-menu: 50; /* a menu opened from anywhere, the full view included */
  --g-z-tour: 60; /* the tutorial: over everything, a menu included */
  --g-z-popover: 30;

  --g-motion-fast: 150ms; /* short opacity or colour fades; nothing slides */
  --g-motion-base: 200ms;
  --g-ease: cubic-bezier(0.4, 0, 0.2, 1);
  --g-motion-pulse: 2000ms; /* core/map.js MAP.PULSE_MS */

  /* --- type -----------------------------------------------------------------*/

  /* IBM Plex Sans for the whole interface, IBM Plex Mono for everything literal; no serif, no condensed, nothing in capitals. */
  --t-sans: var(--k-font-ui);
  --t-mono: var(--k-font-mono);
  --t-title: var(--k-font-ui);   /* headings are the interface's face at 600, tracked in slightly */
  --t-size-tag: 0.71875rem;      /* tag: chips, 11.5/16 mono */
  --t-size-xs: 0.75rem;          /* label: field labels, table heads, 12/16 */
  --t-size-sm: 0.8125rem;        /* small: descriptions, captions, code and IDs, 13/20 */
  --t-size-base: 0.875rem;       /* the interface: tables, buttons, navigation, 14/20 */
  --t-size-md: 0.9375rem;        /* body and subheading, 15/24 and 15/22 */
  --t-size-lg: 1.0625rem;        /* heading: a card's title, 17/24 */
  --t-size-xl: 1.375rem;         /* title: a section's, 22/28 */
  --t-size-metric: 1.75rem;      /* metric: a stat's number, mono 28/32 */
  --t-size-display: 2rem;        /* display: the one title of a screen, 32/38 */
  --t-track-title: -0.01em;
  --t-track-display: -0.02em;
  --t-weight-regular: 400;
  --t-weight-medium: 500;
  --t-weight-semibold: 600;
  --t-lh-tight: 1.1875;          /* 38/32 */
  --t-lh-heading: 1.4118;        /* 24/17 */
  --t-lh-base: 1.4286;           /* 20/14 */
  --t-lh-small: 1.5385;          /* 20/13 */
  --t-lh-text: 1.6;              /* 24/15, running text up to 72ch */
  --t-track-mono: 0;
}

/* Density is the user's, on the frame (views/index.js persists it as kyr_rms_density; keys 1 2 3). Compact is the default since 0.63.0
 * (the owner, 2026-11-02, of the proposal's Items picture: "even the view like THIS is looking way more professional than it is right
 * now!"): the interface at 13 px, rows of 30 px, controls of 28 px, a screen's title at 17 px on one line with its actions, the panes and
 * the page's margins tighter. Normal is the earlier measure (14 px, rows of 40), comfy wider rows still. Only the frame's own tokens move;
 * what a drawing measures in its own units does not. */
.rms-app[data-density="compact"] {
  --g-row: var(--g-row-compact);
  --g-control-h: 1.75rem;
  --g-topbar-h: 2.75rem;
  --g-inspector-w: 20rem;
  --g-col-id: 8.5rem;
  --g-col-kind: 7.5rem;
  --g-col-state: 8rem;
  --g-col-method: 6rem;
  --g-col-proof: 7.5rem;
  --g-col-fill-min: 10rem;
  --g-page-pad: var(--g-space-4);
  --g-pad-btn-x: 0.625rem;
  --g-pad-tab-y: 0.25rem;
  --g-pad-tab-x: 0.5rem;
  --g-tile-h: 6.5rem;
  --g-stat-min: 9.5rem;
  --g-figure: 1.5rem;
  --g-title-xl: 1.0625rem;
  --g-title-xl-narrow: 1.0625rem;
  --t-size-tag: 0.6875rem;
  --t-size-xs: 0.6875rem;
  --t-size-sm: 0.75rem;
  --t-size-base: 0.8125rem;
  --t-size-md: 0.8125rem;
  --t-size-lg: 0.9375rem;
  --t-size-xl: 1.0625rem;
  --t-size-metric: 1.375rem;
  --t-size-display: 1.25rem;
  --t-lh-text: 1.5;
}
.rms-app[data-density="comfy"] { --g-row: var(--g-row-comfy); }

@media (prefers-reduced-motion: reduce) {
  :root {
    --g-motion-fast: 0ms;
    --g-motion-base: 0ms;
    --g-motion-pulse: 0ms;
    --g-motion-show: 0ms;
  }
}
