/* ===========================================================================
   Artificial Reverse Engineer.

   The page is one screen of a 1987 graphic adventure, measured off the CRT
   photograph in art/ref/screen.jpg (tools/refmeasure.mjs, tools/refink.mjs):
   a screen of 1040 x 747 whose six regions are a masthead over a main column
   of 87.5% with a rail of 11.73% beside it, and whose inks are the saturated
   set below on a ground that is 72% unlit.

   What his picture does NOT get to decide is readability. The display face this
   page shipped with (Pixelify Sans) was measured glyph by glyph and retired: its
   c and its o are the SAME GLYPH (0.0% of the ink differs at 18 px, 0.4% at
   32 px), its i and its l differ by 2.9%, its C and its O by 1.8%. So "Decode"
   read as "Deoode", "Docs" as "Doos", "GO TO" as "80 TO" and the project's own
   name as "Artifioial". No size, no tracking and no smoothing hint fixes a face
   whose letters are the same drawing. Every word on this page is therefore set
   in JetBrains Mono, the face the agent log already used, which keeps the
   terminal register his picture is in; the pixel character lives where his
   picture actually puts it, in the rasters. Sentences are Space Grotesk. every ink below is measured at 4.5:1 or better on the
   ground it is painted on (tools/legibility.mjs proves it); the deep blue of
   his picture is 2.9:1 on black and is used as a frame colour only.
   =========================================================================== */

@font-face { font-family: Grot;  src: url("/fonts/spacegrotesk-400.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: Grot;  src: url("/fonts/spacegrotesk-500.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: Grot;  src: url("/fonts/spacegrotesk-700.woff2") format("woff2"); font-weight: 700; font-display: swap; }
@font-face { font-family: Mono;  src: url("/fonts/jetbrains-400.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: Mono;  src: url("/fonts/jetbrains-700.woff2") format("woff2"); font-weight: 700; font-display: swap; }

:root {
  --ground: #05070a;
  --ink-white: #e4f1f3;   /* 16.8:1 on the ground: the brightest text      */
  --ink-cyan:  #6fe2e6;   /* 11.5:1 : structure, rules, titles             */
  --ink-sky:   #58c4f0;   /*  8.6:1 : links and the stage that is live     */
  --ink-green: #6ce06a;   /* 10.6:1 : a reading that came out right        */
  --ink-yellow:#e8e46a;   /* 13.1:1 : a reading in progress                */
  --ink-red:   #ff6a63;   /*  7.3:1 : a call that failed                   */
  --ink-mag:   #f07ae8;   /*  8.1:1 : a call nothing explains              */
  --ink-mint:  #5fe3b2;   /* 11.0:1 : the share already read               */
  --ink-mute:  #8fa3aa;   /*  6.2:1 : separators and disabled keys         */
  --frame:     #1f6f8e;   /* a rule, never text                            */
  --frame-lit: #6fe2e6;

  --page: 1120px;
  --gutter: 24px;
  --gap: 6px;

  --t-micro: 13px;
  --t-small: 14px;
  --t-body: 15px;
  --t-lead: 16px;
  --t-key: 18px;
  --t-head: 20px;
  --t-name: 32px;
  --t-display: 48px;

  --rail: 154px;
  --pad: 22px;
}

* { box-sizing: border-box; }

html { background: var(--ground); }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink-white);
  font: 400 var(--t-body)/1.6 Grot, "Segoe UI", system-ui, sans-serif;
  font-synthesis: none;
  -webkit-text-size-adjust: 100%;
  overflow-x: hidden;
}

/* The phosphor field: even rows, one lit line in four, across the whole page.
   Not noise, not a generated texture: a repeating gradient that cannot drift. */
.scan {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 50;
  background: repeating-linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0.035) 0, rgba(255, 255, 255, 0.035) 1px,
    rgba(0, 0, 0, 0) 1px, rgba(0, 0, 0, 0) 4px);
}
@media (prefers-reduced-motion: no-preference) {
  .scan::after {
    content: "";
    position: absolute;
    left: 0; right: 0; top: -40%;
    height: 40%;
    background: linear-gradient(to bottom, rgba(111, 226, 230, 0) 0%, rgba(111, 226, 230, 0.045) 60%, rgba(111, 226, 230, 0) 100%);
    animation: sweep 9s linear infinite;
  }
}
@keyframes sweep { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(0, 350vh, 0); } }

.screen {
  width: min(100% - var(--gutter) * 2, var(--page));
  margin: 0 auto;
  padding: 12px 0 96px;
}

/* ---------------------------------------------------------------- masthead */

.masthead {
  display: grid;
  grid-template-columns: 70px 1fr;
  grid-template-rows: auto auto;
  column-gap: 20px;
  align-items: center;
  margin-bottom: 12px;
}
.masthead__mark {
  grid-row: 1 / 3;
  width: 70px; height: 70px;
  image-rendering: pixelated;
  filter: drop-shadow(0 0 14px rgba(111, 226, 230, 0.28));
}
.masthead__name {
  margin: 0;
  font: 700 var(--t-name)/1 Mono, ui-monospace, monospace;
  letter-spacing: 0.01em;
  align-self: end;
}
.masthead__name { overflow-wrap: break-word; }
.masthead__word { display: inline-block; white-space: nowrap; }
.masthead__word span { display: inline-block; }
/* the countdown shares the masthead's one line: its own row cost the command line its place on
   the first screen, and a first screen is one screen */
.masthead__clock { color: var(--ink-yellow); }
.masthead__clock:not(:empty)::before { content: "  ·  "; color: var(--ink-mute); }
.masthead__line {
  margin: 8px 0 0;
  align-self: start;
  font: 400 var(--t-small)/1.4 Mono, ui-monospace, monospace;
  color: var(--ink-mute);
  letter-spacing: 0.02em;
}

/* ------------------------------------------------------------------- bench */

.bench {
  display: grid;
  grid-template-columns: 1fr var(--rail);
  grid-template-areas:
    "viewport stages"
    "log      pages"
    "tray     tray"
    "command  command"
    "answer   answer";
  gap: var(--gap);
}
.viewport { grid-area: viewport; }
.rail--stages { grid-area: stages; }
.log { grid-area: log; }
.rail--pages { grid-area: pages; }
.tray { grid-area: tray; }
.command { grid-area: command; }
.command__answer { grid-area: answer; }

/* ------------------------------------------------------------------ panels */
/* His regions are drawn with a rule and the region's name rides ON that rule. */

.panel, .rail {
  position: relative;
  border: 2px solid var(--frame);
  padding: var(--pad) 24px 20px;
  background: var(--ground);
  min-width: 0;
}
.panel__title {
  position: absolute;
  top: -20px;
  left: 18px;
  margin: 0;
  padding: 11px 19px;
  background: var(--ground);
  color: var(--ink-cyan);
  font: 700 var(--t-small)/1 Mono, ui-monospace, monospace;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.panel__title--rail { left: 14px; }

/* ---------------------------------------------------------------- viewport */

.viewport { padding-bottom: 10px; }
.viewport__grid {
  display: grid;
  grid-template-columns: 1fr 244px;
  gap: 20px;
  align-items: stretch;
  min-height: 206px;
}
.viewport__plot {
  min-width: 0;
  width: 100%;
  height: 214px;
  display: flex;
  align-items: center;
  overflow: hidden;
}
.viewport__plot .plot { width: 100%; }
.viewport__side { display: flex; flex-direction: column; justify-content: space-between; gap: 10px; min-width: 0; }
.viewport__art {
  /* a fixed BOX, not a fixed width: the empty state art is nearly square and the bench art is
     three by two, so sizing by width alone made the frame two different heights between states */
  width: 100%; max-width: 206px; height: 112px;
  object-fit: contain;
  image-rendering: pixelated;
  align-self: center;
}
.viewport__caption {
  /* the room is reserved in LINES: a caption that wraps on two stages and not on three made the
     viewport two different heights, and a set of plates that swap in one frame has one height */
  margin: 10px 0 0;
  min-height: calc(var(--t-small) * 1.5 * 2);
  font: 400 var(--t-small)/1.5 Grot, sans-serif;
  color: var(--ink-mute);
}

/* the plot: one row per thing being measured, drawn as cells like his chart */
.plot { display: flex; flex-direction: column; gap: 6px; }
.plot__row { display: grid; grid-template-columns: minmax(96px, max-content) minmax(72px, 1fr) 62px; align-items: center; gap: 12px; min-width: 0; }
.plot__name {
  font: 400 var(--t-small)/1.3 Mono, monospace;
  color: var(--ink-white);
  white-space: nowrap;
}
/* every row has the same number of slots and lights the first N: the bar then divides whatever
   width the track gives it, instead of running off the panel on a phone */
.plot__bar { display: grid; grid-template-columns: repeat(var(--slots, 34), 1fr); gap: 3px; height: 18px; min-width: 0; }
.plot__cell { height: 18px; min-width: 0; }
.plot__cell--off { background: none; }
.plot__num {
  font: 400 var(--t-small)/1.3 Mono, monospace;
  color: var(--ink-mute);
  text-align: right;
}
.plot__legend {
  display: flex; flex-wrap: wrap; gap: 6px 18px;
  margin-top: 12px;
  font: 400 var(--t-micro)/1.4 Grot, sans-serif;
  color: var(--ink-mute);
}
.plot__legend b { font-weight: 500; }
.plot__swatch { display: inline-block; width: 10px; height: 10px; margin-right: 7px; vertical-align: -1px; }

/* what the bars do not say: the stage's own numbers, as label and value rows */
.facts { margin: 14px 0 0; display: grid; grid-template-columns: 232px minmax(0, 1fr); gap: 0 20px; }
.facts dt {
  font: 400 var(--t-micro)/1.5 Grot, sans-serif;
  color: var(--ink-mute);
  padding: 5px 0;
  position: relative;
}
.facts dd {
  margin: 0;
  font: 400 var(--t-small)/1.5 Mono, monospace;
  color: var(--ink-white);
  overflow-wrap: anywhere;
  padding: 5px 0;
  position: relative;
}
.facts dt:not(:first-of-type)::before, .facts dd:not(:nth-of-type(1))::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0;
  height: 2px; background: #15323d;
}

/* the one display element on the screen */
.readout {
  display: grid;
  gap: 1px;
  border: 2px solid var(--frame);
  padding: 10px 32px 11px;
  text-align: center;
}
.readout__label {
  font: 700 var(--t-small)/1 Mono, ui-monospace, monospace;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-cyan);
}
.readout__value {
  /* a NUMBER, so it is mono: the pixel face cannot tell a 2 from an 8 */
  font: 700 var(--t-display)/1 Mono, ui-monospace, monospace;
  letter-spacing: -0.02em;
  /* at 48 px the padding check asks for 20 px of air above and below the glyphs, and the label and
     the note do not supply it on their own */
  padding: 3px 0;
  color: var(--ink-green);
  text-shadow: 0 0 22px rgba(108, 224, 106, 0.4);
}
.readout__value.is-draft { color: var(--ink-yellow); text-shadow: 0 0 22px rgba(232, 228, 106, 0.4); }
.readout__value.is-empty { color: var(--ink-mute); text-shadow: none; }
/* reserved in lines, like the caption: a note that wraps on two stages changes the frame height */
.readout__note { min-height: calc(var(--t-micro) * 1.4 * 2); font: 400 var(--t-micro)/1.4 Grot, sans-serif; color: var(--ink-mute); }

/* -------------------------------------------------------------------- rail */

.rail { padding: 18px 10px 10px; display: flex; flex-direction: column; }
.rail__keys { display: flex; flex-direction: column; gap: 4px; flex: 1 1 auto; }
.rail .key { flex: 1 1 0; }

/* Every key of the STAGE rail, the GO TO rail and every other button on the page share this one
   rule, so no label can end up set differently from its neighbours. Whole pixel sizes only (18 px,
   never an em or a clamp), no shadow and no glow on a label, and no scale transform: the press
   feedback is a two pixel translate, which moves the glyphs by a whole pixel and cannot blur them.
   -webkit-font-smoothing: none is deliberately NOT set: it belongs to a bitmap face, and on an
   outline face it makes the stems ragged. */
.key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 10px 24px;
  border: 2px solid var(--frame);
  background: var(--ground);
  color: var(--ink-sky);
  font: 700 var(--t-key)/1 Mono, ui-monospace, monospace;
  letter-spacing: 0.06em;
  text-shadow: none;
  text-rendering: geometricPrecision;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.08s ease, background-color 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.rail .key { padding: 10px 12px; }
.key:hover { border-color: var(--frame-lit); color: var(--ink-cyan); }
.key:active { transform: translateY(2px); }
.key:focus-visible { outline: 3px solid var(--ink-yellow); outline-offset: 2px; }
.key[aria-current="true"], .key.is-on {
  background: var(--ink-cyan);
  border-color: var(--ink-cyan);
  color: var(--ground);
}
.key[disabled], .key[aria-disabled="true"] { color: var(--ink-mute); border-color: #2a3b42; cursor: not-allowed; opacity: 0.74; }

/* --------------------------------------------------------------------- log */

.log { padding-bottom: 16px; }
.log__lines { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.log__lines li {
  display: grid;
  grid-template-columns: 74px 116px 1fr;
  gap: 14px;
  align-items: baseline;
  font: 400 var(--t-small)/1.45 Mono, monospace;
  min-width: 0;
}
.log__time { color: var(--ink-mute); }
.log__kind { text-transform: uppercase; letter-spacing: 0.06em; }
.log__text { color: var(--ink-white); overflow-wrap: anywhere; }
.kind-dump { color: var(--ink-sky); }
.kind-disasm { color: var(--ink-cyan); }
.kind-decode { color: var(--ink-yellow); }
.kind-instruction { color: var(--ink-mint); }
.kind-verify, .kind-coverage { color: var(--ink-green); }
.kind-publish { color: var(--ink-mint); }
.kind-warning { color: var(--ink-red); }
.kind-memo, .kind-money, .kind-burn { color: var(--ink-mag); }
.kind-scan, .kind-vote { color: var(--ink-mute); }

/* ------------------------------------------------------------------- tray */

.tray__grid { display: grid; grid-template-columns: 1fr 400px; gap: 22px; align-items: start; }
.tray__made { min-width: 0; position: relative; padding-right: 24px; }
.tray__made::after {
  content: "";
  position: absolute; top: -4px; bottom: -4px; right: 0;
  width: 2px; background: var(--frame);
}
.tray__head {
  margin: 0 0 10px;
  font: 500 var(--t-small)/1.3 Grot, sans-serif;
  color: var(--ink-mute);
}
.tray__sub { color: var(--ink-mute); font-weight: 400; }
.ticker { color: var(--ink-cyan); font: 700 var(--t-key)/1 Mono, ui-monospace, monospace; letter-spacing: 0.04em; }

.things { list-style: none; margin: 0; padding: 0; display: flex; gap: 8px; flex-wrap: wrap; }
.thing {
  display: grid; justify-items: center; gap: 6px;
  width: 114px; padding: 11px 12px 9px;
  border: 2px solid var(--frame);
  color: var(--ink-sky);
  text-decoration: none;
  transition: transform 0.12s ease, border-color 0.12s ease, filter 0.12s ease;
}
.thing img { width: 44px; height: 44px; image-rendering: pixelated; }
.thing span { font: 400 var(--t-micro)/1.2 Grot, sans-serif; text-align: center; }
a.thing:hover { transform: scale(1.04); border-color: var(--frame-lit); filter: drop-shadow(0 0 8px rgba(111, 226, 230, 0.45)); }
a.thing:focus-visible { outline: 3px solid var(--ink-yellow); outline-offset: 2px; }
.thing.is-off { color: var(--ink-mute); border-color: #2a3b42; opacity: 0.74; }

.tray__line {
  margin: 14px 0 0;
  font: 400 var(--t-small)/1.6 Mono, monospace;
  color: var(--ink-mute);
  overflow-wrap: anywhere;
}
.tray__line b { color: var(--ink-white); font-weight: 400; }

.mint { display: grid; gap: 5px; margin-bottom: 8px; }
.mint__label { font: 400 var(--t-micro)/1.3 Grot, sans-serif; color: var(--ink-mute); }
.mint__value {
  display: block;
  padding: 11px 16px;
  border: 2px solid var(--frame);
  background: #080d12;
  font: 400 var(--t-small)/1.45 Mono, monospace;
  color: var(--ink-white);
  overflow-wrap: anywhere;
  user-select: all;
}
.mint__value.is-empty { color: var(--ink-mute); user-select: auto; }
.key--copy { width: 100%; margin-bottom: 8px; }

.marks { display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px; }
.mark {
  display: grid; justify-items: center; align-content: center; gap: 5px;
  padding: 9px 8px;
  min-height: 48px;
  border: 2px solid var(--frame);
  color: var(--ink-sky);
  text-decoration: none;
  font: 400 var(--t-micro)/1.2 Grot, sans-serif;
  transition: transform 0.08s ease, border-color 0.12s ease;
}
.mark img { width: 22px; height: 22px; }
.mark:hover { border-color: var(--frame-lit); }
.mark:active { transform: translateY(2px); }
.mark:focus-visible { outline: 3px solid var(--ink-yellow); outline-offset: 2px; }
.mark[aria-disabled="true"] { color: var(--ink-mute); border-color: #2a3b42; opacity: 0.74; cursor: not-allowed; }
.mark[aria-disabled="true"] img { filter: grayscale(1); }

/* ----------------------------------------------------------------- command */

.command {
  display: grid;
  grid-template-columns: 26px 1fr 110px;
  align-items: stretch;
  gap: 10px;
  border: 2px solid var(--frame);
  padding: 5px 22px;
  position: relative;
}
.command__prompt {
  align-self: center;
  font: 700 var(--t-head)/1 Mono, monospace;
  color: var(--ink-green);
}
/* His screen has a filled block cursor sitting after the prompt, blinking: it is the one thing on
   the page that says the line is waiting for you, and it goes out the moment you start typing.
   It hangs off the ROW, not off the prompt, because an ::after on the prompt stretches that
   label's own scroll width and the audit is right to read that as text leaving its box. */
.command:has(.command__input:placeholder-shown:not(:focus))::after {
  content: "";
  position: absolute;
  left: calc(22px + 26px + 10px);
  top: 50%;
  width: 10px;
  height: 19px;
  transform: translateY(-50%);
  background: var(--ink-white);
  animation: blink 1.1s steps(1, end) infinite;
}
@keyframes blink { 0%, 55% { opacity: 1; } 56%, 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .command:has(.command__input:placeholder-shown:not(:focus))::after { animation: none; opacity: 1; }
}
.command__input {
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--ink-white);
  font: 400 var(--t-lead)/1.4 Mono, monospace;
  padding: 8px 0 8px 22px;
}
.command__input::placeholder { color: var(--ink-mute); }
.command__input:focus { outline: none; }
.command:focus-within { border-color: var(--frame-lit); }
.key--run { font-size: var(--t-key); }
.command__answer {
  margin: 0;
  min-height: 24px;
  font: 400 var(--t-small)/1.5 Mono, monospace;
  color: var(--ink-yellow);
  overflow-wrap: anywhere;
}

/* ---------------------------------------------------------------- sections */

.section { margin-top: 72px; }
.section__title {
  margin: 0 0 20px;
  font: 700 28px/1 Mono, ui-monospace, monospace;
  color: var(--ink-white);
  letter-spacing: 0.02em;
}
.section .panel + .panel { margin-top: 28px; }

.lede { margin: 0 0 16px; font-size: var(--t-lead); color: var(--ink-white); max-width: 68ch; }
.note { margin: 14px 0 0; font: 400 var(--t-small)/1.55 Grot, sans-serif; color: var(--ink-mute); max-width: 76ch; }
.sub {
  margin: 26px 0 12px;
  font: 700 var(--t-lead)/1 Mono, ui-monospace, monospace;
  color: var(--ink-cyan);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.rows { display: grid; gap: 0; }
.row {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 20px;
  align-items: baseline;
  padding: 9px 0;
  position: relative;
}
.row + .row::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0;
  height: 2px; background: #15323d;
}
.row__label { font: 400 var(--t-small)/1.4 Grot, sans-serif; color: var(--ink-mute); }
.row__value { font: 400 var(--t-body)/1.5 Mono, monospace; color: var(--ink-white); overflow-wrap: anywhere; min-width: 0; }
.row__value a { color: var(--ink-sky); }
.row__value em { color: var(--ink-mute); font-style: normal; }

.table-wrap { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font: 400 var(--t-small)/1.5 Mono, monospace; }
.table th {
  text-align: left;
  padding: 0 16px 10px 0;
  font: 500 var(--t-micro)/1.3 Grot, sans-serif;
  color: var(--ink-mute);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}
.table td { padding: 9px 16px 9px 0; vertical-align: top; position: relative; }
.table tbody tr td::before {
  content: "";
  position: absolute; left: 0; right: 16px; top: 0;
  height: 2px; background: #15323d;
}
.table td:last-child { padding-right: 0; }
.table td:last-child::before { right: 0; }
.table .num { text-align: right; white-space: nowrap; }
.table a { color: var(--ink-sky); overflow-wrap: anywhere; }
.table .state-verified { color: var(--ink-green); }
.table .state-named { color: var(--ink-cyan); }
.table .state-decoded { color: var(--ink-yellow); }
.table .state-unknown { color: var(--ink-mag); }
.table button.key { min-height: 40px; padding: 6px 16px; font: 700 var(--t-small)/1 Mono, ui-monospace, monospace; letter-spacing: 0; }

/* Four steps, four drawings of four different aspects, and they have to read as ONE SET: every
   illustration sits in a cell of the same size with the same frame and the same ground, centred and
   contained so nothing is stretched, and the three rows (picture, heading, text) are shared across
   all four columns by subgrid, so the headings start on one line whatever the pictures do. Without
   subgrid each step keeps its own three rows and still works, just without the cross alignment. */
.steps {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: auto auto auto;
  gap: 26px;
}
.step {
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid;
  gap: 10px;
  align-content: start;
}
.step__frame {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 120px;
  padding: 10px 14px;
  border: 2px solid var(--frame);
  background: var(--ground);
}
.step img {
  image-rendering: pixelated;
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
}
.step h4 { margin: 0; font: 700 var(--t-lead)/1.2 Mono, ui-monospace, monospace; color: var(--ink-cyan); letter-spacing: 0.03em; }
.step p { margin: 0; font-size: var(--t-small); color: var(--ink-white); }
.step code { font: 400 var(--t-small)/1.45 Mono, monospace; color: var(--ink-yellow); overflow-wrap: anywhere; }

.defs { margin: 0; display: grid; gap: 0; }
.defs dt {
  padding: 14px 0 4px;
  font: 700 var(--t-lead)/1.2 Mono, ui-monospace, monospace;
  color: var(--ink-cyan);
  letter-spacing: 0.03em;
  position: relative;
}
.defs dt + dd { margin: 0 0 4px; }
.defs dd { margin: 0; font-size: var(--t-small); color: var(--ink-white); max-width: 84ch; padding-bottom: 10px; }
.defs dd + dt::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0;
  height: 2px; background: #15323d;
}
.defs em { color: var(--ink-yellow); font-style: normal; }

.split { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 22px; }
.split__part { border: 2px solid var(--frame); padding: 20px 34px; display: grid; gap: 4px; }
.split__pct { font: 700 32px/1 Mono, ui-monospace, monospace; color: var(--ink-cyan); letter-spacing: -0.02em; }
.split__what { font: 400 var(--t-small)/1.4 Grot, sans-serif; color: var(--ink-white); }

.vote-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; margin-bottom: 20px; }
.vote-state { font: 400 var(--t-small)/1.5 Grot, sans-serif; color: var(--ink-mute); }

.ix-detail__head { margin: 0 0 10px; font: 400 var(--t-lead)/1.4 Mono, monospace; color: var(--ink-white); }
.ix-detail__note { margin: 0 0 18px; font-size: var(--t-small); color: var(--ink-mute); }

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

@media (max-width: 1040px) {
  .plot__row { grid-template-columns: minmax(88px, max-content) minmax(64px, 1fr) 58px; gap: 10px; }
  .viewport__grid { grid-template-columns: 1fr 248px; }
  .viewport__art { max-width: 206px; }
  .tray__grid { grid-template-columns: 1fr 360px; }
  .steps { grid-template-columns: repeat(2, 1fr); }
}

/* A six column table cannot fit a phone, and a side scrolling box inside the page swallows the
   wheel and reads as text pressed to the edge of its panel. Under 880 every table becomes a stack
   of label and value rows: the same data, read down instead of across. */
@media (max-width: 880px) {
  .table, .table tbody, .table tr, .table td { display: block; width: 100%; }
  .table thead { display: none; }
  .table tbody tr {
    position: relative;
    padding: 14px 0;
  }
  .table tbody tr + tr::before {
    content: "";
    position: absolute; left: 0; right: 0; top: 0;
    height: 2px; background: #15323d;
  }
  .table td {
    display: grid;
    grid-template-columns: 136px 1fr;
    overflow-wrap: anywhere;
    gap: 14px;
    padding: 4px 0;
    align-items: baseline;
  }
  .table tbody tr td::before {
    content: attr(data-th);
    position: static;
    height: auto;
    background: none;
    font: 400 var(--t-micro)/1.5 Grot, sans-serif;
    color: var(--ink-mute);
  }
  .table td:empty { display: none; }
  .table .num { text-align: left; }
  .table-wrap { overflow-x: visible; }
  .facts { grid-template-columns: 1fr; gap: 0; }
  .facts dd { padding-top: 0; padding-bottom: 12px; }
  .facts dd::before { display: none; }
}

@media (max-width: 880px) {
  :root { --t-display: 48px; --t-name: 30px; --pad: 20px; }
  /* the fixed plot track exists to keep one frame height beside the art column; once the layout
     stacks there is no column beside it, and a fixed height would clip the first row of the plot */
  .viewport__plot { height: auto; overflow: visible; }
  .bench {
    grid-template-columns: 1fr;
    grid-template-areas: "viewport" "stages" "log" "pages" "tray" "command" "answer";
  }
  .rail { padding: var(--pad) 14px 14px; }
  .rail__keys { flex-direction: row; flex-wrap: wrap; }
  .rail .key { flex: 1 1 128px; }
  .viewport__grid { grid-template-columns: 1fr; }
  .viewport__side { flex-direction: row; align-items: center; gap: 18px; }
  .viewport__art { max-width: 240px; height: 132px; }
  .readout { flex: 1 1 auto; }
  .tray__grid { grid-template-columns: 1fr; }
  .tray__made { padding-right: 0; padding-bottom: 22px; }
  .tray__made::after { top: auto; left: 0; right: 0; bottom: 0; width: auto; height: 2px; }
  .masthead { grid-template-columns: 72px 1fr; }
  .masthead__mark { width: 72px; height: 72px; }
  .row { grid-template-columns: 1fr; gap: 2px; }
  .split { grid-template-columns: 1fr; }
}

@media (max-width: 560px) {
  :root { --gutter: 16px; --t-display: 44px; --t-name: 24px; --pad: 18px; --gap: 8px; }
  .panel, .rail { padding-left: 18px; padding-right: 18px; }
  .section { margin-top: 56px; }
  .section__title { font-size: 22px; }
  .steps { grid-template-columns: 1fr; gap: 22px; }
  .viewport__side { flex-direction: column; align-items: stretch; }
  .viewport__art { max-width: 200px; height: 116px; align-self: center; }
  /* the name takes its own line above the bar: nothing is truncated on a phone either */
  .plot__row {
    grid-template-columns: minmax(0, 1fr) 58px;
    grid-template-areas: "name name" "bar num";
    row-gap: 2px;
    column-gap: 8px;
  }
  .plot__name { grid-area: name; }
  .plot__bar { grid-area: bar; gap: 1px; }
  .plot__num { grid-area: num; }
  .plot { gap: 10px; }
  .marks { grid-template-columns: repeat(2, 1fr); }
  .command { grid-template-columns: 20px 1fr; }
  .key--run { grid-column: 1 / 3; }
  .things { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  .thing { width: auto; padding: 11px 14px 9px; }
  .table td { grid-template-columns: 112px 1fr; gap: 10px; }
  .log__lines li { grid-template-columns: 1fr; gap: 0; }
  .log__time, .log__kind { display: inline; margin-right: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
