/* Ticker Tape. One instrument sheet: framed cells in brass on the teal of his safe, a halftone ground
   behind them, and the paper tape running through the middle.

   The reference (art/ref/reference-poster.jpg) is a flat graphic poster, so the rules, the cells and the
   type ARE the objects here (RULES/REFERENCE.md); the only drawn things are the three canvases: the
   dome, the tape and the ground.

   Three decisions hold the whole layout together, and nothing may break them:

   1. EVERY CELL OWNS ITS OWN FRAME AND ITS OWN PADDING. Cells never share a border; a gutter of
      --gap runs between them. That is why no letter can ever sit against a line it does not own:
      the nearest line to any text is its own cell's, --pad-cell away.
   2. ONE ROW GRAMMAR. Every table on the page, from the readings at the top to the steps at the
      bottom, uses --row-cols. The label column, the two number columns and the note column line up
      down the whole sheet. Numbers right, prose left, always.
   3. ONE VERTICAL SEAM. Every two-up band splits on --split, so the gutter between the left and the
      right half is at the same x in all of them.

   Colour names and space names never share a word: one collision drops a whole rule. */

@font-face {
  font-family: "Grotesk";
  src: url("/font/grotesk-gras.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Grotesk";
  src: url("/font/grotesk-regular.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "VG5000";
  src: url("/font/vg5000.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

:root {
  --ink-ground: #0d1f27;
  --ink-deep: #081419;
  --ink-cell: #102730;
  --ink-sunk: #0a1b22;
  --line-brass: #b8862f;
  --line-dim: #3f6675;
  --text-cream: #f2e6c8;
  --text-steel: #9dc0cc;
  --text-dim: #88aab7;
  --glow-brass: #f0cf8c;
  --brass-lit: #ecc46a;
  --paper: #ece0c0;
  --paper-ink: #2b2112;
  --up: #63c98d;
  --down: #e06a53;

  /* the space scale: everything on the sheet is a step of it, nothing is a one-off */
  --gap: 12px;
  --pad-cell: 36px;
  --pad-plate: 28px;
  --row-x: 26px;
  --row-y: 18px;
  --air: 30px;
  --rule: 1px;

  --split: minmax(0, 1.04fr) minmax(0, 1fr);
  --row-cols: minmax(170px, 1.1fr) minmax(112px, 0.62fr) minmax(100px, 0.62fr) minmax(210px, 1.9fr);

  /* VG5000 hangs its ink high in the em box, so a label centred by geometry reads about 4 px high.
     Measured per control by tools/shots.mjs, not guessed. Every VG5000 control drops its content by
     half of this; an icon beside the label is drawn back up so the lockup stays on the middle. */
  --ink-drop: 8px;

  font-synthesis: none;
}

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

[hidden] {
  display: none !important;
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--ink-deep);
  color: var(--text-cream);
  font-family: "Grotesk", "Trebuchet MS", sans-serif;
  font-size: 18px;
  line-height: 1.5;
  overflow-x: hidden;
}

body {
  min-height: 100vh;
  padding: 26px;
}

#ground {
  position: fixed;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  filter: blur(1.5px);
}

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

/* ------------------------------------------------------------- the meta line, above the frame */

.meta {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: baseline;
  gap: 16px;
  max-width: 1760px;
  margin: 0 auto 16px;
  padding: 0 var(--gap);
  font-family: "VG5000", monospace;
  font-size: 17px;
  letter-spacing: 0.14em;
  color: var(--text-steel);
}
.meta-right {
  text-align: right;
}
.meta-mid {
  color: var(--brass-lit);
  white-space: nowrap;
}

/* ------------------------------------------------------------------ the sheet, its bands, its cells */

.sheet {
  position: relative;
  display: grid;
  gap: var(--gap);
  max-width: 1760px;
  margin: 0 auto;
  padding: var(--gap);
  border: var(--rule) solid var(--line-brass);
  box-shadow: 0 0 36px rgba(184, 134, 47, 0.16);
}

.band {
  display: grid;
  gap: var(--gap);
}
.band-split {
  grid-template-columns: var(--split);
  align-items: stretch;
}

/* a cell is the one surface of this page: a framed field with its own padding. Nothing on the sheet
   sits outside one, and nothing inside one comes closer to the frame than --pad-cell. */
.cell {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: var(--pad-cell);
  border: var(--rule) solid var(--line-brass);
  background: linear-gradient(180deg, rgba(16, 39, 48, 0.9), rgba(10, 27, 34, 0.9));
  /* a table answers to the CELL it is in, not to the window: the same four columns that fit the
     full width work cell do not fit a half width one, and a viewport query cannot tell them apart */
  container-type: inline-size;
}

.cell-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 24px;
  padding-bottom: 14px;
  margin-bottom: 22px;
  border-bottom: var(--rule) solid var(--line-dim);
  font-family: "VG5000", monospace;
  font-size: 17px;
  letter-spacing: 0.16em;
  color: var(--brass-lit);
}
.cell-name {
  white-space: nowrap;
}
.cell-note {
  color: var(--text-dim);
  letter-spacing: 0.08em;
  text-align: right;
}

/* the body fills what the head leaves, so two cells side by side end on the same line */
.cell-body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: var(--air);
  min-height: 0;
}

/* ------------------------------------------------------------------------- the two big figures */

.figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--air);
}
.figure {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.figure-label {
  font-family: "VG5000", monospace;
  font-size: 17px;
  letter-spacing: 0.18em;
  color: var(--text-steel);
}
.figure-value {
  font-family: "VG5000", monospace;
  font-size: clamp(40px, 3.8vw, 68px);
  line-height: 1.08;
  letter-spacing: -0.01em;
  color: var(--text-cream);
  text-shadow: 0 0 26px rgba(236, 196, 106, 0.3);
  /* a price with eight decimals must not break across two lines: the script fits it to its cell */
  white-space: nowrap;
}
.figure-price {
  color: var(--brass-lit);
}
.figure-sub {
  font-size: 16px;
  line-height: 1.45;
  color: var(--text-dim);
}

/* --------------------------------------------------------------------------------- the chart well */

.chart {
  position: relative;
  display: flex;
  flex: 1 1 auto;
  min-height: 210px;
  padding: 22px;
  border: var(--rule) solid var(--line-dim);
  background: var(--ink-sunk);
}
.chart canvas {
  display: block;
  flex: 1 1 auto;
  width: 100%;
  height: auto;
  min-height: 166px;
}
.chart-empty {
  position: absolute;
  inset: 22px;
  display: grid;
  place-items: center;
  margin: 0;
  color: var(--text-dim);
  font-family: "VG5000", monospace;
  font-size: 17px;
  letter-spacing: 0.1em;
  text-align: center;
}

/* ------------------------------------------------------------------------- the machine and its day */

.dome-well {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  justify-content: center;
  min-height: 0;
}
#dome {
  display: block;
  width: 100%;
  height: auto;
  max-height: 340px;
  aspect-ratio: 16 / 9;
}

.session {
  display: grid;
  gap: 12px;
}
.session-scale {
  position: relative;
  height: 36px;
  border: var(--rule) solid var(--line-brass);
  background-image: repeating-linear-gradient(to right, var(--line-dim) 0 1px, transparent 1px 100%);
  background-size: calc(100% / 13) 100%;
  background-position: bottom;
  background-repeat: repeat-x;
}
.session-scale::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--progress, 0%);
  background: linear-gradient(90deg, rgba(236, 196, 106, 0.05), rgba(236, 196, 106, 0.28));
  border-right: 2px solid var(--brass-lit);
}
.session-ends {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  font-family: "VG5000", monospace;
  font-size: 16px;
  letter-spacing: 0.14em;
  color: var(--text-dim);
}
.session-ends span:last-child {
  text-align: right;
}
#session-state {
  color: var(--brass-lit);
  text-align: center;
}

/* --------------------------------------------------------------- the maker's plate (contract, links) */

/* the plate is the one cell with a title bar: it is a thing screwed to the sheet, not a panel */
.cell-plate {
  padding: 0;
  background: var(--ink-cell);
}
.plate-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  padding: 12px var(--pad-plate);
  border-bottom: var(--rule) solid var(--line-brass);
  background: rgba(184, 134, 47, 0.14);
  font-family: "VG5000", monospace;
  font-size: 17px;
  letter-spacing: 0.16em;
  color: var(--brass-lit);
}
.plate-name {
  padding-top: calc(var(--ink-drop) / 2);
}
.plate-fold {
  min-height: 44px;
  padding: calc(var(--ink-drop)) 22px 0;
  border: var(--rule) solid var(--line-brass);
  background: transparent;
  color: var(--brass-lit);
  font: inherit;
  letter-spacing: 0.12em;
  cursor: pointer;
}
.plate-fold:hover {
  background: rgba(236, 196, 106, 0.16);
}
.plate-body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 14px;
  padding: var(--pad-plate);
}
.plate-label {
  font-family: "VG5000", monospace;
  font-size: 16px;
  letter-spacing: 0.2em;
  color: var(--text-dim);
}
.mint {
  display: block;
  padding: 16px 20px;
  border: var(--rule) solid var(--line-dim);
  background: var(--ink-sunk);
  font-family: "VG5000", monospace;
  font-size: 19px;
  letter-spacing: 0.02em;
  color: var(--text-cream);
  word-break: break-all;
  overflow-wrap: anywhere;
  min-width: 0;
  user-select: all;
}
/* the footnote follows what it is a note on; the blank surface left under it is plate, which is
   what a plate looks like, where a line pinned to the bottom of a tall cell reads as a hole */
.plate-foot {
  margin: 0;
  padding-top: 8px;
  font-size: 16px;
  color: var(--text-dim);
}

/* ---------------------------------------------------------------------------------------- the keys */

.keys {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 54px;
  /* the drop is what puts the LABEL on the middle of the key, not the line box */
  padding: var(--ink-drop) 26px 0;
  border: var(--rule) solid var(--line-brass);
  background: rgba(184, 134, 47, 0.1);
  color: var(--text-cream);
  font-family: "VG5000", monospace;
  font-size: 17px;
  letter-spacing: 0.1em;
  line-height: 1;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}
.key img {
  display: block;
  position: relative;
  top: calc(var(--ink-drop) / -2);
}
.key:hover {
  background: rgba(236, 196, 106, 0.2);
  color: #fff6de;
}
.key:active {
  background: rgba(236, 196, 106, 0.28);
}
.key[disabled],
.key[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

.field input:focus-visible,
.key:focus-visible,
.station:focus-visible,
button:focus-visible,
a:focus-visible {
  outline: 2px solid var(--brass-lit);
  outline-offset: 2px;
}

/* ---------------------------------------------------- the row grammar, shared by every table here */

.rows {
  display: grid;
  align-content: start;
  border-top: var(--rule) solid var(--line-brass);
}
.row {
  display: grid;
  grid-template-columns: var(--row-cols);
  align-items: center;
  gap: 28px;
  min-height: 64px;
  padding: var(--row-y) var(--row-x);
  border-bottom: var(--rule) solid var(--line-dim);
}
.row:hover {
  background: rgba(184, 134, 47, 0.08);
}
.row-label {
  font-family: "VG5000", monospace;
  font-size: 19px;
  /* VG5000's em box is about 1.65 of its size, so a line-height under that lets `overflow: hidden`
     shave the top of the ascenders. The ellipsis is the safety net for a long ticker; the line box
     has to be taller than the face or the net cuts every label by a pixel. */
  line-height: 1.7;
  letter-spacing: 0.1em;
  color: var(--brass-lit);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* numbers right so the digits line up down the column; prose left so its edge is a straight line */
.row-value {
  font-family: "Grotesk", sans-serif;
  font-weight: 700;
  font-size: 19px;
  letter-spacing: 0.01em;
  color: var(--text-cream);
  text-align: right;
  min-width: 0;
  overflow-wrap: anywhere;
}
/* a value that is words, not a figure, reads from the left like every other piece of prose */
.row-value.is-text {
  text-align: left;
}
.row-note {
  font-size: 16px;
  line-height: 1.4;
  color: var(--text-dim);
  text-align: left;
  min-width: 0;
  overflow-wrap: anywhere;
}
.row-head {
  min-height: 0;
  padding-top: 14px;
  padding-bottom: 14px;
  border-bottom: var(--rule) solid var(--line-brass);
  background: rgba(184, 134, 47, 0.07);
}
.row-head .row-label,
.row-head .row-value,
.row-head .row-note {
  font-family: "VG5000", monospace;
  font-size: 16px;
  font-weight: 400;
  letter-spacing: 0.16em;
  color: var(--text-dim);
}

/* Too narrow for four columns: the note drops under the label and the value, reading from the left,
   instead of being squeezed into a stub or pushed out of the cell. */
@container (max-width: 760px) {
  .row {
    grid-template-columns: minmax(110px, 1fr) minmax(0, 1fr);
    row-gap: 10px;
  }
  .row-note,
  .meter,
  .row-slider {
    grid-column: 1 / -1;
  }
  .row-head {
    display: none;
  }
}
@container (max-width: 430px) {
  .row {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 6px;
  }
  .row-value,
  .row-note {
    text-align: left;
  }
}

/* the weight meter: the reference's star and heart rows, as blocks */
.meter {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.meter-blocks {
  display: flex;
  flex: 0 0 auto;
  gap: 3px;
}
.meter-block {
  width: 13px;
  height: 20px;
  border: var(--rule) solid var(--line-brass);
}
.meter-block.target {
  background: rgba(184, 134, 47, 0.3);
}
.meter-block.on {
  background: var(--brass-lit);
}
.meter-target {
  font-family: "VG5000", monospace;
  font-size: 16px;
  color: var(--text-dim);
  white-space: nowrap;
}

/* ------------------------------------------------------------------ the tape, and its station keys */

.cell-tape {
  padding: 0;
  border-color: var(--paper);
  background: var(--paper);
  color: var(--paper-ink);
  overflow: hidden;
}
/* the sprocket perforation along both edges of the paper */
.cell-tape::before,
.cell-tape::after {
  content: "";
  display: block;
  height: 7px;
  flex: 0 0 auto;
  background-image: repeating-linear-gradient(90deg, var(--paper) 0 10px, var(--ink-deep) 10px 13px);
}

/* six keys, six equal columns: a key is never a different width from its neighbour */
.stations {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  border-bottom: 2px dashed rgba(43, 33, 18, 0.4);
}
.station {
  min-height: 62px;
  padding: calc(var(--ink-drop) + 2px) 16px 2px;
  border: 0;
  border-right: var(--rule) solid rgba(43, 33, 18, 0.3);
  background: transparent;
  color: var(--paper-ink);
  font-family: "VG5000", monospace;
  font-size: 18px;
  letter-spacing: 0.12em;
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
}
.station:last-child {
  border-right: 0;
}
.station:hover {
  background: rgba(43, 33, 18, 0.1);
}
.station[aria-current="true"] {
  background: var(--paper-ink);
  color: var(--paper);
}

.tape-print {
  position: relative;
}
#tape {
  display: block;
  width: 100%;
  height: 96px;
}
.tape-empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  margin: 0;
  font-family: "VG5000", monospace;
  font-size: 17px;
  letter-spacing: 0.1em;
  color: rgba(43, 33, 18, 0.6);
}

/* ------------------------------------------------------------------------------- the work cell */

.cell-work {
  gap: var(--air);
}
.station-head {
  display: grid;
  gap: 14px;
  padding-bottom: 20px;
  border-bottom: var(--rule) solid var(--line-brass);
}
.station-title {
  margin: 0;
  font-family: "VG5000", monospace;
  font-size: clamp(30px, 2.4vw, 38px);
  line-height: 1.2;
  letter-spacing: 0.08em;
  color: var(--text-cream);
}
.station-sub {
  margin: 0;
  max-width: 76ch;
  font-size: 17px;
  line-height: 1.5;
  color: var(--text-dim);
}

/* a stack is the one way blocks are spaced inside a cell: no element carries its own margin */
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--air);
  min-width: 0;
}
/* two blocks side by side are always stretched to one height, so they can never end at different
   lines. Anything that does not fill its half gets a block that does. */
.pair {
  display: grid;
  grid-template-columns: var(--split);
  gap: var(--gap);
  align-items: stretch;
}
.pair > * {
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-width: 0;
  padding: var(--pad-plate);
  border: var(--rule) solid var(--line-dim);
  background: var(--ink-sunk);
}
.pair-title {
  margin: 0;
  font-family: "VG5000", monospace;
  font-size: 17px;
  letter-spacing: 0.16em;
  color: var(--brass-lit);
}

/* a block of prose on the sheet: never a bare paragraph against a rule */
.notice {
  margin: 0;
  padding: 20px var(--row-x);
  border: var(--rule) solid var(--line-dim);
  background: var(--ink-sunk);
  font-size: 17px;
  line-height: 1.5;
  color: var(--text-dim);
}
.notice-bad {
  border-color: var(--down);
  color: var(--down);
  background: rgba(224, 106, 83, 0.08);
}

/* ------------------------------------------------------------------------------ forms and fields */

.form {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 22px;
}
.field {
  display: grid;
  gap: 12px;
}
.field label {
  font-family: "VG5000", monospace;
  font-size: 17px;
  letter-spacing: 0.14em;
  color: var(--text-steel);
}
.field input[type="text"],
.field input[type="number"] {
  width: 100%;
  min-height: 58px;
  padding: var(--ink-drop) 20px 0;
  border: var(--rule) solid var(--line-brass);
  background: var(--ink-sunk);
  color: var(--text-cream);
  font-family: "VG5000", monospace;
  font-size: 20px;
}
.field input::placeholder {
  color: var(--text-dim);
  opacity: 1;
}
.hint {
  margin: 0;
  font-size: 16px;
  line-height: 1.45;
  color: var(--text-dim);
}
.message {
  margin: 0;
  min-height: 26px;
  font-family: "VG5000", monospace;
  font-size: 17px;
  color: var(--brass-lit);
}
.message.bad {
  color: var(--down);
}
.message.good {
  color: var(--up);
}

/* the ballot row is a row of the same table: the slider lives in the value columns, so a paper's
   slider, its points and its current weight are all on ONE line and nothing can drift apart.
   The slider takes the room the two number columns share (0.78 + 0.78 = 1.16 + 0.4), so the note
   column still begins at exactly the x it begins at in every other table on the sheet. */
.rows-ballot {
  --row-cols: minmax(170px, 1.1fr) minmax(170px, 0.9fr) minmax(56px, 0.34fr) minmax(210px, 1.9fr);
}
.row-slider {
  display: flex;
  align-items: center;
  min-width: 0;
}
.row-slider input[type="range"] {
  width: 100%;
  min-height: 36px;
  accent-color: var(--brass-lit);
}
.row-points {
  font-family: "VG5000", monospace;
  font-size: 19px;
  color: var(--text-cream);
  text-align: right;
}

/* ------------------------------------------------------------------ the title block of the sheet */

/* the name is the sheet's title block, not a band of leftover type: it names the thing and says in
   one line what it is, with a full --pad-cell of air on every side of it */
.cell-word {
  justify-content: center;
  gap: 20px;
  padding: calc(var(--pad-cell) + 10px) var(--pad-cell);
  overflow: hidden;
}
.word {
  margin: 0;
  font-family: "VG5000", monospace;
  font-size: 92px;
  line-height: 1.04;
  letter-spacing: 0.02em;
  white-space: nowrap;
  color: var(--text-cream);
  text-shadow: 0 0 30px rgba(236, 196, 106, 0.35), 0 0 70px rgba(236, 196, 106, 0.14);
}
.word-sub {
  margin: 0;
  max-width: 54ch;
  font-size: 17px;
  line-height: 1.5;
  color: var(--text-steel);
}

/* the risk cell is the word cell's opposite number on the same seam, so it is balanced the same way */
.cell-risk .cell-body {
  justify-content: center;
  gap: 18px;
}
.risk {
  margin: 0;
  font-size: 16px;
  line-height: 1.55;
  color: var(--text-dim);
}

/* -------------------------------------------------------------------------- the laptop and the phone */

@media (max-width: 1240px) {
  :root {
    --pad-cell: 28px;
    --row-x: 22px;
    --air: 24px;
    --row-cols: minmax(146px, 1.1fr) minmax(80px, 0.6fr) minmax(80px, 0.6fr) minmax(190px, 1.9fr);
  }
}

@media (max-width: 1080px) {
  .band-split,
  .pair {
    grid-template-columns: minmax(0, 1fr);
  }
  .figure-value {
    font-size: clamp(40px, 7vw, 60px);
  }
  .stations {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .station:nth-child(3n) {
    border-right: 0;
  }
  .station:nth-child(-n + 3) {
    border-bottom: var(--rule) solid rgba(43, 33, 18, 0.3);
  }
}

@media (max-width: 680px) {
  body {
    padding: 12px;
  }
  :root {
    --gap: 10px;
    --pad-cell: 22px;
    --pad-plate: 20px;
    --row-x: 18px;
    --row-y: 16px;
    --air: 22px;
  }
  .meta {
    grid-template-columns: minmax(0, 1fr);
    gap: 4px;
    font-size: 15px;
  }
  .meta-right,
  .meta-mid {
    text-align: left;
  }
  .row-value {
    font-size: 20px;
  }
  .stations {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .station {
    border-right: var(--rule) solid rgba(43, 33, 18, 0.3);
    border-bottom: var(--rule) solid rgba(43, 33, 18, 0.3);
  }
  .station:nth-child(2n) {
    border-right: 0;
  }
  .station:nth-last-child(-n + 2) {
    border-bottom: 0;
  }
  .keys {
    gap: 10px;
  }
  .key {
    flex: 1 1 auto;
    padding-inline: 18px;
  }
  .word {
    letter-spacing: 0;
  }
}

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