/* Shadstone Handbook — Provenance Workbench
 *
 * Every page states who wrote it, when, and whether it can still be trusted.
 * The article holds the centre; the right rail carries its contents above and
 * its provenance below; the left rail switches navigation axis.
 *
 * Contrast pairs below were computed, not estimated. Shadstone orange reaches
 * only 2.1:1 on the light ground, so it is a fill and an indicator here and
 * never body text; the accent text colour is a darkened orange at 5.53:1.
 */

/* ---------- tokens ---------- */

/* Dark is the default on every page, by the owner's decision on 2026-09-02 —
   not a preference the operating system gets a vote on. Light is still here and
   still complete; it is opted into rather than inherited. */
:root {
  color-scheme: dark;

  --ground: #17181a;
  --surface: #1e2023;
  --surface-sunk: #131416;
  --ink: #ecebe8;
  --ink-muted: #a2a5ab;
  --ink-faint: #8b8e95;
  --line: #303338;
  --line-strong: #43474e;
  --accent: #f7941d;
  --accent-text: #ffab43;
  --accent-wash: #2a1e0c;
  --on-accent: #241500;
  --ok: #5fcf8e;
  --warn: #f0be5f;
  --stale: #ff8a7a;
  --ok-wash: #12261a;
  --warn-wash: #2a2110;
  --stale-wash: #2d1614;
  --focus: #6aa9ff;
  --series-1: #d17c10;
  --series-2: #1f9d7e;
  --series-3: #4d7ff0;
  --series-4: #c44a9e;
  --series-5: #b8860b;
  --font-sans: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-serif: "IBM Plex Serif", Georgia, "Times New Roman", serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --step--1: 0.8125rem;
  --step-0: 0.9375rem;
  --step-1: 1.0625rem;
  --step-2: 1.375rem;
  --step-3: 1.75rem;
  --step-4: 2.25rem;
  --step-5: 3rem;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 72px;
  --radius: 10px;
  --radius-sm: 6px;
  --radius-pill: 999px;
  --rail-left: 232px;
  --rail-right: 296px;
  --measure: 68ch;
  /* The same reading width, but resolved once rather than against whatever font
     size the element happens to set. `ch` is right for a single column of body
     text and wrong the moment several different sizes have to agree on an edge. */
  --measure-fixed: 43.5rem;
  --shadow-raise: 0 1px 2px rgba(0, 0, 0, 0.5), 0 8px 24px rgba(0, 0, 0, 0.45);
  --shadow-pop: 0 2px 4px rgba(0, 0, 0, 0.55), 0 18px 44px rgba(0, 0, 0, 0.55);
}

/* The light palette, kept whole rather than defined as a set of exceptions, so
   neither theme is the other one patched. */
:root[data-theme="light"] {
  color-scheme: light;

  --ground: #f7f5f2;
  --surface: #ffffff;
  --surface-sunk: #f1eee9;
  --ink: #202226;
  --ink-muted: #5c5f66;
  --ink-faint: #6a6c73;
  --line: #e2ded7;
  --line-strong: #cdc8bf;
  --accent: #f7941d;
  --accent-text: #8f4a00;
  --accent-wash: #fdf3e4;
  --on-accent: #241500;
  --ok: #1f6b3f;
  --warn: #8a5a00;
  --stale: #9b2c1f;
  --ok-wash: #eaf4ee;
  --warn-wash: #fbf1dd;
  --stale-wash: #fbeceb;
  --focus: #0b62d6;
  --series-1: #f7941d;
  --series-2: #4fc4a1;
  --series-3: #1f4fd0;
  --series-4: #8f1d6e;
  --series-5: #b8860b;
  --font-sans: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-serif: "IBM Plex Serif", Georgia, "Times New Roman", serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --step--1: 0.8125rem;
  --step-0: 0.9375rem;
  --step-1: 1.0625rem;
  --step-2: 1.375rem;
  --step-3: 1.75rem;
  --step-4: 2.25rem;
  --step-5: 3rem;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 72px;
  --radius: 10px;
  --radius-sm: 6px;
  --radius-pill: 999px;
  --rail-left: 232px;
  --rail-right: 296px;
  --measure: 68ch;
  /* The same reading width, but resolved once rather than against whatever font
     size the element happens to set. `ch` is right for a single column of body
     text and wrong the moment several different sizes have to agree on an edge. */
  --measure-fixed: 43.5rem;
  --shadow-raise: 0 1px 2px rgba(32, 34, 38, 0.06), 0 8px 24px rgba(32, 34, 38, 0.08);
  --shadow-pop: 0 2px 4px rgba(32, 34, 38, 0.08), 0 18px 44px rgba(32, 34, 38, 0.16);
}


/* ---------- faces ---------- */

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/IBMPlexSans-Regular-Latin1.woff2") format("woff2");
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153,
    U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022,
    U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/IBMPlexSans-Italic-Latin1.woff2") format("woff2");
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153,
    U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022,
    U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/IBMPlexSans-Medium-Latin1.woff2") format("woff2");
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153,
    U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022,
    U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/IBMPlexSans-SemiBold-Latin1.woff2") format("woff2");
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153,
    U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022,
    U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}
@font-face {
  font-family: "IBM Plex Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/IBMPlexSerif-Regular-Latin1.woff2") format("woff2");
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153,
    U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022,
    U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}
@font-face {
  font-family: "IBM Plex Serif";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/IBMPlexSerif-Italic-Latin1.woff2") format("woff2");
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153,
    U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022,
    U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/IBMPlexMono-Regular-Latin1.woff2") format("woff2");
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153,
    U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022,
    U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}

/* ---------- base ---------- */

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  display: flex;
  flex-direction: column;
  margin: 0;
  min-height: 100vh;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.6;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

/* Browser surfaces the design still owns. */
::selection {
  background: var(--accent);
  color: var(--on-accent);
}
:root {
  caret-color: var(--accent-text);
  scrollbar-color: var(--line-strong) transparent;
  scrollbar-width: thin;
}
::-webkit-scrollbar {
  width: 11px;
  height: 11px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  border: 3px solid transparent;
  border-radius: var(--radius-pill);
  background: var(--line-strong);
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--ink-faint);
  background-clip: content-box;
}

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

a {
  color: inherit;
  text-decoration-color: var(--line-strong);
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}
a:hover {
  text-decoration-color: var(--accent);
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: 600;
  line-height: 1.22;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

svg.icon {
  display: block;
  width: 1em;
  height: 1em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

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

.skip-link {
  position: absolute;
  z-index: 100;
  top: var(--space-2);
  left: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
  transform: translateY(-200%);
}
.skip-link:focus {
  transform: none;
}

/* ---------- shell ---------- */

.masthead {
  position: sticky;
  z-index: 40;
  top: 0;
  display: flex;
  align-items: center;
  gap: var(--space-5);
  min-height: 60px;
  padding: 0 var(--space-5);
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}

.brand {
  display: inline-flex;
  flex: none;
  align-items: center;
  text-decoration: none;
}
.brand img {
  display: block;
  width: 148px;
  height: auto;
}

.masthead-search {
  flex: 1 1 auto;
  max-width: 520px;
}

.masthead-actions {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
}

.app-shell {
  display: grid;
  flex: 1 0 auto;
  /* `body` is a column flex container so the agent footer can sit at the
     bottom. The shell also has inline auto margins; without an explicit width
     that combination shrink-wraps it to its contents, reducing Explore's
     full-viewport canvas to the width of its 210px control rail. */
  width: 100%;
  grid-template-columns: var(--rail-left) minmax(0, 1fr) var(--rail-right);
  align-items: start;
  gap: var(--space-7);
  max-width: 1520px;
  margin: 0 auto;
  padding: var(--space-6) var(--space-5) var(--space-8);
}

.site-footer {
  flex: none;
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--line);
  background: var(--surface);
}
.site-footer nav {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: flex-end;
  gap: var(--space-2) var(--space-3);
  max-width: 1520px;
  margin: 0 auto;
  color: var(--ink-faint);
  font-size: var(--step--1);
}
.site-footer a {
  color: var(--ink-muted);
  font-weight: 600;
}
.site-footer a:hover {
  color: var(--accent-text);
}
.site-footer code {
  margin-left: var(--space-1);
  color: var(--accent-text);
  font-family: var(--font-mono);
  font-size: 0.92em;
}

.app-shell.no-rails {
  grid-template-columns: minmax(0, 1fr);
  max-width: calc(var(--measure) + 8ch);
}

.rail {
  position: sticky;
  top: calc(60px + var(--space-6));
  max-height: calc(100vh - 60px - var(--space-7));
  overflow-y: auto;
  overscroll-behavior: contain;
}

.rail-heading {
  margin-bottom: var(--space-3);
  color: var(--ink-faint);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.rail-heading.spaced {
  margin-top: var(--space-6);
}

/* ---------- axis switcher ---------- */

.axis-switch {
  display: grid;
  gap: 2px;
  margin-bottom: var(--space-6);
}
.axis-switch a {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--ink-muted);
  font-weight: 500;
  text-decoration: none;
}
.axis-switch a:hover {
  background: var(--surface-sunk);
  color: var(--ink);
}
.axis-switch a[aria-current="true"] {
  background: var(--accent-wash);
  color: var(--accent-text);
  font-weight: 600;
}
.axis-switch .count {
  margin-left: auto;
  color: var(--ink-faint);
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
}

.axis-tree {
  display: grid;
  gap: 1px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.axis-tree a {
  display: flex;
  gap: var(--space-3);
  padding: 5px var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--ink-muted);
  font-size: var(--step-0);
  text-decoration: none;
}
.axis-tree a:hover {
  background: var(--surface-sunk);
  color: var(--ink);
}
.axis-tree a[aria-current="page"] {
  background: var(--surface-sunk);
  color: var(--ink);
  font-weight: 600;
}
.axis-tree .count {
  margin-left: auto;
  color: var(--ink-faint);
  font-size: var(--step--1);
}
.axis-tree ul {
  margin: 0 0 var(--space-2) var(--space-4);
  padding: 0 0 0 var(--space-3);
  border-left: 1px solid var(--line);
  list-style: none;
}

/* ---------- search ---------- */

.search-field {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  background: var(--ground);
  color: var(--ink-faint);
}
.search-field:focus-within {
  border-color: var(--accent);
  background: var(--surface);
  box-shadow: 0 0 0 3px var(--accent-wash);
}
.search-field input {
  flex: 1;
  min-width: 0;
  padding: 9px 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
}
.search-field input::placeholder {
  color: var(--ink-faint);
}
.search-field input:focus {
  outline: none;
}
.search-field button {
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink-muted);
  cursor: pointer;
}
.search-field button:hover {
  color: var(--accent-text);
}

/* Added by app.js, so it is only ever shown where the shortcut is bound.
   It hides the moment the field is in use — while focused, or once there is a
   query in it — because at that point it is describing what already happened. */
.kbd-hint {
  flex: none;
  padding: 2px 6px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-sunk);
  /* Muted rather than faint: faint lands at 3.15:1 on this surface, and a key
     hint is text a person reads rather than decoration. */
  color: var(--ink-muted);
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.6;
  white-space: nowrap;
  -webkit-user-select: none;
  user-select: none;
}
.search-field:focus-within .kbd-hint,
.search-field input:not(:placeholder-shown) + .kbd-hint {
  display: none;
}
/* No hardware keyboard to press it with. */
@media (hover: none) {
  .kbd-hint {
    display: none;
  }
}

.search-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
}

/* An internal link is coloured, an outbound one is not.
   The selector is on the href rather than a class because the sanitizer strips
   class from anchors — which is deliberate, since it also makes it impossible
   to mark a resolved and an unresolved link differently by accident. Contrast
   measured: 6.13:1 light, 9.44:1 dark. */
.document-body a[href^="/handbook/"],
.document-body a[href^="/media/"] {
  color: var(--accent-text);
  text-underline-offset: 2px;
  text-decoration-color: color-mix(in srgb, var(--accent-text) 40%, transparent);
}
.document-body a[href^="/handbook/"]:hover,
.document-body a[href^="/media/"]:hover {
  text-decoration-color: currentColor;
}

/* Select and the inline access editor on the sections screen. */
.field select {
  width: 100%;
  padding: 9px var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
}
.field select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-wash);
}
.optional {
  color: var(--ink-faint);
  font-weight: 400;
}
.role-option.compact {
  padding: var(--space-1) 0;
}

.chip-tag {
  border-style: dashed;
  color: var(--ink-muted);
}

/* ---------- connections ---------- */
/* Related documents and backlinks, under the article body. Two columns where
   there is room, stacked where there is not. */

.connections {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-5);
  max-width: var(--measure);
  margin-top: var(--space-7);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
}

.connection-list {
  margin: 0;
  padding: 0;
  list-style: none;
}
.connection-list li {
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--line);
}
.connection-list li:last-child {
  border-bottom: 0;
}
.connection-list a {
  color: var(--ink);
  text-decoration: none;
}
.connection-list a:hover {
  color: var(--accent-text);
  text-decoration: underline;
}
.connection-note {
  display: block;
  margin-top: 2px;
  color: var(--ink-faint);
  font-size: var(--step--1);
}

/* ---------- document ---------- */

.document {
  max-width: var(--measure);
}

/* A diagram breaks out of the reading measure. 68ch is right for prose and
   wrong for a map — a three-column figure in a 755px column is a figure nobody
   can read. The prose stays at its measure; only the drawing widens.
   The page gives up its right rail to make the room, rather than sliding the
   figure underneath it, which is what the first attempt did: the panel drew on
   top and took a third of the diagram with it. */
.app-shell-wide {
  grid-template-columns: var(--rail-left) minmax(0, 1fr);
}

/* The document itself gives up the cap so the figure can use the room; the
   prose puts it back on itself, one element at a time. Capping the container and
   widening the child does not work — a child cannot be wider than the box it is
   in, which is how the first attempt produced a *narrower* diagram than before. */
.app-shell-wide .document {
  max-width: none;
}

/* Everything that is prose lands on one edge. Two things were wrong here: the
   list left out `table`, `pre`, `hr` and the smaller headings — so a table drew
   full-bleed beside paragraphs that stopped 275px short — and the cap was
   `--measure`, which is `68ch` and resolves against each element's *own* font
   size, so a heading's cap sat 200px wider than a paragraph's. Three right edges
   on one page. A fixed measure puts them all on one. */
.app-shell-wide .document-body > p,
.app-shell-wide .document-body > ul,
.app-shell-wide .document-body > ol,
.app-shell-wide .document-body > dl,
.app-shell-wide .document-body > h2,
.app-shell-wide .document-body > h3,
.app-shell-wide .document-body > h4,
.app-shell-wide .document-body > h5,
.app-shell-wide .document-body > h6,
.app-shell-wide .document-body > hr,
.app-shell-wide .document-body > pre,
.app-shell-wide .document-body > table,
.app-shell-wide .document-body > .table-scroll,
.app-shell-wide .document-body > blockquote,
.app-shell-wide .document-body > .block-callout {
  max-width: var(--measure-fixed);
}

/* A paragraph that is nothing but a picture is not prose, and the reading
   measure is the wrong cap for it. A screenshot captured at 1430 and drawn at
   696 is half scale: any label on it renders at half the size it was written
   for, which is the difference between an annotation and a smudge. It gets the
   room a diagram gets, because that is what it is. */
.app-shell-wide .document-body > p:has(> img:only-child) {
  max-width: none;
  text-align: center;
}

/* And the other axis. A screenshot of a settings pane is taller than it is
   wide, and giving it the figure's full width then let it run past a whole
   screen — the reader scrolls a picture rather than reading a page. The same
   ceiling a video gets, for the same reason. */
.document-body p > img:only-child {
  max-height: 68vh;
  width: auto;
  object-fit: contain;
}

/* The rail's content, at the foot, on the pages that gave the rail up to a
   drawing. It is a second placement rather than the same one moved by the
   cascade: reordering with flex meant the document stopped collapsing its
   margins and every heading on the page drifted. */
.provenance-foot {
  display: none;
}

.app-shell-wide .provenance-foot {
  display: block;
  margin-top: var(--space-7);
  max-width: var(--measure);
}

.document-title {
  font-size: var(--step-4);
  letter-spacing: -0.025em;
}

.page-head {
  margin-bottom: var(--space-6);
}
.page-lede {
  margin: var(--space-2) 0 0;
  max-width: 60ch;
  color: var(--ink-muted);
  font-size: var(--step-1);
}

/* A title standing alone still has to clear whatever follows it. */
.document-title + *:not(.document-body) {
  margin-top: var(--space-5);
}

.document-body {
  margin-top: var(--space-6);
  font-size: var(--step-1);
  line-height: 1.68;
}
.document-body > * + * {
  margin-top: var(--space-4);
}
.document-body h2 {
  margin-top: var(--space-7);
  font-size: var(--step-2);
}
.document-body h3 {
  margin-top: var(--space-6);
  font-size: var(--step-1);
}
.document-body h2 + *,
.document-body h3 + * {
  margin-top: var(--space-3);
}
.document-body p,
.document-body li {
  max-width: var(--measure);
}
.document-body ul,
.document-body ol {
  padding-left: 1.4em;
}
.document-body li + li {
  margin-top: var(--space-2);
}
.document-body blockquote {
  margin-left: 0;
  padding-left: var(--space-4);
  border-left: 1px solid var(--accent);
  color: var(--ink-muted);
  font-family: var(--font-serif);
}
.document-body code {
  padding: 0.12em 0.36em;
  border-radius: var(--radius-sm);
  background: var(--surface-sunk);
  font-family: var(--font-mono);
  font-size: 0.9em;
}
.document-body pre {
  overflow-x: auto;
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-sunk);
}
.document-body pre code {
  padding: 0;
  background: none;
}
.document-body img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius);
}
.document-body table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step-0);
}
.document-body th,
.document-body td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}
.document-body th {
  color: var(--ink-muted);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.document-body hr {
  margin: var(--space-7) 0;
  border: 0;
  border-top: 1px solid var(--line);
}

.table-scroll {
  overflow-x: auto;
}

/* ---------- provenance ---------- */

/* The article carries provenance twice in the markup: once in the right rail,
   and once inline for the widths where that rail is gone. Only one is ever
   shown. */
.provenance-inline {
  display: none;
  margin-top: var(--space-5);
}

.provenance {
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.provenance dl {
  display: grid;
  gap: var(--space-3);
  margin: 0;
}
.provenance dt {
  color: var(--ink-faint);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.provenance dd {
  margin: 2px 0 0;
  font-weight: 500;
}
/* The editor's name sits under the date rather than beside it: the two read as
   one fact, and side by side they competed for the same short column. */
.provenance dd .by {
  display: block;
  color: var(--ink-muted);
  font-weight: 400;
}
.provenance span.unset {
  color: var(--ink-faint);
  font-style: italic;
  font-weight: 400;
}

.provenance-actions {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}

/* ---------- contents ---------- */

.contents ol {
  display: grid;
  gap: 1px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.contents a {
  display: block;
  padding: 3px var(--space-3);
  border-left: 1px solid var(--line);
  color: var(--ink-muted);
  font-size: var(--step-0);
  text-decoration: none;
}
.contents a:hover {
  border-left-color: var(--line-strong);
  color: var(--ink);
}
.contents a[aria-current="true"] {
  border-left-color: var(--accent);
  color: var(--ink);
  font-weight: 600;
}
.contents .depth-3 {
  padding-left: var(--space-6);
}

/* ---------- lists of records ---------- */

/* Headings are margin:0 globally, so a group label needs its own spacing.
   Scoped to a class rather than to `h2` so nothing else on the site moves. */
.result-group {
  margin-bottom: var(--space-3);
}
/* The gap that separates one group from the last row of the one above it. */
.record-list + .result-group {
  margin-top: var(--space-6);
}

.record-list {
  display: grid;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}
.record {
  display: grid;
  gap: var(--space-1);
  padding: var(--space-4);
  color: inherit;
  text-decoration: none;
}
.record + .record {
  border-top: 1px solid var(--line);
}
.record:hover {
  background: var(--surface-sunk);
}
.record-title {
  font-size: var(--step-1);
  font-weight: 600;
}
.record-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  color: var(--ink-faint);
  font-size: var(--step--1);
}
.record-excerpt {
  color: var(--ink-muted);
  font-size: var(--step-0);
}
.record-excerpt mark {
  padding: 0 2px;
  border-radius: 3px;
  background: var(--accent-wash);
  color: var(--accent-text);
  font-weight: 600;
}

/* ---------- controls ---------- */

.button,
.button-quiet {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 9px var(--space-4);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.button {
  background: var(--accent);
  color: var(--on-accent);
}
.button:hover {
  background: #e08312;
}
.button-quiet {
  border-color: var(--line-strong);
  background: var(--surface);
  color: var(--ink);
}
.button-quiet:hover {
  border-color: var(--ink-faint);
  background: var(--surface-sunk);
}
.button:disabled,
.button-quiet:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 3px var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  color: var(--ink-muted);
  font-size: var(--step--1);
  font-weight: 500;
  text-decoration: none;
}
.chip:hover {
  border-color: var(--accent);
  background: var(--accent-wash);
  color: var(--accent-text);
}
.chip[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--accent-wash);
  color: var(--accent-text);
}

.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0 0 var(--space-4);
  padding: 0;
  color: var(--ink-faint);
  font-size: var(--step--1);
  list-style: none;
}
.breadcrumbs li + li::before {
  margin-right: var(--space-2);
  content: "/";
}
.breadcrumbs a {
  color: var(--ink-muted);
  text-decoration: none;
}
.breadcrumbs a:hover {
  color: var(--accent-text);
}
.breadcrumbs [aria-current="page"] {
  overflow: hidden;
  max-width: 40ch;
  color: var(--ink);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.notice {
  margin-bottom: var(--space-5);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}
.notice-error {
  border-color: var(--stale);
  background: var(--stale-wash);
  color: var(--stale);
}
.notice-success {
  border-color: var(--ok);
  background: var(--ok-wash);
  color: var(--ok);
}

.empty {
  padding: var(--space-7) var(--space-5);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  color: var(--ink-muted);
  text-align: center;
}
.empty h2 {
  margin-bottom: var(--space-2);
  color: var(--ink);
  font-size: var(--step-2);
}

/* ---------- not found ---------- */

.not-found {
  display: grid;
  grid-template-columns: minmax(0, 0.75fr) minmax(300px, 1fr);
  align-items: center;
  gap: var(--space-7);
  min-height: min(620px, calc(100vh - 180px));
}
.not-found-code {
  margin: 0;
  color: var(--surface-sunk);
  font: 600 clamp(8rem, 25vw, 19rem) / 0.72 var(--font-mono);
  letter-spacing: -0.1em;
  text-shadow: -1px 0 var(--line-strong), 0 1px var(--line-strong),
    1px 0 var(--line-strong), 0 -1px var(--line-strong);
  user-select: none;
}
.not-found-copy {
  max-width: 560px;
}
.not-found-copy h1 {
  margin-bottom: var(--space-4);
  font-size: clamp(var(--step-3), 5vw, var(--step-5));
}
.not-found-copy > p:not(.eyebrow) {
  color: var(--ink-muted);
}
.not-found-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-5);
}

/* ---------- human guide ---------- */

.human-intro {
  max-width: 760px;
}
.human-paths {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-7);
}
.human-paths a {
  display: grid;
  align-content: start;
  gap: var(--space-2);
  min-height: 190px;
  padding: var(--space-5);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink-muted);
  text-decoration: none;
  transition: border-color 160ms cubic-bezier(0.16, 1, 0.3, 1),
              background 160ms cubic-bezier(0.16, 1, 0.3, 1);
}
.human-paths a:hover {
  border-color: var(--accent);
  background: var(--accent-wash);
}
.human-paths strong {
  color: var(--ink);
  font-size: var(--step-1);
}
.human-path-number {
  color: var(--accent-text);
  font: 500 var(--step--1) / 1 var(--font-mono);
}
.human-guide {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}
.human-guide-card {
  padding: var(--space-5);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}
.human-guide-card h2 {
  margin-bottom: var(--space-3);
  font-size: var(--step-2);
}
.human-guide-card p,
.human-guide-card li {
  color: var(--ink-muted);
}
.human-guide-card ul {
  margin: 0;
  padding-left: 1.25em;
}
.human-guide-card li + li {
  margin-top: var(--space-3);
}
.human-guide-card strong,
.human-guide-card a {
  color: var(--ink);
}
.human-guide-card kbd {
  padding: 0.12em 0.42em;
  border: 1px solid var(--line-strong);
  border-bottom-width: 2px;
  border-radius: var(--radius-sm);
  background: var(--surface-sunk);
  color: var(--ink);
  font: 400 0.82em / 1.4 var(--font-mono);
  white-space: nowrap;
}
.human-guide-wide {
  grid-column: 1 / -1;
}

/* ---------- public getting-started guide ---------- */

.public-guide {
  width: min(100%, var(--measure));
  margin: 0 auto;
}
.public-guide-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
  padding-bottom: var(--space-5);
  border-bottom: 1px solid var(--line);
}
.public-guide-actions .button,
.public-guide-actions .button-quiet {
  width: auto;
}

/* ---------- entry pages ---------- */

.entry {
  display: grid;
  flex: 1 0 auto;
  align-content: center;
  min-height: 0;
  padding: var(--space-6);
  background: var(--ground);
}
.entry-panel {
  width: 100%;
  max-width: 460px;
  margin: 0 auto;
  padding: var(--space-7);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-raise);
}
.entry-panel img {
  display: block;
  width: 168px;
  height: auto;
  margin-bottom: var(--space-6);
}
.entry-panel h1 {
  font-size: var(--step-3);
}
.entry-panel p {
  margin: var(--space-3) 0 0;
  color: var(--ink-muted);
}
.entry-panel .button {
  width: 100%;
  margin-top: var(--space-6);
}
.entry-panel .button-quiet {
  width: 100%;
  margin-top: var(--space-3);
}

/* ---------- axis home ---------- */

.axis-board + .axis-board {
  margin-top: var(--space-7);
}
.axis-board h2 {
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--line);
  font-size: var(--step-2);
}
.axis-board-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 0 var(--space-6);
  margin: 0;
  padding: 0;
  list-style: none;
}
.axis-board-list > li {
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--line);
}
.axis-board-list a {
  display: flex;
  gap: var(--space-3);
  color: inherit;
  font-weight: 600;
  text-decoration: none;
}
.axis-board-list a:hover {
  color: var(--accent-text);
}
.axis-board-list .count {
  margin-left: auto;
  color: var(--ink-faint);
  font-weight: 400;
}
.axis-board-list .children {
  margin: var(--space-2) 0 0;
  padding: 0;
  color: var(--ink-muted);
  font-size: var(--step--1);
  list-style: none;
}
.axis-board-list .children li {
  display: inline;
}
.axis-board-list .children li + li::before {
  content: " · ";
}
.axis-board-list .children a {
  display: inline;
  font-weight: 400;
}

/* ---------- responsive ---------- */

@media (max-width: 1200px) {
  .app-shell {
    grid-template-columns: var(--rail-left) minmax(0, 1fr);
  }
  .rail-right {
    display: none;
  }
  .provenance-inline {
    display: block;
  }
}

@media (max-width: 900px) {
  .masthead {
    flex-wrap: wrap;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
  }
  .masthead-search {
    order: 3;
    flex-basis: 100%;
    max-width: none;
  }
  .app-shell {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-5);
    padding: var(--space-5) var(--space-4) var(--space-7);
  }
  .rail-left {
    position: static;
    max-height: none;
  }
  .axis-switch {
    display: flex;
    overflow-x: auto;
    gap: var(--space-2);
    margin-bottom: var(--space-4);
    padding-bottom: var(--space-2);
  }
  .axis-switch a {
    flex: none;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-pill);
  }
  .axis-switch .count {
    display: none;
  }
  /* The scoped tree collapses to the chip row above it; its headings would
     otherwise stand alone over nothing. */
  .axis-tree,
  .rail-left .rail-heading {
    display: none;
  }
  .document-title {
    font-size: var(--step-3);
  }
  .not-found {
    grid-template-columns: minmax(0, 1fr);
    align-content: center;
    gap: var(--space-5);
  }
  .not-found-code {
    font-size: clamp(7rem, 34vw, 12rem);
  }
  .site-footer nav {
    justify-content: flex-start;
  }
  .human-paths,
  .human-guide {
    grid-template-columns: minmax(0, 1fr);
  }
  .human-paths a {
    min-height: 0;
  }
  .human-guide-wide {
    grid-column: auto;
  }
}

/* ---------- print ---------- */

@media print {
  :root {
    --ground: #fff;
    --surface: #fff;
    --ink: #000;
    --ink-muted: #333;
    --line: #bbb;
  }
  .masthead,
  .site-footer,
  .rail-left,
  .contents,
  .provenance-actions,
  .skip-link,
  .search-field {
    display: none !important;
  }
  .app-shell {
    display: block;
    max-width: none;
    padding: 0;
  }
  .document {
    max-width: none;
  }
  .document-body {
    font-size: 11pt;
  }
  .document-body a::after {
    color: #555;
    font-size: 9pt;
    content: " (" attr(href) ")";
  }
  .provenance {
    border: 1px solid #bbb;
    break-inside: avoid;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---------- editor ---------- */

.editor {
  display: grid;
  gap: var(--space-5);
  max-width: var(--measure);
}
.field {
  display: grid;
  gap: var(--space-1);
}
.field label {
  font-weight: 600;
}
.field-hint {
  margin: 0;
  color: var(--ink-muted);
  font-size: var(--step--1);
}
.field input,
.field textarea {
  width: 100%;
  padding: 9px var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
}
.field textarea {
  font-family: var(--font-mono);
  font-size: var(--step-0);
  line-height: 1.6;
  resize: vertical;
}
.field input:focus,
.field textarea:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-wash);
}
.editor-actions {
  display: flex;
  gap: var(--space-3);
}

/* ---------- versions and diffs ---------- */

.axis-switch.spaced {
  margin-top: var(--space-6);
}

.version-list {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  list-style: none;
}
.version {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-4);
}
.version + .version {
  border-top: 1px solid var(--line);
}
.version-current {
  background: var(--accent-wash);
}
.version-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.version-number {
  font-family: var(--font-mono);
  font-size: var(--step-1);
  font-weight: 600;
}
.version-summary {
  margin: 0;
  font-size: var(--step-1);
}
.version-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-1);
}
.version-actions form {
  margin: 0;
}
.version-actions button.chip {
  background: var(--surface);
  cursor: pointer;
}

.diff {
  overflow-x: auto;
  margin-bottom: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}
.diff table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  line-height: 1.55;
}
.diff td {
  padding: 1px var(--space-2);
  vertical-align: top;
}
.diff-number {
  width: 1%;
  border-right: 1px solid var(--line);
  color: var(--ink-faint);
  text-align: right;
  user-select: none;
  white-space: nowrap;
}
.diff-marker {
  width: 1%;
  padding-left: var(--space-3);
  user-select: none;
}
.diff-text {
  width: 100%;
  white-space: pre-wrap;
  word-break: break-word;
}
.diff-added {
  background: var(--ok-wash);
}
.diff-added .diff-marker,
.diff-added-count {
  color: var(--ok);
  font-weight: 600;
}
.diff-removed {
  background: var(--stale-wash);
}
.diff-removed .diff-marker,
.diff-removed-count {
  color: var(--stale);
  font-weight: 600;
}
.diff-context {
  color: var(--ink-muted);
}

/* ---------- visual blocks ---------- */

.block {
  margin: var(--space-6) 0;
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}
.block figcaption,
.block > figcaption {
  margin-bottom: var(--space-3);
  font-weight: 600;
}
.block-unit {
  color: var(--ink-faint);
  font-weight: 400;
}

.block-canvas {
  overflow-x: auto;
}
.block-chart {
  display: block;
  width: 100%;
  min-width: 480px;
  height: auto;
}
.block-grid {
  stroke: var(--line);
  stroke-width: 1;
}
.block-axis-line {
  stroke: var(--line-strong);
  stroke-width: 1;
}
/* Text wears text tokens, never a series colour. */
.block-axis {
  fill: var(--ink-muted);
  font-family: var(--font-sans);
  font-size: 12px;
}
.block-value {
  fill: var(--ink);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.block-line {
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.block-dot {
  stroke: var(--surface);
  stroke-width: 2;
}

rect.series-1, circle.series-1 { fill: var(--series-1); }
rect.series-2, circle.series-2 { fill: var(--series-2); }
rect.series-3, circle.series-3 { fill: var(--series-3); }
rect.series-4, circle.series-4 { fill: var(--series-4); }
rect.series-5, circle.series-5 { fill: var(--series-5); }
path.series-1 { stroke: var(--series-1); }
path.series-2 { stroke: var(--series-2); }
path.series-3 { stroke: var(--series-3); }
path.series-4 { stroke: var(--series-4); }
path.series-5 { stroke: var(--series-5); }

.block-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin: 0 0 var(--space-3);
  padding: 0;
  color: var(--ink-muted);
  font-size: var(--step--1);
  list-style: none;
}
.block-legend li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.swatch {
  width: 11px;
  height: 11px;
  border-radius: 3px;
}
.swatch.series-1 { background: var(--series-1); }
.swatch.series-2 { background: var(--series-2); }
.swatch.series-3 { background: var(--series-3); }
.swatch.series-4 { background: var(--series-4); }
.swatch.series-5 { background: var(--series-5); }

/* With no script there is no tooltip, so the figures are always reachable. */
.block-data {
  margin-top: var(--space-3);
  border-top: 1px solid var(--line);
  padding-top: var(--space-3);
}
.block-data summary {
  color: var(--ink-muted);
  font-size: var(--step--1);
  cursor: pointer;
}
.block-data summary:hover {
  color: var(--accent-text);
}
.block-data table {
  width: 100%;
  margin-top: var(--space-3);
  border-collapse: collapse;
  font-size: var(--step--1);
}
.block-data caption {
  margin-bottom: var(--space-2);
  color: var(--ink-muted);
  text-align: left;
}
.block-data th,
.block-data td,
.block-compare th,
.block-compare td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--line);
  text-align: left;
}
.block-data td,
.block-compare td {
  font-variant-numeric: tabular-nums;
}

.block-compare table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step-0);
}
.block-compare caption {
  margin-bottom: var(--space-3);
  font-weight: 600;
  text-align: left;
}
.block-compare thead th {
  color: var(--ink-muted);
  font-size: var(--step--1);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.flow,
.timeline,
.decision {
  display: grid;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}
.flow-step {
  display: flex;
  gap: var(--space-3);
}
.flow-number {
  display: grid;
  flex: none;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: var(--radius-pill);
  background: var(--accent-wash);
  color: var(--accent-text);
  font-size: var(--step--1);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.flow-label {
  margin: 3px 0 0;
  font-weight: 600;
}
.flow-detail {
  margin: var(--space-1) 0 0;
  color: var(--ink-muted);
  font-size: var(--step-0);
}

.timeline-event {
  display: flex;
  gap: var(--space-4);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--line);
}
.timeline-event:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}
.timeline-when {
  flex: none;
  width: 9ch;
  color: var(--accent-text);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.decision-question {
  margin: 0 0 var(--space-3);
  font-weight: 600;
}
.decision-branch {
  display: flex;
  gap: var(--space-3);
  align-items: baseline;
}
.decision-answer {
  flex: none;
  min-width: 7ch;
  padding: 2px var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--surface-sunk);
  font-size: var(--step--1);
  font-weight: 600;
  text-align: center;
}
.decision-then {
  color: var(--ink-muted);
}

.block-callout {
  border-left-width: 1px;
}
.callout-title {
  margin: 0 0 var(--space-1);
  font-weight: 600;
}
.block-callout p:last-child {
  margin: 0;
}
.callout-note {
  border-color: var(--line-strong);
  background: var(--surface-sunk);
}
.callout-warning {
  border-color: var(--warn);
  background: var(--warn-wash);
}
.callout-warning .callout-title {
  color: var(--warn);
}
.callout-danger {
  border-color: var(--stale);
  background: var(--stale-wash);
}
.callout-danger .callout-title {
  color: var(--stale);
}

.block-frame {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: var(--charcoal, #202226);
  aspect-ratio: 16 / 9;
}
.block-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
/* A drawing has an aspect ratio the server chose; a video has whatever the
   recording happened to be. A walkthrough cut from screenshots comes out nearly
   square, and at the full figure width that is a whole viewport of one picture
   — the reader has to scroll past it to get back to the sentence it belongs to.
   So a video gets a height ceiling and keeps its shape inside it. */
.block-video {
  display: block;
  width: 100%;
  max-height: 68vh;
  object-fit: contain;
  margin-inline: auto;
  border-radius: var(--radius-sm);
  background: #000;
}
.block-embed figcaption {
  margin: var(--space-3) 0 0;
}

/* An article filed under the Archive axis. The state is read from where the
   document sits, so it cannot disagree with the rail it appears under. */
.record-badge {
  display: inline-block;
  padding: 1px var(--space-2);
  border-radius: 4px;
  background: var(--stale-wash);
  color: var(--stale);
  font-size: var(--step--1);
  font-weight: 500;
  vertical-align: middle;
}
.record-badge-standalone {
  margin: 0 0 var(--space-3);
  padding: var(--space-1) var(--space-3);
}

/* ── System map ───────────────────────────────────────────────────────────
   The shape of a job rather than its order: which systems it touches, what
   passes between them, and what comes back. Drawn entirely by the server, which
   is what lets it measure text before placing it — the tones are shared with the
   workflow block so one application looks the same wherever it appears. */

.block-system {
  display: grid;
  gap: var(--space-4);
}
.block-system > figcaption {
  margin-bottom: 0;
}
.map {
  display: block;
  width: 100%;
  min-width: 720px;
  height: auto;
}

/* Past three lanes the drawing needs more room than the page has. It takes it
   and scrolls inside its own container, rather than scaling down until the text
   is too small to read — the viewBox scales to the width it is given, so a wider
   drawing that is not also given a wider floor just draws everything smaller. */
.map-lanes-4 {
  min-width: 900px;
}
.map-lanes-5 {
  min-width: 1080px;
}
.map-lane {
  fill: var(--ink-faint);
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}
.map-box {
  fill: var(--surface);
  stroke: var(--line-strong);
  stroke-width: 1.25;
}
/* The one node the diagram is about. Every other box is quiet so this reads
   first, which is the whole job of a map. */
.map-box-lit {
  fill: var(--ok-wash);
  stroke: var(--ok);
  stroke-width: 1.5;
}
.map-title {
  fill: var(--ink);
  font-family: var(--font-sans);
  font-size: 14.5px;
  font-weight: 600;
}
/* A route is an address, not a caption. It is the one thing a reader came to the
   diagram for — where do I click — and drawn like a subtitle it read as a
   description of the box. Monospaced so it looks like a literal string; the
   steps you pass through are quiet, the step you land on is not, and the
   separators carry the accent so the shape of a path is visible before any of
   the words are read. */
.map-route {
  font-family: var(--font-mono);
  font-size: 12px;
}
.map-route-step {
  fill: var(--ink-faint);
}
.map-route-sep {
  fill: var(--accent-text);
}
.map-route-here {
  fill: var(--ink);
  font-weight: 500;
}

.map-note,
.map-flow-label {
  fill: var(--ink-muted);
  font-family: var(--font-sans);
  font-size: 12.5px;
}
.map-flow-label {
  font-size: 12px;
}
.map-item {
  fill: var(--ink);
  font-family: var(--font-sans);
  font-size: 12.5px;
}
.map-rule {
  stroke: var(--line);
  stroke-width: 1;
}
.map-mark {
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 600;
  fill: var(--wf-tone);
}
.map-mark-ring {
  fill: var(--wf-wash);
  stroke: var(--wf-tone);
  stroke-width: 1;
}
.map-tone-1 { --wf-tone: var(--wf-tone-1); }
.map-tone-2 { --wf-tone: var(--wf-tone-2); }
.map-tone-3 { --wf-tone: var(--wf-tone-3); }
.map-tone-4 { --wf-tone: var(--wf-tone-4); }
.map-tone-5 { --wf-tone: var(--wf-tone-5); }
.map-tone-6 { --wf-tone: var(--wf-tone-6); }
.map-tone-7 { --wf-tone: var(--wf-tone-7); }
.map-tone-8 { --wf-tone: var(--wf-tone-8); }
.map-tone-9 { --wf-tone: var(--wf-tone-9); }
.map-tone-10 { --wf-tone: var(--wf-tone-10); }
.map-tone-1, .map-tone-2, .map-tone-3, .map-tone-4, .map-tone-5,
.map-tone-6, .map-tone-7, .map-tone-8, .map-tone-9, .map-tone-10 {
  --wf-wash: color-mix(in srgb, var(--wf-tone) var(--wf-wash-mix), var(--surface));
}
.map-flow {
  stroke: var(--ok);
  stroke-width: 1.4;
  fill: none;
}
.map-arrowhead {
  fill: var(--ok);
}
/* What comes back. Dashed and quiet, routed under everything, because a return
   drawn like a forward step reads as part of the sequence. */
.map-flow-return {
  stroke: var(--line-strong);
  stroke-width: 1.3;
  fill: none;
  stroke-dasharray: 5 4;
}
.map-arrowhead-quiet {
  fill: var(--line-strong);
}
.map a:focus-visible rect {
  stroke: var(--focus);
  stroke-width: 2;
}
.map-footnote {
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}
.map-footnote p {
  margin: 0;
  color: var(--ink-muted);
}

/* ── Workflow ─────────────────────────────────────────────────────────────
   A job drawn as the applications it passes through. Every other block draws
   one shape; this one draws a route, so it carries a colour per application
   rather than a single accent. The tones are declared here and named by class
   from the server, because a section's tone is stored data and the policy
   admits no inline style. */

:root {
  --wf-tone-1: #e0902a;
  --wf-tone-2: #6f95f5;
  --wf-tone-3: #3fbf9a;
  --wf-tone-4: #d872b8;
  --wf-tone-5: #c9a227;
  --wf-tone-6: #7c8df0;
  --wf-tone-7: #4bb3c9;
  --wf-tone-8: #cf7d5c;
  --wf-tone-9: #9d8ae0;
  --wf-tone-10: #6ec06e;
  --wf-wash-mix: 16%;
}

:root[data-theme="light"] {
  --wf-tone-1: #b8660a;
  --wf-tone-2: #2f5fd1;
  --wf-tone-3: #167a63;
  --wf-tone-4: #a53b86;
  --wf-tone-5: #8a6d00;
  --wf-tone-6: #4753c4;
  --wf-tone-7: #10708a;
  --wf-tone-8: #a2512c;
  --wf-tone-9: #6a4fc0;
  --wf-tone-10: #2f7a35;
  --wf-wash-mix: 12%;
}

.wf-tone-1 { --wf-tone: var(--wf-tone-1); }
.wf-tone-2 { --wf-tone: var(--wf-tone-2); }
.wf-tone-3 { --wf-tone: var(--wf-tone-3); }
.wf-tone-4 { --wf-tone: var(--wf-tone-4); }
.wf-tone-5 { --wf-tone: var(--wf-tone-5); }
.wf-tone-6 { --wf-tone: var(--wf-tone-6); }
.wf-tone-7 { --wf-tone: var(--wf-tone-7); }
.wf-tone-8 { --wf-tone: var(--wf-tone-8); }
.wf-tone-9 { --wf-tone: var(--wf-tone-9); }
.wf-tone-10 { --wf-tone: var(--wf-tone-10); }

/* Mixed here rather than on :root. A custom property whose value references an
   undefined one is invalid where it is declared, not resolved later where the
   reference exists — so a wash declared at the root computed to nothing and the
   marks and step numbers drew with no background at all, in both themes. It is
   set on the elements that carry a tone, where `--wf-tone` is real. */
.wf-tone-1,
.wf-tone-2,
.wf-tone-3,
.wf-tone-4,
.wf-tone-5,
.wf-tone-6,
.wf-tone-7,
.wf-tone-8,
.wf-tone-9,
.wf-tone-10 {
  --wf-wash: color-mix(in srgb, var(--wf-tone) var(--wf-wash-mix), var(--surface));
}

.block-workflow {
  display: grid;
  gap: var(--space-5);
}

.wf-caption {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-2) var(--space-4);
  margin-bottom: 0;
}
.wf-title {
  font-weight: 600;
}
.wf-summary {
  color: var(--ink-muted);
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
}

/* The strip is a glance, never the only telling: the key below repeats every
   application as a name and a count, so the figure reads without colour. */
.wf-route {
  display: grid;
  gap: var(--space-2);
}
.wf-bar {
  display: flex;
  gap: 2px;
  height: 10px;
  overflow: hidden;
  border-radius: var(--radius-pill);
}
.wf-seg {
  background: var(--wf-tone);
}
.wf-weight-1 { flex: 1; }
.wf-weight-2 { flex: 2; }
.wf-weight-3 { flex: 3; }
.wf-weight-4 { flex: 4; }
.wf-weight-5 { flex: 5; }
.wf-weight-6 { flex: 6; }
.wf-weight-7 { flex: 7; }
.wf-weight-8 { flex: 8; }

.wf-keys {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--step--1);
  color: var(--ink-muted);
}
.wf-key {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.wf-swatch {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  background: var(--wf-tone);
}
.wf-key-name {
  color: var(--ink);
}
.wf-key-count {
  font-variant-numeric: tabular-nums;
}

.wf-stages {
  display: grid;
  gap: var(--space-1);
}
.wf-stage {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr);
  column-gap: var(--space-4);
}
.wf-rail {
  display: grid;
  grid-template-rows: auto 1fr;
  justify-items: center;
}
.wf-rail-line {
  width: 2px;
  margin: var(--space-2) 0;
  border-radius: 1px;
  background: var(--line);
}
.wf-stage:last-child .wf-rail-line {
  background: transparent;
}
.wf-mark {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--wf-tone);
  border-radius: 9px;
  background: var(--wf-wash);
  color: var(--wf-tone);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.wf-mark-image {
  overflow: hidden;
  padding: 3px;
}
.wf-mark-image img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.wf-stage-body {
  display: grid;
  gap: var(--space-3);
  padding-bottom: var(--space-5);
}
.wf-app {
  display: flex;
  align-items: center;
  min-height: 36px;
  margin: 0;
  padding-top: var(--space-2);
  font-weight: 600;
}
.wf-app-link {
  color: var(--ink);
}

.wf-steps {
  display: grid;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.wf-step {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr);
  column-gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
/* An agent runs this one. Sunk rather than coloured: it is a fact about the
   step, not a state a reader has to act on. */
.wf-step-agent {
  background: var(--surface-sunk);
}
.wf-number {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: var(--radius-pill);
  background: var(--wf-wash);
  color: var(--wf-tone);
  font-size: var(--step--1);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.wf-step-body {
  display: grid;
  gap: var(--space-1);
  min-width: 0;
}
.wf-screen {
  color: var(--ink-muted);
  font-size: var(--step--1);
}
.wf-label {
  font-weight: 600;
}
.wf-detail {
  color: var(--ink-muted);
}

.wf-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.wf-chip {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--ink-muted);
  font-size: var(--step--1);
  text-decoration: none;
}
.wf-chip-person {
  border-color: var(--line-strong);
  color: var(--ink);
}
.wf-chip-agent {
  border-color: var(--accent);
  background: var(--accent-wash);
  color: var(--accent-text);
}
/* Where the job stops until somebody senior looks at it. The one place in the
   figure that wears the warning colour. */
.wf-chip-owner {
  border-color: var(--stale);
  background: var(--stale-wash);
  color: var(--stale);
}
.wf-chip-skill {
  font-family: var(--font-mono);
  font-size: var(--step--1);
}
.wf-chip-link,
.wf-chip-skill {
  color: var(--accent-text);
}

.wf-decision {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-sunk);
}
.wf-question {
  margin: 0;
  font-weight: 600;
  font-size: var(--step-0);
}
.wf-branches {
  display: grid;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}
.wf-branch {
  display: flex;
  gap: var(--space-3);
  align-items: baseline;
}
.wf-answer {
  flex: none;
  min-width: 7ch;
  padding: 1px var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--surface);
  font-size: var(--step--1);
  font-weight: 600;
  text-align: center;
}
.wf-then {
  color: var(--ink-muted);
}

.wf-before {
  display: grid;
  gap: var(--space-2);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}
.wf-before-title {
  margin: 0;
  font-size: var(--step--1);
  font-weight: 600;
}
.wf-before-none {
  margin: 0;
  color: var(--ink-muted);
  font-size: var(--step-0);
}
.wf-before-list {
  display: grid;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--step-0);
}

/* On a phone the rail costs more than it carries: the marks stay, the column
   narrows, and the stages read as a list. */
@media (max-width: 640px) {
  .wf-stage {
    grid-template-columns: 28px minmax(0, 1fr);
    column-gap: var(--space-3);
  }
  .wf-mark {
    width: 28px;
    height: 28px;
    border-radius: 7px;
    font-size: 11px;
  }
  .wf-app {
    min-height: 28px;
  }
  .wf-step {
    grid-template-columns: 22px minmax(0, 1fr);
    column-gap: var(--space-2);
    padding: var(--space-2);
  }
  .wf-number {
    width: 22px;
    height: 22px;
  }
}

@media print {
  .block-data[open] summary {
    display: none;
  }
  .block-data {
    border-top: 0;
  }
  .block-frame,
  .block-video {
    display: none;
  }
  .block-embed::after {
    color: #555;
    content: "Video — open the handbook to watch.";
  }
}

/* A section following the editor form needs to clear its buttons. */
.editor + .axis-board {
  margin-top: var(--space-7);
}

/* ---------- administration ---------- */

.panel {
  margin-bottom: var(--space-7);
  padding: var(--space-5);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}
.panel > h2,
.panel-head h2 {
  font-size: var(--step-2);
}
.panel-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
}
.panel-head .count {
  color: var(--ink-faint);
  font-size: var(--step-0);
  font-variant-numeric: tabular-nums;
}
.panel > * + * {
  margin-top: var(--space-4);
}
.panel form > * + * {
  margin-top: var(--space-4);
}
/* A form in a table's action cell is one button, not a stack of fields. The
   rule above would count its hidden CSRF input as the first item and push the
   button down, out of line with the rest of its row. */
.admin-table .cell-action form > * + * {
  margin-top: 0;
}

.prefixed-input {
  display: flex;
  align-items: center;
  overflow: hidden;
  max-width: 420px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
.prefixed-input span {
  padding: 0 var(--space-2) 0 var(--space-3);
  color: var(--ink-faint);
}
.prefixed-input input {
  flex: 1;
  min-width: 0;
  padding: 9px var(--space-3) 9px 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
}
.prefixed-input input:focus {
  outline: none;
}
.prefixed-input:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-wash);
}

.roles {
  display: grid;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  border: 0;
}
.roles legend {
  padding: 0;
  font-weight: 600;
}
/* The whole row is the target, and the description sits under its own name
   rather than running into it. */
.role-option {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.role-option:hover {
  border-color: var(--line-strong);
  background: var(--surface-sunk);
}
.role-option input {
  margin: 3px 0 0;
  accent-color: var(--accent);
  flex: none;
}
.role-option:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-wash);
}
.role-copy {
  display: grid;
  gap: 2px;
}
.role-name {
  font-weight: 600;
}
.role-detail {
  color: var(--ink-muted);
  font-size: var(--step--1);
}

.admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step-0);
}
.admin-table th,
.admin-table td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}
.admin-table thead th {
  color: var(--ink-faint);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}
.admin-table tbody tr:last-child td {
  border-bottom: 0;
}
.admin-table code {
  padding: 2px 6px;
  border-radius: var(--radius-sm);
  background: var(--surface-sunk);
  font-family: var(--font-mono);
  font-size: 0.9em;
}
.cell-name {
  min-width: 15ch;
}
.cell-action {
  text-align: right;
}
.who-name,
.who-detail {
  display: block;
}
.who-name {
  font-weight: 600;
}
.who-detail {
  color: var(--ink-faint);
  font-size: var(--step--1);
  word-break: break-word;
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* Status reads as one line plus a quieter second, never two words run together. */
.state {
  display: inline-block;
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--step--1);
  font-weight: 600;
  white-space: nowrap;
}
.state-detail {
  display: block;
  margin-top: var(--space-1);
  color: var(--ink-faint);
  font-size: var(--step--1);
}
.state-active {
  background: var(--ok-wash);
  color: var(--ok);
}
/* Waiting on an administrator, so it reads as something to do rather than as
   a neutral fact. `awaiting-signin` is waiting on the person instead, and is
   deliberately quieter. */
.state-awaiting-role,
.state-awaiting-resignin,
.state-pending {
  background: var(--warn-wash);
  color: var(--warn);
}
.state-awaiting-signin {
  background: var(--surface-sunk);
  color: var(--ink-muted);
}
.state-revoked {
  background: var(--stale-wash);
  color: var(--stale);
}

.chip-rank {
  border-color: var(--accent);
  background: var(--accent-wash);
  color: var(--accent-text);
  font-weight: 600;
}

/* An account that arrived by token rather than by approval. */
.tag-agent {
  display: inline-block;
  margin-left: var(--space-2);
  padding: 1px 6px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  color: var(--ink-muted);
  font-family: var(--font-sans);
  font-size: 11px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.role-editor {
  margin-top: var(--space-2);
}
.role-editor summary {
  color: var(--ink-muted);
  font-size: var(--step--1);
  cursor: pointer;
}
.role-editor summary:hover {
  color: var(--accent-text);
}
.role-editor form {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-sunk);
}
.role-editor .roles {
  gap: var(--space-2);
}
.role-editor .roles + .roles {
  margin-top: var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
}
.role-editor .role-option {
  background: var(--surface);
  font-size: var(--step--1);
}
.role-editor input {
  accent-color: var(--accent);
}
.role-editor button {
  justify-self: start;
  margin-top: var(--space-1);
}

.button-danger {
  padding: 5px var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--stale);
  font: inherit;
  font-size: var(--step--1);
  font-weight: 600;
  cursor: pointer;
}
.button-danger:hover {
  border-color: var(--stale);
  background: var(--stale-wash);
}

/* The delete confirmation. A real dialog rather than confirm(), because the
   policy carries no 'unsafe-inline' and the wording matters: the alternative
   to deleting is nearly always archiving, so the dialog says so. */
.confirm {
  max-width: 34rem;
  padding: var(--space-4);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
}
.confirm::backdrop {
  background: rgb(0 0 0 / 45%);
}
.confirm h2 {
  margin: 0 0 var(--space-2);
  font-size: var(--step-1);
}
.confirm p {
  margin: 0 0 var(--space-2);
}
.confirm-aside {
  color: var(--ink-muted);
  font-size: var(--step--1);
}
.confirm-actions {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  justify-content: flex-end;
  margin-top: var(--space-3);
}
.confirm-actions form {
  margin: 0;
}

@media (max-width: 760px) {
  .admin-table thead {
    display: none;
  }
  .admin-table tbody tr {
    display: grid;
    gap: var(--space-2);
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--line);
  }
  .admin-table td {
    padding: 0;
    border: 0;
  }
  .cell-action {
    text-align: left;
  }
}

/* ── Explore ──────────────────────────────────────────────────────────────
   The graph owns the viewport, so this section is the one place the shell's
   measure does not apply. Node colours are declared here rather than in the
   script, and read back from it, so the palette has one home. */

:root {
  --explore-section: #f7941d;
  --explore-tag: #7fa8c9;
  --explore-article: #8b93a0;
  --explore-workflow: #5fcf8e;
  --explore-dim: #4a5058;
  --explore-edge: rgba(236, 235, 232, 0.07);
  --explore-accent: #ffab43;
  --explore-label: rgba(236, 235, 232, 0.72);
}

:root[data-theme="light"] {
  --explore-tag: #1f4fd0;
  --explore-article: #5c5f66;
  --explore-workflow: #1d7a4e;
  --explore-dim: #b3aea6;
  --explore-edge: rgba(32, 34, 38, 0.10);
  --explore-accent: #b8620a;
  --explore-label: rgba(32, 34, 38, 0.72);
}

/* Explore is the one surface the reading measure does not apply to: the field
   is the content, and a graph in a 636px column is a graph nobody can read. */
.app-shell.app-shell-full {
  max-width: none;
  padding: 0;
}

.app-shell.app-shell-full > main {
  padding: 0;
  max-width: none;
}

.explore {
  position: relative;
  min-height: calc(100vh - 8rem);
}

.explore-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
}

.explore-canvas.dragging { cursor: grabbing; }

.explore-fallback { padding: var(--space-6) var(--space-5); }
.explore-lede { color: var(--ink-muted); font-size: var(--step-1); }
.explore-plain { margin-top: var(--space-5); }

.explore-bar {
  position: absolute;
  top: var(--space-4);
  left: var(--space-4);
  right: var(--space-4);
  display: flex;
  gap: var(--space-4);
  align-items: center;
  flex-wrap: wrap;
  z-index: 2;
}

.explore-find {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-3);
  flex: 1 1 220px;
  max-width: 320px;
}

.explore-find:focus-within { border-color: var(--accent); }
.explore-find .icon { flex: none; color: var(--ink-faint); }

.explore-find input {
  border: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  padding: var(--space-3) 0;
  width: 100%;
  caret-color: var(--accent);
}

.explore-find input:focus { outline: none; }

.explore-views {
  display: flex;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--surface);
}

.explore-views button {
  border: 0;
  border-right: 1px solid var(--line);
  background: transparent;
  color: var(--ink-muted);
  font: 500 var(--step--1) / 1 var(--font-sans);
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
  transition: color 160ms cubic-bezier(0.16, 1, 0.3, 1),
              background 160ms cubic-bezier(0.16, 1, 0.3, 1);
}

.explore-views button:last-child { border-right: 0; }
.explore-views button:hover { color: var(--ink); background: var(--surface-sunk); }
.explore-views button[aria-pressed="true"] {
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
}

.explore-rail {
  position: absolute;
  top: 5rem;
  left: var(--space-4);
  width: 210px;
  z-index: 2;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: var(--space-4);
  max-height: min(52vh, 460px);
  overflow-y: auto;
}

.explore-group { border: 0; margin: 0 0 var(--space-4); padding: 0; }
.explore-group:last-child { margin-bottom: 0; }

.explore-group legend {
  font: 500 0.6875rem / 1 var(--font-sans);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding: 0 0 var(--space-2);
}

.explore-group label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) 0;
  color: var(--ink-muted);
  font-size: var(--step--1);
  cursor: pointer;
}

.explore-group label:hover { color: var(--ink); }
.explore-group .count {
  margin-left: auto;
  font: 400 0.6875rem / 1 var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
}

.explore-figures {
  position: absolute;
  left: var(--space-4);
  bottom: var(--space-4);
  z-index: 2;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  width: 210px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.explore-figure:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}

.explore-figure {
  background: var(--surface);
  border: 0;
  padding: var(--space-3);
  text-align: left;
  cursor: pointer;
  transition: background 160ms cubic-bezier(0.16, 1, 0.3, 1);
}

.explore-figure:disabled { cursor: default; }
.explore-figure:not(:disabled):hover { background: var(--surface-sunk); }
.explore-figure[aria-pressed="true"] { background: var(--accent-wash); }
.explore-figure[aria-pressed="true"] .explore-value { color: var(--accent-text); }

.explore-value {
  display: block;
  font: 600 var(--step-1) / 1 var(--font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin-bottom: var(--space-1);
}

.explore-figure-label {
  display: block;
  font-size: 0.625rem;
  line-height: 1.25;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.explore-panel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 320px;
  z-index: 3;
  background: var(--surface);
  border-left: 1px solid var(--line);
  padding: var(--space-6) var(--space-5) var(--space-5);
  overflow-y: auto;
}

.explore-kind {
  display: block;
  font: 500 0.6875rem / 1 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: var(--space-2);
}

.explore-panel h2 { font-size: var(--step-2); margin: 0 0 var(--space-4); }

.explore-open {
  display: inline-block;
  margin-bottom: var(--space-4);
  font-weight: 500;
}

.explore-close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  width: 28px;
  height: 28px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
  line-height: 1;
}

.explore-close:hover { color: var(--ink); border-color: var(--line-strong); }

.explore-prov {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-2) var(--space-4);
  margin: 0 0 var(--space-4);
  border-top: 1px solid var(--line);
  padding-top: var(--space-4);
}

.explore-prov dt { color: var(--ink-faint); font-size: var(--step--1); }
.explore-prov dd {
  margin: 0;
  text-align: right;
  font: 400 var(--step--1) / 1.4 var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.explore-connected {
  border-top: 1px solid var(--line);
  padding-top: var(--space-4);
}

.explore-connected button {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  padding: var(--space-2) 0;
  color: var(--ink-muted);
  font: inherit;
  font-size: var(--step--1);
  cursor: pointer;
}

.explore-connected button:hover { color: var(--accent-text); }
.explore-connected p { color: var(--ink-faint); font-size: var(--step--1); }

.explore-error {
  position: absolute;
  top: 5rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  background: var(--stale-wash);
  border: 1px solid var(--stale);
  color: var(--stale);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  font-size: var(--step--1);
}

/* The phone layout is a rework, not a squeeze. The canvas stops being a
   backdrop and becomes a block of its own with the controls stacked beneath it,
   because a floating rail over a 375px-wide field covers the field. */
@media (max-width: 900px) {
  .explore { min-height: 0; display: flex; flex-direction: column; }

  .explore-canvas {
    position: static;
    height: 58vh;
    min-height: 320px;
    order: 2;
    border-block: 1px solid var(--line);
  }

  .explore-chrome { display: contents; }

  .explore-bar {
    position: static;
    order: 1;
    padding: var(--space-4);
    gap: var(--space-3);
  }

  .explore-find { max-width: none; }
  .explore-views { width: 100%; }
  .explore-views button { flex: 1; padding: var(--space-3) var(--space-2); }

  .explore-rail {
    position: static;
    order: 3;
    width: auto;
    max-height: none;
    border: 0;
    border-bottom: 1px solid var(--line);
    border-radius: 0;
  }

  .explore-figures {
    position: static;
    order: 4;
    width: auto;
    border: 0;
    border-radius: 0;
  }

  .explore-panel {
    position: fixed;
    inset: auto 0 0 0;
    top: 30vh;
    width: auto;
    border-left: 0;
    border-top: 1px solid var(--line);
    z-index: 5;
  }

  .explore-error { position: static; order: 0; margin: var(--space-4); transform: none; }
}

/* ── Browse menu ──────────────────────────────────────────────────────────
   Explore draws no rails, so the axes live in the shell. A details element
   rather than a script: no inline anything is permitted, and this keeps the
   menu keyboard-operable and working with JavaScript off. */

.menu { position: relative; }

.menu > summary { list-style: none; cursor: pointer; }
.menu > summary::-webkit-details-marker { display: none; }
.menu > summary::after {
  content: "";
  display: inline-block;
  width: 0.4em;
  height: 0.4em;
  margin-left: 0.5em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-0.15em) rotate(45deg);
}
.menu[open] > summary::after { transform: translateY(0.1em) rotate(-135deg); }
.menu[open] > summary { background: var(--surface-sunk); border-color: var(--line-strong); }

.menu-panel {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  z-index: 20;
  min-width: 240px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: var(--space-2);
  box-shadow: 0 6px 24px rgb(0 0 0 / 0.16);
}

.menu-panel a {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--ink);
  text-decoration: none;
  font-size: var(--step--1);
}

.menu-panel a:hover { background: var(--surface-sunk); }
.menu-panel a[aria-current] { color: var(--accent-text); font-weight: 600; }

/* The theme menu is built by the script rather than shipped in the markup, so
   its rows are buttons where Browse's are links. Same panel, same rows — the
   selector is joined here rather than the styles copied, or the two menus drift
   the first time either is touched. */
.menu-panel button {
  display: flex;
  width: 100%;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: var(--step--1);
  text-align: left;
  cursor: pointer;
}
.menu-panel button:hover { background: var(--surface-sunk); }
.menu-panel button[aria-current] { color: var(--accent-text); font-weight: 600; }

.theme-menu .menu-panel {
  min-width: 168px;
}
.menu-panel .icon { flex: none; color: var(--ink-faint); }
.menu-panel a[aria-current] .icon { color: var(--accent-text); }
.menu-panel .count {
  margin-left: auto;
  font: 400 0.6875rem / 1 var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
}

.menu-foot {
  border-top: 1px solid var(--line);
  margin-top: var(--space-2);
  padding-top: var(--space-3) !important;
  color: var(--ink-muted) !important;
}

@media (max-width: 700px) {
  .menu-panel { right: auto; left: 0; min-width: 210px; }
}
