/* Typing Optional: the recorder-paper system.
 *
 * Thesis in Site/DESIGN.md. Speech is a wave and text is a line, so the page is
 * a strip of chart paper: a ruled horizontal trace, the machine in monospace,
 * the person in a serif.
 *
 * ONE MOOD, deliberately. There is no prefers-color-scheme branch: the app has a
 * dark mode, the page has a point of view. The dark that exists here is
 * structural (the instrument, the HUD, the menu bar) rather than a theme.
 */

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

:root {
  /* Ground. A mid-light violet-grey: the color of recorder chart paper, and the
     app icon's own violet pulled back to a paper value. */
  --roll: #e2ddee;
  --roll-2: #efecf6;

  /* The dark stage carved out of the page. */
  --stage: #171130;
  --stage-2: #1f1842;

  --ink: #17122b;      /* 13.7:1 on --roll */
  --ink-2: #4a4166;    /*  7.1:1 */

  /* One accent, ramped rather than flat. */
  --signal: #5233d6;      /* 5.6:1 on --roll   */
  --signal-dk: #3f23b0;   /* 7.6:1, small type on paper */
  --signal-hi: #8b80f6;   /* the app icon's top gradient stop */
  --signal-lo: #b3a7ff;   /* 8.5:1 on --stage, small type there */
  --dim: #a79edb;         /* 7.4:1 on --stage */

  /* Hairlines are the ink at low alpha, never a grey. */
  --hair: rgba(23, 18, 43, .17);
  --hair-2: rgba(23, 18, 43, .1);
  --hair-lo: rgba(226, 221, 238, .16);

  --ok: #1d7a4f;

  --display: "Fraunces", Georgia, "Times New Roman", serif;
  --mono: "DM Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --measure: 62ch;
  --pad: clamp(18px, 4.4vw, 46px);
  --gutter: clamp(16px, 3.2vw, 40px);
  --max: 1220px;

  --ease-settle: cubic-bezier(.22, 1, .36, 1);
  --ease-latch: cubic-bezier(.7, 0, .2, 1);
}

/* --------------------------------------------------------------- resets */

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

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

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--roll);
  color: var(--ink);
  font-family: var(--display);
  font-variation-settings: "opsz" 14, "SOFT" 20, "WONK" 0;
  font-size: clamp(1.02rem, .96rem + .22vw, 1.14rem);
  line-height: 1.58;
  font-synthesis-weight: none;
  text-rendering: optimizeLegibility;
}

/* The chart-paper tooth. A fixed grain plate, multiplied into the ground, so the
   violet reads as stock rather than as a fill. Costs one pseudo-element. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .05;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

body > * { position: relative; z-index: 1; }
main { flex: 1 0 auto; }
.foot { flex: none; }

img, svg { max-width: 100%; }
svg { display: inline-block; vertical-align: middle; }

a { color: var(--signal-dk); text-decoration-thickness: 1px; text-underline-offset: .18em; }
a:hover { color: var(--signal); }

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

::selection { background: var(--signal); color: #fff; }

::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: var(--roll); }
::-webkit-scrollbar-thumb { background: var(--ink); border: 3px solid var(--roll); border-radius: 8px; }
::-webkit-scrollbar-thumb:hover { background: var(--signal); }

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

.wrap {
  width: min(100% - (2 * var(--gutter)), var(--max));
  margin-inline: auto;
}

/* ------------------------------------------------------------- typography */

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: -.022em;
  line-height: 1.02;
  text-wrap: balance;
  margin: 0;
}

p { text-wrap: pretty; }

.kicker {
  font-family: var(--mono);
  font-size: clamp(10px, .44vw + 8.4px, 11.5px);
  font-weight: 400;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--signal-dk);
  margin: 0;
}

/* A kicker with a rule before it is a BLOCK with an inline-block ::before, never
   a flex row: flex turns every text node into an item and the label wraps into
   ragged columns on a phone. */
.kicker--ruled::before {
  content: "";
  display: inline-block;
  width: 40px;
  height: 1px;
  margin-right: .8em;
  vertical-align: .32em;
  background: currentColor;
}

.lede {
  font-size: clamp(1.14rem, 1.02rem + .5vw, 1.42rem);
  font-variation-settings: "opsz" 28, "SOFT" 28, "WONK" 0;
  line-height: 1.46;
  color: var(--ink-2);
  max-width: var(--measure);
}

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

/* ------------------------------------------------------------------ chrome */

.masthead {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--roll) 90%, transparent);
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
  border-bottom: 1px solid var(--hair);
}

/* The stylus. A chart recorder's pen, running along the masthead's own
   hairline: the filled part is what has been read, the nib is where you are.
   It is the thesis doing a job, which is the only reason it is here. */
.stylus {
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  pointer-events: none;
}

.stylus::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--p, 0%);
  background: linear-gradient(90deg, var(--signal-dk), var(--signal));
}

.stylus i {
  position: absolute;
  top: -4px;
  left: var(--p, 0%);
  width: 2px;
  height: 10px;
  background: var(--signal);
  transform: translateX(-1px);
}

.masthead__in {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: clamp(12px, 2vw, 28px);
  padding: 11px 0;
}

.masthead__in > * { min-width: 0; }

.lockup {
  display: inline-flex;
  align-items: center;
  gap: .52em;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.04rem;
  font-variation-settings: "opsz" 20, "SOFT" 10, "WONK" 0;
  letter-spacing: -.018em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}

.lockup svg { width: 1.32em; height: 1.32em; border-radius: .3em; }
.lockup:hover { color: var(--signal-dk); }

.nav {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: clamp(10px, 1.5vw, 24px);
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: .015em;
}

.nav a {
  position: relative;
  color: var(--ink-2);
  text-decoration: none;
  padding: 3px 0;
  white-space: nowrap;
}

.nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .4s var(--ease-settle);
}

.nav a:hover { color: var(--signal-dk); }
.nav a:hover::after { transform: scaleX(1); transform-origin: left; }

.masthead__news {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--signal-dk);
  text-decoration: none;
  white-space: nowrap;
  border: 1px solid currentColor;
  padding: 5px 9px;
  transition: background .25s var(--ease-settle), color .25s var(--ease-settle);
}

.masthead__news:hover { background: var(--signal-dk); color: var(--roll-2); }

@media (max-width: 1080px) { .masthead__news { display: none; } }

@media (max-width: 860px) {
  .masthead__in { grid-template-columns: auto 1fr; }
  .nav { justify-content: flex-end; }
}

@media (max-width: 620px) {
  .masthead__in { grid-template-columns: minmax(0, 1fr); row-gap: 6px; }
  /* Five items will not fit on one phone line, and three rows of sticky chrome
     is an eighth of the viewport. One scrolling row keeps every item reachable
     and the header two rows tall. */
  .nav {
    justify-content: flex-start;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    font-size: 12px;
    gap: 16px;
    padding-bottom: 2px;
    -webkit-mask-image: linear-gradient(90deg, #000 90%, transparent);
    mask-image: linear-gradient(90deg, #000 90%, transparent);
  }
  .nav::-webkit-scrollbar { display: none; }
}

/* ------------------------------------------------------------------ hero */

.hero { padding: clamp(26px, 3.6vw, 46px) 0 clamp(34px, 5vw, 66px); }

.hero__kicker { margin-bottom: clamp(14px, 2vw, 22px); }

.hero h1 {
  font-size: clamp(1.94rem, 1.02rem + 2.9vw, 3.25rem);
  font-weight: 500;
  font-variation-settings: "opsz" 120, "SOFT" 0, "WONK" 1;
  letter-spacing: -.028em;
  line-height: 1.02;
  margin: 0;
}

.hero h1 .ln { display: block; }

.hero h1 em {
  font-style: italic;
  font-weight: 600;
  color: var(--signal);
  font-variation-settings: "opsz" 120, "SOFT" 0, "WONK" 1;
}

/* The staggered hero: the middle line steps across the page, so the headline
   reads as a trace rather than as a flush-left block. */
.hero h1 .step { margin-left: clamp(0px, 3.4vw, 54px); }

.hero__top {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, .7fr);
  gap: clamp(18px, 3vw, 46px);
  align-items: start;
}

.hero__spec {
  font-family: var(--mono);
  font-size: clamp(11.5px, .3vw + 10.4px, 12.5px);
  line-height: 1.78;
  color: var(--ink-2);
  border-top: 1px solid var(--hair);
  padding-top: 9px;
}

.hero__spec b { color: var(--ink); font-weight: 500; }

@media (max-width: 980px) {
  .hero__top { grid-template-columns: minmax(0, 1fr); gap: 20px; }
}

@media (max-width: 700px) {
  .hero h1 { text-wrap: balance; }
  .hero h1 .ln { display: inline; }
  .hero h1 .step { margin-left: 0; }
}

/* ------------------------------------------------------- the instrument */

.rig {
  margin-top: clamp(22px, 3.4vw, 40px);
  background: var(--stage);
  color: var(--roll-2);
  border: 1px solid var(--stage-2);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .06) inset;
}

.rig__rail {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px 16px;
  padding: 10px var(--pad);
  border-bottom: 1px solid var(--hair-lo);
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--dim);
}

.rig__rail > * { min-width: 0; }

.rig__state {
  display: inline-flex;
  align-items: center;
  gap: .62em;
  color: var(--signal-lo);
  white-space: nowrap;
}

.rig__lamp {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--dim);
  flex: none;
  transition: background .2s var(--ease-latch), box-shadow .2s var(--ease-latch);
}

.rig.is-live .rig__lamp {
  background: var(--signal-hi);
  box-shadow: 0 0 0 4px rgba(139, 128, 246, .22);
  animation: pulse 1.15s ease-in-out infinite;
}

.rig.is-work .rig__lamp { background: var(--signal-lo); }
.rig.is-done .rig__lamp { background: #4ad08a; }

@keyframes pulse {
  50% { box-shadow: 0 0 0 8px rgba(139, 128, 246, .09); }
}

.rig__engine { text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rig__clock { text-align: center; color: var(--dim); text-transform: none; }

/* Three readouts will not fit on a phone rail, and a clock overlapping an
   engine name is worse than two lines. */
@media (max-width: 680px) {
  .rig__rail { grid-template-columns: auto auto; justify-content: space-between; row-gap: 6px; }
  .rig__engine { grid-column: 1 / -1; text-align: left; white-space: normal; }
  .rig__clock { text-align: right; }
}

.rig__trace {
  display: block;
  width: 100%;
  height: clamp(66px, 8vw, 96px);
  background:
    repeating-linear-gradient(90deg, var(--hair-lo) 0 1px, transparent 1px 34px),
    linear-gradient(var(--stage-2), var(--stage));
}

.rig__well {
  padding: clamp(15px, 2vw, 20px) var(--pad) clamp(20px, 3vw, 30px);
  min-height: clamp(62px, 7vw, 78px);
  display: flex;
  flex-direction: column;
  gap: 14px;
  justify-content: flex-start;
}

.well__raw {
  font-family: var(--mono);
  font-size: clamp(.9rem, .82rem + .34vw, 1.02rem);
  line-height: 1.66;
  color: var(--dim);
  margin: 0;
  overflow-wrap: anywhere;
}

/* The interim transcript is the text somebody is reading WHILE they speak, so
   it cannot be the one thing on the page under the contrast floor. It is marked
   as provisional by its underline and its italic, not by being faint. */
.well__raw .interim {
  color: var(--dim);
  font-style: italic;
  text-decoration: underline dotted;
  text-decoration-color: rgba(167, 158, 219, .5);
  text-underline-offset: .22em;
}
.well__raw .fill { color: var(--signal-lo); text-decoration: line-through; text-decoration-thickness: 1px; }

.well__clean {
  font-family: var(--display);
  font-variation-settings: "opsz" 40, "SOFT" 24, "WONK" 0;
  font-size: clamp(1.18rem, 1rem + .72vw, 1.72rem);
  font-weight: 400;
  line-height: 1.34;
  color: #fff;
  margin: 0;
  overflow-wrap: anywhere;
}

.well__clean:empty { display: none; }

/* A word arrives from the raw: up, into focus, in reading order. The class is
   removed a frame later, so the transition runs from the "set" state back to
   rest rather than needing a second pass. */
.well__clean .w, .pair__clean .w {
  display: inline-block;
  transition:
    opacity .5s var(--ease-settle) var(--d, 0ms),
    transform .5s var(--ease-settle) var(--d, 0ms),
    filter .5s var(--ease-settle) var(--d, 0ms);
}

.well__clean.set .w, .pair__clean.set .w {
  opacity: 0;
  transform: translateY(.34em);
  filter: blur(3px);
}

@media (prefers-reduced-motion: reduce) {
  .well__clean .w, .pair__clean .w { transition: none; }
}
.well__raw:empty { display: none; }

.well__hint {
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.6;
  color: var(--dim);
  margin: 0;
  max-width: 130ch;
}

/* The sentence to say is the most load-bearing instruction on the page: if
   nobody reads it aloud, the demonstration produces nothing worth seeing. It
   gets its own line, at a size a person will actually read. */
.well__hint b {
  display: block;
  margin-top: .6em;
  font-weight: 400;
  font-size: clamp(.94rem, .86rem + .34vw, 1.06rem);
  line-height: 1.55;
  color: var(--signal-lo);
}

/* The cleanup bar, drawn the way the app draws it: a caption, a bar, the
   estimate counting down, and a Skip that hands back the raw text. */
.bar[hidden] { display: none; }

.bar {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--dim);
}

.bar__track { height: 3px; background: var(--hair-lo); overflow: hidden; }
.bar__fill { display: block; height: 100%; width: 0; background: var(--signal-hi); transition: width .18s linear; }
.bar__left { color: var(--signal-lo); white-space: nowrap; font-variant-numeric: tabular-nums; }

.rig__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  padding: clamp(16px, 2.2vw, 22px) var(--pad);
  border-top: 1px solid var(--hair-lo);
}

.hold {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--stage);
  background: var(--signal-hi);
  border: 1px solid var(--signal-hi);
  padding: 13px 22px;
  cursor: pointer;
  touch-action: none;
  transition: transform .12s var(--ease-latch), background .16s var(--ease-latch);
}

.hold:hover { background: #a294ff; }
.hold.is-down { transform: translateY(2px); background: #cfc7ff; }
/* Unavailable reads as unavailable through the ghost treatment, not through a
   muted fill that lands at 3.8:1. */
.hold[disabled] {
  background: none;
  border-color: var(--hair-lo);
  color: var(--dim);
  cursor: default;
}

.ghost {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--signal-lo);
  background: none;
  border: 1px solid var(--hair-lo);
  padding: 13px 18px;
  cursor: pointer;
  transition: border-color .2s var(--ease-settle), color .2s var(--ease-settle);
}

.ghost:hover { border-color: var(--signal-lo); color: #fff; }
.ghost[disabled] { color: var(--dim); border-color: var(--hair-lo); cursor: default; }

.keycue {
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--dim);
  letter-spacing: .04em;
}

kbd {
  font-family: var(--mono);
  font-size: .92em;
  border: 1px solid currentColor;
  border-radius: 3px;
  padding: 1px 5px;
  white-space: nowrap;
}

.rig__foot {
  padding: 13px var(--pad);
  border-top: 1px solid var(--hair-lo);
  background: rgba(0, 0, 0, .17);
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.7;
  color: var(--dim);
  margin: 0;
}

/* The measure goes on the text, never on the plate: a max-width on the element
   itself stopped its background and its top rule two thirds across the panel. */
.rig__foot > span { display: block; max-width: 104ch; }

.rig__foot b { color: var(--signal-lo); font-weight: 400; }

/* The receipt: what the cleanup pass actually did, listed. */
.receipt {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 5px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--dim);
}

.receipt li {
  display: grid;
  grid-template-columns: 1.1em minmax(0, 1fr);
  gap: .6em;
  align-items: start;
}

.receipt li > span { min-width: 0; }
.receipt svg { width: 1.05em; height: 1.05em; color: var(--signal-hi); margin-top: .22em; }
.receipt .arrow { width: 1.1em; height: 1.1em; margin: 0 .1em -.26em; color: var(--signal-hi); }
.receipt:empty { display: none; }

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

main { counter-reset: sec; }

/* Every section boundary is a graduation on the roll. The tick pitch is 34px,
   the same pitch the trace's own grid runs at, so the page and the instrument
   are measured in one unit rather than two. */
.band {
  position: relative;
  padding: clamp(50px, 6.6vw, 98px) 0;
  border-top: 1px solid var(--hair);
}

.band::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 7px;
  pointer-events: none;
  background: repeating-linear-gradient(90deg, var(--hair-2) 0 1px, transparent 1px 34px);
}
.band--tight { padding-block: clamp(38px, 4.6vw, 66px); }

/* The heading and a one-sentence standfirst share the row. A lone heading in a
   1220px measure leaves nine hundred pixels of nothing beside it, and a ch
   measure set on the CONTAINER resolves against the body font rather than the
   heading's, which is how the h2 came out four words wide. The measure goes on
   the h2. */
.band__head {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, .92fr);
  gap: clamp(16px, 3vw, 56px);
  align-items: end;
}

.band__head > * { min-width: 0; }

.band__stand {
  font-size: clamp(1.02rem, .96rem + .28vw, 1.16rem);
  font-variation-settings: "opsz" 22, "SOFT" 26, "WONK" 0;
  line-height: 1.5;
  color: var(--ink-2);
  margin: 0;
  max-width: 48ch;
}

@media (max-width: 880px) {
  .band__head { grid-template-columns: minmax(0, 1fr); gap: 14px; }
}

.band__head h2 {
  max-width: 19ch;
  font-size: clamp(1.72rem, 1.12rem + 2.5vw, 2.96rem);
  font-weight: 500;
  font-variation-settings: "opsz" 80, "SOFT" 8, "WONK" 1;
  letter-spacing: -.028em;
  margin: .34em 0 0;
}

.band__head h2 em { font-style: italic; color: var(--signal); font-weight: 600; }

.band__num::before {
  counter-increment: sec;
  content: counter(sec, decimal-leading-zero);
}

.split {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: clamp(22px, 3.6vw, 56px);
  align-items: stretch;
  margin-top: clamp(22px, 3vw, 40px);
}

/* Two things in one row share its height: a card ending halfway down its
   neighbour reads as two things that landed next to each other by accident. */
.split > * { display: flex; flex-direction: column; }
.split > * > .plate:last-child { flex: 1; }

/* The lab fills its row, and the rule it ends on is pinned to the bottom, so
   the card matches its neighbour without three hundred pixels of nothing in it. */
.split > .lab { display: flex; flex-direction: column; }
.lab__rule {
  margin: auto 0 0;
  padding-top: 18px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.7;
  color: var(--dim);
  max-width: 56ch;
}
.lab .hud + .lab__rule, .lab__rule + .hud { margin-top: 16px; }

.split--wide-right { grid-template-columns: minmax(0, .88fr) minmax(0, 1.12fr); }
.split--wide-left { grid-template-columns: minmax(0, 1.18fr) minmax(0, .82fr); }
.split > * { min-width: 0; }

@media (max-width: 880px) {
  .split, .split--wide-right, .split--wide-left { grid-template-columns: minmax(0, 1fr); }
}

.prose { max-width: var(--measure); }
.prose p { margin: 0 0 1em; }
.prose p:last-child { margin-bottom: 0; }
.prose > p + h3 { margin-top: 1.5em; }

h3 {
  font-size: 1.12rem;
  font-weight: 600;
  font-variation-settings: "opsz" 24, "SOFT" 14, "WONK" 0;
  letter-spacing: -.012em;
  margin: 0 0 .4em;
}

.note {
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--ink-2);
  max-width: 58ch;
  margin: 0;
}

/* ------------------------------------------------------- plates and lists */

.plate {
  background: var(--roll-2);
  border: 1px solid var(--hair);
  padding: clamp(16px, 2.3vw, 26px);
}

.plate h3 { margin-bottom: .3em; }
.plate .facts { max-width: none; }

/* The value track SHRINKS. An `auto` track sizes to its own max-content and
   runs straight over the label beside it the moment the column is narrower
   than the pair: that is how "Distribution" and "Direct download, signed and
   notarized" came out as "DistribDirect download". */
.facts {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  align-items: baseline;
  column-gap: clamp(16px, 2vw, 34px);
  font-family: var(--mono);
  font-size: 12.5px;
  max-width: min(100%, 62ch);
}

.facts dt, .facts dd {
  min-width: 0;
  margin: 0;
  padding: 8px 0;
  border-bottom: 1px solid var(--hair-2);
}

.facts dt { color: var(--ink-2); }
.facts dd { color: var(--ink); text-align: right; font-variant-numeric: tabular-nums; }
.facts dt:nth-last-of-type(1), .facts dd:nth-last-of-type(1) { border-bottom: 0; }

/* On a phone an `auto` value track sizes to its own max-content and runs
   straight over the label beside it. Below 560px the pair stacks. */
@media (max-width: 560px) {
  .facts { grid-template-columns: minmax(0, 1fr); max-width: none; }
  .facts dt { padding: 9px 0 0; border-bottom: 0; font-size: 11px; letter-spacing: .16em; text-transform: uppercase; }
  .facts dd { padding: 1px 0 9px; text-align: left; }
  .facts dd:nth-last-of-type(1) { border-bottom: 0; }
}

/* -------------------------------------------------- the cleanup workbench */

/* The sample picker is a vertical list, not a chip row: these are whole
   utterances, and a long string of words in a pill is a pill nobody can read. */
.picks {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
  display: grid;
  gap: 0;
  border: 1px solid var(--hair);
}

.picks li + li { border-top: 1px solid var(--hair); }

.picks button {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 12px;
  align-items: baseline;
  width: 100%;
  text-align: left;
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink-2);
  background: none;
  border: 0;
  padding: 11px 14px;
  cursor: pointer;
  transition: background .2s var(--ease-settle), color .2s var(--ease-settle);
}

.picks button > * { min-width: 0; }
.picks button .n { color: var(--signal-dk); letter-spacing: .16em; font-size: 11px; }
.picks button:hover { background: var(--roll-2); color: var(--ink); }

.picks button[aria-selected="true"] {
  background: var(--ink);
  color: var(--roll-2);
}

.picks button[aria-selected="true"] .n { color: var(--signal-lo); }

/* Chips. A row of them balances into even, centered lines rather than wrapping
   into a full line and two orphans; balanced-chips.js does the partition. */
.chips {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.chip-row { display: flex; flex-wrap: nowrap; gap: 8px; }

.chip {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--ink-2);
  border: 1px solid var(--hair);
  padding: 6px 11px;
  white-space: nowrap;
}

.pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  border: 1px solid var(--hair);
  background: var(--roll-2);
}

.pair__row { padding: clamp(15px, 2.2vw, 22px); }
.pair__row + .pair__row { border-top: 1px solid var(--hair); }

.pair__label {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin: 0 0 .7em;
}

.pair__raw {
  font-family: var(--mono);
  font-size: clamp(.86rem, .8rem + .26vw, .96rem);
  line-height: 1.72;
  color: var(--ink-2);
  margin: 0;
  overflow-wrap: anywhere;
}

.pair__raw del {
  color: var(--signal-dk);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
  opacity: .78;
}

.pair__clean {
  font-family: var(--display);
  font-variation-settings: "opsz" 36, "SOFT" 24, "WONK" 0;
  font-size: clamp(1.08rem, .96rem + .58vw, 1.38rem);
  line-height: 1.42;
  color: var(--ink);
  margin: 0;
  overflow-wrap: anywhere;
}

.pair__clean mark {
  background: none;
  color: var(--signal);
  font-weight: 600;
}

/* --------------------------------------------------------- the dictionary */

.lab .hud { border-color: var(--hair-lo); background: rgba(0, 0, 0, .26); margin-top: 16px; flex: none; }

.lab {
  background: var(--stage);
  color: var(--roll-2);
  border: 1px solid var(--stage-2);
  padding: clamp(18px, 2.6vw, 28px);
}

.lab__label {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0 0 .85em;
}

.lab__line {
  font-family: var(--display);
  font-variation-settings: "opsz" 40, "SOFT" 24, "WONK" 0;
  font-size: clamp(1.1rem, .98rem + .6vw, 1.44rem);
  line-height: 1.44;
  color: #fff;
  margin: 0 0 16px;
  overflow-wrap: anywhere;
}

.lab__line .term {
  color: var(--stage);
  background: var(--signal-hi);
  padding: 0 .22em;
  transition: background .3s var(--ease-settle), color .3s var(--ease-settle);
}

.lab__line.is-fixed .term { background: #4ad08a; }

.lab__note {
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.68;
  color: var(--dim);
  margin: 0 0 16px;
  max-width: 54ch;
}

.fix {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-bottom: 14px;
}

.fix label {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--dim);
}

.fix input {
  font-family: var(--mono);
  font-size: 14px;
  color: #fff;
  background: rgba(0, 0, 0, .28);
  border: 1px solid var(--hair-lo);
  padding: 10px 12px;
  width: 11ch;
  min-width: 0;
}

.fix input:focus { border-color: var(--signal-lo); outline: none; }

.entries {
  list-style: none;
  margin: 14px 0 0;
  padding: 14px 0 0;
  border-top: 1px solid var(--hair-lo);
  display: grid;
  gap: 9px;
  font-family: var(--mono);
  font-size: 12.5px;
}

.entries li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 6px 14px;
  align-items: baseline;
  color: var(--dim);
}

.entries li > * { min-width: 0; }
.entries b { color: var(--signal-lo); font-weight: 500; }
.entries .origin { text-align: right; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; }
.entries .empty { grid-column: 1 / -1; color: var(--dim); }

/* ---------------------------------------------------------------- the HUD */

.hud[hidden] { display: none; }

.hud {
  background: var(--stage);
  border: 1px solid var(--stage-2);
  color: var(--roll-2);
  padding: 16px 18px;
  font-family: var(--mono);
  display: grid;
  gap: 11px;
}

.hud__top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
  align-items: baseline;
  font-size: 12.5px;
}

.hud__top > * { min-width: 0; }
.hud__top b { color: #fff; font-weight: 500; }
.hud__top .count { color: var(--signal-lo); font-variant-numeric: tabular-nums; }

.hud__term {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px 14px;
  align-items: baseline;
  font-size: 12.5px;
  color: var(--dim);
  padding: 8px 0;
  border-top: 1px solid var(--hair-lo);
}

.hud__term > * { min-width: 0; }
.hud__term strong { color: var(--signal-lo); font-weight: 500; }
.hud__term .why { text-align: right; font-size: 11px; }

.hud__drain { height: 3px; background: var(--hair-lo); overflow: hidden; }
.hud__drain span { display: block; height: 100%; width: 42%; background: var(--signal-hi); transition: width 1s linear; }

/* ------------------------------------------------------------- menu bar */

.menubar {
  background: var(--stage);
  border: 1px solid var(--stage-2);
  padding: 0;
  overflow: hidden;
}

/* The status menu leads with a branded header in the app, so the mock does too: the
   mark, the wordmark, what it is doing right now, and the key that starts it. One
   violet rule closes it and there is no separator under that, because two rules four
   points apart read as a mistake. */
.menubar__head {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  padding: 9px 14px 8px;
  border-bottom: 1px solid var(--signal-hi);
}

.menubar__head > * { min-width: 0; }
.menubar__mark { width: 28px; height: 28px; }
.menubar__head b {
  display: block;
  font-family: var(--display);
  font-variation-settings: "opsz" 20, "SOFT" 0, "WONK" 0;
  font-weight: 700;
  font-size: 14px;
  color: var(--roll-2);
}

.menubar__state {
  display: flex;
  align-items: center;
  gap: .5em;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--dim);
  white-space: nowrap;
}

.menubar__state i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ok);
  flex: none;
}

.menubar__head kbd { color: var(--dim); font-size: 11px; }

.menubar__strip {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 18px;
  padding: 7px 14px;
  background: rgba(0, 0, 0, .3);
  border-bottom: 1px solid var(--hair-lo);
  font-family: var(--mono);
  font-size: 11px;
  color: var(--dim);
}

.menubar__strip .state {
  display: inline-flex;
  align-items: center;
  gap: .5em;
  white-space: nowrap;
}

.menubar__strip svg { width: 15px; height: 15px; color: var(--roll-2); }
.menubar__strip .state.on svg { color: var(--signal-hi); }

.menulist {
  list-style: none;
  margin: 0;
  padding: 7px 0;
  font-family: var(--mono);
  font-size: 12.5px;
  color: var(--roll-2);
}

.menulist li {
  display: grid;
  grid-template-columns: 1.2em minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  padding: 5px 16px;
}

.menulist li > * { min-width: 0; }
.menulist svg { width: 1.05em; height: 1.05em; color: var(--dim); }
.menulist .key { color: var(--dim); font-size: 11.5px; text-align: right; white-space: nowrap; }
.menulist .rule { display: block; grid-column: 1 / -1; height: 1px; background: var(--hair-lo); padding: 0; margin: 6px 0; }
.menulist li.sep { display: block; padding: 0; }
.menulist li.sep hr { border: 0; height: 1px; background: var(--hair-lo); margin: 6px 12px; }

/* ------------------------------------------------------------ the pipeline */

.rail {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  margin-top: clamp(20px, 3vw, 34px);
  border: 1px solid var(--hair);
  background: var(--roll-2);
}

.rail > * { min-width: 0; }

.stop {
  padding: clamp(14px, 1.9vw, 20px);
  border-right: 1px solid var(--hair);
  display: grid;
  gap: 7px;
  align-content: start;
}

.stop:last-child { border-right: 0; }

.stop__n {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .24em;
  color: var(--signal-dk);
}

.stop h3 { font-size: 1rem; margin: 0; }

.stop p {
  margin: 0;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.62;
  color: var(--ink-2);
}

@media (max-width: 900px) {
  .rail { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stop:nth-child(2) { border-right: 0; }
  .stop:nth-child(1), .stop:nth-child(2) { border-bottom: 1px solid var(--hair); }
}

@media (max-width: 520px) {
  .rail { grid-template-columns: minmax(0, 1fr); }
  .stop { border-right: 0; border-bottom: 1px solid var(--hair); }
  .stop:last-child { border-bottom: 0; }
}

.wire {
  margin-top: 14px;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 10px 14px;
  align-items: center;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-2);
  border: 1px solid var(--hair);
  padding: 12px 16px;
}

.wire > * { min-width: 0; }
.wire__label { letter-spacing: .2em; text-transform: uppercase; color: var(--signal-dk); white-space: nowrap; }
.wire__empty { height: 1px; background: repeating-linear-gradient(90deg, var(--hair) 0 5px, transparent 5px 12px); }

/* ------------------------------------------------------------ early access */

.coupon {
  border: 2px solid var(--ink);
  background: var(--roll-2);
  max-width: 560px;
}

.coupon__band {
  margin: 0;
  background: var(--ink);
  color: var(--roll);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .24em;
  text-transform: uppercase;
  padding: 8px 16px;
}

.coupon__body { padding: clamp(16px, 2.3vw, 24px); }
.coupon__body p { margin: 0 0 1em; }

.earlyform {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
  align-items: stretch;
}

.earlyform > * { min-width: 0; }

.earlyform input[type="email"] {
  font-family: var(--mono);
  font-size: 14px;
  color: var(--ink);
  background: var(--roll);
  border: 1px solid var(--ink);
  padding: 12px 13px;
  min-width: 0;
}

.earlyform input[type="email"]:focus { outline: 2px solid var(--signal); outline-offset: 2px; }

.btn {
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--roll-2);
  background: var(--signal-dk);
  border: 1px solid var(--signal-dk);
  padding: 12px 18px;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  transition: background .2s var(--ease-settle);
}

.btn:hover { background: var(--signal); border-color: var(--signal); color: var(--roll-2); }
.btn[disabled] { opacity: .6; cursor: default; }

.hp { position: absolute; left: -9999px; }

.earlymsg {
  grid-column: 1 / -1;
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.6;
  margin: 2px 0 0;
  overflow-wrap: anywhere;
}

.earlymsg.is-bad { color: #a11a1a; }

.earlydone {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 11px;
  align-items: start;
  font-size: .98rem;
  line-height: 1.55;
}

.earlydone > * { min-width: 0; }
.earlydone svg { width: 20px; height: 20px; color: var(--ok); margin-top: .2em; }

@media (max-width: 520px) {
  .earlyform { grid-template-columns: minmax(0, 1fr); }
}

/* ---------------------------------------------------------------- footer */

.foot {
  border-top: 1px solid var(--hair);
  padding: clamp(28px, 3.6vw, 46px) 0 clamp(34px, 4vw, 54px);
}

.foot__in {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 16px 32px;
  align-items: end;
}

.foot__in > * { min-width: 0; }

.foot__links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  font-family: var(--mono);
  font-size: 12.5px;
  justify-content: flex-end;
}

.foot__links a { color: var(--ink-2); text-decoration: none; }
.foot__links a:hover { color: var(--signal-dk); text-decoration: underline; }

.foot__note {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-2);
  margin: 10px 0 0;
}

@media (max-width: 680px) {
  .foot__in { grid-template-columns: minmax(0, 1fr); }
  .foot__links { justify-content: flex-start; }
}

/* ------------------------------------------------------------- documents */

.doc { padding: clamp(34px, 4.6vw, 66px) 0 clamp(44px, 5vw, 78px); }

.doc__grid {
  display: grid;
  max-width: 980px;
  grid-template-columns: minmax(0, 190px) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 64px);
  align-items: start;
}

.doc__grid > * { min-width: 0; }

.doc__rail {
  position: sticky;
  top: 86px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.9;
}

.doc__rail ol { list-style: none; margin: .6em 0 0; padding: 0; counter-reset: c; }
.doc__rail li { counter-increment: c; }
.doc__rail li::before { content: counter(c, decimal-leading-zero) "  "; color: var(--signal-dk); }
.doc__rail a { color: var(--ink-2); text-decoration: none; }
.doc__rail a:hover { color: var(--signal-dk); text-decoration: underline; }

.doc__body { max-width: 66ch; }
.doc__body h1 + p { margin-top: .9em; }
.doc__body h1 { font-size: clamp(1.9rem, 1.3rem + 2.4vw, 2.9rem); font-weight: 500; font-variation-settings: "opsz" 90, "SOFT" 8, "WONK" 1; }
.doc__body h2 { font-size: 1.32rem; font-weight: 600; font-variation-settings: "opsz" 28, "SOFT" 14, "WONK" 0; margin: 2.1em 0 .5em; scroll-margin-top: 90px; }
.doc__body p { margin: 0 0 1.05em; }
.doc__body ul { margin: 0 0 1.05em; padding-left: 1.2em; }
.doc__body li { margin-bottom: .35em; }
.doc__body .updated { font-family: var(--mono); font-size: 12px; color: var(--ink-2); margin-top: .8em; }
.doc__body a.btn { color: var(--roll-2); text-decoration: none; }

@media (max-width: 860px) {
  .doc__grid { grid-template-columns: minmax(0, 1fr); }
  .doc__rail { position: static; border-bottom: 1px solid var(--hair); padding-bottom: 14px; }
}

/* ---------------------------------------------------------------- reveals */

/* The reveal is opt-in from the script that undoes it. Without this the whole
   page below the hero is invisible with JavaScript off, which is content hidden
   behind an animation that never runs: the exact failure the reduced-motion
   rule exists to prevent, arriving by a different road. */
.js .rise {
  opacity: 0;
  transform: translateY(24px);
  filter: blur(5px);
  transition:
    opacity .8s var(--ease-settle) var(--delay, 0ms),
    transform .8s var(--ease-settle) var(--delay, 0ms),
    filter .8s var(--ease-settle) var(--delay, 0ms);
}

.js .rise.in { opacity: 1; transform: none; filter: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .rise { opacity: 1; transform: none; filter: none; transition: none; }
  .rig.is-live .rig__lamp { animation: none; }
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}
