/* Oraclizer research figure kit (rfig).
 *
 * One stylesheet for every figure on research.oraclizer.io. It inherits the docs figure kit
 * (Web/Docs/src/app/figure-kit.css, root class `ofig`): a pale sheet in a hairline frame with corner
 * ticks, small-caps labels in Space Grotesk, square markers, solid connectors, parts named by meaning,
 * one markup that reflows on the figure's own width, and both themes drawn from variables.
 *
 * What research adds to docs: a palette of eight hues and a four-step level ramp (S0 to S3 and other
 * ordered steps), tinted and solid grounds, a large display glyph, formulas set in a math face, a
 * soft wash on the sheet and a soft shadow on the node a figure is about.
 *
 * A figure is plain markup with these classes: no <style>, no <script>, no colours. A hue or level
 * class (`rfig-hue-coral`, `rfig-lv3`, `rfig-tone-neg`) on any element sets the local hue variables
 * (--rf-h, --rf-h-text, --rf-h-tint, --rf-h-deep) that every part inside it reads. Per-figure layout
 * goes through the custom properties listed in research-figure-kit-rules.md.
 *
 * No box in the kit carries a coloured edge on its left side. Notes that read a figure are glosses
 * (a ruled band with a head cell), emphasis is a step in tone, weight or a chip with words, and the
 * only vertical lines are axes that carry order: the ladder rail, a narrow time axis, lifelines.
 *
 * Figures use div and span (with ARIA roles where list or table semantics matter), never p, ul, li,
 * table or headings, so the article prose styles cannot reach into them. Every text colour here
 * passes 4.5:1 on its ground in both themes; every marker, stripe and arrow that carries meaning
 * passes 3:1. Rules for the people drawing figures: research-figure-kit-rules.md next to this file.
 *
 * Relations are drawn, not described: labelled links that touch the boxes they join (.rfig-link),
 * parallel links, forks and joins over a row that never collapses (.rfig-links, .rfig-row), stair
 * bars stepping down to a reference line (.rfig-stairs), bars with a line (.rfig-bars--line), value
 * axes with ticks and gridlines on both (.rfig-stairs__axis, .rfig-bars__axis), a banded gauge
 * (.rfig-gauge), a four-step flow that wraps into two rows (.rfig-flow--wrap), a dashed region
 * boundary (.rfig-group--dash), a label with chips beside it (.rfig-chipline), a wide and a narrow
 * version of one part (.rfig-wide, .rfig-narrow) and a matrix that stays a matrix on phones. Filled
 * marks (bars, solid swatches, solid SVG shapes, solid nodes and tags) all use the hue's deep value,
 * which passes 3:1 against the sheet and the node in both themes.
 *
 * Type has one table (rules 0.1): eight roles (label, lede, name, body, small, value, math, code) and
 * the caption's two, each one face, size, weight, tracking and case in the --rfig-t-* tokens on .rfig.
 * One rule per role lists the parts that take it; no part sets a size of its own, and emphasis is one
 * step of weight and colour. SVG words take the same roles as classes (t-label, t-name, t-body, t-small,
 * t-value, t-math, t-sub, t-sup) in user units, a wide drawing being 640 units drawn at 640px. */

/* ---------- Tokens: light (default) ---------- */

.rfig {
  /* Neutrals: the company tokens of oraclizer.io. */
  --rfig-ink: #07101d;
  --rfig-ink-soft: #314056;
  --rfig-muted: #59677b;
  --rfig-sheet: #f7faff;                 /* homepage diagram ground */
  --rfig-node: #ffffff;
  --rfig-frame: #c5d1e3;
  --rfig-hair: #dce3ee;
  --rfig-faint: #8ea0bb;                 /* corner ticks, absent markers */
  --rfig-wash: rgba(36, 115, 255, 0.075);
  --rfig-shadow: 0 1px 2px rgba(7, 16, 29, 0.05), 0 14px 30px -20px rgba(7, 16, 29, 0.34);
  --rfig-on: #ffffff;                    /* text on a solid (deep) ground */

  /* The brand night field, for bands and callouts that stand apart from the sheet. */
  --rfig-night: #0b111b;
  --rfig-night-ink: #edf2f9;
  --rfig-night-soft: #c0cad8;
  --rfig-night-line: rgba(221, 235, 255, 0.16);
  --rfig-night-blue: #8fb4fb;
  --rfig-night-cyan: #5bdcf3;

  /* Eight hues. solid: lines, markers, stripes (3:1 on the sheet). text: words in the hue (4.5:1 on
     the sheet, a node and the tint). tint: pale ground. deep: ground behind white text (4.5:1). */
  --rfig-blue: #2473ff;
  --rfig-blue-text: #0758d2;
  --rfig-blue-tint: #eaf1ff;
  --rfig-blue-deep: #0758d2;
  --rfig-cyan: #0b93b0;
  --rfig-cyan-text: #09647a;
  --rfig-cyan-tint: #e2f6fa;
  --rfig-cyan-deep: #09647a;
  --rfig-mint: #15976c;
  --rfig-mint-text: #0b7151;
  --rfig-mint-tint: #e2f5ed;
  --rfig-mint-deep: #0b7151;
  --rfig-amber: #c27a00;
  --rfig-amber-text: #8a5200;
  --rfig-amber-tint: #fdf1da;
  --rfig-amber-deep: #8a5200;
  --rfig-coral: #e2553d;
  --rfig-coral-text: #b1351f;
  --rfig-coral-tint: #fdece8;
  --rfig-coral-deep: #b1351f;
  --rfig-violet: #7a5cf0;
  --rfig-violet-text: #5a3dcc;
  --rfig-violet-tint: #f0edff;
  --rfig-violet-deep: #5a3dcc;
  --rfig-indigo: #3d3fd0;
  --rfig-indigo-text: #3134b0;
  --rfig-indigo-tint: #ecedff;
  --rfig-indigo-deep: #3134b0;
  --rfig-slate: #7a89a0;
  --rfig-slate-text: #4f5d72;
  --rfig-slate-tint: #eef2f7;
  --rfig-slate-deep: #4f5d72;
  --rfig-ink-deep: #07101d;
  /* Ink's pale ground: a neutral fill for ink bars, gauge bands and boxes, apart from the white node and the
     sheet (an ink stair on a white box reads as filled, not hollow; 2026-10-17). */
  --rfig-ink-tint: #e9edf3;

  /* Faces. The site defines --display, --body and --mono; the fallbacks keep a figure readable alone. */
  --rfig-display: var(--display, "Space Grotesk Variable", "Space Grotesk", system-ui, sans-serif);
  --rfig-body: var(--body, "Manrope Variable", "Manrope", system-ui, sans-serif);
  --rfig-mono: var(--mono, ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace);
  /* Formulas: the KaTeX faces the article formulas use, upright parts in KaTeX_Main and italic variables in
     KaTeX_Math, as KaTeX sets them; an installed math face stands in where the page has no KaTeX faces. */
  --rfig-mathface: "KaTeX_Main", "KaTeX_Math", "Cambria Math", "STIX Two Math", "Latin Modern Math", serif;
  --rfig-varface: "KaTeX_Math", "KaTeX_Main", "Cambria Math", "STIX Two Math", "Latin Modern Math", serif;

  /* Type roles (rules 0.1). Each role is one face, size, weight, tracking and case; the rules in "Type: one
     role table" are the only readers. Sizes are px at 1440; SVG classes use the same numbers in user units. */
  --rfig-t-label-family: var(--rfig-display);
  --rfig-t-label-size: 12px;
  --rfig-t-label-weight: 700;
  --rfig-t-label-track: 0.12em;
  --rfig-t-label-case: uppercase;
  --rfig-t-lede-family: var(--rfig-body);
  --rfig-t-lede-size: 15px;
  --rfig-t-lede-weight: 400;
  --rfig-t-name-family: var(--rfig-display);
  --rfig-t-name-size: 15px;
  --rfig-t-name-weight: 600;
  --rfig-t-body-family: var(--rfig-body);
  --rfig-t-body-size: 14px;
  --rfig-t-body-weight: 400;
  --rfig-t-small-family: var(--rfig-body);
  --rfig-t-small-size: 13px;
  --rfig-t-small-weight: 500;
  --rfig-t-value-family: var(--rfig-display);
  --rfig-t-value-size: 22px;
  --rfig-t-value-weight: 600;
  --rfig-t-value-track: -0.01em;
  --rfig-t-math-family: var(--rfig-mathface);
  --rfig-t-math-var-family: var(--rfig-varface);
  --rfig-t-math-size: 15px;
  --rfig-t-math-weight: 400;
  --rfig-t-code-family: var(--rfig-mono);
  --rfig-t-code-size: 13px;
  --rfig-t-code-weight: 500;
  --rfig-t-cap-family: var(--rfig-body);
  --rfig-t-cap-size: 14px;
  --rfig-t-cap-weight: 600;
  --rfig-t-capnum-family: var(--rfig-display);
  --rfig-t-capnum-size: 13px;
  --rfig-t-capnum-weight: 600;
  --rfig-t-capnum-track: 0.1em;
  --rfig-t-capnum-case: uppercase;
  /* Roles without their own tracking or case use these. */
  --rfig-t-track: 0;
  --rfig-t-case: none;
  /* Emphasis: one step of weight (400 to 600) and colour, never size. A label keeps its 700. */
  --rfig-t-emw: 600;
  /* Sub- and superscripts: 0.72 of their line (SVG t-sub, t-sup). A subscript sits 3 units under the baseline; a
     superscript rises a third of its line, as HTML sup does, so 7ⁿ in a 22-unit value line still reads as a power
     (the script is 0.72 of its line: a third of the line is 0.463 of the script's own em). */
  --rfig-t-script: 0.72em;
  --rfig-t-sub-shift: 3px;
  --rfig-t-sup-shift: 0.463em;

  --rfig-pad: clamp(16px, 3.4cqi, 30px);

  /* The active hue: blue unless a hue or level class says otherwise. */
  --rf-h: var(--rfig-blue);
  --rf-h-text: var(--rfig-blue-text);
  --rf-h-tint: var(--rfig-blue-tint);
  --rf-h-deep: var(--rfig-blue-deep);

  /* The ground under a part: marks that must hide a line behind them (a gate diamond, a halo around
     SVG words) fill with it. Boxes set it to their own ground. */
  --rf-ground: var(--rfig-sheet);
}

.rfig-node,
.rfig-rung,
.rfig-stage {
  --rf-ground: var(--rfig-node);
}

.rfig-node--tint,
.rfig-panel,
.rfig-layer,
.rfig-rung--key {
  --rf-ground: var(--rf-h-tint);
}

.rfig-node--solid {
  --rf-ground: var(--rf-h-deep);
}

.rfig-panel--night,
.rfig-band {
  --rf-ground: var(--rfig-night);
}

/* ---------- Tokens: dark ---------- */

/* The site switches theme with <html data-theme="dark">; a preview may set it on any ancestor. */
[data-theme="dark"] .rfig {
  --rfig-ink: #edf2f9;
  --rfig-ink-soft: #c0cad8;
  --rfig-muted: #8c99ab;
  --rfig-sheet: #0c131f;
  --rfig-node: #121b2a;
  --rfig-frame: rgba(221, 235, 255, 0.22);
  --rfig-hair: rgba(221, 235, 255, 0.12);
  --rfig-faint: rgba(221, 235, 255, 0.34);
  --rfig-wash: rgba(91, 140, 255, 0.11);
  --rfig-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 16px 32px -20px rgba(0, 0, 0, 0.8);

  --rfig-night: #060a11;
  --rfig-night-line: rgba(221, 235, 255, 0.14);

  --rfig-blue: #5b8cff;
  --rfig-blue-text: #8fb4fb;
  --rfig-blue-tint: #13213b;
  --rfig-blue-deep: #3366e6;
  --rfig-cyan: #3cc8e6;
  --rfig-cyan-text: #6fd6ea;
  --rfig-cyan-tint: #0c2630;
  --rfig-cyan-deep: #0d7e98;
  --rfig-mint: #3fcf98;
  --rfig-mint-text: #75e3b0;
  --rfig-mint-tint: #0d2a21;
  --rfig-mint-deep: #0f7f5b;
  --rfig-amber: #f0a63a;
  --rfig-amber-text: #ffba66;
  --rfig-amber-tint: #2a1f0e;
  --rfig-amber-deep: #9a5d00;
  /* Deep values on the dark sheet sit between 3.15:1 against the node and 4.6:1 under white text:
     a filled mark stays visible and white words on it stay readable (2026-10-17). */
  --rfig-coral: #f07a62;
  --rfig-coral-text: #f59c87;
  --rfig-coral-tint: #2d1612;
  --rfig-coral-deep: #ba3f28;
  --rfig-violet: #9c87ff;
  --rfig-violet-text: #b9a9ff;
  --rfig-violet-tint: #1c1838;
  --rfig-violet-deep: #6b52db;
  --rfig-indigo: #7d84ff;
  --rfig-indigo-text: #a9adff;
  --rfig-indigo-tint: #171a3a;
  --rfig-indigo-deep: #5c5fde; /* 2026-10-17: 3:1 on the darkest node ground (19,33,59), white text 4.76:1 */
  --rfig-slate: #76859c;
  --rfig-slate-text: #a9b5c6;
  --rfig-slate-tint: #151d2a;
  --rfig-slate-deep: #5a6b83;
  --rfig-ink-deep: #556b8d;
  /* Darker than the node, not lighter: the deep values sit only about 3.15:1 above the node, so a lighter ink ground
     would drop a deep mark on it (an ink stair top, a coral bar in an ink box) under 3:1. On #0a1019 they keep 3.48:1
     and more, and the ground still reads as a fill, one step below the node (2026-10-17 trial of four values). */
  --rfig-ink-tint: #0a1019;
}

/* ---------- Hues, levels and tones ---------- */

/* Categorical hues: one meaning per hue inside a figure, named in the figure's own words. */
.rfig-hue-blue,
.rfig-lv2 {
  --rf-h: var(--rfig-blue);
  --rf-h-text: var(--rfig-blue-text);
  --rf-h-tint: var(--rfig-blue-tint);
  --rf-h-deep: var(--rfig-blue-deep);
}

.rfig-hue-cyan,
.rfig-lv1 {
  --rf-h: var(--rfig-cyan);
  --rf-h-text: var(--rfig-cyan-text);
  --rf-h-tint: var(--rfig-cyan-tint);
  --rf-h-deep: var(--rfig-cyan-deep);
}

.rfig-hue-mint,
.rfig-tone-pos {
  --rf-h: var(--rfig-mint);
  --rf-h-text: var(--rfig-mint-text);
  --rf-h-tint: var(--rfig-mint-tint);
  --rf-h-deep: var(--rfig-mint-deep);
}

.rfig-hue-amber,
.rfig-tone-warn {
  --rf-h: var(--rfig-amber);
  --rf-h-text: var(--rfig-amber-text);
  --rf-h-tint: var(--rfig-amber-tint);
  --rf-h-deep: var(--rfig-amber-deep);
}

.rfig-hue-coral,
.rfig-tone-neg {
  --rf-h: var(--rfig-coral);
  --rf-h-text: var(--rfig-coral-text);
  --rf-h-tint: var(--rfig-coral-tint);
  --rf-h-deep: var(--rfig-coral-deep);
}

.rfig-hue-violet {
  --rf-h: var(--rfig-violet);
  --rf-h-text: var(--rfig-violet-text);
  --rf-h-tint: var(--rfig-violet-tint);
  --rf-h-deep: var(--rfig-violet-deep);
}

.rfig-hue-indigo,
.rfig-lv3 {
  --rf-h: var(--rfig-indigo);
  --rf-h-text: var(--rfig-indigo-text);
  --rf-h-tint: var(--rfig-indigo-tint);
  --rf-h-deep: var(--rfig-indigo-deep);
}

.rfig-hue-slate,
.rfig-lv0 {
  --rf-h: var(--rfig-slate);
  --rf-h-text: var(--rfig-slate-text);
  --rf-h-tint: var(--rfig-slate-tint);
  --rf-h-deep: var(--rfig-slate-deep);
}

/* Neutral emphasis (a conclusion, a result, a quantity that is no category): ink lines and marks, and a pale neutral
   ground for its fills (stairs, gauge bands, tinted boxes), which the white node never was. */
.rfig-hue-ink {
  --rf-h: var(--rfig-ink);
  --rf-h-text: var(--rfig-ink);
  --rf-h-tint: var(--rfig-ink-tint);
  --rf-h-deep: var(--rfig-ink-deep);
}

/* ---------- Figure, sheet, caption ---------- */

.rfig {
  container: rfig / inline-size;
  margin: 12px 0 36px;
  color: var(--rfig-ink-soft);
  font-family: var(--rfig-t-body-family);
  font-size: var(--rfig-t-body-size);
  font-weight: var(--rfig-t-body-weight);
  letter-spacing: var(--rfig-t-track);
  line-height: 1.55;
  overflow-wrap: break-word;
  text-align: left;
  text-transform: var(--rfig-t-case);
}

.rfig *,
.rfig *::before,
.rfig *::after {
  box-sizing: border-box;
}

.rfig-sheet {
  background:
    radial-gradient(120% 60% at 0% 0%, var(--rfig-wash), transparent 62%),
    var(--rfig-sheet);
  border: 1px solid var(--rfig-frame);
  display: flex;
  flex-direction: column;
  gap: var(--rfig-gap, 20px);
  padding: var(--rfig-pad);
  position: relative;
}

/* Corner ticks, as on the homepage and docs sheets: two thin strips inside the padding. */
.rfig-sheet::before,
.rfig-sheet::after {
  --t: var(--rfig-faint);
  background:
    linear-gradient(var(--t) 0 0) left top / 10px 1px no-repeat,
    linear-gradient(var(--t) 0 0) left top / 1px 10px no-repeat,
    linear-gradient(var(--t) 0 0) right top / 10px 1px no-repeat,
    linear-gradient(var(--t) 0 0) right top / 1px 10px no-repeat;
  content: "";
  height: 10px;
  left: 6px;
  pointer-events: none;
  position: absolute;
  right: 6px;
}

.rfig-sheet::before {
  top: 6px;
}

.rfig-sheet::after {
  bottom: 6px;
  transform: scaleY(-1);
}

/* Caption under the sheet: the figure number in the hue, then the title in ink. Text parts that
   mix words and inline elements flow as text (block or inline-block), never as flex items, so a
   <sub> or <var> inside them keeps its spaces. A caption never ends on one lone word (on a phone the
   enlarge button floats at the end of its first line): the browser evens out its last lines. */
.rfig-cap {
  color: var(--rfig-ink);
  display: block;
  font-family: var(--rfig-t-cap-family);
  font-size: var(--rfig-t-cap-size);
  font-weight: var(--rfig-t-cap-weight);
  letter-spacing: var(--rfig-t-track);
  line-height: 1.5;
  margin-top: 12px;
  text-transform: var(--rfig-t-case);
  text-wrap: pretty;
}

.rfig-cap__num {
  color: var(--rf-h-text);
  font-family: var(--rfig-t-capnum-family);
  font-size: var(--rfig-t-capnum-size);
  font-weight: var(--rfig-t-capnum-weight);
  letter-spacing: var(--rfig-t-capnum-track);
  margin-right: 12px;
  text-transform: var(--rfig-t-capnum-case);
}

/* ---------- Type: one role table (rules 0.1) ---------- */

/* Every word in a figure takes one role. The rules in this block are the only places in the kit that set a
   face, a size, a weight, a tracking or a case (the base .rfig, the caption and the SVG classes read the same
   tokens); each lists the parts that take its role, and the parts below carry colour and layout only. A part
   that seems to need a size the table does not have is a question for the rules, not a new size here. On
   narrow figures a few tokens step down (the container rules at the end of the file). */

/* label: kickers, table and gloss heads, party names, event times, caps tags, caps link words, marks */
.rfig-kicker,
.rfig-th,
.rfig-gloss__head,
.rfig-party,
.rfig-event__when,
.rfig-tag.rfig-tag--caps,
.rfig-link--caps .rfig-link__label,
.rfig-mark {
  --rfig-t-emw: var(--rfig-t-label-weight);
  font-family: var(--rfig-t-label-family);
  font-size: var(--rfig-t-label-size);
  font-weight: var(--rfig-t-label-weight);
  letter-spacing: var(--rfig-t-label-track);
  text-transform: var(--rfig-t-label-case);
}

/* A label whose case carries meaning (an identifier, a version, S_min) keeps its case. */
.rfig-case {
  letter-spacing: var(--rfig-t-track);
  text-transform: var(--rfig-t-case);
}

/* lede: the one sentence under the head */
.rfig-lede {
  font-family: var(--rfig-t-lede-family);
  font-size: var(--rfig-t-lede-size);
  font-weight: var(--rfig-t-lede-weight);
  letter-spacing: var(--rfig-t-track);
  text-transform: var(--rfig-t-case);
}

/* name: what a box, a region, a row, an axis end, a stage, a bar, a band or a matrix cell is called, and the
   verdict and step lines of a box */
.rfig-name,
.rfig-title,
.rfig-rh,
.rfig-axis__start,
.rfig-axis__end,
.rfig-stair__name,
.rfig-when__k,
.rfig-step,
.rfig-verdict__claim,
.rfig-bar-label,
.rfig-gauge__band,
.rfig-table--grid .rfig-td {
  font-family: var(--rfig-t-name-family);
  font-size: var(--rfig-t-name-size);
  font-weight: var(--rfig-t-name-weight);
  letter-spacing: var(--rfig-t-track);
  text-transform: var(--rfig-t-case);
}

/* body: running lines, table cells, list lines, legend lines (the figure's own words are body too) */
.rfig-text,
.rfig-td,
.rfig-list,
.rfig-legend__item {
  font-family: var(--rfig-t-body-family);
  font-size: var(--rfig-t-body-size);
  font-weight: var(--rfig-t-body-weight);
  letter-spacing: var(--rfig-t-track);
  text-transform: var(--rfig-t-case);
}

/* small: notes, link and message words, tags and numbers, bar values and the names of reference lines,
   stair gates and notes, gauge ticks and marks, the tick values of an axis, the words of an ellipsis */
.rfig-note,
.rfig-link__label,
.rfig-link__sub,
.rfig-msg__text,
.rfig-more,
.rfig-tag,
.rfig-num,
.rfig-bar-value,
.rfig-bar-mark,
.rfig-bars__tick,
.rfig-stairs__line,
.rfig-stairs__tick,
.rfig-stair__gate,
.rfig-stair__note,
.rfig-gauge__tick,
.rfig-gauge__mark,
.rfig-scroll-hint {
  font-family: var(--rfig-t-small-family);
  font-size: var(--rfig-t-small-size);
  font-weight: var(--rfig-t-small-weight);
  letter-spacing: var(--rfig-t-track);
  text-transform: var(--rfig-t-case);
}

/* value: a large value, a degree glyph, a stair's value; digits keep one width */
.rfig-big,
.rfig-glyph,
.rfig-stair__value {
  font-family: var(--rfig-t-value-family);
  font-size: var(--rfig-t-value-size);
  font-variant-numeric: tabular-nums;
  font-weight: var(--rfig-t-value-weight);
  letter-spacing: var(--rfig-t-value-track);
  text-transform: var(--rfig-t-case);
}

/* math: formulas in the faces of the article formulas, upright parts in KaTeX_Main and variables (var, or i
   inside a formula) in KaTeX_Math. A formula is the math size, or the size of its line where that line is
   larger (a formula inside a value); inside a sub- or superscript it takes the script's size. It keeps its
   case inside small capitals: beta stays beta. */
.rfig-math,
.rfig-formula {
  font-family: var(--rfig-t-math-family);
  font-size: max(var(--rfig-t-math-size), 1em);
  font-weight: var(--rfig-t-math-weight);
  letter-spacing: var(--rfig-t-track);
  text-transform: var(--rfig-t-case);
}

.rfig var,
.rfig :is(.rfig-math, .rfig-formula) i {
  font-family: var(--rfig-t-math-var-family);
  font-size: max(var(--rfig-t-math-size), 1em);
  font-style: italic;
  font-weight: var(--rfig-t-math-weight);
  letter-spacing: var(--rfig-t-track);
  text-transform: var(--rfig-t-case);
}

.rfig :is(.rfig-math, .rfig-formula) :is(var, i),
.rfig :is(sub, sup) :is(var, .rfig-math) {
  font-size: 1em;
}

/* code: identifiers, word for word, in their own case */
.rfig .rfig-code {
  font-family: var(--rfig-t-code-family);
  font-size: var(--rfig-t-code-size);
  font-weight: var(--rfig-t-code-weight);
  letter-spacing: var(--rfig-t-track);
  text-transform: var(--rfig-t-case);
}

/* Emphasis is one step of weight and a colour, never a size: strong and b, links, rfig-em, the highlight of
   the night field, and code inside any of them. Inside a label it stays at the label's weight. */
.rfig .rfig-sheet :is(strong, b),
.rfig .rfig-cap :is(strong, b),
.rfig .rfig-sheet a,
.rfig .rfig-em,
.rfig .rfig-hl,
.rfig :is(strong, b, a, .rfig-em, .rfig-hl) .rfig-code,
.rfig .rfig-code.rfig-em {
  font-weight: var(--rfig-t-emw);
}

/* Sub- and superscripts: 0.72 of their line. */
.rfig sub,
.rfig sup {
  font-size: var(--rfig-t-script);
  line-height: 0;
}

/* ---------- Text parts: colour and layout (their type is the role above) ---------- */

/* Header of a figure: a small-caps line and, optionally, one sentence under it. */
.rfig-head {
  display: grid;
  gap: 6px;
}

.rfig-kicker {
  color: var(--rfig-muted);
  display: block;
  line-height: 1.4;
}

.rfig-kicker--hue {
  color: var(--rf-h-text);
}

.rfig-kicker--ink {
  color: var(--rfig-ink);
}

.rfig-lede {
  color: var(--rfig-ink-soft);
  display: block;
  line-height: 1.55;
  max-width: 64ch;
}

.rfig-title {
  color: var(--rfig-ink);
  display: block;
  line-height: 1.3;
}

.rfig-title--hue {
  color: var(--rf-h-text);
}

.rfig-name {
  color: var(--rfig-ink);
  display: block;
  line-height: 1.3;
}

.rfig-text {
  color: var(--rfig-ink-soft);
  display: block;
  line-height: 1.55;
}

.rfig-note {
  color: var(--rfig-muted);
  display: block;
  line-height: 1.5;
}

/* A large display glyph: a degree (S0), a quantifier, a step number. */
.rfig-glyph {
  color: var(--rf-h-text);
  display: inline-block;
  line-height: 1;
}

/* A large value: a complexity, a count, a result. */
/* A value is one unbroken piece (≤ 33% never breaks after its sign); keep it short. */
.rfig-big {
  color: var(--rf-h-text);
  display: block;
  line-height: 1.25;
  white-space: nowrap;
}

.rfig-math {
  line-height: 1.45;
}

/* A variable in running words ("Gate n Computation"): a hair of room for the italic overhang. */
.rfig var {
  margin: 0 0.05em 0 0.02em;
}

.rfig :is(.rfig-math, .rfig-formula) :is(var, i) {
  margin: 0;
}

/* A name too long for its box is hyphenated ("commit-ment"), not cut at an arbitrary letter
   ("commitm / ent"); the break-word fallback stays only for a word no dictionary can split, so a box
   never overflows. Long words only (nine letters or more, three on each side). Names that must not
   break at all are code (.rfig-code) or wrapped in .rfig-keep. */
.rfig :is(.rfig-name, .rfig-title, .rfig-kicker, .rfig-th, .rfig-rh, .rfig-tag, .rfig-link__label, .rfig-stair__name) {
  -webkit-hyphens: auto;
  hyphenate-limit-chars: 9 3 3;
  hyphens: auto;
}

/* Code identifiers, word for word, without the prose code box. Use only for real code. An identifier
   never breaks inside a word (the figure's break-word fallback would split Operational_Failure into
   "Operational_Fai / lure"): it breaks only at a space or at a <wbr> the writer puts after "_", ".",
   "::" or "/". A cell too narrow for one unbroken piece overflows, which the checks catch, and the
   writer widens the cell or adds a <wbr>. */
.rfig .rfig-code {
  background: none;
  border: 0;
  color: var(--rfig-ink);
  hyphens: manual;
  overflow-wrap: normal;
  padding: 0;
  word-break: normal;
}

/* Code on a deep or night ground keeps the light text of that ground. */
.rfig :is(.rfig-node--solid, .rfig-tag--solid, .rfig-when--solid, .rfig-party, .rfig-quant--solid, .rfig-mark) .rfig-code {
  color: var(--rfig-on);
}

.rfig :is(.rfig-panel--night, .rfig-band) .rfig-code {
  color: var(--rfig-night-ink);
}

.rfig .rfig-nowrap {
  white-space: nowrap;
}

.rfig .rfig-sheet strong,
.rfig .rfig-sheet b {
  color: var(--rfig-ink);
}

.rfig .rfig-sheet a {
  color: var(--rf-h-text);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
  text-underline-offset: 3px;
}

.rfig .rfig-sheet a:hover {
  text-decoration-color: currentColor;
}

/* A name that must not break at all: at its hyphen (D-quencer, StateSync-GKR) or, for a one-word
   state name (CONFISCATED), inside the word. */
.rfig-keep {
  white-space: nowrap;
}

/* Words for screen readers only (for example the state a marker shows). */
.rfig-sr {
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

/* ---------- Markers and tags ---------- */

/* Square before a line: present (filled), partial (--half), open (--open) or absent (--off). */
.rfig-sq {
  display: block;
  padding-left: 17px;
  position: relative;
}

.rfig-sq::before {
  background: var(--rf-h);
  content: "";
  height: 8px;
  left: 0;
  position: absolute;
  top: 0.5em;
  top: calc(0.5lh - 4px);
  width: 8px;
}

.rfig-sq--half::before {
  background: linear-gradient(135deg, var(--rf-h) 50%, transparent 50%);
  box-shadow: inset 0 0 0 1.5px var(--rf-h);
}

.rfig-sq--open::before {
  background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--rf-h);
}

.rfig-sq--off {
  color: var(--rfig-muted);
}

/* The absent square carries meaning ("not done"), so its outline and stroke use the muted ink (5.5:1
   or more on the sheet and the node in both themes), not the faint tick colour (2.5:1). */
.rfig-sq--off::before {
  background: linear-gradient(to top right, transparent calc(50% - 0.75px), var(--rfig-muted) calc(50% - 0.75px) calc(50% + 0.75px), transparent calc(50% + 0.75px));
  box-shadow: inset 0 0 0 1px var(--rfig-muted);
}

/* A list of marked lines (body). Markup: div.rfig-list[role=list] > span.rfig-sq[role=listitem]. */
.rfig-list {
  display: grid;
  gap: 5px;
  line-height: 1.45;
}

/* Short tag (small; with --caps a label): a status, a qualifier, a count. */
.rfig-tag {
  align-self: flex-start;
  background: var(--rfig-node);
  border: 1px solid var(--rfig-frame);
  color: var(--rfig-ink-soft);
  display: inline-block;
  line-height: 1.45;
  max-width: 100%;
  padding: 2px 9px;
  vertical-align: middle;
}

.rfig-tag--tint {
  background: var(--rf-h-tint);
  border-color: color-mix(in srgb, var(--rf-h) 42%, transparent);
  color: var(--rf-h-text);
}

.rfig-tag--solid {
  background: var(--rf-h-deep);
  border-color: var(--rf-h-deep);
  color: var(--rfig-on);
}

.rfig-tag--ghost {
  background: transparent;
  border-style: dashed;
}

.rfig-tag--mute {
  background: transparent;
  color: var(--rfig-muted);
}

/* A tag set in small capitals (a kind: UNIVERSAL, FINAL) takes the label role (Type, above). */

/* A number the source carries as text (step 1, round i); small. */
.rfig-num {
  background: var(--rf-h-tint);
  border: 1px solid color-mix(in srgb, var(--rf-h) 45%, transparent);
  color: var(--rf-h-text);
  display: inline-block;
  font-variant-numeric: tabular-nums;
  line-height: 1.45;
  min-width: 26px;
  padding: 2px 10px;
  text-align: center;
  vertical-align: middle;
}

/* The kit has no icon badge: a small square or circle holding an icon in front of a stage or an item
   is the same kind of generated-figure habit as the coloured left edge (rules, section 6). A stage
   is told by its name, its place in the order, the hue of its column and the toll after it. */

/* ---------- Nodes and panels ---------- */

/* A box. Its children stack with a small gap; .rfig-push sends one to the bottom. */
.rfig-node {
  background: var(--rfig-node);
  border: 1px solid var(--rfig-frame);
  color: var(--rfig-ink-soft);
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
  padding: 14px 16px 15px;
  position: relative;
}

.rfig-push {
  margin-top: auto;
}

/* A coloured stripe on top and a faint wash of the hue: the node belongs to a hue or level. */
.rfig-node--stripe {
  background: linear-gradient(180deg, color-mix(in srgb, var(--rf-h) 8%, var(--rfig-node)) 0, var(--rfig-node) 76px);
  border-top: 3px solid var(--rf-h);
  padding-top: 13px;
}

/* A pale ground of the hue. */
.rfig-node--tint {
  background: var(--rf-h-tint);
  border-color: color-mix(in srgb, var(--rf-h) 36%, transparent);
}

/* The strongest frame: 2px of the hue. */
.rfig-node--strong {
  border: 2px solid var(--rf-h);
  padding: 13px 15px 14px;
}

.rfig-node--strong.rfig-node--stripe {
  border-top-width: 3px;
  padding-top: 12px;
}

/* The node the figure is about lifts off the sheet. */
.rfig-node--lift {
  box-shadow: var(--rfig-shadow);
}

/* A deep ground of the hue with white text. The fill reaches under a transparent border (border-box): a deep
   border on the deep fill drew nothing of its own and measured as a 1.19:1 mark (2026-10-17). */
.rfig-node--solid {
  background: linear-gradient(160deg, var(--rf-h-deep), color-mix(in srgb, var(--rf-h-deep) 80%, #000)) border-box;
  border-color: transparent;
  color: var(--rfig-on);
}

/* .rfig-formula sets its own ink colour, so it is listed here too (W7 writer report 2026-10-18). */
.rfig-node--solid :is(.rfig-name, .rfig-title, .rfig-text, .rfig-note, .rfig-kicker, .rfig-big, .rfig-glyph, .rfig-code, .rfig-formula),
.rfig .rfig-node--solid strong {
  color: var(--rfig-on);
}

/* Proposed, optional or pending: dashed and unfilled. */
.rfig-node--ghost {
  background: transparent;
  border-style: dashed;
}

/* Label beside the text instead of above it; above it again on narrow figures. */
.rfig-node--split {
  align-items: baseline;
  column-gap: 18px;
  display: grid;
  grid-template-columns: minmax(0, var(--rfig-aside, 9rem)) minmax(0, 1fr);
}

/* A field of the hue: a region set apart from the sheet by a step in tone, with no border and no
   coloured edge. Notes that explain the figure are glosses (.rfig-gloss), not panels. */
.rfig-panel {
  background: var(--rf-h-tint);
  color: var(--rfig-ink-soft);
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  padding: 14px 18px 15px;
}

/* The brand night field inside a figure: what the figure concludes or requires. */
.rfig-panel--night {
  background:
    radial-gradient(90% 140% at 100% 0%, rgba(91, 220, 243, 0.12), transparent 60%),
    var(--rfig-night);
  border-top: 2px solid var(--rfig-night-cyan);
  border-image: linear-gradient(90deg, var(--rfig-night-blue), var(--rfig-night-cyan)) 1;
  color: var(--rfig-night-soft);
}

[data-theme="dark"] .rfig-panel--night {
  box-shadow: inset 0 0 0 1px var(--rfig-night-line);
}

.rfig-panel--night :is(.rfig-text, .rfig-note) {
  color: var(--rfig-night-soft);
}

.rfig-panel--night .rfig-kicker {
  color: var(--rfig-night-blue);
}

.rfig .rfig-panel--night strong {
  color: var(--rfig-night-ink);
}

/* A highlighted phrase on the night field (emphasis weight, Type above). */
.rfig-hl {
  color: var(--rfig-night-cyan);
}

/* A framed region holding a sub-diagram. */
.rfig-group {
  background: color-mix(in srgb, var(--rf-h) 4%, transparent);
  border: 1px solid color-mix(in srgb, var(--rf-h) 45%, transparent);
  container: rfig-box / inline-size;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
  padding: 14px 16px 16px;
}

/* A region boundary (an assumption, a guarantee, a model or trust boundary, a layer such as the L3): the dashed
   line of an SVG s-dash region in HTML, 1.5px dashes of 5 with gaps of 4 in the hue, no fill (rules 0.3). Its name
   is the region's kicker inside the top left corner. The dashes are a drawing on the frame, so the region keeps
   its size and padding. */
.rfig-group--dash {
  background: none;
  border-color: transparent;
  position: relative;
}

.rfig-group--dash::before {
  background:
    repeating-linear-gradient(90deg, currentColor 0 5px, transparent 5px 9px) 0 0 / 100% 1.5px no-repeat,
    repeating-linear-gradient(90deg, currentColor 0 5px, transparent 5px 9px) 0 100% / 100% 1.5px no-repeat,
    repeating-linear-gradient(180deg, currentColor 0 5px, transparent 5px 9px) 0 0 / 1.5px 100% no-repeat,
    repeating-linear-gradient(180deg, currentColor 0 5px, transparent 5px 9px) 100% 0 / 1.5px 100% no-repeat;
  color: var(--rf-h);
  content: "";
  inset: -1px;
  pointer-events: none;
  position: absolute;
}

/* A large faint glyph in the corner of a node (a quantifier, a degree), drawn for the eye only:
   mark it aria-hidden and keep the same symbol in the text. It is decoration, the one size outside the
   role table (92px, 70px on narrow figures); its face is the math face. */
.rfig-watermark {
  color: color-mix(in srgb, var(--rf-h) 16%, transparent);
  font-family: var(--rfig-t-math-family);
  font-size: 92px;
  line-height: 1;
  pointer-events: none;
  position: absolute;
  right: 14px;
  top: 6px;
  user-select: none;
}

/* ---------- Glosses, keys and marks: the notes that read a figure ---------- */

/* A gloss says how to read the drawing, what it aims at or why it is built so. It is a ruled band,
   not a box: a hairline across the top that thickens into a short bar of the local hue over the
   head cell, a small-caps head beside the body, no fill and no side edge. The kit draws no coloured
   edge on the left of any box (rules, section 6); a gloss replaces that habit.
   Markup: div.rfig-gloss[.rfig-hue-*] > span.rfig-gloss__head + div.rfig-gloss__body. The head
   column is --rfig-aside wide (8.5rem by default); on narrow figures the head sits above the body.
   In a figure that uses the level ramp, give the gloss rfig-hue-ink so its bar is not read as a level. */
.rfig-gloss {
  align-items: baseline;
  border-top: 1px solid var(--rfig-frame);
  column-gap: 24px;
  display: grid;
  grid-template-columns: minmax(0, var(--rfig-aside, 8.5rem)) minmax(0, 1fr);
  min-width: 0;
  padding-top: 13px;
  position: relative;
  row-gap: 8px;
}

/* The bar over the head cell: 2px of the hue laid over the hairline. */
.rfig-gloss::before {
  background: var(--rf-h);
  content: "";
  height: 2px;
  left: 0;
  position: absolute;
  top: -1px;
  width: min(100%, var(--rfig-aside, 8.5rem));
}

.rfig-gloss__head {
  color: var(--rf-h-text);
  line-height: 1.45;
  min-width: 0;
}

.rfig-gloss__body {
  display: grid;
  gap: 8px;
  min-width: 0;
}

/* Keyed lines, mostly inside a gloss: a chip that names the thing (a degree, a symbol, a mark) and
   the words about it. The chip carries the colour, the words stay in ink, the chips share one column.
   Markup: div.rfig-keys[role=list] > div.rfig-key[role=listitem] > (chip) + span.rfig-text, where
   the chip is .rfig-num, .rfig-tag or .rfig-mark with its own hue or level class. */
.rfig-keys {
  column-gap: 12px;
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  row-gap: 7px;
}

.rfig-key {
  align-items: baseline;
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
}

.rfig-key > :first-child {
  justify-self: start;
}

/* A mark: a small numbered square set in the drawing, right after the name or label it points at,
   and repeated at the start of the gloss head that explains that part. Marks tie a note to a place;
   they are not list numbering and never decorate. In the drawing write
   <span class="rfig-mark"><span class="rfig-sr">Note </span>1</span>, in the gloss head
   <span class="rfig-mark">1</span>Words. A mark takes the hue of the part it points at. */
.rfig-mark {
  align-items: center;
  background: var(--rf-h-deep);
  color: var(--rfig-on);
  display: inline-flex;
  font-style: normal;
  font-variant-numeric: tabular-nums;
  height: 20px;
  justify-content: center;
  line-height: 1;
  min-width: 20px;
  padding: 0 5px;
  vertical-align: 0.08em;
}

.rfig-gloss__head > .rfig-mark {
  margin-right: 8px;
}

/* In running words or after a name, a little room before the mark. */
:is(.rfig-name, .rfig-title, .rfig-text, .rfig-msg__text, .rfig-step, .rfig-kicker) > .rfig-mark {
  margin-left: 6px;
}

/* ---------- Arrows ---------- */

/* Arrow between parts, drawn in CSS in the local hue: solid unless --dashed (a return, recovery or
   secondary path). Points right by default. Markup: <span class="rfig-arrow" aria-hidden="true">. */
.rfig-arrow {
  align-self: center;
  color: var(--rf-h);
  display: block;
  flex: 0 0 auto;
  height: 10px;
  position: relative;
  width: var(--rfig-arrow, 30px);
}

.rfig-arrow::before {
  background: currentColor;
  content: "";
  height: 1.5px;
  left: 0;
  position: absolute;
  right: 7px;
  top: 4.25px;
}

.rfig-arrow::after {
  background: currentColor;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
  content: "";
  height: 10px;
  position: absolute;
  right: 0;
  top: 0;
  width: 9px;
}

.rfig-arrow--left::before {
  left: 7px;
  right: 0;
}

.rfig-arrow--left::after {
  clip-path: polygon(100% 0, 0 50%, 100% 100%);
  left: 0;
  right: auto;
}

.rfig-arrow--both::before {
  left: 7px;
  right: 7px;
}

.rfig-arrow--both::after {
  clip-path: polygon(0 50%, 9px 0, 9px 100%, 0 50%, 100% 50%, calc(100% - 9px) 0, calc(100% - 9px) 100%, 100% 50%);
  left: 0;
  right: 0;
  width: auto;
}

/* Vertical arrows. --rf-dash-dir turns the dashes of a dashed shaft with it (every vertical arrow sets it: these,
   the arrows of a flow folded into a column and the messages of a sequence on a phone). */
.rfig-arrow--down,
.rfig-arrow--up {
  --rf-dash-dir: 180deg;
  height: var(--rfig-arrow, 26px);
  width: 10px;
}

.rfig-arrow--down::before,
.rfig-arrow--up::before {
  bottom: 7px;
  height: auto;
  left: 4.25px;
  right: auto;
  top: 0;
  width: 1.5px;
}

.rfig-arrow--down::after {
  bottom: 0;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  height: 9px;
  left: 0;
  right: auto;
  top: auto;
  width: 10px;
}

.rfig-arrow--up::before {
  bottom: 0;
  top: 7px;
}

.rfig-arrow--up::after {
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
  height: 9px;
  left: 0;
  right: auto;
  top: 0;
  width: 10px;
}

/* A dashed shaft: dashes along the arrow, across by default and down where the arrow points down or up. */
.rfig-arrow--dashed::before {
  background: repeating-linear-gradient(var(--rf-dash-dir, 90deg), currentColor 0 5px, transparent 5px 9px);
}

/* An arrow that takes the free width of its row (an axis, a message between two parties). */
.rfig-arrow--fill {
  flex: 1 1 auto;
  min-width: 30px;
  width: auto;
}

/* Arrow inside a line of text, where the source had a glyph such as A -> B. Use <i> so the line
   stays one text piece: <i class="rfig-arrow rfig-arrow--inline" aria-hidden="true"></i>. */
.rfig-arrow--inline {
  display: inline-block;
  margin: 0 0.35em;
  vertical-align: 0.02em;
  width: 1.2em;
}

/* ---------- Connectors with words ---------- */

/* Axis: an arrow with words at its ends and a label above it. With --rev the head is at the start
   (read: the start is reached from the end). The shaft may run from one colour to another:
   style="--rfig-from: var(--rfig-indigo); --rfig-to: var(--rfig-slate)". */
.rfig-axis {
  align-items: center;
  column-gap: 12px;
  display: grid;
  grid-template-areas:
    "label label label"
    "start line end";
  grid-template-columns: auto minmax(30px, 1fr) auto;
  row-gap: 6px;
}

.rfig-axis__label {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 12px;
  justify-content: center;
  text-align: center;
}

/* The label takes its area only inside an axis. Anywhere else (a grid of cards) a named area would
   open new tracks and lay the label over its neighbours. A labelled arrow outside an axis is a
   .rfig-link. */
.rfig-axis > .rfig-axis__label {
  grid-area: label;
}

.rfig-axis__start,
.rfig-axis__end {
  color: var(--rf-h-text);
  line-height: 1.2;
}

.rfig-axis__start {
  grid-area: start;
}

.rfig-axis__end {
  grid-area: end;
  text-align: right;
}

.rfig-axis__line {
  grid-area: line;
  height: 10px;
  position: relative;
}

.rfig-axis__line::before {
  background: linear-gradient(90deg, var(--rfig-from, var(--rf-h)), var(--rfig-to, var(--rf-h)));
  content: "";
  height: 2px;
  left: 0;
  position: absolute;
  right: 8px;
  top: 4px;
}

.rfig-axis__line::after {
  background: var(--rfig-to, var(--rf-h));
  clip-path: polygon(0 0, 100% 50%, 0 100%);
  content: "";
  height: 10px;
  position: absolute;
  right: 0;
  top: 0;
  width: 9px;
}

.rfig-axis--rev .rfig-axis__line::before {
  left: 8px;
  right: 0;
}

.rfig-axis--rev .rfig-axis__line::after {
  background: var(--rfig-from, var(--rf-h));
  clip-path: polygon(100% 0, 0 50%, 100% 100%);
  left: 0;
  right: auto;
}

/* A dark band across the figure: a router, a bus, a channel. Code and arrows sit on it. */
.rfig-band {
  align-items: center;
  background: var(--rfig-night);
  box-shadow: inset 0 0 0 1px var(--rfig-night-line);
  color: var(--rfig-night-ink);
  display: flex;
  gap: 12px;
  padding: 9px 14px;
  --rf-h: var(--rfig-night-cyan);
}
.rfig-band .rfig-kicker,
.rfig-band .rfig-name,
.rfig-band .rfig-note,
.rfig-band .rfig-text,
.rfig-band .rfig-title {
  color: var(--rfig-night-ink);
}

.rfig .rfig-band .rfig-code {
  color: var(--rfig-night-ink);
}

.rfig .rfig-band .rfig-code + .rfig-code,
.rfig-band .rfig-band__end {
  color: var(--rfig-night-blue);
}

/* Columns that hang from a band: a short connector in each column's hue (wide figures only). The
   columns are striped nodes (3px top edge); the connector runs from the band to that edge. */
.rfig-cols--drop {
  margin-top: calc(-1 * var(--rfig-gap, 20px));
}

.rfig-cols--drop > * {
  margin-top: 18px;
}

.rfig-cols--drop > *::after {
  background: var(--rf-h);
  content: "";
  height: 18px;
  left: calc(50% - 1px);
  position: absolute;
  top: -21px;
  width: 2px;
}

/* A vertical ellipsis drawn in CSS and the words that go with it ("repeat for all n gates"). */
.rfig-more {
  color: var(--rfig-muted);
  display: block;
  line-height: 1.4;
  text-align: center;
}

.rfig-more::before {
  background: radial-gradient(circle, currentColor 1.7px, transparent 2px) center top / 5px 6px repeat-y;
  content: "";
  display: inline-block;
  height: 18px;
  vertical-align: middle;
  width: 5px;
}

/* With words after the dots, a little room between them. */
.rfig-more:not(:empty)::before {
  margin-right: 10px;
}

/* ---------- Links: labelled connectors that touch what they join ---------- */

/* A link joins the box before it to the box after it. Its shaft starts on the edge of the first box
   and its arrowhead ends on the edge of the second: the link takes the gap its parent leaves on each
   side (--rf-eat), so nothing floats. Its words sit on the line and break it, as on a technical
   drawing: a condition (< 3%), a relation (settles on), an amount (110M OZ).
   Markup:  <div class="rfig-link"><span class="rfig-link__label">settles on</span></div>
            <div class="rfig-link"><span class="rfig-link__label">Critical &lt; 50%<span
              class="rfig-link__sub">governance</span></span></div>
   An empty .rfig-link draws a plain arrow that still touches both boxes.
   It points down in a column, and along the row inside a .rfig-flow row (down again when that row
   folds into a column on a narrow figure). --back points the other way, --both both ways, --plain
   has no head, --dashed is a return or secondary path, --blocked is a path that does not exist
   (dashed, a crossed square on the line; say it in the words too: "no direct path"). --caps sets
   the words in small capitals (a relation: SETTLES ON). --pair draws two arrows beside the words
   instead of one through them (a whole layer settling on the next, as on docs). Keep the words to
   a short label and, at most, one short sub line: a link names a condition, it does not explain. */
.rfig-link {
  --rf-eat: 0px;
  align-items: center;
  color: var(--rf-h);
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  margin-block: calc(-1 * var(--rf-eat));
  min-height: 36px;
  min-width: 0;
  position: relative;
}

.rfig-link::before,
.rfig-link::after {
  background: currentColor;
  content: "";
  flex: 1 1 0;
  width: 1.5px;
}

.rfig-link::before {
  min-height: 6px;
}

/* A link joins two boxes. Placed first, or right after a name line, it has no box before it: its tail is
   left out instead of hanging in the air (rules 5.2: put a link only between two boxes). */
:not(.rfig-links) > .rfig-link:first-child::before,
:is(.rfig-kicker, .rfig-head, .rfig-lede) + .rfig-link::before {
  visibility: hidden;
}

/* Shaft and head in one piece: a 1.5px shaft, a 10 by 9px head, the tip on the far edge. */
.rfig-link::after {
  clip-path: polygon(calc(50% - 0.75px) 0, calc(50% + 0.75px) 0, calc(50% + 0.75px) calc(100% - 9px), 100% calc(100% - 9px), 50% 100%, 0 calc(100% - 9px), calc(50% - 0.75px) calc(100% - 9px));
  min-height: 16px;
  width: 10px;
}

.rfig-link:is(.rfig-link--back, .rfig-link--both)::before {
  clip-path: polygon(50% 0, 100% 9px, calc(50% + 0.75px) 9px, calc(50% + 0.75px) 100%, calc(50% - 0.75px) 100%, calc(50% - 0.75px) 9px, 0 9px);
  min-height: 16px;
  width: 10px;
}

.rfig-link:is(.rfig-link--back, .rfig-link--plain)::after,
.rfig-links--join > .rfig-link::after {
  clip-path: none;
  min-height: 6px;
  width: 1.5px;
}

.rfig-link:is(.rfig-link--dashed, .rfig-link--blocked)::before,
.rfig-link:is(.rfig-link--dashed, .rfig-link--blocked):is(.rfig-link--back, .rfig-link--plain)::after,
.rfig-links--join > .rfig-link:is(.rfig-link--dashed, .rfig-link--blocked)::after {
  background: repeating-linear-gradient(180deg, currentColor 0 5px, transparent 5px 9px);
}

/* A dashed shaft keeps a solid head. */
.rfig-link:is(.rfig-link--dashed, .rfig-link--blocked)::after {
  background:
    linear-gradient(currentColor 0 0) 50% 100% / 100% 9px no-repeat,
    repeating-linear-gradient(180deg, currentColor 0 5px, transparent 5px 9px);
}

.rfig-link:is(.rfig-link--dashed, .rfig-link--blocked):is(.rfig-link--back, .rfig-link--both)::before {
  background:
    linear-gradient(currentColor 0 0) 50% 0 / 100% 9px no-repeat,
    repeating-linear-gradient(0deg, currentColor 0 5px, transparent 5px 9px);
}

/* The words of a link are small (in the hue, the sub line muted); with --caps they are a label. */
.rfig-link__label {
  color: var(--rf-h-text);
  display: block;
  line-height: 1.35;
  max-width: min(100%, 15rem);
  padding: 4px 6px;
  text-align: center;
}

.rfig-link__sub {
  color: var(--rfig-muted);
  display: block;
}

/* The crossed square of a path that does not exist, on the line before its words; .rfig-x is the
   same mark anywhere else (aria-hidden, with the words beside it). */
.rfig-link--blocked .rfig-link__label::before,
.rfig-x {
  background:
    linear-gradient(45deg, transparent calc(50% - 1px), currentColor calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)),
    linear-gradient(-45deg, transparent calc(50% - 1px), currentColor calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px));
  box-shadow: inset 0 0 0 1.5px currentColor;
  color: var(--rf-h);
  content: "";
  display: block;
  height: 18px;
  margin: 0 auto 5px;
  width: 18px;
}

.rfig-x {
  display: inline-block;
  flex: none;
  margin: 0;
  vertical-align: -4px;
}

/* A gate: a set of conditions a step must pass. A small open diamond, aria-hidden, with words. */
.rfig-gate,
.rfig-stair__gate::before {
  box-shadow: inset 0 0 0 1.5px currentColor;
  color: var(--rf-h);
  content: "";
  display: inline-block;
  flex: none;
  height: 8px;
  margin: 0 7px 0 2px;
  transform: rotate(45deg);
  vertical-align: 1px;
  width: 8px;
}

/* Two arrows beside the words. */
.rfig-link--pair {
  column-gap: 12px;
  flex-direction: row;
  justify-content: center;
}

.rfig-link--pair::before,
.rfig-link--pair::after {
  align-self: stretch;
  clip-path: polygon(calc(50% - 0.75px) 0, calc(50% + 0.75px) 0, calc(50% + 0.75px) calc(100% - 9px), 100% calc(100% - 9px), 50% 100%, 0 calc(100% - 9px), calc(50% - 0.75px) calc(100% - 9px));
  flex: 0 0 10px;
  min-height: 0;
  width: 10px;
}

/* The gap a link takes from its parent: the parent's own gap. */
.rfig-sheet > :is(.rfig-link, .rfig-links) {
  --rf-eat: var(--rfig-gap, 20px);
}

:is(.rfig-flow--col, .rfig-pipe, .rfig-panel, .rfig-notes, .rfig-layers) > :is(.rfig-link, .rfig-links) {
  --rf-eat: 6px;
}

.rfig-node > :is(.rfig-link, .rfig-links) {
  --rf-eat: 7px;
}

.rfig-group > :is(.rfig-link, .rfig-links) {
  --rf-eat: 14px;
}

/* Parallel links: one link per column, the columns of the row above or below (.rfig-row with the
   same --rfig-n). A column with no link holds an empty span. --fork starts every link from one stem
   out of the middle of the box above (a split); --join ends every link on one bar that runs into the
   middle of the box below (a merge). Markup:
   <div class="rfig-links rfig-links--fork" style="--rfig-n:2"><div class="rfig-link">..</div><div
   class="rfig-link">..</div></div> */
.rfig-links {
  --rf-eat: 0px;
  --rf-col-gap: 12px;
  color: var(--rf-h);
  column-gap: var(--rf-col-gap);
  display: grid;
  flex: 0 0 auto;
  grid-template-columns: repeat(var(--rfig-n, 2), minmax(0, 1fr));
  margin-block: calc(-1 * var(--rf-eat));
  min-height: 36px;
  min-width: 0;
  position: relative;
}

.rfig-links > .rfig-link {
  margin-block: 0;
  min-height: 0;
}

.rfig-links--fork {
  padding-top: 14px;
}

.rfig-links--join {
  padding-bottom: 22px;
}

/* The bus: from the middle of the first column to the middle of the last. */
.rfig-links--fork::after,
.rfig-links--join::after {
  background: currentColor;
  content: "";
  height: 1.5px;
  left: calc((100% - (var(--rfig-n, 2) - 1) * var(--rf-col-gap)) / (2 * var(--rfig-n, 2)) - 0.75px);
  position: absolute;
  right: calc((100% - (var(--rfig-n, 2) - 1) * var(--rf-col-gap)) / (2 * var(--rfig-n, 2)) - 0.75px);
  top: 13.25px;
}

.rfig-links--join::after {
  bottom: 20.75px;
  top: auto;
}

/* The stem of a fork, from the box above to the bus. */
.rfig-links--fork::before {
  background: currentColor;
  content: "";
  height: 14px;
  left: calc(50% - 0.75px);
  position: absolute;
  top: 0;
  width: 1.5px;
}

/* The stem of a join, from the bus to the box below, with its head. */
.rfig-links--join::before {
  background: currentColor;
  bottom: 0;
  clip-path: polygon(calc(50% - 0.75px) 0, calc(50% + 0.75px) 0, calc(50% + 0.75px) calc(100% - 9px), 100% calc(100% - 9px), 50% 100%, 0 calc(100% - 9px), calc(50% - 0.75px) calc(100% - 9px));
  content: "";
  height: 22px;
  left: calc(50% - 5px);
  position: absolute;
  width: 10px;
}

/* A row of boxes that stays a row at every width (a fork's branches, a hub's inputs). Columns match
   a .rfig-links with the same --rfig-n. Two or three boxes; one or two short words per name on a
   phone. */
.rfig-row {
  --rf-col-gap: 12px;
  display: grid;
  gap: var(--rf-col-gap);
  grid-template-columns: repeat(var(--rfig-n, 2), minmax(0, 1fr));
  min-width: 0;
}

.rfig-row > * {
  min-width: 0;
}

/* A column of boxes and links with no gap of its own: the links make the spacing, and when the
   column is stretched (beside a taller column) the links grow, not the gaps. */
.rfig-stack {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-width: 0;
}

.rfig-stack > :is(.rfig-link, .rfig-links) {
  flex-grow: 1;
}

/* A stack's own name line. */
.rfig-stack > .rfig-kicker {
  margin-bottom: 12px;
}

/* ---------- Layouts ---------- */

/* Nodes and arrows in a row; a column on narrow figures (and always with --col). Arrows take the gap
   on both sides, so their tail starts on one box and their tip ends on the next. */
.rfig-flow {
  align-items: stretch;
  display: flex;
  gap: 10px;
}

.rfig-flow > :not(.rfig-arrow, .rfig-link) {
  flex: var(--rfig-grow, 1) 1 0;
  min-width: 0;
}

.rfig-flow > .rfig-arrow:not(.rfig-arrow--down, .rfig-arrow--up) {
  margin-inline: -10px;
  width: calc(var(--rfig-arrow, 30px) + 20px);
}

.rfig-flow--col {
  flex-direction: column;
  gap: 6px;
}

.rfig-flow--col > :not(.rfig-arrow) {
  flex: 0 0 auto;
}

:is(.rfig-flow--col, .rfig-pipe) > :is(.rfig-arrow--down, .rfig-arrow--up) {
  height: calc(var(--rfig-arrow, 26px) + 12px);
  margin-block: -6px;
}

/* A horizontal link in a flow row. Below 600px the row folds into a column and the link points down
   again (the rules here no longer apply). The line on each side of the words is at least --rfig-shaft long
   (8px by default; a head adds its 10px), so a squeezed row cannot leave a stub between a box and the words:
   set style="--rfig-shaft:20px" on the link or its flow when the words should stand clear of both boxes. */
@container rfig (min-width: 600px) {
  .rfig-flow:not(.rfig-flow--col) > .rfig-link {
    --rf-eat: 10px;
    align-self: center;
    flex: 0 1 auto;
    flex-direction: row;
    margin: 0 calc(-1 * var(--rf-eat));
    min-height: 0;
    min-width: 56px;
  }

  .rfig-flow:not(.rfig-flow--col) > .rfig-link::before,
  .rfig-flow:not(.rfig-flow--col) > .rfig-link::after {
    flex: 1 1 0;
    height: 1.5px;
    min-height: 0;
    min-width: var(--rfig-shaft, 8px);
    width: auto;
  }

  .rfig-flow:not(.rfig-flow--col) > .rfig-link::after {
    clip-path: polygon(0 calc(50% - 0.75px), calc(100% - 9px) calc(50% - 0.75px), calc(100% - 9px) 0, 100% 50%, calc(100% - 9px) 100%, calc(100% - 9px) calc(50% + 0.75px), 0 calc(50% + 0.75px));
    height: 10px;
    min-width: calc(var(--rfig-shaft, 8px) + 10px);
  }

  .rfig-flow:not(.rfig-flow--col) > .rfig-link:is(.rfig-link--back, .rfig-link--both)::before {
    clip-path: polygon(0 50%, 9px 0, 9px calc(50% - 0.75px), 100% calc(50% - 0.75px), 100% calc(50% + 0.75px), 9px calc(50% + 0.75px), 9px 100%);
    height: 10px;
    min-width: calc(var(--rfig-shaft, 8px) + 10px);
  }

  .rfig-flow:not(.rfig-flow--col) > .rfig-link:is(.rfig-link--back, .rfig-link--plain)::after {
    clip-path: none;
    height: 1.5px;
    min-width: var(--rfig-shaft, 8px);
  }

  .rfig-flow:not(.rfig-flow--col) > .rfig-link:is(.rfig-link--dashed, .rfig-link--blocked)::before,
  .rfig-flow:not(.rfig-flow--col) > .rfig-link:is(.rfig-link--dashed, .rfig-link--blocked):is(.rfig-link--back, .rfig-link--plain)::after {
    background: repeating-linear-gradient(90deg, currentColor 0 5px, transparent 5px 9px);
  }

  .rfig-flow:not(.rfig-flow--col) > .rfig-link:is(.rfig-link--dashed, .rfig-link--blocked)::after {
    background:
      linear-gradient(currentColor 0 0) 100% 50% / 9px 100% no-repeat,
      repeating-linear-gradient(90deg, currentColor 0 5px, transparent 5px 9px);
  }

  .rfig-flow:not(.rfig-flow--col) > .rfig-link:is(.rfig-link--dashed, .rfig-link--blocked):is(.rfig-link--back, .rfig-link--both)::before {
    background:
      linear-gradient(currentColor 0 0) 0 50% / 9px 100% no-repeat,
      repeating-linear-gradient(270deg, currentColor 0 5px, transparent 5px 9px);
  }

  .rfig-flow:not(.rfig-flow--col) > .rfig-link > .rfig-link__label {
    max-width: 11rem;
    padding: 2px 6px;
  }

  .rfig-flow:not(.rfig-flow--col) > .rfig-link--blocked > .rfig-link__label::before {
    display: inline-block;
    margin: 0 7px 0 0;
    vertical-align: -4px;
  }
}

/* Equal columns: --rfig-n of them; --rfig-n-mid of them on middle widths (default --rfig-n); one
   on narrow figures. */
.rfig-cols {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(var(--rfig-n, 2), minmax(0, 1fr));
}

/* Four or more columns of cards with lists: a tighter gap and card padding so a two-word line
   ("bidirectional commit") stays on one line at the article width. */
.rfig-cols--dense {
  gap: 10px;
}

.rfig-cols--dense > .rfig-node {
  padding-left: 13px;
  padding-right: 13px;
}

.rfig-cols--dense > .rfig-node--strong {
  padding-left: 12px;
  padding-right: 12px;
}

/* As many cards per row as fit, each at least --rfig-min wide. */
.rfig-grid {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--rfig-min, 11rem)), 1fr));
}

/* A vertical pipeline of stages joined by down arrows, with tolls (a cost paid between stages). */
.rfig-pipe {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.rfig-pipe > .rfig-arrow {
  align-self: center;
}

/* A stage: its name and one line about it, on a faint ground of the column's hue. No icon in front.
   Markup: div.rfig-stage > span.rfig-name + span.rfig-note. */
.rfig-stage {
  align-content: start;
  background: color-mix(in srgb, var(--rf-h) 6%, var(--rfig-node));
  border: 1px solid color-mix(in srgb, var(--rf-h) 34%, transparent);
  display: grid;
  gap: 2px;
  min-width: 0;
  padding: 10px 14px 11px;
}

.rfig-toll {
  align-self: stretch;
  justify-content: center;
  text-align: center;
}

/* Ordered rungs with a rail on the left that runs through the level ramp: weak at the top, strong
   at the bottom. Markup: div.rfig-ladder[role=list] > div.rfig-rung.rfig-lv0..3[role=listitem],
   each with __head, __body and __side. */
.rfig-ladder {
  display: grid;
  gap: 10px;
  padding-left: 30px;
  position: relative;
}

.rfig-ladder::before {
  background: linear-gradient(180deg, var(--rfig-slate), var(--rfig-cyan) 38%, var(--rfig-blue) 68%, var(--rfig-indigo));
  bottom: 12px;
  content: "";
  left: 9px;
  position: absolute;
  top: 10px;
  width: 3px;
}

.rfig-ladder::after {
  background: var(--rfig-indigo);
  bottom: 2px;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  content: "";
  height: 11px;
  left: 4.5px;
  position: absolute;
  width: 12px;
}

.rfig-rung {
  align-items: start;
  background: var(--rfig-node);
  border: 1px solid var(--rfig-frame);
  column-gap: 18px;
  display: grid;
  grid-template-columns: minmax(0, var(--rfig-aside, 9.5rem)) minmax(0, 1fr) minmax(0, var(--rfig-side, 13.5rem));
  min-width: 0;
  padding: 14px 16px;
  position: relative;
  row-gap: 8px;
}

/* The rung's stop on the rail. */
.rfig-rung::before {
  background: var(--rf-h);
  box-shadow: 0 0 0 3px var(--rfig-sheet);
  content: "";
  height: 11px;
  left: -26px;
  position: absolute;
  top: 18px;
  width: 11px;
}

.rfig-rung__head,
.rfig-rung__body {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.rfig-rung__side {
  align-self: stretch;
}

/* The strongest rung: the whole rung one step deeper in tone, framed in the hue. */
.rfig-rung--key {
  background: var(--rf-h-tint);
  border: 2px solid var(--rf-h);
  box-shadow: var(--rfig-shadow);
  padding: 13px 15px;
}

.rfig-rung--key::before {
  left: -27px;
  top: 17px;
}

/* A verdict box: when, how, or whether something holds. Mute, tint or solid. */
.rfig-when {
  background: var(--rf-h-tint);
  border: 1px solid color-mix(in srgb, var(--rf-h) 40%, transparent);
  display: flex;
  flex-direction: column;
  gap: 3px;
  justify-content: center;
  min-width: 0;
  padding: 10px 12px;
}

.rfig-when__k {
  color: var(--rf-h-text);
  display: block;
  line-height: 1.35;
}

.rfig-when--mute {
  background: transparent;
  border-color: var(--rfig-hair);
}

.rfig-when--mute .rfig-when__k {
  color: var(--rfig-muted);
}

/* Solid: the deep fill under a transparent border, as .rfig-node--solid, with white words. */
.rfig-when--solid {
  background: linear-gradient(160deg, var(--rf-h-deep), color-mix(in srgb, var(--rf-h-deep) 80%, #000)) border-box;
  border-color: transparent;
  color: var(--rfig-on);
}

.rfig-when--solid :is(.rfig-when__k, .rfig-note) {
  color: var(--rfig-on);
}

/* Two parties and the messages between them, round by round (an interactive protocol). The lane
   between the parties is --rfig-lane wide; thin lifelines run down from each party.
   Markup: div.rfig-seq > div.rfig-seq__heads (two .rfig-party), then one div.rfig-round per round:
   .rfig-round__tag, .rfig-seq__a (left party's node), .rfig-msg (to the right party),
   .rfig-seq__b (right party's node), .rfig-msg.rfig-msg--back (back to the left party). */
.rfig-seq {
  --rfig-lane: 12.5rem;
  --rfig-life-a: color-mix(in srgb, var(--rfig-blue) 45%, transparent);
  --rfig-life-b: color-mix(in srgb, var(--rfig-mint) 50%, transparent);
  background:
    linear-gradient(var(--rfig-life-a) 0 0) calc((100% - var(--rfig-lane)) / 4) 0 / 1px 100% no-repeat,
    linear-gradient(var(--rfig-life-b) 0 0) calc(100% - (100% - var(--rfig-lane)) / 4) 0 / 1px 100% no-repeat;
  display: grid;
  gap: 14px;
}

.rfig-seq__heads,
.rfig-seq__foot {
  column-gap: var(--rfig-lane);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

.rfig-party {
  background: linear-gradient(160deg, var(--rf-h-deep), color-mix(in srgb, var(--rf-h-deep) 80%, #000));
  color: var(--rfig-on);
  line-height: 1.4;
  padding: 9px 12px;
  text-align: center;
}

.rfig-round {
  display: grid;
  grid-template-areas:
    "tag tag tag"
    "a fwd b"
    "a back b";
  grid-template-columns: minmax(0, 1fr) var(--rfig-lane) minmax(0, 1fr);
  grid-template-rows: auto 1fr 1fr;
  row-gap: 8px;
}

.rfig-round__tag {
  grid-area: tag;
  justify-self: center;
}

.rfig-seq__a {
  grid-area: a;
}

.rfig-seq__b {
  grid-area: b;
}

/* The party name inside a node: shown only where the columns stack (narrow figures). */
.rfig-seq__who {
  display: none;
}

.rfig-msg {
  align-content: end;
  display: grid;
  gap: 3px;
  grid-area: fwd;
  justify-items: center;
  min-width: 0;
  padding: 0 10px;
  text-align: center;
}

.rfig-msg--back {
  align-content: start;
  grid-area: back;
}

.rfig-msg > .rfig-arrow {
  width: 100%;
}

/* A round with one message only (the last one): the message sits in the middle of the lane. */
.rfig-round--final > .rfig-msg {
  align-content: center;
  grid-row: 2 / 4;
}

.rfig-msg__text {
  color: var(--rf-h-text);
  line-height: 1.4;
}

/* Bottom row of a sequence: values under each party. */
.rfig-seq__foot > * {
  min-width: 0;
}

/* Stacked bands (layers, tiers). Each band: an aside (label and title) and its content. A band is
   told from its neighbours by its tone alone (the level ramp from top to bottom), never by an edge. */
.rfig-layers {
  display: grid;
  gap: 6px;
}

.rfig-layer {
  background: var(--rf-h-tint);
  column-gap: 22px;
  display: grid;
  grid-template-columns: minmax(0, var(--rfig-aside, 9rem)) minmax(0, 1fr);
  padding: 14px 16px 16px;
  row-gap: 10px;
}

.rfig-layer__aside {
  align-self: center;
  display: grid;
  gap: 4px;
  min-width: 0;
}

/* Events on a time axis: across on wide figures, down on narrow ones.
   Markup: div.rfig-timeline[role=list] > div.rfig-event[role=listitem] > .rfig-event__when + text. */
.rfig-timeline {
  display: grid;
  gap: 16px;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
  padding-top: 28px;
  position: relative;
}

.rfig-timeline::before {
  background: linear-gradient(90deg, var(--rfig-from, var(--rf-h)), var(--rfig-to, var(--rf-h)));
  content: "";
  height: 2px;
  left: 0;
  position: absolute;
  right: 0;
  top: 9px;
}

.rfig-event {
  display: grid;
  gap: 4px;
  min-width: 0;
  position: relative;
}

.rfig-event::before {
  background: var(--rfig-sheet);
  border: 2px solid var(--rf-h);
  border-radius: 50%;
  content: "";
  height: 12px;
  left: 0;
  position: absolute;
  top: -24px;
  width: 12px;
}

.rfig-event--key::before {
  background: var(--rf-h);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--rf-h) 22%, transparent);
}

.rfig-event__when {
  color: var(--rf-h-text);
  font-variant-numeric: tabular-nums;
}

/* Table with ARIA roles. --rfig-cols sets the columns; it stacks on narrow figures, where a value
   cell with data-label shows that name first. Rows: --head, --key (the row that matters), --mute. */
.rfig-table {
  display: grid;
}

.rfig-tr {
  border-top: 1px solid var(--rfig-hair);
  column-gap: 22px;
  display: grid;
  grid-template-columns: var(--rfig-cols, minmax(0, 13rem) minmax(0, 1fr));
  padding: 11px 12px 12px;
  row-gap: 4px;
}

.rfig-tr--head {
  border-top: 0;
  padding-bottom: 9px;
  padding-top: 0;
}

.rfig-th {
  color: var(--rf-h-text);
  line-height: 1.4;
  min-width: 0;
}

.rfig-rh {
  color: var(--rfig-ink);
  line-height: 1.4;
  min-width: 0;
}

.rfig-td {
  color: var(--rfig-ink-soft);
  line-height: 1.55;
  min-width: 0;
}

/* A quiet row: muted colour, its weights unchanged (emphasis and quiet are colour and weight steps only). */
.rfig-tr--mute :is(.rfig-td, .rfig-rh) {
  color: var(--rfig-muted);
}

/* The row that matters: the whole row one step deeper in tone, ruled above and below in the hue,
   its words in ink. Say why it matters in words (a tag such as PROVED), never with a coloured edge. */
.rfig-tr--key {
  background: var(--rf-h-tint);
  border-top-color: color-mix(in srgb, var(--rf-h) 45%, transparent);
  box-shadow: 0 1px 0 color-mix(in srgb, var(--rf-h) 45%, transparent);
}

.rfig-tr--key :is(.rfig-td, .rfig-rh) {
  color: var(--rfig-ink);
}

/* A matrix: every cell boxed and centred; cells take hue or level classes for their ground. */
.rfig-table--grid .rfig-tr {
  border-top: 0;
  column-gap: 4px;
  padding: 0 0 4px;
}

.rfig-table--grid .rfig-td {
  align-content: center;
  background: var(--rf-h-tint);
  color: var(--rf-h-text);
  display: block;
  min-height: 38px;
  padding: 6px 8px;
  text-align: center;
}

.rfig-table--grid .rfig-rh {
  align-self: center;
}

/* Column heads of a matrix sit over the centre of their cells. */
.rfig-table--grid .rfig-th:not(:first-child) {
  text-align: center;
}

/* Bars: one value per row, as a share of the axis (--rfig-v, 0 to 1), or a range (--rfig-from and
   --rfig-to, 0 to 1) with .rfig-bar--range. The fill is the hue's deep value, flat: it passes 3:1
   against the sheet and the node in both themes (the pale start of the old gradient did not). The
   track is a hairline frame around the ground, not a tint, so the fill is read against the ground. */
.rfig-bars {
  align-items: center;
  display: grid;
  gap: 10px 14px;
  grid-template-columns: minmax(0, max-content) minmax(6rem, 1fr) minmax(0, max-content);
}

.rfig-bar-row {
  display: contents;
}

.rfig-bar-label {
  color: var(--rfig-ink);
  min-width: 0;
}

.rfig-bar {
  box-shadow: inset 0 0 0 1px var(--rfig-hair);
  height: 12px;
  position: relative;
}

.rfig-bar::before {
  background: var(--rf-h-deep);
  bottom: 0;
  content: "";
  left: 0;
  position: absolute;
  top: 0;
  width: calc(var(--rfig-v, 0) * 100%);
}

.rfig-bar--range::before {
  left: calc(var(--rfig-from, 0) * 100%);
  width: calc((var(--rfig-to, 0) - var(--rfig-from, 0)) * 100%);
}

.rfig-bar-value {
  color: var(--rf-h-text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Bars with a reference line (a limit, a target, a survival line): .rfig-bars.rfig-bars--line with
   --rfig-line (0 to 1, on the same axis as the bars). Rows are one line high (labels do not wrap), so
   each bar draws its piece of the line across its row and half the gap on each side, and the pieces
   meet into one dashed line. A mark row names the line:
   div.rfig-bar-row.rfig-bar-row--mark > span.rfig-bar-label + span.rfig-bar-mark + span.rfig-bar-value
   (label and value empty). The line is ink, not a hue: it is a reference, not a category. */
.rfig-bars--line {
  grid-auto-rows: 28px;
  row-gap: 6px;
}

.rfig-bars--line .rfig-bar-label {
  white-space: nowrap;
}

.rfig-bars--line .rfig-bar::after,
.rfig-bar-mark::after {
  background: repeating-linear-gradient(180deg, currentColor 0 4px, transparent 4px 7px);
  bottom: -11px;
  color: var(--rfig-ink-soft);
  content: "";
  left: calc(var(--rfig-line, 0.5) * 100% - 0.75px);
  position: absolute;
  top: -11px;
  width: 1.5px;
}

.rfig-bar-mark {
  align-items: center;
  align-self: stretch;
  color: var(--rfig-ink-soft);
  display: flex;
  min-width: 0;
  padding-left: calc(var(--rfig-line, 0.5) * 100% + 8px);
  position: relative;
  white-space: nowrap;
}

/* The mark row starts the line at its own middle. */
.rfig-bar-mark::after {
  top: 50%;
  bottom: -3px;
}

/* A value axis on bars (rules 0.5, 5.5): span.rfig-bars__axis[aria-hidden=true] as the first child of .rfig-bars,
   holding span.rfig-bars__tick[style="--rfig-v:.5"] with its value, one tick per step of the scale from 0 to its
   end. It is laid over the bar column only (grid column 2, absolutely placed, so it takes no cell): a light
   gridline down the column at each tick, the values in a band under the last row and the zero axis on the left
   edge in muted ink. Under a mark row (--line) it starts below that row. On a phone such bars keep their three
   columns, so their row names stay short (the narrow rules at the end). */
.rfig-bars:has(> .rfig-bars__axis) {
  padding-bottom: 26px;
  position: relative;
}

.rfig-bars__axis {
  bottom: 26px;
  /* Both lines: with only the start line, an absolutely placed grid child takes the auto end line and stretched
     over the value column too, so the ticks sat off the bar scale (W7 writer report 2026-10-18). */
  grid-column: 2 / 3;
  left: 0;
  pointer-events: none;
  position: absolute;
  right: 0;
  top: 0;
}

.rfig-bars--line > .rfig-bars__axis {
  top: 34px;
}

.rfig-bars__axis::before {
  background: var(--rfig-muted);
  bottom: 0;
  content: "";
  left: -0.75px;
  position: absolute;
  top: 0;
  width: 1.5px;
  z-index: 1;
}

.rfig-bars__tick {
  align-items: center;
  bottom: -26px;
  color: var(--rfig-muted);
  display: flex;
  flex-direction: column;
  font-variant-numeric: tabular-nums;
  justify-content: flex-end;
  left: calc(var(--rfig-v, 0) * 100%);
  line-height: 1.2;
  position: absolute;
  top: 0;
  white-space: nowrap;
  width: 0;
}

.rfig-bars__tick::before {
  background: var(--rfig-frame);
  bottom: 26px;
  content: "";
  left: -0.5px;
  position: absolute;
  top: 0;
  width: 1px;
}

/* Stair bars: a value stepping down (or up) phase by phase toward a reference line. Each stair is a
   column: its name, a bar whose height is its share of the axis (--rfig-v, 0 to 1) with the value
   inside its top, then at most a gate and a note under the name. A stair after the first carries the
   previous value as --rfig-from and draws the step: along the top of the previous bar, then down onto
   its own, the head on its top edge. A stair reached through a gate (conditions a step must pass)
   holds .rfig-stair__gate, and the step carries an open diamond. The reference line (--rfig-line on
   .rfig-stairs, 0 to 1) is dashed ink across the bars and is drawn only when .rfig-stairs__line
   names it; the name sits over the last column, whose bar ends at or under the line.
   Markup:
   div.rfig-stairs[role=list][style="--rfig-n:3; --rfig-line:.55"]
     > div.rfig-stair[role=listitem][style="--rfig-v:.92"]
         > span.rfig-stair__name + span.rfig-stair__bar > span.rfig-stair__value, + span.rfig-stair__note
     > div.rfig-stair[role=listitem][style="--rfig-v:.67; --rfig-from:.92"]
         > span.rfig-stair__name + span.rfig-stair__bar (value) + span.rfig-stair__gate
     > span.rfig-stairs__line (last child: the line's name)
   Keep every bar at 0.2 of the axis or more so its value fits inside (scale the axis: 55% of a 0 to
   60% axis is 0.92).
   A value axis (rules 0.5, 5.5) goes first: span.rfig-stairs__axis[aria-hidden=true] > span.rfig-stairs__tick
   [style="--rfig-v:.333"] (its value inside, four characters or fewer; the unit is in the chart name), one tick per
   step of the scale from 0 to its top. The stairs then take a gutter on the left for the tick values, draw a light
   gridline across the bars at each tick and the baseline as the zero axis. */
/* The gap between stairs follows the chart's own width (7%, 12 to 28px): a chart in half a figure
   keeps room for its words. The stairs read the same gap in cqi, the chart being their container. */
.rfig-stairs {
  --rf-stair-h: 9.5rem;
  column-gap: clamp(12px, 7%, 28px);
  container: rfig-stairs / inline-size;
  display: grid;
  grid-template-columns: repeat(var(--rfig-n, 3), minmax(0, 1fr));
  grid-template-rows: var(--rf-stair-h) auto auto auto;
  min-width: 0;
  position: relative;
}

/* With an axis: a first column for the tick values (the stairs keep their own width as the chart width, so its narrow
   steps below are unchanged), the top value half a line over the bars (hence the margin) and the baseline as a zero
   axis in muted ink. The axis takes the first cell of the bar row, so every stair, held to all rows, falls into the
   columns after it in order. */
.rfig-stairs:has(> .rfig-stairs__axis) {
  /* 2.5rem from a 300px chart up, 2rem under it (a half-width chart on a phone or at 1280: the bars keep room). The
     percentage is the chart's own width wherever the gutter is read (grid track, offsets of its lines). */
  --rf-axis-w: clamp(2rem, calc((100% - 300px) * 1000 + 2rem), 2.5rem);
  --rf-base: var(--rfig-muted);
  --rf-base-w: 1.5px;
  grid-template-columns: var(--rf-axis-w) repeat(var(--rfig-n, 3), minmax(0, 1fr));
  margin-top: 8px;
}

.rfig-stairs__axis {
  grid-column: 1;
  grid-row: 1;
  min-width: 0;
  pointer-events: none;
  position: relative;
}

/* A tick value, right-aligned in the gutter at its height, and its gridline across the bars (frame colour, behind
   the bars: the axis comes first, so the bars are drawn over it). */
.rfig-stairs__tick {
  color: var(--rfig-muted);
  font-variant-numeric: tabular-nums;
  left: 0;
  line-height: 1.2;
  position: absolute;
  right: 6px;
  text-align: right;
  top: calc((1 - var(--rfig-v, 0)) * 100%);
  transform: translateY(-50%);
  white-space: nowrap;
}

.rfig-stairs__tick::before {
  background: var(--rfig-frame);
  content: "";
  height: 1px;
  left: calc(100% + 6px);
  position: absolute;
  top: 50%;
  width: calc(100cqi - 100% - 6px);
}

.rfig-stair {
  --rf-stair-gap: clamp(12px, 7cqi, 28px);
}

/* A narrow chart (in half a figure, or on a phone) sets its words a step smaller, by its own width: the
   value, name and small tokens step down inside the chart only. At 1440 a chart this narrow is off the role
   table, and the checker says so: give the chart more width there. */
@container rfig-stairs (max-width: 299px) {
  .rfig-stairs .rfig-stair__value {
    --rf-value-top: 6px;
    --rfig-t-value-size: 14px;
    padding-inline: 2px;
  }

  .rfig-stairs .rfig-stair__name {
    --rfig-t-name-size: 13.5px;
  }

  .rfig-stairs .rfig-stairs__tick {
    --rfig-t-small-size: 12px;
  }
}

@container rfig-stairs (max-width: 259px) {
  .rfig-stairs .rfig-stair__value {
    --rfig-t-value-size: 13px;
  }

  .rfig-stairs .rfig-stair__name {
    --rfig-t-name-size: 13px;
  }
}

@container rfig-stairs (max-width: 219px) {
  .rfig-stairs .rfig-stair__gate,
  .rfig-stairs .rfig-stair__note,
  .rfig-stairs .rfig-stairs__line {
    --rfig-t-small-size: 12px;
  }
}

/* The baseline under the bars, from the end of the gutter when there is an axis (then it is the zero axis: muted
   ink, 1.5px, over the zero gridline). */
.rfig-stairs::before {
  background: var(--rf-base, var(--rfig-frame));
  content: "";
  height: var(--rf-base-w, 1px);
  left: var(--rf-axis-w, 0px);
  position: absolute;
  right: 0;
  top: var(--rf-stair-h);
  z-index: 1;
}

/* The reference line, over the bars. */
.rfig-stairs:has(> .rfig-stairs__line)::after {
  background: repeating-linear-gradient(90deg, currentColor 0 5px, transparent 5px 9px);
  color: var(--rfig-ink-soft);
  content: "";
  height: 1.5px;
  left: var(--rf-axis-w, 0px);
  pointer-events: none;
  position: absolute;
  right: 0;
  top: calc(var(--rf-stair-h) * (1 - var(--rfig-line, 0.5)) - 0.75px);
  z-index: 1;
}

/* The line's name: a key in the top right corner of the chart, a dashed sample before the words, so
   it never meets a step or a value however narrow the chart is. Keep the last two bars under 0.85 of
   the axis so the corner stays free. */
.rfig-stairs__line {
  align-items: center;
  background: var(--rf-ground);
  color: var(--rfig-ink-soft);
  column-gap: 7px;
  display: inline-flex;
  line-height: 1.3;
  padding-left: 4px;
  position: absolute;
  right: 0;
  top: 0;
  white-space: nowrap;
  z-index: 2;
}

.rfig-stairs__line::before {
  background: repeating-linear-gradient(90deg, currentColor 0 5px, transparent 5px 9px);
  content: "";
  flex: none;
  height: 1.5px;
  width: 23px;
}

.rfig-stair {
  color: var(--rf-h);
  display: grid;
  grid-row: 1 / -1;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: subgrid;
  min-width: 0;
  position: relative;
  text-align: center;
}

/* The bar: a pale field with the hue's edge and a deep top, the value inside the top. Edges are
   drawn inside the box, so the step lines meet its corners exactly. */
.rfig-stair__bar {
  align-self: end;
  background: var(--rf-h-tint);
  box-shadow: inset 0 3px 0 var(--rf-h-deep), inset 0 0 0 1px var(--rf-h);
  display: block;
  grid-row: 1;
  height: calc(var(--rfig-v, 0) * 100%);
  position: relative;
}

/* The value sits over the reference line where the line crosses it: its own small field of the bar's
   tint covers the line behind the words only. */
/* A value whose bar top sits less than 0.2 of the axis above the reference line would have the dashed line
   run through it (it reads as struck out). The kit then moves the value under the line, inside the bar:
   --rf-near is 1 in that case and 0 otherwise, from the stair's --rfig-v and the chart's --rfig-line.
   The value is the value role (22px; 19px on phones): one line set solid, 4px under the bar's deep top,
   so a bar of 0.2 of the axis (30px; 26px on phones) still holds it (rules 5.5). */
.rfig-stair__value {
  --rf-gapv: calc(var(--rfig-v, 0) - var(--rfig-line, -1));
  --rf-near: calc(clamp(0, (0.2 - var(--rf-gapv)) * 1000, 1) * clamp(0, var(--rf-gapv) * 1000 + 1, 1));
  background: var(--rf-h-tint);
  color: var(--rf-h-text);
  display: block;
  line-height: 1;
  margin: calc(var(--rf-value-top, 4px) + var(--rf-near) * (var(--rf-gapv) * var(--rf-stair-h) - 1px)) auto 0;
  padding: 1px 4px;
  position: relative;
  white-space: nowrap;
  width: fit-content;
  z-index: 2;
}

/* The words under a stair break between words only: a long word in a narrow column reaches a little into the gap
   beside it (as a chart's labels do) rather than splitting as "probati / on"; words that would meet their
   neighbour's are too long for the chart, and the checker finds them overlapping. */
.rfig-stair__name {
  color: var(--rfig-ink);
  grid-row: 2;
  line-height: 1.3;
  overflow-wrap: normal;
  padding-top: 9px;
}

.rfig-stair__gate,
.rfig-stair__note {
  color: var(--rfig-muted);
  line-height: 1.4;
  overflow-wrap: normal;
  padding-top: 3px;
}

.rfig-stair__gate {
  color: var(--rfig-ink-soft);
  grid-row: 3;
}

/* A note takes the gate's line when its stair has no gate, and the line under it when it has one. */
.rfig-stair__note {
  grid-row: 3;
}

.rfig-stair:has(> .rfig-stair__gate) > .rfig-stair__note {
  grid-row: 4;
}

/* The step from the previous bar: across the gap at the previous height, then down onto this bar. */
.rfig-stair + .rfig-stair > .rfig-stair__bar::before,
.rfig-stair + .rfig-stair > .rfig-stair__bar::after {
  background: currentColor;
  content: "";
  position: absolute;
  top: calc(-1 * (var(--rfig-from, 0) - var(--rfig-v, 0)) * var(--rf-stair-h) - 0.75px);
}

.rfig-stair + .rfig-stair > .rfig-stair__bar::before {
  height: 1.5px;
  left: calc(-1 * var(--rf-stair-gap));
  width: calc(var(--rf-stair-gap) + 16.75px);
}

.rfig-stair + .rfig-stair > .rfig-stair__bar::after {
  clip-path: polygon(calc(50% - 0.75px) 0, calc(50% + 0.75px) 0, calc(50% + 0.75px) calc(100% - 9px), 100% calc(100% - 9px), 50% 100%, 0 calc(100% - 9px), calc(50% - 0.75px) calc(100% - 9px));
  height: calc((var(--rfig-from, 0) - var(--rfig-v, 0)) * var(--rf-stair-h) + 0.75px);
  left: 11px;
  width: 10px;
}

/* Stairs going up (.rfig-stairs--up): the step runs from the top of the lower bar straight across
   into the side of the taller one, the head on its edge. */
.rfig-stairs--up .rfig-stair + .rfig-stair > .rfig-stair__bar::before {
  content: none;
}

.rfig-stairs--up .rfig-stair + .rfig-stair > .rfig-stair__bar::after {
  clip-path: polygon(0 calc(50% - 0.75px), calc(100% - 9px) calc(50% - 0.75px), calc(100% - 9px) 0, 100% 50%, calc(100% - 9px) 100%, calc(100% - 9px) calc(50% + 0.75px), 0 calc(50% + 0.75px));
  height: 10px;
  left: calc(-1 * var(--rf-stair-gap) - 16px);
  top: calc((var(--rfig-v, 0) - var(--rfig-from, 0)) * var(--rf-stair-h) - 5px);
  width: calc(var(--rf-stair-gap) + 16px);
}

/* The gate on the step, in the middle of the gap, at the height of the previous bar. */
.rfig-stair:has(> .rfig-stair__gate) > .rfig-stair__name::before {
  background: var(--rf-ground);
  box-shadow: inset 0 0 0 1.5px currentColor;
  color: var(--rf-h);
  content: "";
  height: 10px;
  left: calc(-1 * var(--rf-stair-gap) / 2 - 5px);
  position: absolute;
  top: calc(var(--rf-stair-h) * (1 - var(--rfig-from, 0)) - 5px);
  transform: rotate(45deg);
  width: 10px;
  z-index: 1;
}

/* A gauge: one scale cut into named bands (a fill level: Critical, Building, Surplus), ticks at the
   band edges and, when it matters, a mark at the current value. Positions are shares of the scale,
   0 to 1: a band takes --rfig-from and --rfig-to, a tick and the mark take --rfig-v. A scale that runs
   past 100% maps its end to 1 (100% of a 0 to 150% scale is 0.667).
   Markup: div.rfig-gauge > span.rfig-gauge__band.rfig-tone-neg[style="--rfig-from:0; --rfig-to:.333"]
   (its name inside), more bands, span.rfig-gauge__tick[style="--rfig-v:.333"] (its value inside),
   optional span.rfig-gauge__mark[style="--rfig-v:.6"]. Band names fit their band (one short word). */
.rfig-gauge {
  height: 34px;
  margin-bottom: 26px;
  min-width: 0;
  position: relative;
}

.rfig-gauge:has(> .rfig-gauge__mark) {
  margin-top: 30px;
}

/* A band: the pale ground of its hue under a 3px top in the deep value, as a stair bar's top (a solid top on the
   tint of its own hue fell under 3:1 for mint, 2026-10-17). */
.rfig-gauge__band {
  align-items: center;
  background: var(--rf-h-tint);
  box-shadow: inset 0 3px 0 var(--rf-h-deep);
  color: var(--rf-h-text);
  display: flex;
  height: 100%;
  justify-content: center;
  left: calc(var(--rfig-from, 0) * 100% + 1px);
  padding: 3px 6px 0;
  position: absolute;
  top: 0;
  white-space: nowrap;
  width: calc((var(--rfig-to, 1) - var(--rfig-from, 0)) * 100% - 2px);
}

.rfig-gauge__tick {
  color: var(--rfig-ink-soft);
  font-variant-numeric: tabular-nums;
  left: calc(var(--rfig-v, 0) * 100%);
  line-height: 1.2;
  position: absolute;
  top: calc(100% + 7px);
  transform: translateX(-50%);
  white-space: nowrap;
}

.rfig-gauge__tick::before {
  background: currentColor;
  content: "";
  height: 10px;
  left: calc(50% - 0.5px);
  position: absolute;
  top: -10px;
  width: 1px;
}

.rfig-gauge__mark {
  bottom: calc(100% + 9px);
  color: var(--rfig-ink);
  left: calc(var(--rfig-v, 0) * 100%);
  line-height: 1.2;
  position: absolute;
  transform: translateX(-50%);
  white-space: nowrap;
}

.rfig-gauge__mark::after {
  background: currentColor;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  content: "";
  height: 7px;
  left: calc(50% - 5px);
  position: absolute;
  top: calc(100% + 2px);
  width: 10px;
}

/* ---------- Notes, legend, wide content ---------- */

/* A thin solid rule above an element. */
.rfig-bound {
  border-top: 1px solid var(--rfig-frame);
  padding-top: 14px;
}

.rfig-notes {
  display: grid;
  gap: 6px;
}

.rfig-legend {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
}

.rfig-legend__item {
  color: var(--rfig-ink-soft);
  display: inline-block;
  line-height: 1.5;
}

/* The sample in front of a legend line: a swatch or an arrow, on the text's middle. */
.rfig-legend__item > .rfig-swatch,
.rfig-legend__item > .rfig-arrow {
  display: inline-block;
  margin-right: 8px;
  vertical-align: middle;
}

/* Sample of a hue in a legend (aria-hidden): a tint with the hue's edge, or solid. The solid swatch is
   the deep value, the same colour as a filled bar, a solid node and an SVG .s-solid shape, so a legend
   and the shape it names always match. */
.rfig-swatch {
  background: var(--rf-h-tint);
  border: 1.5px solid var(--rf-h);
  display: inline-block;
  flex: none;
  height: 12px;
  width: 18px;
}

.rfig-swatch--solid {
  background: var(--rf-h-deep);
  border-color: var(--rf-h-deep);
}

/* A line sample for a legend: dashed for a return or a reference line. */
.rfig-swatch--line,
.rfig-swatch--dash {
  background: linear-gradient(currentColor 0 0) 0 50% / 100% 1.5px no-repeat;
  border: 0;
  color: var(--rf-h);
}

.rfig-swatch--dash {
  background: repeating-linear-gradient(90deg, currentColor 0 4px, transparent 4px 7px) 0 50% / 100% 1.5px no-repeat;
}

/* Production rule: figures never contain a second scrolling surface. Wide content must
   reflow or be split into multiple panels during conversion. */
.rfig-scroll {
  max-width: 100%;
  overflow: visible;
}

.rfig-scroll > * {
  min-width: 0;
}

.rfig-scroll-hint {
  color: var(--rfig-muted);
  display: none;
  margin-top: -10px;
  text-align: right;
}

/* ---------- SVG drawings ---------- */

/* For drawings the HTML parts cannot express (state graphs, curves, geometry, a radial hub): one
   inline <svg class="rfig-svg" viewBox="..."> whose shapes and text take these classes, never
   colours. Hue and level classes work on <g> and on shapes. The scale is fixed (rules 0.2): a wide
   version is 640 units across and draws at most 640px wide (1 unit = 1px at 1440), a narrow version
   is 320 units across and draws at most 420px; .rfig-wide and .rfig-narrow show one or the other and
   set these widths, so a drawing needs no --rfig-svg-max of its own. Arrowheads: a marker with
   markerUnits="userSpaceOnUse" whose tip (refX) is the end of the path, so the tip lands on the box
   edge the path ends at; a marker takes the hue of the element it sits in, so give each hue its own
   marker inside a <g> of that hue in <defs>. Rules section 5.4 has the full recipe. */
.rfig-svg {
  display: block;
  font-family: var(--rfig-t-name-family);
  height: auto;
  margin-inline: auto;
  max-width: var(--rfig-svg-max, 640px);
  overflow: visible;
  width: 100%;
}

.rfig-svg.rfig-wide {
  --rfig-svg-max: 640px;
}

.rfig-svg.rfig-narrow {
  --rfig-svg-max: 420px;
}

/* Words in a drawing take the roles of the type table in user units, as classes on text and tspan, with no
   font-size, font-weight or font-family attribute: t-label, t-name, t-body, t-small, t-value, t-math, and t-sub
   or t-sup on the tspan of a script. A text without a role class is a name. The older classes are aliases:
   s-text is t-body, s-label is t-label, s-math is t-math, s-cond is t-small in the hue with a halo of its
   ground, and s-halo gives that halo to any text. A text that still carries a font-size attribute is not
   migrated: it keeps its attribute size and the older look (s-label and s-cond at weight 600) until its
   writer removes the attribute, and the checker fails every such attribute. */
.rfig-svg text {
  fill: var(--rfig-ink);
  font-family: var(--rfig-t-name-family);
}

.rfig-svg :where(text:not([font-size])),
.rfig-svg .t-name {
  font-family: var(--rfig-t-name-family);
  font-size: var(--rfig-t-name-size);
  font-weight: var(--rfig-t-name-weight);
  letter-spacing: var(--rfig-t-track);
  text-transform: var(--rfig-t-case);
}

/* Every role rule weighs the same (one class after .rfig-svg), so the later one decides where a text has two:
   a formula class wins over the body class. */
.rfig-svg :is(.t-label, .s-label:where(:not([font-size]))) {
  font-family: var(--rfig-t-label-family);
  font-size: var(--rfig-t-label-size);
  font-weight: var(--rfig-t-label-weight);
  letter-spacing: var(--rfig-t-label-track);
  text-transform: var(--rfig-t-label-case);
}

.rfig-svg :is(.t-body, .s-text:where(:not([font-size]))) {
  font-family: var(--rfig-t-body-family);
  font-size: var(--rfig-t-body-size);
  font-weight: var(--rfig-t-body-weight);
  letter-spacing: var(--rfig-t-track);
  text-transform: var(--rfig-t-case);
}

.rfig-svg :is(.t-small, .s-cond:where(:not([font-size]))) {
  font-family: var(--rfig-t-small-family);
  font-size: var(--rfig-t-small-size);
  font-weight: var(--rfig-t-small-weight);
  letter-spacing: var(--rfig-t-track);
  text-transform: var(--rfig-t-case);
}

.rfig-svg .t-value {
  font-family: var(--rfig-t-value-family);
  font-size: var(--rfig-t-value-size);
  font-variant-numeric: tabular-nums;
  font-weight: var(--rfig-t-value-weight);
  letter-spacing: var(--rfig-t-value-track);
  text-transform: var(--rfig-t-case);
}

/* A formula: the faces of the article formulas; a tspan with font-style="italic" inside it (a variable) is
   KaTeX_Math. Its size is the math size, or its line's where that is larger (a formula inside a value). */
.rfig-svg :is(.t-math, .s-math) {
  font-family: var(--rfig-t-math-family);
  font-weight: var(--rfig-t-math-weight);
  letter-spacing: var(--rfig-t-track);
  text-transform: var(--rfig-t-case);
}

.rfig-svg :is(.t-math, :where(text.s-math:not([font-size]), text:not([font-size]) tspan.s-math:not([font-size]))):not(.t-sub, .t-sup) {
  font-size: max(var(--rfig-t-math-size), 1em);
}

.rfig-svg :is(.t-math, .s-math)[font-style="italic"],
.rfig-svg :is(.t-math, .s-math) [font-style="italic"] {
  font-family: var(--rfig-t-math-var-family);
}

/* Scripts: 0.72 of their line; a subscript 3 units under its baseline, a superscript a third of its line above it. */
.rfig-svg :is(.t-sub, .t-sup) {
  font-size: var(--rfig-t-script);
}

.rfig-svg .t-sub {
  baseline-shift: calc(-1 * var(--rfig-t-sub-shift));
}

.rfig-svg .t-sup {
  baseline-shift: var(--rfig-t-sup-shift);
}

/* Not migrated yet (the text still carries a font-size attribute): the older look of the aliases. */
.rfig-svg .s-text[font-size] {
  font-family: var(--rfig-t-body-family);
}

.rfig-svg .s-label[font-size] {
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.rfig-svg .s-cond[font-size] {
  font-weight: 600;
}

/* Colours of the roles; s-hue, s-on and s-cond (below) override them. */
.rfig-svg :is(.t-body, .s-text) {
  fill: var(--rfig-ink-soft);
}

.rfig-svg :is(.t-label, .s-label, .t-small) {
  fill: var(--rfig-muted);
}

.rfig-svg .t-value {
  fill: var(--rf-h-text);
}

.rfig-svg .s-hue {
  fill: var(--rf-h-text);
}

.rfig-svg .s-node {
  fill: var(--rfig-node);
  stroke: var(--rfig-frame);
}

.rfig-svg .s-tint {
  fill: var(--rf-h-tint);
  stroke: color-mix(in srgb, var(--rf-h) 40%, transparent);
}

.rfig-svg .s-solid {
  fill: var(--rf-h-deep);
}

.rfig-svg .s-on {
  fill: var(--rfig-on);
}

.rfig-svg .s-line {
  fill: none;
  stroke: var(--rf-h);
  stroke-width: 1.5;
}

.rfig-svg .s-dash {
  fill: none;
  stroke: var(--rf-h);
  stroke-dasharray: 5 4;
  stroke-width: 1.5;
}

.rfig-svg .s-bound {
  fill: none;
  stroke: var(--rfig-frame);
}

/* A neutral line that carries meaning (a region boundary, the branches of a tree): muted ink, 5.5:1 or
   more on the sheet in both themes. It is not a hue and does not count toward the colours of a figure. */
.rfig-svg .s-edge {
  fill: none;
  stroke: var(--rfig-muted);
  stroke-width: 1.5;
}

/* The absent mark of .rfig-sq--off in SVG: one path, a square and its diagonal, in muted ink. Draw it as
   <path class="s-off" d="M0.5 0.5H8.5V8.5H0.5Z M0.5 8.5L8.5 0.5"/> moved into place. Neutral, not a hue. */
.rfig-svg .s-off {
  fill: none;
  stroke: var(--rfig-muted);
  stroke-width: 1.25;
}

/* An empty data bar: a count drawn without a hue beside filled bars (events beside Sync Units), the node ground
   in a 1.5 muted outline, one rect. The outlined counterpart of s-solid; neutral, not a hue. Its legend sample is
   the same rect, small. */
.rfig-svg .s-hollow {
  fill: var(--rfig-node);
  stroke: var(--rfig-muted);
  stroke-width: 1.5;
}

.rfig-svg .s-head,
.rfig-svg .s-dot {
  fill: var(--rf-h);
  stroke: none;
}

/* The box a drawing is about: a pale field with a 2px edge in the hue. */
.rfig-svg .s-strong {
  fill: var(--rf-h-tint);
  stroke: var(--rf-h);
  stroke-width: 2;
}

/* A path with an arrowhead marker (the same line as .s-line). */
.rfig-svg .s-arrow {
  fill: none;
  stroke: var(--rf-h);
  stroke-width: 1.5;
}

/* A reference line (a limit, a threshold): dashed ink, not a hue. */
.rfig-svg .s-ref {
  fill: none;
  stroke: var(--rfig-ink-soft);
  stroke-dasharray: 5 4;
  stroke-width: 1.5;
}

/* The crossed square of a path that does not exist: a square .s-xbox and its two strokes .s-xline. Its fill is the
   ground under it: the sheet, unless the group says it sits inside a white box (s-in-node, below). */
.rfig-svg .s-xbox {
  fill: var(--rf-ground);
  stroke: var(--rf-h);
  stroke-width: 1.5;
}

/* A group drawn inside a white node box (an X mark, a word with a halo): its ground is the node, not the sheet, so
   the X square and the halos match the box. <g class="rfig-tone-neg s-in-node">. */
.rfig-svg .s-in-node {
  --rf-ground: var(--rfig-node);
}

.rfig-svg .s-xline {
  fill: none;
  stroke: var(--rf-h);
  stroke-linecap: square;
  stroke-width: 2;
}

/* A condition written on a line (small, the text part of s-cond): the hue's text colour, with a halo of the
   ground so the line under it gives way. .s-halo gives the same halo to any other text that crosses a line. */
.rfig-svg .s-cond {
  fill: var(--rf-h-text);
}

.rfig-svg :is(.s-cond, .s-halo) {
  paint-order: stroke;
  stroke: var(--rf-ground);
  stroke-linejoin: round;
  stroke-width: 4px;
}

/* ---------- Compositions built from the parts ---------- */

/* A phrase in the local hue at the emphasis weight: the answer a row or a panel arrives at. Also on code. */
.rfig .rfig-em {
  color: var(--rf-h-text);
}

/* A short instruction line inside a node, in the hue ("Consistency check:"); a name. */
.rfig-step {
  color: var(--rf-h-text);
  display: block;
  line-height: 1.35;
}

/* A formula on its own line (math). */
.rfig-formula {
  color: var(--rfig-ink);
  display: block;
  line-height: 1.45;
}

/* A worked example inside a node: a quiet box on the sheet ground. */
.rfig-example {
  background: var(--rfig-sheet);
  border: 1px solid var(--rfig-hair);
  display: grid;
  gap: 4px;
  padding: 10px 12px;
}

/* Summary at the foot of a panel: a large value and the line that explains it. */
.rfig-sum {
  background: var(--rf-h-tint);
  border: 1px solid color-mix(in srgb, var(--rf-h) 40%, transparent);
  display: grid;
  gap: 2px;
  justify-items: center;
  padding: 12px 14px;
  text-align: center;
}

/* The conclusion under a sequence or a flow, centred under both parties. */
.rfig-result {
  align-items: center;
  justify-self: center;
  max-width: 36rem;
  text-align: center;
  width: 100%;
}

/* Degree card head: the large degree glyph beside its name. */
.rfig-degree {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
}

/* A name or label with what sits beside it on one line: a chip (tag, number, mark), a value or a short emphasis
   ("Direct compensation [OZ]", "WHAT IS PROVED [UNIVERSAL]", "D-quencer finality 1–2 s"). Every piece stands on the
   label's baseline (a tag would otherwise sit at the top, its rule in a column); the line wraps under the label
   where the box is too narrow. Markup: div.rfig-chipline > span.rfig-name (or .rfig-kicker) + chips. */
.rfig-chipline {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
}

.rfig-chipline > * {
  align-self: baseline;
}

/* A pairing written as code: Asset<S0> -> Path<S3>. */
.rfig-pair {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 0;
}

.rfig-pair > .rfig-arrow {
  margin: 0 10px;
}

/* A statement in logic with its kind beside it (UNIVERSAL, EXISTENTIAL). */
.rfig-quant {
  align-items: center;
  background: var(--rf-h-tint);
  border: 1px solid color-mix(in srgb, var(--rf-h) 40%, transparent);
  color: var(--rf-h-text);
  display: flex;
  flex-wrap: wrap;
  gap: 6px 12px;
  justify-content: space-between;
  padding: 8px 12px;
}

.rfig-quant .rfig-math {
  color: var(--rf-h-text);
}

.rfig-quant--solid {
  /* The fill reaches under a transparent border (border-box), so the edge is the fill itself; a deep border on the
     deep fill drew nothing and made check-figures measure it as a 1.18:1 mark (2026-10-17). */
  background: linear-gradient(160deg, var(--rf-h-deep), color-mix(in srgb, var(--rf-h-deep) 80%, #000)) border-box;
  border-color: transparent;
}

.rfig-quant--solid .rfig-math {
  color: var(--rfig-on);
}

.rfig-quant--solid .rfig-tag {
  background: transparent;
  border-color: color-mix(in srgb, var(--rfig-on) 60%, transparent);
  color: var(--rfig-on);
}

/* Verdict line at the foot of a panel: a rule, then the claim in the hue. */
.rfig-verdict {
  border-top: 1px solid var(--rfig-hair);
  display: grid;
  gap: 3px;
  padding-top: 10px;
}

.rfig-verdict__claim {
  color: var(--rf-h-text);
  line-height: 1.35;
}

/* ---------- Narrow figures (phones, narrow columns) ---------- */

/* Four columns need about 760px before their lines start to wrap; below that, --rfig-n-mid. */
@container rfig (max-width: 759px) {
  .rfig-cols {
    grid-template-columns: repeat(var(--rfig-n-mid, var(--rfig-n, 2)), minmax(0, 1fr));
  }

  /* The drop connectors only make sense while the columns hang in one row under the band. */
  .rfig-cols--drop {
    margin-top: 0;
  }

  .rfig-cols--drop > * {
    margin-top: 0;
  }

  .rfig-cols--drop > *::after {
    content: none;
  }
}

@container rfig (max-width: 699px) {
  .rfig-rung {
    grid-template-columns: minmax(0, var(--rfig-aside, 9.5rem)) minmax(0, 1fr);
  }

  .rfig-rung__side {
    grid-column: 1 / -1;
  }
}

@container rfig (max-width: 639px) {
  /* The sequence turns into one column: node, message down, node, message up. */
  .rfig-seq {
    background: none;
    gap: 18px;
  }

  .rfig-seq__heads {
    display: none;
  }

  .rfig-seq__who {
    display: block;
  }

  .rfig-seq__foot {
    column-gap: 10px;
  }

  .rfig-round {
    grid-template-areas:
      "tag"
      "a"
      "fwd"
      "b"
      "back";
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    row-gap: 6px;
  }

  .rfig-round__tag {
    justify-self: start;
  }

  .rfig-msg,
  .rfig-msg--back {
    align-items: center;
    display: flex;
    gap: 10px;
    justify-content: flex-start;
    padding: 0 0 0 16px;
    text-align: left;
  }

  .rfig-round--final > .rfig-msg {
    grid-row: auto;
  }

  .rfig-msg > .rfig-arrow {
    --rf-dash-dir: 180deg;
    flex: none;
    height: 28px;
    order: -1;
    width: 10px;
  }

  .rfig-msg > .rfig-arrow::before {
    bottom: 7px;
    height: auto;
    left: 4.25px;
    right: auto;
    top: 0;
    width: 1.5px;
  }

  .rfig-msg > .rfig-arrow::after {
    bottom: 0;
    clip-path: polygon(0 0, 100% 0, 50% 100%);
    height: 9px;
    left: 0;
    right: auto;
    top: auto;
    width: 10px;
  }

  .rfig-msg--back > .rfig-arrow::before {
    bottom: 0;
    top: 7px;
  }

  .rfig-msg--back > .rfig-arrow::after {
    bottom: auto;
    clip-path: polygon(50% 0, 100% 100%, 0 100%);
    top: 0;
  }
}

/* A flow of four (or six) steps wraps into rows of two on middle widths, where four boxes in one row
   would be about 130px each. The arrow between the rows (every fourth child: node, arrow, node, ARROW)
   turns: down from the end of the upper row, across, and down into the start of the next. Use plain
   .rfig-arrow between the steps of a wrapping flow; put a step's condition inside its box. */
@container rfig (min-width: 600px) and (max-width: 759px) {
  .rfig-flow--wrap {
    column-gap: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr) calc(var(--rfig-arrow, 30px) + 20px) minmax(0, 1fr);
    row-gap: 0;
  }

  .rfig-flow--wrap > .rfig-arrow:not(.rfig-arrow--down, .rfig-arrow--up) {
    margin: 0;
    width: 100%;
  }

  .rfig-flow--wrap > .rfig-arrow:nth-child(4n) {
    align-self: stretch;
    grid-column: 1 / -1;
    height: 38px;
  }

  /* Down from the middle of the right box, then across to the middle of the left column. */
  .rfig-flow--wrap > .rfig-arrow:nth-child(4n)::before {
    background: none;
    border-color: currentColor;
    border-style: none solid solid none;
    border-width: 1.5px;
    bottom: auto;
    height: 19.5px;
    left: calc((100% - var(--rfig-arrow, 30px) - 20px) / 4 - 0.75px);
    right: calc((100% - var(--rfig-arrow, 30px) - 20px) / 4 - 0.75px);
    top: 0;
    width: auto;
  }

  /* Down into the next row, the head on the top edge of its first box. */
  .rfig-flow--wrap > .rfig-arrow:nth-child(4n)::after {
    clip-path: polygon(calc(50% - 0.75px) 0, calc(50% + 0.75px) 0, calc(50% + 0.75px) calc(100% - 9px), 100% calc(100% - 9px), 50% 100%, 0 calc(100% - 9px), calc(50% - 0.75px) calc(100% - 9px));
    height: auto;
    left: calc((100% - var(--rfig-arrow, 30px) - 20px) / 4 - 5px);
    right: auto;
    top: 18px;
    bottom: 0;
    width: 10px;
  }
}

@container rfig (max-width: 599px) {
  .rfig-flow {
    flex-direction: column;
    gap: 6px;
  }

  .rfig-flow > :not(.rfig-arrow) {
    flex: 0 0 auto;
  }

  .rfig-flow > .rfig-arrow {
    --rf-dash-dir: 180deg;
    height: var(--rfig-arrow, 26px);
    width: 10px;
  }

  /* Folded into a column, an arrow takes the 6px gaps above and below it. */
  .rfig-flow > .rfig-arrow:not(.rfig-arrow--down, .rfig-arrow--up) {
    height: calc(var(--rfig-arrow, 26px) + 12px);
    margin: -6px 0;
    width: 10px;
  }

  .rfig-flow > :is(.rfig-link, .rfig-links) {
    --rf-eat: 6px;
  }

  .rfig-flow > .rfig-arrow::before {
    bottom: 7px;
    height: auto;
    left: 4.25px;
    right: auto;
    top: 0;
    width: 1.5px;
  }

  .rfig-flow > .rfig-arrow::after {
    bottom: 0;
    clip-path: polygon(0 0, 100% 0, 50% 100%);
    height: 9px;
    left: 0;
    right: auto;
    top: auto;
    width: 10px;
  }

  .rfig-cols {
    grid-template-columns: minmax(0, 1fr);
  }

  .rfig-timeline {
    grid-auto-flow: row;
    padding-left: 26px;
    padding-top: 0;
  }

  .rfig-timeline::before {
    background: linear-gradient(180deg, var(--rfig-from, var(--rf-h)), var(--rfig-to, var(--rf-h)));
    bottom: 0;
    height: auto;
    left: 5px;
    right: auto;
    top: 4px;
    width: 2px;
  }

  .rfig-event::before {
    left: -26px;
    top: 3px;
  }

  .rfig-scroll-hint {
    display: block;
  }
}

@container rfig (max-width: 559px) {
  .rfig-tr {
    grid-template-columns: minmax(0, 1fr);
    padding-left: 12px;
  }

  .rfig-tr--head {
    display: none;
  }

  .rfig-tr:nth-child(2) {
    border-top: 0;
  }

  /* A stacked table loses its column heads, so a value cell with data-label names itself (a label). */
  .rfig-td[data-label]::before {
    color: var(--rfig-muted);
    content: attr(data-label) ": ";
    font-family: var(--rfig-t-label-family);
    font-size: var(--rfig-t-label-size);
    font-weight: var(--rfig-t-label-weight);
    letter-spacing: var(--rfig-t-label-track);
    text-transform: var(--rfig-t-label-case);
  }

  .rfig-scroll .rfig-tr {
    grid-template-columns: var(--rfig-cols, minmax(0, 13rem) minmax(0, 1fr));
  }

  .rfig-scroll .rfig-tr--head {
    display: grid;
  }

  .rfig-scroll .rfig-td[data-label]::before {
    content: none;
  }

  /* A matrix stays a matrix: its row name moves onto its own line over its cells, the cells keep
     their columns (--rfig-n of them on the table), and the column heads stay. A head too long for a
     narrow column carries a short form: <span class="rfig-long">CONFISCATE</span><span
     class="rfig-short" aria-hidden="true">CNF</span>. Cells hold a mark or a short value. */
  .rfig-table--grid .rfig-tr {
    column-gap: 3px;
    grid-template-columns: repeat(var(--rfig-n, 4), minmax(0, 1fr));
    padding: 0 0 3px;
  }

  .rfig-table--grid .rfig-tr--head {
    display: grid;
    padding-bottom: 6px;
  }

  .rfig-table--grid .rfig-tr--head > .rfig-th:first-child {
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    height: 1px;
    overflow: hidden;
    position: absolute;
    white-space: nowrap;
    width: 1px;
  }

  /* Narrow matrix: tighter heads, a smaller row name and cell (name role, phone sizes). */
  .rfig-table--grid .rfig-th {
    --rfig-t-label-track: 0.04em;
    text-align: center;
  }

  .rfig-table--grid .rfig-rh {
    --rfig-t-name-size: 13.5px;
    grid-column: 1 / -1;
    padding: 6px 0 2px;
  }

  .rfig-table--grid .rfig-td {
    --rfig-t-name-size: 13px;
    min-height: 32px;
    padding: 5px 2px;
  }

  .rfig-table--grid .rfig-td[data-label]::before {
    content: none;
  }

  .rfig .rfig-long {
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    height: 1px;
    overflow: hidden;
    position: absolute;
    white-space: nowrap;
    width: 1px;
  }
}

@container rfig (max-width: 519px) {
  /* Phone sizes of the roles: tighter label tracking, a smaller lede, value and caption number. The rest of
     the table holds on phones (12px is the smallest size). */
  .rfig-sheet,
  .rfig-cap {
    --rfig-t-label-track: 0.08em;
    --rfig-t-lede-size: 14px;
    --rfig-t-value-size: 19px;
    --rfig-t-capnum-size: 12px;
    --rfig-t-capnum-track: 0.08em;
  }

  .rfig-node--split,
  .rfig-layer,
  .rfig-rung,
  .rfig-gloss {
    grid-template-columns: minmax(0, 1fr);
  }

  .rfig-node--split {
    row-gap: 6px;
  }

  /* A stacked gloss: the head above the body, the bar as long as a short word. */
  .rfig-gloss {
    padding-top: 11px;
    row-gap: 6px;
  }

  .rfig-gloss::before {
    width: 2.5rem;
  }

  .rfig-ladder {
    padding-left: 24px;
  }

  .rfig-ladder::before {
    left: 6px;
  }

  .rfig-ladder::after {
    left: 1.5px;
  }

  .rfig-rung::before {
    left: -23px;
  }

  .rfig-rung--key::before {
    left: -24px;
  }

  .rfig-watermark {
    font-size: 70px;
  }

  .rfig-bars {
    grid-template-columns: minmax(0, 1fr) minmax(0, max-content);
    row-gap: 4px;
  }

  .rfig-bar-label {
    grid-column: 1 / -1;
    margin-top: 6px;
  }

  /* Bars with a line or an axis keep their three columns (their labels are short), so the line stays whole and
     the axis stays over the bar column. */
  .rfig-bars.rfig-bars--line,
  .rfig-bars:has(> .rfig-bars__axis) {
    grid-template-columns: minmax(0, max-content) minmax(4rem, 1fr) minmax(0, max-content);
    row-gap: 6px;
  }

  .rfig-bars--line .rfig-bar-label,
  .rfig-bars:has(> .rfig-bars__axis) .rfig-bar-label {
    grid-column: auto;
    margin-top: 0;
  }

  /* Rows that stay rows: a tighter gap and tighter boxes. A row of three on a phone gives each box
     about 100px: one word of up to nine letters a line. */
  .rfig-row,
  .rfig-links {
    --rf-col-gap: 8px;
  }

  .rfig-row > :is(.rfig-node, .rfig-stage) {
    padding: 10px 9px 11px;
  }

  .rfig-row > .rfig-node--strong {
    padding: 9px 8px 10px;
  }

  /* A name in a row of boxes about 100 to 150px wide steps down one size. */
  .rfig-row {
    --rfig-t-name-size: 14px;
  }

  .rfig-link__label {
    padding-inline: 2px;
  }

  .rfig-stairs {
    --rf-stair-h: 8rem;
  }

  /* A gauge on a phone: band names and ticks at the smallest size so a band keeps its one word. */
  .rfig-gauge {
    --rfig-t-name-size: 12px;
    --rfig-t-small-size: 12px;
  }

  .rfig-gauge__band {
    padding-inline: 3px;
  }
}

/* A group too narrow for its columns stacks them. */
@container rfig-box (max-width: 299px) {
  .rfig-cols {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------- One part in two versions: wide and narrow ---------- */

/* When one drawing cannot serve both widths (a radial SVG, a two-dimensional layout that becomes a
   column), write it twice with the same content: .rfig-wide shows from a 600px figure up, .rfig-narrow
   below. The hidden one is display: none, so it is neither seen nor read aloud; still give each
   version its own ids. Put the class on one part (an svg) or on a div that holds several parts; that
   div stacks them with the sheet's gap. Do not put it on an element that also carries a layout class
   (.rfig-stack.rfig-wide): wrap instead. */
div.rfig-wide,
div.rfig-narrow {
  display: flex;
  flex-direction: column;
  gap: var(--rfig-gap, 20px);
  min-width: 0;
}

:is(div.rfig-wide, div.rfig-narrow) > :is(.rfig-link, .rfig-links) {
  --rf-eat: var(--rfig-gap, 20px);
}

@container rfig (min-width: 600px) {
  .rfig .rfig-narrow {
    display: none;
  }
}

@container rfig (max-width: 599px) {
  .rfig .rfig-wide {
    display: none;
  }
}

/* The short form of a head shows only where the matrix is narrow. */
.rfig .rfig-short {
  display: none;
}

@container rfig (max-width: 559px) {
  .rfig .rfig-short {
    display: inline;
  }
}

/* On paper the halo around SVG words is dropped: Chrome writes a stroked word into the PDF text layer a
   second time. */
@media print {
  .rfig-svg :is(.s-cond, .s-halo) {
    stroke: none;
  }
}

/* Windows high contrast: keep the drawn arrows, markers and rules visible. */
@media (forced-colors: active) {
  .rfig-arrow::before,
  .rfig-arrow::after,
  .rfig-axis__line::before,
  .rfig-axis__line::after,
  .rfig-sq::before,
  .rfig-ladder::before,
  .rfig-ladder::after,
  .rfig-rung::before,
  .rfig-cols--drop > *::after,
  .rfig-gloss::before,
  .rfig-bars__axis::before {
    background: CanvasText;
    forced-color-adjust: none;
  }

  .rfig-mark {
    border: 1px solid CanvasText;
  }

  /* The newer connectors draw with currentColor: make that the system text colour. */
  .rfig-link,
  .rfig-links,
  .rfig-stair,
  .rfig-x,
  .rfig-gate,
  .rfig-bars--line .rfig-bar::after,
  .rfig-bar-mark::after,
  .rfig-stairs::after,
  .rfig-stairs__line,
  .rfig-gauge__tick,
  .rfig-gauge__mark,
  .rfig-group--dash::before {
    color: CanvasText;
  }

  .rfig-link::before,
  .rfig-link::after,
  .rfig-links::before,
  .rfig-links::after,
  .rfig-link--blocked .rfig-link__label::before,
  .rfig-stair__bar::before,
  .rfig-stair__bar::after,
  .rfig-stair__value::before,
  .rfig-stair__gate::before,
  .rfig-stairs::after,
  .rfig-stairs__line::before,
  .rfig-gauge__tick::before,
  .rfig-gauge__mark::after,
  .rfig-bars--line .rfig-bar::after,
  .rfig-bar-mark::after,
  .rfig-x,
  .rfig-gate,
  .rfig-group--dash::before {
    forced-color-adjust: none;
  }

  .rfig-bar::before,
  .rfig-swatch--solid {
    background: CanvasText;
    forced-color-adjust: none;
  }
}
