/* Layout and treatment. The values live in tokens.css, which is generated from
 * the specification; nothing here invents a colour or a radius.
 *
 * CSS is a better language for CSS than a document would be, so layout rules
 * stay here — presentation-system says so, and moving them into the document
 * would be capability in the wrong place because it could technically go there.
 */

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

/* A panel parked off-screen still counts toward the scrollable width, and the
 * result is a page that scrolls sideways to reveal nothing. `clip` stops that
 * without breaking `position: sticky`, which `hidden` would. */
html, body { overflow-x: clip; }

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--face-body);
  font-size: var(--size-base);
  line-height: var(--line-base);
  -webkit-font-smoothing: antialiased;
}

.mono, .tabular { font-family: var(--face-mono); }
.tabular { font-variant-numeric: tabular-nums; }

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

.appbar {
  position: sticky; top: 0; z-index: 10;
  min-height: var(--appbar-h);
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px var(--gutter);
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
/* The bar must never be the reason the page is wider than the window: it sets
 * the width every container query below it measures against, so one unwrapped
 * row of buttons quietly switches off every responsive rule in the document. */
.appbar > * { min-width: 0; }
.appbar .doc-name { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wordmark { font-weight: 700; letter-spacing: -0.02em; font-size: 17px; }
.wordmark small { color: var(--dim); font-weight: 400; margin-left: 8px; letter-spacing: 0; }
.appbar .doc-name { color: var(--fg-soft); font-size: 13px; margin-left: 4px; }
.appbar .spacer { flex: 1 1 0; min-width: 0; }

button, .filepick {
  font: inherit; font-size: 13px;
  padding: 7px 13px; border-radius: var(--r-sm);
  border: 1px solid var(--line-strong);
  background: var(--raised); color: var(--fg-soft);
  cursor: pointer;
}
button:hover, .filepick:hover { border-color: var(--accent); color: var(--accent); }
button.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
button:focus-visible, .filepick:focus-within { outline: none; box-shadow: var(--ring); }
.filepick input { display: none; }

.layout { display: flex; align-items: flex-start; max-width: 100%; }
.rail {
  width: var(--sidebar-w); flex: none;
  position: sticky; top: var(--appbar-h);
  max-height: calc(100vh - var(--appbar-h));
  overflow: auto; padding: var(--gutter);
  border-right: 1px solid var(--line);
}
.rail h4 { margin: 0 0 8px; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--dim); }
.rail a { display: block; padding: 4px 0; color: var(--fg-soft); text-decoration: none; font-size: 13px; }
.rail a:hover { color: var(--accent); }

main { flex: 1 1 0; min-width: 0; max-width: 100%; padding: 28px var(--gutter) 120px; }
/* The document takes the width it is given, up to a bound. Only prose is held
 * to a measure — see typography.the-measure-is-for-prose-only. */
.document { max-width: var(--page); margin: 0 auto; }


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

.doc-head { margin-bottom: 30px; }
.doc-head h1 { font-size: 30px; letter-spacing: -0.02em; margin: 0 0 6px; }
.doc-meta { color: var(--dim); font-size: 12px; margin: 0; }

/* Each top-level part of the document is a card.
 *
 * It used to be one by accident: before the envelope was unwrapped, these were
 * entries inside a collection and inherited the entry treatment. Unwrapping
 * made them sections and they lost it, which is the kind of regression a
 * structural change makes silently — nothing errored and the content was all
 * still there, just flat against the page. */
.section {
  margin: 0 0 18px;
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
  padding: 18px 22px 22px;
}
.section > h2 {
  font-size: 13px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--dim); font-weight: 600;
  margin: 0 0 14px; padding-bottom: 9px; border-bottom: 1px solid var(--line);
}
/* Cards inside a card recede, or the page becomes a stack of boxes in boxes. */
.section .entry { background: var(--panel); box-shadow: none; }
.section-ann { text-transform: none; letter-spacing: 0; font-size: 12px; }

.fields { display: flex; flex-direction: column; gap: 9px; }
.field { display: grid; grid-template-columns: minmax(9rem, 22%) 1fr; gap: 14px; align-items: baseline; }
.field.block { grid-template-columns: 1fr; gap: 6px; }
.field-key { font-size: 13px; }
.field-value { min-width: 0; }

.prose { margin: 0 0 10px; max-width: var(--measure); }
/* The author's notes: present, findable, and not in the way. */
.note { margin: 0 0 14px; }
.note > summary {
  list-style: none; cursor: pointer; display: inline-flex; align-items: baseline; gap: 9px;
  padding: 3px 9px 3px 3px; border-radius: var(--r-sm);
  color: var(--dim); font-size: 12.5px;
}
.note > summary::-webkit-details-marker { display: none; }
.note > summary:hover { color: var(--fg-soft); background: var(--panel); }
.note > summary:focus-visible { outline: none; box-shadow: var(--ring); }
.note-mark {
  font-size: 10px; letter-spacing: .09em; text-transform: uppercase;
  border: 1px solid var(--line-strong); border-radius: 999px; padding: 1px 7px;
  color: var(--dim); flex: none;
}
.note-title { font-style: italic; }
.note[open] > summary { margin-bottom: 4px; }
.note[open] .note-title { color: var(--fg-soft); font-style: normal; font-weight: 600; }
.note-body {
  border-left: 2px solid var(--line-strong); padding: 2px 0 2px 14px; margin-left: 6px;
}
.note-body p { margin: 0 0 9px; max-width: var(--measure); font-size: 14px; color: var(--fg-soft); }
.note-body p:last-child { margin-bottom: 0; }
.note-body code {
  font-family: var(--face-mono); font-size: 12.5px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 4px; padding: 0 4px;
}

/* ---------------------------------------------------------------- constructs */

.c-key { color: var(--c-key); }
.c-string { color: var(--c-string); }
.c-symbol { color: var(--c-symbol); }
.c-identifier { color: var(--c-identifier); }
.c-bytes { color: var(--c-bytes); }
.c-number { color: var(--c-number); }
.c-timestamp { color: var(--c-timestamp); border-bottom: 1px dotted var(--line-strong); cursor: help; }
.c-comment { color: var(--c-comment); }
a.c-identifier { text-decoration: none; }
a.c-identifier:hover { text-decoration: underline; }

.annotated .qualifier { font-size: 11px; margin-right: 6px; opacity: .85; }

/* ---------------------------------------------------------------- treatments */

.grid, .matrix { border-collapse: collapse; width: 100%; font-size: 13px; }
.grid th {
  text-align: left; font-weight: 600; font-size: 11px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--dim);
  padding: 6px 10px; border-bottom: 1px solid var(--line-strong); white-space: nowrap;
}
.grid td { padding: 6px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
.grid tr:last-child td { border-bottom: 0; }
.grid td.num, .matrix td { text-align: right; font-family: var(--face-mono); font-variant-numeric: tabular-nums; }
.matrix { width: auto; }
.matrix td { padding: 3px 12px; border: 0; }

.glossary { margin: 0; }
.glossary dt { font-weight: 600; font-size: 13px; color: var(--c-key); margin-top: 12px; }
.glossary dt:first-child { margin-top: 0; }
.glossary dd { margin: 3px 0 0; max-width: var(--measure); }

.settings { display: flex; flex-wrap: wrap; gap: 6px 20px; }
.setting { display: flex; gap: 9px; align-items: baseline; font-size: 13px; }
.setting-key { color: var(--dim); }

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  font-size: 12px; padding: 2px 9px; border-radius: 999px;
  border: 1px solid var(--line-strong); background: var(--panel);
  font-family: var(--face-mono);
}

.breakdown { display: flex; flex-direction: column; gap: 5px; max-width: 46ch; }
.bar-row { display: grid; grid-template-columns: 9rem 1fr 5rem; gap: 11px; align-items: center; font-size: 13px; }
.bar-key { color: var(--dim); }
.bar-track { height: 8px; background: var(--panel); border-radius: 999px; overflow: hidden; }
.bar-fill { height: 100%; background: var(--accent); border-radius: 999px; }
.bar-num { text-align: right; font-family: var(--face-mono); }

.vector { font-variant-numeric: tabular-nums; }
.vector .unit { color: var(--dim); }

/* auto-FIT, not auto-fill: empty tracks collapse, so two cards on a wide screen
 * become two wide cards rather than two narrow ones beside a gap. The minimum
 * is the point at which a card stops being able to hold a labelled field. */
.entries {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr));
  align-items: stretch;
}
.entry {
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--raised); padding: 14px 16px; box-shadow: var(--shadow);
}
.entry-name { margin: 0 0 9px; font-size: 14px; letter-spacing: -0.01em; }
.entry .field { grid-template-columns: minmax(7rem, 40%) 1fr; gap: 10px; }

.plain-list { margin: 0; padding-left: 18px; }
.plain-list li { margin: 2px 0; }

.primitive, .extension {
  border: 1px solid var(--line); border-left: 3px solid var(--c-extension);
  border-radius: var(--r-md); padding: 13px 15px; background: var(--panel);
}
.ext-head { margin-bottom: 12px; }
.ext-kind {
  font-size: 15px; font-weight: 600; letter-spacing: -0.01em;
  color: var(--c-extension); margin-right: 9px;
}
.ext-ns {
  font-size: 11px; font-family: var(--face-mono); color: var(--dim);
  border: 1px solid var(--line); border-radius: 999px; padding: 1px 8px;
  vertical-align: 1px;
}
.ext-note { margin: 5px 0 0; font-size: 12px; color: var(--dim); max-width: var(--measure); }

/* ---------------------------------------------------------------- payloads */

.payload-block { display: flex; flex-direction: column; gap: 11px; }
.payload {
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--panel); padding: 13px 15px;
  display: flex; flex-direction: column; gap: 10px; align-items: flex-start;
}
.payload-head { display: flex; flex-wrap: wrap; gap: 12px; font-size: 12px; align-items: baseline; }
.payload-type { color: var(--c-bytes); }
.payload-size, .payload-route { color: var(--dim); }
.payload-media { max-width: 100%; border-radius: var(--r-sm); }
img.payload-media { max-height: 380px; }
audio.payload-media { width: min(100%, 30rem); }
object.payload-doc { width: 100%; height: 460px; border: 1px solid var(--line); background: #fff; display: block; }
object.payload-doc .rung-note { padding: 18px; }
/* controls.variants, as declared. An action is a button with a stated variant;
 * an action rendered as prose gives no sign that it is one. */
.btn {
  font: inherit; font-size: 13px; line-height: 1;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px; border-radius: var(--r-sm);
  text-decoration: none; cursor: pointer; white-space: nowrap;
}
.btn.primary { background: var(--accent); border: 1px solid var(--accent); color: #fff; }
.btn.secondary { background: var(--raised); border: 1px solid var(--line-strong); color: var(--fg-soft); }
.btn.secondary:hover { border-color: var(--accent); color: var(--accent); }
.btn.quiet { background: transparent; border: 1px solid transparent; color: var(--fg-soft); }
.btn.quiet:hover { border-color: var(--line-strong); }
.btn:focus-visible { outline: none; box-shadow: var(--ring); }
.payload-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.rung-note { margin: 0; font-size: 12px; color: var(--dim); }

.verify {
  font-size: 11px; padding: 2px 8px; border-radius: 999px;
  font-family: var(--face-mono); letter-spacing: .02em;
}
.verify.ok { background: color-mix(in srgb, var(--c-bytes) 16%, transparent); color: var(--c-bytes); }
.verify.bad { background: var(--err-soft); color: var(--err); }
.verify.pending, .verify.unknown { background: var(--panel); color: var(--dim); }

/* ---------------------------------------------------------------- disclosure */

.inferred { position: relative; }
body.show-marks .inferred { outline: 1px dashed color-mix(in srgb, var(--c-inferred) 55%, transparent); outline-offset: 2px; }
body.show-marks .inferred::after {
  content: attr(data-rule);
  position: absolute; top: -8px; right: -4px;
  font: 9px/1.4 var(--face-mono); color: var(--c-inferred);
  background: var(--bg); padding: 0 3px; border-radius: 3px;
  pointer-events: none;
}

.panel {
  position: fixed; right: 0; top: var(--appbar-h); bottom: 0; width: min(30rem, 92vw);
  background: var(--raised); border-left: 1px solid var(--line);
  box-shadow: var(--shadow); overflow: auto; padding: var(--gutter);
  transform: translateX(101%); transition: transform 180ms cubic-bezier(.2,0,0,1), visibility 180ms;
  z-index: 20;
  /* Hidden rather than merely moved, so nothing inside it takes focus or is
   * read out while it is closed. */
  visibility: hidden;
}
.panel.open { transform: none; visibility: visible; }
.panel h3 { margin: 0 0 4px; font-size: 15px; }
.panel .sub { color: var(--dim); font-size: 12px; margin: 0 0 16px; }
.inf-rule {
  display: grid; grid-template-columns: 3.4rem 1fr auto; gap: 10px;
  padding: 8px 0; border-bottom: 1px solid var(--line); font-size: 12.5px; align-items: baseline;
}
.inf-rule code { color: var(--c-inferred); font-family: var(--face-mono); }
.inf-rule .count { color: var(--dim); font-variant-numeric: tabular-nums; }
.conf { font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--dim); }

.drop {
  margin: 60px auto; max-width: 46rem; padding: 60px 32px; text-align: center;
  border: 1px dashed var(--line-strong); border-radius: var(--r-lg); background: var(--panel);
}
.drop.live { border-color: var(--accent); background: var(--accent-soft); }
.drop h2 { margin: 0 0 8px; font-size: 22px; letter-spacing: -0.02em; }
.drop p { margin: 0 0 20px; color: var(--fg-soft); }
.samples { display: flex; flex-wrap: wrap; gap: 7px; justify-content: center; margin-top: 22px; }
.samples button { font-size: 12px; }
.err { color: var(--err); background: var(--err-soft); padding: 12px 15px; border-radius: var(--r-sm); font-size: 13px; }

/* ---------------------------------------------------------------- grids */

.gridfig { margin: 4px 0 14px; }
.board {
  display: grid;
  grid-template-columns: auto repeat(var(--cols), minmax(0, 1fr));
  gap: 1px;
  width: min(100%, calc(var(--cols) * 2.6rem + 1.6rem));
  background: var(--line);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  overflow: hidden;
  padding: 1px;
}
.board-corner { background: var(--bg); }
.board-label {
  background: var(--bg); color: var(--dim);
  font: 11px/1 var(--face-mono);
  display: flex; align-items: center; justify-content: center;
  padding: 5px 4px;
}
.board-label.row { padding-right: 7px; }
.board-cell { aspect-ratio: 1; background: var(--raised); }
.board-cell.state-1 { background: color-mix(in srgb, var(--bg) 88%, var(--fg)); }
.board-cell.state-2 { background: color-mix(in srgb, var(--fg) 42%, var(--bg)); }
.gridfig-cap { margin: 9px 0 0; font-size: 12px; color: var(--dim); }
.gridfig-guess { color: var(--c-inferred); }
.gridfig-holder { display: flex; flex-direction: column; gap: 10px; }

/* a URL is something you click */
a.c-string { color: var(--accent); text-decoration: none; border-bottom: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); }
a.c-string:hover { border-bottom-color: var(--accent); }

/* a colour shown as itself */
.chip.swatch { display: inline-flex; align-items: center; gap: 7px; padding-left: 7px; }
.chip.has-colour { border-width: 1px; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fg) 8%, transparent); }
.chip.has-colour .swatch-name { mix-blend-mode: normal; }
.chip.swatch.state-1 { background: color-mix(in srgb, var(--bg) 88%, var(--fg)); color: var(--fg); }
.chip.swatch.state-2 { background: color-mix(in srgb, var(--fg) 42%, var(--bg)); color: var(--bg); }
.swatch-name { font-size: 12px; }
.gridfig-legend { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-top: 8px; font-size: 12px; }

/* a mention of something this document defines */
a.mention { text-decoration: none; border-bottom: 1px dotted color-mix(in srgb, var(--c-identifier) 55%, transparent); }
a.mention:hover { border-bottom-style: solid; border-bottom-color: var(--accent); }
.entry:target, .glossary dt:target { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: var(--r-sm); }
a.wordmark { color: inherit; text-decoration: none; }
a.wordmark:hover { color: var(--accent); }
tr:target { outline: 2px solid var(--accent); outline-offset: -2px; }

/* ---------------------------------------------------------------- overflow */

/* Wide content scrolls within its own box. Nothing pushes out of its container
 * and the page never scrolls sideways. */
.table-scroll { overflow-x: auto; max-width: 100%; }
.matrix, .board { max-width: 100%; }

/* Grid and flex children refuse to shrink below their content unless told. */
.entry, .field, .field-value, .fields, .section, .document,
.gridfig, .gridfig-holder, .payload, .payload-block, main { min-width: 0; }
.entry { overflow: hidden; }

/* A card holding a table wants the whole row: a seven-column table in a
 * 22rem card is a scrollbar where a table would have fitted. */
.entry.wide { grid-column: 1 / -1; }

/* Long unbroken values — digests, base64, paths — wrap rather than widen. */
.field-value, .glossary dd, .prose, .setting-value { overflow-wrap: anywhere; }
.grid td, .grid th { overflow-wrap: anywhere; }

/* ---------------------------------------------------------------- narrow */

/* These are container queries, not device breakpoints. A field stacks because
 * the column holding it is narrow, which is a fact about the layout and not
 * about the screen — the same field is roomy in a wide card and cramped in a
 * narrow one on the same display. The shell's breakpoint is a declared value
 * and is generated into tokens.css; this is not that, and does not duplicate it.
 */
main { container-type: inline-size; container-name: content; }

@container content (max-width: 32rem) {
  .field { grid-template-columns: 1fr; gap: 2px; }
  .field-key { color: var(--dim); }
  .bar-row { grid-template-columns: 1fr 4rem; }
  .bar-row .bar-track { grid-column: 1 / -1; }
  .entries { grid-template-columns: 1fr; }
  .entry .field { grid-template-columns: 1fr; }
}

@container content (max-width: 22rem) {
  .settings { flex-direction: column; gap: 4px; }
}

/* Prose is measured; structure is not. A field whose value is running text is
 * held to the measure even inside a wide layout, because the constraint is
 * about the line and not about the container. */
.field-value > .prose, .comment, .rung-note, .gridfig-cap { max-width: var(--measure); }
.field-value.is-text { max-width: var(--measure); }

/* The author's own name for a part, shown where they wrote it and no louder. */
.note-caption {
  margin: -6px 0 12px; font-size: 12.5px; font-style: italic; color: var(--dim);
  max-width: var(--measure);
}
.note-caption::first-letter { text-transform: uppercase; }

/* A reference that resolves inside this document, and one that does not. */
a.c-identifier.resolved { border-bottom: 1px dotted color-mix(in srgb, var(--c-identifier) 60%, transparent); }
a.c-identifier.resolved:hover { border-bottom-style: solid; color: var(--accent); }
.c-identifier.unresolved { opacity: .72; border-bottom: 1px dashed var(--line-strong); cursor: help; }
.entry:target, .field:target, .section:target { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: var(--r-sm); }

/* ---------------------------------------------------------------- sound */

.sounded {
  border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: var(--r-md); background: var(--panel);
  padding: 15px 17px; display: flex; flex-direction: column; gap: 11px;
  align-items: flex-start;
}
.sounded-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.sounded-title { font-size: 14px; font-weight: 600; }
.sounded-detail { font-size: 12px; color: var(--dim); font-family: var(--face-mono); }
.sounded-why { margin: 0; font-size: 12.5px; color: var(--dim); max-width: var(--measure); }
.sounded-why code {
  font-family: var(--face-mono); font-size: 12px; color: var(--c-key);
  background: var(--raised); border: 1px solid var(--line); border-radius: 4px; padding: 0 4px;
}
.btn.playing { background: var(--err); border-color: var(--err); }
.sounded-table { width: 100%; }
.sounded-table > summary { list-style: none; cursor: pointer; display: inline-flex;
  align-items: baseline; gap: 9px; color: var(--dim); font-size: 12.5px; padding: 3px 0; }
.sounded-table > summary::-webkit-details-marker { display: none; }
.sounded-table > summary:hover { color: var(--fg-soft); }

/* ---------------------------------------------------------------- lattices */

.lattice { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }
.lattice-svg {
  width: min(100%, 34rem); height: auto;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-md);
}
.lattice-node { fill: var(--fg-soft); }
.lattice-edge { stroke: var(--line-strong); stroke-width: 2; stroke-linecap: round; }
.lattice-edge.claimed { stroke-width: 4.5; }
.lattice-edge.claimed.seat-0 { stroke: var(--accent); }
.lattice-edge.claimed.seat-1 { stroke: var(--c-extension); }
.lattice-face { fill: transparent; transition: fill 160ms linear; }
.lattice-face.owned.seat-0 { fill: color-mix(in srgb, var(--accent) 22%, transparent); }
.lattice-face.owned.seat-1 { fill: color-mix(in srgb, var(--c-extension) 22%, transparent); }
.lattice-face-label { font: 600 11px var(--face-mono); fill: var(--fg-soft); text-anchor: middle; }
.lattice-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; width: min(100%, 34rem); }
.lattice-scrub { flex: 1 1 8rem; accent-color: var(--accent); }
.lattice-status { font-size: 12px; color: var(--dim); font-family: var(--face-mono); flex: 1 1 100%; }
.treatment-failed { border-left: 3px solid var(--err); padding-left: 12px; }
.treatment-failed .rung-note { color: var(--err); }
.lattice-edge.playable { cursor: pointer; }
.lattice-edge.playable:hover { stroke: var(--accent); stroke-width: 4; }
.lattice.interactive .lattice-svg { border-color: var(--accent); }
.induced { width: min(100%, 34rem); }
.induced > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: baseline;
  gap: 9px; color: var(--dim); font-size: 12.5px; padding: 3px 0; }
.induced > summary::-webkit-details-marker { display: none; }
.induced > summary:hover { color: var(--fg-soft); }
.support { display: block; font-size: 11px; color: var(--c-inferred); font-family: var(--face-mono); margin-top: 2px; }

/* ---------------------------------------------------------------- trees */

.tree, .tree-children { list-style: none; margin: 0; padding: 0; }
.tree-children { margin-left: 18px; border-left: 1px solid var(--line); padding-left: 14px; }
.tree-node { margin: 1px 0; }
.tree-row { display: flex; align-items: baseline; gap: 12px; }
.tree-label { flex: 1 1 auto; min-width: 0; }
.tree-extra, .tree-page { color: var(--dim); font-family: var(--face-mono); font-size: 12px; flex: none; }
/* The marker is a flex item beside the row, not a block above it. As a block
 * it took a line of its own and made every branch two rows tall, so branches
 * and leaves read as different sizes when they are the same kind of thing. */
.tree-branch > summary {
  list-style: none; cursor: pointer; border-radius: var(--r-sm);
  display: flex; align-items: baseline; gap: 7px;
}
.tree-branch > summary::-webkit-details-marker { display: none; }
.tree-branch > summary::before {
  content: '▸'; color: var(--dim); font-size: 10px; flex: none;
  width: 9px; text-align: center; transition: transform 120ms linear;
}
.tree-branch[open] > summary::before { content: '▾'; }
.tree-branch > summary:hover { background: var(--panel); }
.tree-branch > summary > .tree-row { flex: 1 1 auto; min-width: 0; }
/* Leaves line up with the text of branches rather than with their markers. */
.tree-node > .tree-row { padding-left: 16px; }
button.tree-page.linked {
  background: none; border: 1px solid transparent; padding: 0 5px; cursor: pointer;
  color: var(--accent); font-family: var(--face-mono); font-size: 12px; border-radius: 4px;
}
button.tree-page.linked:hover { border-color: var(--accent); }

/* ---------------------------------------------------------------- positions */

.position { display: inline-flex; flex-direction: column; gap: 5px; align-items: flex-start; }
.position-grid {
  display: grid; grid-template-columns: repeat(var(--cols), 1.5rem);
  gap: 1px; background: var(--line-strong); border: 1px solid var(--line-strong);
  border-radius: var(--r-sm); overflow: hidden;
}
.position-cell {
  aspect-ratio: 1; background: var(--raised); display: flex;
  align-items: center; justify-content: center;
  font: 600 13px var(--face-mono); color: var(--fg);
}
.position-cell.empty { background: var(--panel); }
.position-raw { font-family: var(--face-mono); font-size: 11px; color: var(--dim); }
.payload-channel {
  font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--c-inferred); border: 1px solid color-mix(in srgb, var(--c-inferred) 40%, transparent);
  border-radius: 999px; padding: 1px 8px;
}

/* ------------------------------------------------------------------ places */

.places { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.places-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.places-title { font-weight: 600; font-size: 13px; }
.places-detail { font-size: 12px; color: var(--dim); font-family: var(--face-mono); }
.places-svg {
  width: min(100%, 30rem); height: auto;
  border: 1px solid var(--line); border-radius: var(--r-md);
}
.places-ground { fill: var(--panel); }
.places-grat { stroke: var(--line-strong); stroke-width: .7; stroke-dasharray: 3 3; }
.places-grat.strong { stroke: var(--fg-soft); stroke-dasharray: none; stroke-width: .9; }
.places-tick { font: 9px var(--face-mono); fill: var(--dim); }
.places-label { font: 11px var(--face-body); fill: var(--fg); }
.places-dot { fill: var(--accent); }
.places-halo { fill: color-mix(in srgb, var(--accent) 22%, transparent); }
.places-scale line { stroke: var(--fg-soft); stroke-width: 1.1; }
.places-scale text { font: 10px var(--face-mono); fill: var(--fg-soft); }
.places-why { font-size: 12px; color: var(--dim); max-width: 62ch; margin: 0; }
.places-rows { width: 100%; }
.places-rows > summary {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--dim); cursor: pointer;
}

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

.mesh { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.mesh-svg {
  width: min(100%, 22rem); height: auto; touch-action: none; cursor: grab;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-md);
}
.mesh-svg:active { cursor: grabbing; }
.mesh-face { fill: var(--accent); stroke: color-mix(in srgb, var(--fg) 40%, transparent); stroke-width: .6; }
.mesh-point { fill: var(--fg-soft); }
.wave-svg { width: min(100%, 22rem); height: auto; background: var(--raised);
  border: 1px solid var(--line); border-radius: var(--r-sm); }
.wave-line { fill: none; stroke: var(--c-inferred); stroke-width: 1.4; }
.frames { display: flex; flex-direction: column; gap: 9px; align-items: flex-start; }
.frames-canvas {
  image-rendering: pixelated; width: min(100%, 16rem); height: auto;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-sm);
}
