/* ============================================================================
   OxOn — the page you can unplug.

   ⭐ THE IDEA. The visitor pulls the NETWORK cable in the hero. The page does
   not break, it changes: everything on it that depends on somebody else's
   computer dies, and everything the Ox1 does keeps working. One mechanism,
   one state, propagated everywhere. The visitor does the argument instead of
   reading it.

   ⛔ It is the NETWORK lead, never the mains. Pull the mains and the box dies
   like any box; the acceptance test is run with the network cable out, and a
   lab manager clocks the difference instantly. Keep the physics honest and
   this is the product's own behaviour dramatised rather than a gimmick.

   Grammar: hairline rules, tiny letterspaced capitals, tabular numerals.
   Ruled rows, never cards — cards say "web app", rules say "specification".
   ========================================================================= */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { max-width: 100%; height: auto; display: block; }
::selection { background: var(--ink); color: var(--paper); }
a { color: inherit; }

.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }
.sect { padding-block: var(--section-y); }
.band-dark { background: var(--dark); color: var(--on-dark); }
.band-deep { background: var(--paper-deep); }

/* ── The plate: every section header ────────────────────────────────────── */
.plate {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 1.5rem;
  border-top: var(--hair) solid var(--alu);
  padding-top: 0.85rem;
  margin-bottom: clamp(2rem, 1rem + 3vw, 3.75rem);
}
.band-dark .plate { border-top-color: var(--dark-edge); }
.label {
  font-size: var(--t-micro); letter-spacing: var(--track-label);
  text-transform: uppercase; font-weight: 500; color: var(--ink-faint);
  line-height: 1.4;
}
.band-dark .label { color: var(--on-dark-faint); }
.plate .label + .label { text-align: right; }

/* ── Type ───────────────────────────────────────────────────────────────── */
.display, h1, h2 {
  font-weight: 300; letter-spacing: var(--track-display);
  line-height: var(--lh-display); margin: 0; text-wrap: balance;
}
h1 { font-size: var(--t-display); }
h2 { font-size: var(--t-h2); max-width: var(--measure-display); }
h3 { font-size: var(--t-h3); font-weight: 500; letter-spacing: -0.006em; line-height: var(--lh-tight); margin: 0; }
p { margin: 0 0 1em; max-width: var(--measure); }
p:last-child { margin-bottom: 0; }
.lead { font-size: var(--t-lead); font-weight: 300; line-height: 1.5; max-width: 48ch; }
.muted { color: var(--ink-soft); }
.band-dark .muted { color: var(--on-dark-soft); }
.small { font-size: var(--t-small); }
.num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* ── Buttons ────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 0.7em;
  padding: 0.95em 1.6em; font-size: var(--t-small); font-weight: 500;
  letter-spacing: 0.13em; text-transform: uppercase; text-decoration: none;
  border: var(--hair) solid var(--ink); border-radius: var(--radius);
  background: var(--ink); color: var(--paper); cursor: pointer;
  font-family: inherit;
  transition: background 240ms var(--ease), color 240ms var(--ease);
}
.btn:hover { background: transparent; color: var(--ink); }
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--alu); }
.btn-ghost:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.band-dark .btn { background: var(--on-dark); color: var(--dark); border-color: var(--on-dark); }
.band-dark .btn:hover { background: transparent; color: var(--on-dark); }
.btn:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible, button:focus-visible {
  outline: 2px solid var(--oxon-local); outline-offset: 3px;
}
.band-dark :focus-visible { outline-color: var(--on-dark); }

/* ── Nav ────────────────────────────────────────────────────────────────── */
.nav {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: var(--hair) solid transparent;
  transition: border-color 240ms var(--ease);
}
.nav.stuck { border-bottom-color: var(--paper-edge); }
.nav-in { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; height: 62px; }
.nav-mark { display: flex; align-items: center; gap: 0.6rem; text-decoration: none; }
.nav-mark b { font-weight: 400; font-size: 1.05rem; }
.nav-links { display: flex; gap: clamp(0.9rem, 2vw, 2rem); align-items: center; min-width: 0; }
.nav-links a { text-decoration: none; font-size: var(--t-small); color: var(--ink-soft); white-space: nowrap; }
.nav-links a:hover { color: var(--ink); }
@media (max-width: 1080px) { .nav-mark .opt { display: none; } }
@media (max-width: 920px)  { .nav-links .opt { display: none; } }
@media (max-width: 740px)  { .nav-links .sec { display: none; } }

/* ── THE STATUS PILL — the page's own privacy indicator, mirroring the one
   on the machine. It is the single thing that never lies. ───────────────── */
.pill {
  display: inline-flex; align-items: center; gap: 0.5em;
  font-size: var(--t-micro); letter-spacing: 0.14em; text-transform: uppercase;
  font-weight: 500; padding: 0.42em 0.8em; border-radius: 100px;
  background: var(--oxon-local-tint); color: var(--oxon-local);
  border: var(--hair) solid color-mix(in srgb, var(--oxon-local) 26%, transparent);
  white-space: nowrap;
}
.pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.unplugged .pill { background: var(--oxon-amber-tint); color: var(--oxon-amber); border-color: color-mix(in srgb, var(--oxon-amber) 26%, transparent); }
.pill .on-plug { display: inline; }
.pill .on-unplug { display: none; }
.unplugged .pill .on-plug { display: none; }
.unplugged .pill .on-unplug { display: inline; }

/* ── Hero ───────────────────────────────────────────────────────────────── */
.hero { padding-top: clamp(2rem, 1rem + 4vw, 4rem); padding-bottom: clamp(1.5rem,3vw,2.5rem); overflow: hidden; }
.hero-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr);
  gap: clamp(1.5rem, 1rem + 3vw, 4rem); align-items: end;
}
.hero-copy { padding-bottom: clamp(1.5rem, 1rem + 3vw, 3.5rem); }
.hero h1 { margin: 1.2rem 0 0; max-width: 13ch; }
.hero .lead { margin-top: clamp(1.1rem, 0.8rem + 1.2vw, 1.7rem); }
.hero-cta { display: flex; flex-wrap: wrap; gap: 0.85rem; margin-top: clamp(1.4rem, 1rem + 1.8vw, 2.2rem); }
/* ⛔ ULTRA-WIDE. The bleed had no floor, so the image grew with the viewport
   and pushed the headline off the fold — at 3440 the H1 began at y=1498 and a
   visitor saw a logo and a photograph. Cap the bleed and the height. */
.hero-fig {
  position: relative;
  margin-right: clamp(-360px, calc(var(--max) / 2 - 50vw - var(--gutter)), calc(var(--gutter) * -1));
}
.hero-fig img {
  width: auto; max-width: 100%; margin-left: auto;
  max-height: min(84vh, 980px); object-fit: contain;
  /* The corrected render is transparent, so there is no seam to hide and no
     colour-matching to do. The mask that used to live here is gone. */
}
@media (min-width: 1700px) {
  :root { --max: clamp(1240px, 58vw, 1480px); }
  /* Bottom-aligned copy against a full-height image leaves a void top-left on
     a very wide display. Centre it there; it stays bottom-aligned at laptop
     widths, where the alignment is the editorial choice. */
  .hero-grid { align-items: center; }
  .hero-copy { padding-bottom: 0; }
}
@media (max-width: 900px) {
  .hero-grid { grid-template-columns: 1fr; }
  .hero-fig { margin-inline: calc(var(--gutter) * -1); order: 2; }
  .hero-fig img { max-height: none; width: 100%; }
  .hero h1 { max-width: 15ch; }
}
.hero-rule {
  display: flex; flex-wrap: wrap; gap: 0.6rem clamp(1.2rem, 3vw, 2.6rem);
  border-top: var(--hair) solid var(--alu);
  padding-top: 0.9rem; margin-top: clamp(0.8rem, 2vw, 1.6rem);
}

/* ── THE CABLE — the hero statement of act 03 ────────────────────────────
   ⛔ Founder, twice: "this looks shit not disconnected — fix it to be a hero
   statement not a wonky piece of shit." It was a small pill with a 22px glyph
   that slid half out of its own button. It is now the widest, loudest thing
   in the act: a full-width socket-and-lead that visibly parts, with the verb
   set at display size. If you are going to ask someone to pull a cable, the
   cable has to look worth pulling. */
.cable {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.5rem);
  width: 100%;
  padding: clamp(1.1rem, 2.5vw, 1.9rem) clamp(1.1rem, 2.5vw, 2rem);
  background: var(--paper-raise);
  border: var(--hair) solid var(--alu);
  border-radius: var(--radius);
  font-family: inherit; text-align: left; cursor: pointer;
  transition: border-color 260ms var(--ease), background 260ms var(--ease);
}
.cable:hover { border-color: var(--ink); }
.unplugged .cable { background: var(--oxon-amber-tint); border-color: color-mix(in srgb, var(--oxon-amber) 40%, transparent); }

.cable-label {
  font-size: clamp(1.15rem, 0.9rem + 1.1vw, 1.75rem);
  font-weight: 300; letter-spacing: -0.015em; line-height: 1.05;
  color: var(--ink); white-space: nowrap;
}
.cable-state {
  font-size: var(--t-micro); letter-spacing: var(--track-label);
  text-transform: uppercase; font-weight: 500; white-space: nowrap;
  color: var(--oxon-local);
  display: inline-flex; align-items: center; gap: 0.5em;
}
.cable-state::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.unplugged .cable-state { color: var(--oxon-amber); }
.cable-state .on-unplug { display: none; }
.unplugged .cable-state .on-plug { display: none; }
.unplugged .cable-state .on-unplug { display: inline; }

/* The art: a socket that stays, and a lead that leaves. */
/* overflow hidden, or the wire runs straight through the state chip beside it */
.cable-art { width: 100%; height: clamp(46px, 5vw, 62px); overflow: hidden; }
.cable-art .sock rect { fill: none; stroke: var(--ink); stroke-width: 3; }
.cable-art .lead { transition: transform 520ms var(--ease); }
.cable-art .plugbox { fill: var(--paper-raise); stroke: var(--ink); stroke-width: 3; }
.cable-art .clip { fill: none; stroke: var(--ink); stroke-width: 3; }
.cable-art .wire { fill: none; stroke: var(--ink); stroke-width: 3; stroke-linecap: round; }
.cable-art .gapline {
  stroke: var(--oxon-amber); stroke-width: 2; stroke-dasharray: 3 6;
  opacity: 0; transition: opacity 300ms var(--ease) 220ms;
}
.unplugged .cable-art .lead { transform: translateX(112px); }
.unplugged .cable-art .gapline { opacity: 1; }
.unplugged .cable-art .plugbox { fill: var(--oxon-amber-tint); }
@media (prefers-reduced-motion: reduce) { .cable-art .lead, .cable-art .gapline { transition: none; } }

.cable-note {
  font-size: var(--t-body); color: var(--ink-soft);
  max-width: 52ch; margin: clamp(0.9rem, 2vw, 1.3rem) 0 0;
}
@media (max-width: 760px) {
  .cable { grid-template-columns: minmax(0, 1fr) auto; gap: 0.9rem 1rem; }
  .cable-art { grid-column: 1 / -1; order: 3; }
  /* ⛔ Founder on his own phone, 2026-09-03: the label and the CONNECTED chip
     collided. Both carried white-space:nowrap, so on a narrow screen two
     unbreakable strings shared one row and pushed each other out of the card.
     The label may wrap; the chip may not. */
  .cable-label { white-space: normal; line-height: 1.15; }
}
/* Narrower than a large phone, stop asking them to share a row at all. */
@media (max-width: 480px) {
  .cable { grid-template-columns: minmax(0, 1fr); gap: 0.7rem; }
  .cable-label { order: 1; }
  .cable-state { order: 2; }
  .cable-art { order: 3; grid-column: 1; }
}

/* ── THE DEMONSTRATION — two windows, one dies ──────────────────────────── */
.demo { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1rem, 2.5vw, 2rem); }
@media (max-width: 820px) { .demo { grid-template-columns: 1fr; } }

.win {
  border: var(--hair) solid var(--alu); border-radius: var(--radius);
  background: var(--paper-raise); overflow: hidden;
  display: flex; flex-direction: column; min-height: 17rem;
}
.win-head {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.7rem 0.95rem; border-bottom: var(--hair) solid var(--paper-edge);
}
.win-body { padding: 1.1rem 0.95rem; flex: 1; }
.win-q { font-size: var(--t-small); color: var(--ink-soft); margin-bottom: 0.9rem; }
.win-a { font-size: var(--t-small); line-height: 1.65; min-height: 7.5em; }
.caret { display: inline-block; width: 0.5em; height: 1.05em; background: var(--ink);
         vertical-align: -0.18em; animation: blink 1.05s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .caret { animation: none; } }

/* The window that depends on somebody else's computer. */
.win-remote { background: var(--paper); }
.unplugged .win-remote { border-style: dashed; }
.unplugged .win-remote .win-a { color: var(--ink-faint); }
.win-stall { display: none; font-size: var(--t-small); color: var(--oxon-amber); margin-top: 0.9rem; }
.unplugged .win-remote.stalled .win-stall { display: block; }
.unplugged .win-remote.stalled .caret { display: none; }

/* ⭐ THE GENERAL RULE: anything that lives on somebody else's computer dies
   when the cable is out. One class, used everywhere on the page. */
.dies { transition: opacity 320ms var(--ease), filter 320ms var(--ease); }
.unplugged .dies { opacity: 0.26; filter: grayscale(1); }
.unplugged .dies--strike { text-decoration: line-through; text-decoration-thickness: 1px; }

/* ── Ruled rows and grids ───────────────────────────────────────────────── */
.rows { border-top: var(--hair) solid var(--paper-edge); }
.band-dark .rows { border-top-color: var(--dark-edge); }
.row { padding: clamp(1.1rem, 0.8rem + 1.2vw, 1.8rem) 0; border-bottom: var(--hair) solid var(--paper-edge); }
.band-dark .row { border-bottom-color: var(--dark-edge); }
.row p { margin: 0; }
.row-gloss { display: grid; grid-template-columns: minmax(0, 1fr) 11rem; gap: 0.5rem 2rem; }
@media (max-width: 720px) {
  /* Stacked, the label must come FIRST — a value above its own caption reads
     backwards. */
  .row-gloss { grid-template-columns: minmax(0,1fr); }
  .row-gloss .gloss { text-align: left; order: -1; margin-bottom: 0.15rem; }
}

.grid { display: grid; gap: 0; border-top: var(--hair) solid var(--paper-edge); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid > .cell {
  min-width: 0;
  padding: clamp(1.4rem, 1rem + 1.5vw, 2.2rem) clamp(1.1rem, 2vw, 2rem);
  border-bottom: var(--hair) solid var(--paper-edge);
  border-right: var(--hair) solid var(--paper-edge);
}
.grid-3 > .cell:nth-child(3n) { border-right: 0; padding-right: 0; }
.grid-2 > .cell:nth-child(2n) { border-right: 0; padding-right: 0; }
.grid-3 > .cell:nth-child(3n+1) { padding-left: 0; }
.grid-2 > .cell:nth-child(2n+1) { padding-left: 0; }
.band-dark .grid, .band-dark .grid > .cell { border-color: var(--dark-edge); }
.cell h3 { margin-bottom: 0.5rem; }
.cell p { font-size: var(--t-small); color: var(--ink-soft); }
.band-dark .cell p { color: var(--on-dark-soft); }
@media (max-width: 820px) {
  .grid-3, .grid-2 { grid-template-columns: 1fr; }
  .grid > .cell { border-right: 0; padding-inline: 0; }
}

/* ── Claims ─────────────────────────────────────────────────────────────── */
.claim {
  display: grid; grid-template-columns: 3rem minmax(0, 1fr) 11rem;
  gap: 0 clamp(1rem, 2.5vw, 2.5rem);
  padding: clamp(1.5rem, 1rem + 1.6vw, 2.4rem) 0;
  border-bottom: var(--hair) solid var(--paper-edge);
  align-items: start;
}
.claim-n { font-size: var(--t-h3); font-weight: 300; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.claim h3 { margin-bottom: 0.55rem; }
.claim p { font-size: var(--t-small); color: var(--ink-soft); max-width: 58ch; }
.gloss { text-align: right; }
@media (max-width: 880px) {
  .claim { grid-template-columns: 2.2rem minmax(0, 1fr); }
  .gloss { grid-column: 2; text-align: left; margin-top: 0.8rem; }
}

.local {
  display: inline-flex; align-items: center; gap: 0.5em;
  font-size: var(--t-micro); letter-spacing: var(--track-label);
  text-transform: uppercase; font-weight: 500; color: var(--oxon-local);
}
.local::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--oxon-local); flex: none; }

.figure { margin: 0; }
.figure img { width: 100%; border: var(--hair) solid var(--alu); border-radius: var(--radius); background: var(--paper-raise); }
figcaption { margin-top: 0.85rem; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem 1.5rem; }

/* ── The refusal — "No." ────────────────────────────────────────────────── */
.refuse { display: flex; align-items: center; gap: 1.2rem; flex-wrap: wrap; }
.refuse-out { font-size: var(--t-lead); font-weight: 300; min-height: 1.6em; }

/* ── Price ──────────────────────────────────────────────────────────────── */
.cell p.price-fig, .price-fig {
  font-size: clamp(2.4rem, 1.4rem + 4vw, 4.2rem); font-weight: 300;
  letter-spacing: -0.03em; line-height: 1; font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.calc { display: grid; gap: 0.9rem; }
.calc-row { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; }
.calc input[type=number] {
  font: inherit; font-size: var(--t-lead); width: 7.5rem;
  /* a control needs a 3:1 boundary; aluminium on paper is 1.76:1 */
  padding: 0.45em 0.6em; border: var(--hair) solid var(--ink-soft);
  border-radius: var(--radius); background: var(--paper-raise); color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.seg { display: inline-flex; border: var(--hair) solid var(--alu); border-radius: 100px; overflow: hidden; }
.seg button {
  font: inherit; font-size: var(--t-micro); letter-spacing: 0.12em; text-transform: uppercase;
  padding: 0.6em 1em; background: transparent; color: var(--ink-soft);
  border: 0; cursor: pointer; font-weight: 500;
}
.seg button[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
/* overflow:hidden on .seg clipped the ring drawn 3px OUTSIDE the button */
.seg button:focus-visible { outline-offset: -3px; }
.calc-out {
  border-top: var(--hair) solid var(--alu); margin-top: 0.4rem; padding-top: 1rem;
  font-size: var(--t-lead); font-weight: 300;
}
.calc-out strong { font-weight: 400; font-variant-numeric: tabular-nums; }

/* ── The quadrant — the investor reads this in three seconds ────────────── */
.quad { display: grid; grid-template-columns: auto 1fr 1fr; grid-template-rows: auto 1fr 1fr; gap: 0; }
.quad-cell { border: var(--hair) solid var(--paper-edge); padding: clamp(1rem,2vw,1.6rem); min-height: 8.5rem; }
.quad-h { border: 0; padding: 0 0 0.7rem; }
.quad-v { border: 0; padding-right: 0.7rem; display: flex; align-items: center; }
.quad-v .label { writing-mode: vertical-rl; transform: rotate(180deg); }
.quad-cell.is-us { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.quad-cell.is-us .label { color: var(--on-dark-faint); }
/* ⛔ On a dark band the black "us" cell vanishes into the ground — and that
   cell is the entire point of the diagram. Invert it there. */
.band-dark .quad-cell { border-color: var(--dark-edge); }
.band-dark .quad-cell.is-us { background: var(--on-dark); color: var(--dark); border-color: var(--on-dark); }
.band-dark .quad-cell.is-us p { color: #3a3833 !important; }
.band-dark .quad-cell p { color: var(--on-dark-soft); }
.quad-cell h3 { margin-bottom: 0.4rem; }
.quad-cell p { font-size: var(--t-small); color: var(--ink-soft); margin: 0; }
@media (max-width: 780px) {
  .quad { grid-template-columns: 1fr; }
  .quad-v { display: none; }
  .quad-h { display: none; }
  .quad-cell { min-height: 0; }
}

/* ── The page's own health, in the machine's own three states ───────────── */
.health { border-top: var(--hair) solid var(--dark-edge); }
.health-row {
  display: grid; grid-template-columns: minmax(0,1fr) auto;
  gap: 0.4rem 1.5rem; align-items: baseline;
  padding: 0.85rem 0; border-bottom: var(--hair) solid var(--dark-edge);
}
.health-row p { margin: 0; font-size: var(--t-body); max-width: none; }
.health-row .why { display: block; font-size: var(--t-small); color: var(--on-dark-soft); margin-top: 0.3rem; max-width: 58ch; }
.state { font-size: var(--t-micro); letter-spacing: var(--track-label); text-transform: uppercase; font-weight: 500; white-space: nowrap; }
.health .state { display: inline-flex; align-items: center; gap: 0.5em; }
.health .state::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.health-row { align-items: start; padding: 1.05rem 0; }
.health-row .state { padding-top: 0.35em; }
@media (max-width: 560px) {
  .health-row { grid-template-columns: minmax(0, 1fr); }
  .health-row .state { order: -1; padding-top: 0; }
}
.state-ok { color: var(--oxon-local); }
.state-unknown { color: var(--oxon-amber); }

/* ── Form ───────────────────────────────────────────────────────────────── */
.form { display: grid; gap: 0.9rem; max-width: 34rem; }
.field { display: grid; gap: 0.4rem; }
.field label { font-size: var(--t-micro); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-faint); font-weight: 500; }
.band-dark .field label { color: var(--on-dark-soft); }
.field input, .field select {
  font: inherit; font-size: var(--t-small); padding: 0.8em 0.9em;
  border: var(--hair) solid var(--alu); border-radius: var(--radius);
  background: var(--paper-raise); color: var(--ink);
}
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.9rem; }
@media (max-width: 620px) { .form-row { grid-template-columns: 1fr; } }
.form-msg { font-size: var(--t-small); padding: 0.9rem 1rem; border-left: 2px solid var(--oxon-local); background: var(--paper-raise); }
.band-dark .form-msg { background: var(--dark-panel); color: var(--on-dark); }
.form-msg[hidden] { display: none; }
.send-plug { display: none; }
.unplugged .send-normal { display: none; }
.unplugged .send-plug { display: inline; }

/* ── Colophon ───────────────────────────────────────────────────────────── */
.colophon {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem 2rem;
  border-top: var(--hair) solid var(--dark-edge); border-bottom: var(--hair) solid var(--dark-edge);
  padding-block: 1.1rem;
}
.colophon > :nth-child(2) { text-align: center; }
.colophon > :nth-child(3) { text-align: right; }
@media (max-width: 720px) { .colophon { grid-template-columns: 1fr; } .colophon > * { text-align: left !important; } }

/* ── Reveal — fails VISIBLE, never hidden. See the note in index.html. ──── */
.rv { opacity: 1; transform: none; }
.reveal .rv { opacity: 0; transform: translateY(14px); transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease); }
.reveal .rv.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .reveal .rv { opacity: 1; transform: none; transition: none; } }

.skip { position: absolute; left: -9999px; background: var(--ink); color: var(--paper); padding: 0.8em 1.2em; z-index: 100; }
.skip:focus { left: var(--gutter); top: 0.5rem; }

/* ============================================================================
   THE FIVE ACTS
   Founder ruling 2026-09-02: "treat each section as 1….5 and when you get to 5
   all you want to do is either buy one or believe so strongly in our vision",
   and "it's just way too much blah blah blah text". So: one idea per act, a
   number you can count, and the object carried large throughout.
   ========================================================================= */

.act-head {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  gap: 0 clamp(1.2rem, 3vw, 2.6rem); align-items: start;
  border-top: var(--hair) solid var(--alu);
  padding-top: clamp(1rem, 2vw, 1.6rem);
  margin-bottom: clamp(1.6rem, 3vw, 2.6rem);
}
/* ⛔ The heading and its lead both sat in a narrow left column while only the
   ruled rows spanned the container, so from ~1500px up the right half of every
   act was dead. Widening --max made it worse, not better. Above 1100 the act
   header becomes a proper masthead: number · heading · lead, filling the width. */
.act-lead { margin: 0; max-width: 46ch; }
@media (min-width: 1100px) {
  .act-head { grid-template-columns: auto minmax(0, 1.02fr) minmax(0, 0.98fr); align-items: end; }
  .act-head .act-n { align-self: start; }
  .act-lead { padding-bottom: 0.35em; }
}
@media (max-width: 1099px) {
  .act-lead { grid-column: 2; margin-top: clamp(1rem, 2vw, 1.4rem); }
}

/* A sub-heading block inside an act gets the same two-column treatment. */
.sub-head { display: grid; gap: 0 clamp(1.5rem, 3vw, 3rem); align-items: end; }
@media (min-width: 1100px) { .sub-head { grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.98fr); } }
.sub-head .lead { margin: 0; }
.band-dark .act-head { border-top-color: var(--dark-edge); }
.act-n {
  font-size: clamp(2.2rem, 1.2rem + 3.4vw, 4rem);
  font-weight: 300; line-height: 0.85; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums; color: var(--ink-faint);
}
.band-dark .act-n { color: var(--on-dark-faint); }
.act-head h2 { max-width: 17ch; margin-top: 0.1em; }
.act-head .label { display: block; margin-bottom: 0.7rem; }

/* One-line facts. No paragraph where a line will do. */
.lines { border-top: var(--hair) solid var(--paper-edge); margin-top: clamp(1.6rem,3vw,2.4rem); }
.band-dark .lines { border-top-color: var(--dark-edge); }
.lines li {
  list-style: none;
  border-bottom: var(--hair) solid var(--paper-edge);
  padding: clamp(0.85rem, 1.6vw, 1.25rem) 0;
  font-size: var(--t-lead); font-weight: 300; line-height: 1.35;
  display: grid; grid-template-columns: minmax(0,1fr) auto; gap: 0.4rem 2rem; align-items: baseline;
}
.band-dark .lines li { border-bottom-color: var(--dark-edge); }
.lines { padding: 0; margin-left: 0; }
.lines li:last-child { border-bottom: 0; }
@media (max-width: 700px) { .lines li { grid-template-columns: minmax(0,1fr); } .lines li .label { text-align: left; } }

/* The pivot line that turns an act. */
.pivot {
  font-size: clamp(1.3rem, 1rem + 1.6vw, 2rem); font-weight: 300;
  line-height: 1.25; letter-spacing: -0.015em;
  max-width: 34ch; margin-top: clamp(1.8rem, 3.5vw, 3rem); text-wrap: balance;
}

/* ── The object, shown like an object ──────────────────────────────────── */
.obj { margin: clamp(2rem,4vw,3.5rem) 0 0; }
.obj-main { position: relative; }
.obj-main img { width: 100%; }
.details { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: clamp(0.6rem,1.4vw,1.1rem); margin-top: clamp(1rem,2vw,1.6rem); }
.details figure { margin: 0; }
.details img {
  width: 100%; aspect-ratio: 16/9; object-fit: cover;
  image-rendering: auto;
  border: var(--hair) solid var(--alu); border-radius: var(--radius); background: var(--paper-raise);
}
.details figcaption { margin-top: 0.6rem; display: block; }
@media (max-width: 860px) { .details { grid-template-columns: repeat(2, minmax(0,1fr)); } }

/* Nav mark, at a size you can actually see. */
.nav-mark img { width: clamp(52px, 3vw, 84px); height: auto; }
.nav-mark b { font-size: clamp(1.15rem, 1rem + 0.5vw, 1.4rem); }
.nav-mark .rule { width: 1px; height: 22px; background: var(--alu); flex: none; }
@media (max-width: 1080px) { .nav-mark .rule { display: none; } }


/* ── From the accessibility and HCI audit ───────────────────────────────── */
.band-dark .state-ok      { color: var(--oxon-local-on-dark); }
.band-dark .state-unknown { color: var(--oxon-amber-on-dark); }
.band-dark .local         { color: var(--oxon-local-on-dark); }
.band-dark .local::before { background: var(--oxon-local-on-dark); }

/* Hit targets: nav links were 23px tall, segment buttons 32px. */
.nav-links a { padding: 0.6rem 0; }
.seg button  { padding: 0.8em 1.1em; }

/* Grid children default to min-width:auto — the form poked 2px out at 834px. */
.field { min-width: 0; }
.field input, .field select { width: 100%; min-width: 0; min-height: 2.85em; }

/* A live region that is `hidden` when it changes may never announce. */
.form-msg:empty { display: none; }
/* Green is this page's "stayed on your machine" colour; a non-delivery is not
   that, so it takes amber. */
.form-msg.is-wait { border-left-color: var(--oxon-amber); }
.band-dark .form-msg.is-wait { border-left-color: var(--oxon-amber-on-dark); }

/* The 2x2's axes are hidden on phones, and the axes ARE the argument — so each
   cell carries its own coordinates there. */
.quad-tag { display: none; }
@media (max-width: 780px) { .quad-tag { display: block; margin-bottom: 0.5rem; } }

/* The plug visibly leaves the socket instead of shuffling 13px. */
.plug { width: 70px; }
.unplugged .plug-body, .unplugged .plug-lead { transform: translateX(-24px); }

/* 29 reveal items sit at opacity:0 until scrolled to, so print and reader-mode
   snapshots came out blank. */
@media print { .reveal .rv { opacity: 1; transform: none; } }

/* ── THE OBJECT, EXPLORABLE ──────────────────────────────────────────────
   Founder: "put the box and a mouse over showing its options of GPU and hard
   drives etc." ⛔ It names WHAT you choose and never what you get — the
   messaging pack holds every hardware figure blank until Reference Hardware
   001 is measured, so there is not a capacity, a model or a number in here.
   It is also the illustration act 04 promises when it says where you land in
   the price band depends on the configuration. */
.config { display: grid; gap: clamp(1.5rem, 3vw, 3rem); align-items: start; }
@media (min-width: 900px) { .config { grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); } }

.config-fig { position: relative; margin: 0; }
.config-fig img { width: 100%; }

.hot {
  position: absolute; left: var(--x); top: var(--y);
  transform: translate(-50%, -50%);
  width: 44px; height: 44px;            /* Fitts: a real target, not a dot */
  display: grid; place-items: center;
  background: none; border: 0; padding: 0; cursor: pointer;
}
.hot::after {
  content: ""; width: 13px; height: 13px; border-radius: 50%;
  background: var(--paper);
  border: 2px solid var(--ink);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--paper) 72%, transparent);
  transition: transform 200ms var(--ease), background 200ms var(--ease);
}
.hot:hover::after, .hot:focus-visible::after, .hot[aria-current="true"]::after {
  background: var(--ink); transform: scale(1.42);
}
.hot:focus-visible { outline: 2px solid var(--oxon-local); outline-offset: 0; border-radius: 50%; }

.config-out { border-top: var(--hair) solid var(--alu); padding-top: 1.1rem; min-height: 12rem; }
@media (min-width: 900px) { .config-out { margin-top: clamp(2rem, 6vw, 5rem); } }
.config-out h3 { margin: 0.6rem 0 0.5rem; font-size: var(--t-h3); }
.config-out p { font-size: var(--t-body); color: var(--ink-soft); max-width: 40ch; margin: 0; line-height: 1.55; }
.config-out .config-hint { font-size: var(--t-small); color: var(--ink-faint); margin-top: 1.1rem; }
@media (prefers-reduced-motion: reduce) { .hot::after { transition: none; } }

/* ── THE SIXTH DOT ────────────────────────────────────────────────────────
   Founder, 2026-09-03: "we should have a twist… it's NOT a gaming rig — and
   that's the thing, it quite certainly CAN be… a tiny quirk you don't see
   until you click on one of the dots which is a bit different to the others…
   we are using irony and reverse psychology."

   ⭐ THE JOKE IS THE PAGE'S OWN DISCIPLINE CRACKING FOR ONE SECOND. This is
   the only place in 10,000px where the monochrome breaks.

   ⛔ IT WAS HOLLOW AND GREY UNTIL YOU HOVERED IT, ON THE THEORY THAT IT SHOULD
   BE FOUND RATHER THAN SIGNPOSTED. That was wrong and the founder caught it,
   2026-09-04: "we lost our neon pinky purple hot spot on the box overlay for
   gta - its grey so it doesnt make users currently click." A secret nobody
   opens is not a secret, it is dead markup. The dot is lit at rest now and
   breathes slowly — still the only colour on the page, still small, still
   low on the casework where a maker's mark would be, but it now ASKS. */
.hot--secret::after {
  width: 11px; height: 11px;
  background: var(--oxon-neon);
  border: 1px solid var(--oxon-neon);
  box-shadow:
    0 0 0 3px color-mix(in srgb, var(--oxon-neon) 26%, transparent),
    0 0 14px 2px color-mix(in srgb, var(--oxon-neon) 55%, transparent);
  animation: secret-breath 2.6s var(--ease) infinite;
}
@keyframes secret-breath {
  0%, 100% { transform: scale(1);
             box-shadow: 0 0 0 3px color-mix(in srgb, var(--oxon-neon) 26%, transparent),
                         0 0 14px 2px color-mix(in srgb, var(--oxon-neon) 55%, transparent); }
  50%      { transform: scale(1.18);
             box-shadow: 0 0 0 6px color-mix(in srgb, var(--oxon-neon) 16%, transparent),
                         0 0 22px 4px color-mix(in srgb, var(--oxon-neon) 75%, transparent); }
}
@media (prefers-reduced-motion: reduce) { .hot--secret::after { animation: none; } }
.hot--secret:hover::after,
.hot--secret:focus-visible::after,
.hot--secret[aria-current="true"]::after {
  background: var(--oxon-neon); border-color: var(--oxon-neon);
  transform: scale(1.5); animation: none;
  box-shadow:
    0 0 0 6px color-mix(in srgb, var(--oxon-neon) 24%, transparent),
    0 0 26px 6px color-mix(in srgb, var(--oxon-neon) 85%, transparent);
}

/* ⛔ Founder, 2026-09-03, on the first two attempts: "a pink label on a grey
   box" and then "no change on this boring tile which is supposed to really
   sell the fact you can even play it… garbage, unacceptable." Then: "i want
   the box to come alive with cars and characters."

   ⭐ SO THE BOX COMES ALIVE. The sixth dot does not open a card; it turns the
   page over. The paper goes dark for the full width of the screen, the world
   is rendered OUT of the machine — a neon horizon and a grid unroll from its
   base, its grille lights up window by window like a tower at night, a
   striped sun comes up, sports cars run the strip with their headlights
   raking the grid, a few faceless figures walk it — and the readout lands on
   the joke in the page's own dry voice. It is the only place in 11,000px
   where the paper discipline breaks, so when it breaks it is unmistakable.

   ⛔ 1980s MIAMI SYNTHWAVE — a genre, not a product. Generic wedge cars,
   palms, a grid, silhouettes with no faces. Nothing here may be pointed at
   and named, and there is no figure but the price anywhere on this page.

   Cost: transforms and opacity only. The grid scrolls by translating a
   composited layer, the cars and figures translate, the windows blink with
   steps() so they repaint a few times a second and not sixty. Everything is
   display:none until the dot is engaged and paused when the block leaves the
   viewport. Reduced motion gets the whole scene, composed, standing still. */
#machine { overflow-x: clip; }
@supports not (overflow-x: clip) { #machine { overflow-x: hidden; } }

.config { position: relative; --hz: 60%; --fb: 92%; }   /* JS sets these in px */
.config-fig, .config-out { position: relative; z-index: 1; }

.vc {
  display: none; position: absolute; z-index: 0; pointer-events: none; overflow: hidden;
  /* the top bleed is the .obj margin less a hairline, so the sky never covers the lead */
  top: calc(6px - clamp(2rem, 4vw, 3.5rem)); bottom: -1.4rem; left: calc(50% - 50vw); right: calc(50% - 50vw);
  --vc-body: #0a0322; --vc-neon: #ff2e88;
}
.vc-front { z-index: 2; overflow: visible; }
.config.is-live .vc { display: block; animation: vcIn 700ms var(--ease) both; }
@keyframes vcIn { from { opacity: 0; } to { opacity: 1; } }
.vc-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ── the sky, the stars, the sun, the skyline ─────────────────────────── */
.vc-sky {
  position: absolute; left: 0; right: 0; top: 0; height: var(--hz);
  background: linear-gradient(to bottom, #060216 0%, #12052e 34%, #3a0d52 62%, #8a1a63 84%, #ff5f4a 100%);
}
.vc-stars {
  position: absolute; left: 0; right: 0; top: 0; height: calc(var(--hz) * .72);
  background:
    radial-gradient(1.4px 1.4px at 9% 28%,  #fff 55%, transparent 65%),
    radial-gradient(1.1px 1.1px at 22% 12%, #fff 55%, transparent 65%),
    radial-gradient(1.6px 1.6px at 41% 34%, #fff 55%, transparent 65%),
    radial-gradient(1.1px 1.1px at 57% 9%,  #fff 55%, transparent 65%),
    radial-gradient(1.4px 1.4px at 70% 24%, #fff 55%, transparent 65%),
    radial-gradient(1.2px 1.2px at 84% 15%, #fff 55%, transparent 65%),
    radial-gradient(1.5px 1.5px at 93% 40%, #fff 55%, transparent 65%),
    radial-gradient(1.1px 1.1px at 33% 55%, #fff 55%, transparent 65%),
    radial-gradient(1.3px 1.3px at 63% 62%, #fff 55%, transparent 65%),
    radial-gradient(1.1px 1.1px at 4% 70%,  #fff 55%, transparent 65%);
  background-size: 331px 211px, 331px 211px, 331px 211px, 331px 211px, 331px 211px,
                   457px 283px, 457px 283px, 457px 283px, 457px 283px, 457px 283px;
  -webkit-mask-image: linear-gradient(to bottom, #000 40%, transparent);
          mask-image: linear-gradient(to bottom, #000 40%, transparent);
  animation: vcTwinkle 2.6s ease-in-out infinite alternate;
}
@keyframes vcTwinkle { from { opacity: .5; } to { opacity: 1; } }

.vc-sun {
  --sun: clamp(150px, 18vw, 240px);
  position: absolute; width: var(--sun); height: var(--sun); border-radius: 50%;
  left: 82%; top: calc(var(--hz) - var(--sun) * .6); transform: translateX(-50%);
  background:
    repeating-linear-gradient(to bottom,
      transparent 0 9px, #12052e 9px 11px,
      transparent 11px 26px, #12052e 26px 30px,
      transparent 30px 52px, #12052e 52px 59px,
      transparent 59px 90px, #12052e 90px 99px),
    linear-gradient(to bottom, #ffd166 0%, #ff8b3d 45%, #ff2e88 100%);
  box-shadow: 0 0 60px rgba(255,139,61,.35);
  animation: vcSun 1.6s var(--ease) both;
}
@keyframes vcSun { from { transform: translate(-50%, 40%); opacity: 0; } to { transform: translate(-50%, 0); opacity: 1; } }
@media (max-width: 1199px) { .vc-sun { left: 91%; top: calc(var(--hz) - var(--sun) * .42); } }
@media (max-width: 899px) { .vc-sun { left: 94%; } }

.vc-skyline {
  --sk: clamp(36px, 6vw, 76px);
  position: absolute; left: 0; right: 0; width: 100%; height: var(--sk);
  top: calc(var(--hz) - var(--sk) + 1px);
}
.vc-skyline .blk { fill: #0e0426; }
.vc-skyline .win { fill: url(#vcWin); opacity: .85; }

/* ── the floor: a grid that runs to the horizon, and keeps running ──────── */
.vc-floor {
  position: absolute; left: 0; right: 0; top: var(--hz); bottom: 0; overflow: hidden;
  background: linear-gradient(to bottom, #ff5f4a 0%, #7a1450 10%, #1b0736 42%, #08021c 100%);
  transform-origin: top center;
  animation: vcUnroll 900ms var(--ease) both;
}
@keyframes vcUnroll { from { transform: scaleY(0); } to { transform: none; } }
.vc-floor::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px; z-index: 2;
  background: #9ff8ff; box-shadow: 0 0 10px #00f0ff, 0 0 32px rgba(0,240,255,.7);
}
.vc-grid {
  position: absolute; left: -12%; right: -12%; top: -70%; bottom: 0; overflow: hidden;
  transform: perspective(320px) rotateX(56deg); transform-origin: bottom center;
  -webkit-mask-image: linear-gradient(to bottom, transparent 22%, #000 62%);
          mask-image: linear-gradient(to bottom, transparent 22%, #000 62%);
}
.vc-grid i {
  position: absolute; left: 0; right: 0; top: -56px; bottom: 0; display: block;
  background:
    repeating-linear-gradient(to right, rgba(0,240,255,.55) 0 1px, transparent 1px 56px),
    repeating-linear-gradient(to bottom, rgba(0,240,255,.55) 0 1px, transparent 1px 56px);
  animation: vcGrid 1.3s linear infinite; will-change: transform;
}
@keyframes vcGrid { to { transform: translateY(56px); } }

/* ── the cars. Two lanes: far, behind the machine, running left; near, in
   front of its feet, running right. Headlights are part of the drawing, so
   they rake the grid for free. ─────────────────────────────────────────── */
.vc-lane { position: absolute; left: 0; right: 0; height: 0; }
.vc-lane-far  { top: calc(var(--hz) + clamp(14px, 2vw, 30px)); --cw: clamp(84px, 9vw, 150px); transform: scaleX(-1); }
.vc-lane-near { top: calc(var(--fb) + .5rem); --cw: clamp(160px, 19vw, 300px); }
.vc-car {
  position: absolute; left: 0; bottom: 0; width: var(--cw); height: auto; aspect-ratio: 380 / 80;
  transform: translateX(var(--p)); will-change: transform;
  animation: vcDrive var(--t) linear infinite; animation-delay: var(--d);
}
.vc-car-1 { --p: 14vw; --t: 9s;   --d: -1.5s; --vc-neon: #ff2e88; }
.vc-car-2 { --p: 58vw; --t: 12s;  --d: -7s;   --vc-neon: #7ff6ff; }
.vc-car-3 { --p: 30vw; --t: 15s;  --d: -4s;   --vc-neon: #7ff6ff; }
.vc-car-4 { --p: 76vw; --t: 18s;  --d: -12s;  --vc-neon: #ffd166; }
@keyframes vcDrive { from { transform: translateX(-110%); } to { transform: translateX(100vw); } }

/* ── the people. Two-frame walk cycles, stepped, faceless. ──────────────── */
.vc-strip { position: absolute; left: 0; right: 0; top: var(--hz); height: 0; --fw: clamp(13px, 1.5vw, 24px); }
.vc-fig {
  position: absolute; left: 0; bottom: -2px; width: var(--fw); height: calc(var(--fw) * 2);
  transform: translateX(var(--p)); animation: vcStroll var(--t) linear infinite; animation-delay: var(--d);
}
.vc-pose { position: absolute; inset: 0; }
.flip .vc-pose { transform: scaleX(-1); }
.vc-strip .vc-pose { filter: drop-shadow(0 0 2px rgba(255,46,136,.95)); }
.vc-pose svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.vc-pose .pa { animation: vcStepA .72s steps(1, end) infinite; }
.vc-pose .pb { animation: vcStepB .72s steps(1, end) infinite; }
@keyframes vcStepA { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
@keyframes vcStepB { 0%, 100% { opacity: 0; } 50% { opacity: 1; } }
@keyframes vcStroll { from { transform: translateX(-4vw); } to { transform: translateX(104vw); } }
.vc-fig-1 { --p: 22vw; --t: 70s; --d: -14s; }
.vc-fig-2 { --p: 66vw; --t: 84s; --d: -60s; animation-direction: reverse; }
.vc-fig-3 { --p: 88vw; --t: 76s; --d: -48s; --vc-neon: #7ff6ff; }
/* the corner: a lamp post, someone under it, someone walking past — in
   front of the machine, at the feet, where a pavement would be. */
.vc-corner { position: absolute; left: 0; right: 14%; top: calc(var(--fb) + .6rem); height: 0; --fw: clamp(26px, 3.1vw, 46px); }
.vc-lamp  { position: absolute; right: 0; bottom: 0; width: calc(var(--fw) * 1.15); height: calc(var(--fw) * 3.45); overflow: visible; }
.vc-stand { position: absolute; right: calc(var(--fw) * 1.1); bottom: 0; width: var(--fw); height: calc(var(--fw) * 2); overflow: visible; }
.vc-fig-4 { left: auto; right: calc(var(--fw) * 2.4); bottom: 0; --p: 0; --t: 9s; --d: -3s; --vc-neon: #7ff6ff; animation: vcPace var(--t) ease-in-out infinite alternate; }
@keyframes vcPace { from { transform: translateX(0); } to { transform: translateX(calc(var(--fw) * -4)); } }
.vc-fig-4.flip .vc-pose { animation: vcFace var(--t) steps(1, end) infinite; }
@keyframes vcFace { 0%, 100% { transform: scaleX(-1); } 50% { transform: scaleX(1); } }

/* ── palms, the caption, the ribbon ──────────────────────────────────────── */
.vc-palm {
  position: absolute; bottom: -6px; height: clamp(120px, 24vw, 330px); width: auto; aspect-ratio: 120 / 200;
  transform-origin: 50% 100%; animation: vcSway 5.2s ease-in-out infinite alternate; overflow: visible;
}
.vc-palm-l { left: 1%; }
.vc-palm-r { right: 1.5%; height: clamp(90px, 17vw, 240px); animation-delay: -2.7s; animation-duration: 6.1s; }
@keyframes vcSway { from { transform: rotate(-2deg); } to { transform: rotate(2deg); } }
@media (max-width: 899px) { .vc-palm-l { left: -5%; height: clamp(100px, 22vw, 200px); } .vc-palm-r { right: -4%; } }

.vc-cap {
  position: absolute; left: var(--gutter); top: .5rem; margin: 0;
  font-size: var(--t-micro); letter-spacing: 0.3em; text-transform: uppercase; font-weight: 500;
  color: #7ff6ff; text-shadow: 0 0 10px rgba(0,240,255,.7);
}
.vc-ribbon {
  position: absolute; left: 0; right: 0; bottom: 0; overflow: hidden; white-space: nowrap;
  padding: .55rem 0 .6rem; background: rgba(6,1,20,.55);
  border-top: 1px solid rgba(0,240,255,.35);
  font-size: var(--t-micro); letter-spacing: 0.22em; text-transform: uppercase; font-weight: 500;
  color: #7ff6ff; text-shadow: 0 0 8px rgba(0,240,255,.6);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.vc-ribbon span { display: inline-block; animation: vcRun 34s linear infinite; }
@keyframes vcRun { to { transform: translateX(-50%); } }

/* ── night on the machine: dimmed, washed in neon, and lit from inside ──── */
.config-fig img { transition: filter 700ms var(--ease); }
.config.is-live .config-fig img { filter: brightness(.42) contrast(1.12) saturate(.7); }
.vc-wash {
  position: absolute; inset: 0; pointer-events: none; opacity: 0; mix-blend-mode: screen;
  background: linear-gradient(100deg, rgba(255,46,136,.7) 0%, rgba(255,46,136,.16) 40%, rgba(0,240,255,.12) 58%, rgba(0,240,255,.62) 100%);
  -webkit-mask: url(/assets/img/ox1-machine.webp) center / 100% 100% no-repeat;
          mask: url(/assets/img/ox1-machine.webp) center / 100% 100% no-repeat;
  transition: opacity 700ms var(--ease);
}
.config.is-live .vc-wash { opacity: 1; }
@supports not ((mask-image: url("")) or (-webkit-mask-image: url(""))) { .vc-wash { display: none; } }
.vc-lights {
  position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; visibility: hidden;
  opacity: 0; transition: opacity 900ms var(--ease) 250ms, visibility 0s 1200ms; will-change: opacity;
  filter: drop-shadow(0 0 4px rgba(255,200,120,.8));
}
.config.is-live .vc-lights { visibility: visible; opacity: 1; transition-delay: 250ms, 0s; }
.vc-lights .w { fill: #ffcf7a; } .vc-lights .h { fill: #fff4d6; } .vc-lights .k { fill: #5ff0ff; } .vc-lights .p { fill: #ff4fa0; }
.config.is-live .vc-lights .g0 { animation: vcWin0 5.3s steps(1, end) infinite; }
.config.is-live .vc-lights .g1 { animation: vcWin1 7.1s steps(1, end) infinite; }
.config.is-live .vc-lights .g2 { animation: vcWin2 6.2s steps(1, end) infinite; }
.config.is-live .vc-lights .g3 { animation: vcWin3 8.3s steps(1, end) infinite; }
.config.is-live .vc-lights .g4 { animation: vcWin4 4.7s steps(1, end) infinite; }
.config.is-live .vc-lights .g5 { animation: vcWin5 9.1s steps(1, end) infinite; }
@keyframes vcWin0 { 0%, 100% { opacity: 1; } 41% { opacity: 1; } 42%, 55% { opacity: .08; } 56% { opacity: 1; } }
@keyframes vcWin1 { 0%, 100% { opacity: 1; } 12% { opacity: 1; } 13%, 21% { opacity: .08; } 22% { opacity: 1; } 70% { opacity: 1; } 71%, 73% { opacity: .3; } 74% { opacity: 1; } }
@keyframes vcWin2 { 0%, 100% { opacity: .08; } 30% { opacity: .08; } 31%, 88% { opacity: 1; } 89% { opacity: .08; } }
@keyframes vcWin3 { 0%, 100% { opacity: 1; } 60% { opacity: 1; } 61%, 79% { opacity: .08; } 80% { opacity: 1; } }
@keyframes vcWin4 { 0%, 100% { opacity: 1; } 24% { opacity: 1; } 25%, 27% { opacity: .1; } 28% { opacity: 1; } 83% { opacity: 1; } 84%, 96% { opacity: .08; } 97% { opacity: 1; } }
@keyframes vcWin5 { 0%, 100% { opacity: 1; } 50% { opacity: 1; } 51%, 66% { opacity: .08; } 67% { opacity: 1; } }

/* ── the readout, landing the joke on the sky ────────────────────────────── */
.config-out.is-secret {
  border-top: 0; min-height: 0; padding: 0 0 .2rem;
  background: radial-gradient(ellipse 80% 90% at 40% 50%, rgba(8,2,26,.82) 12%, rgba(8,2,26,.42) 50%, rgba(8,2,26,0) 78%);
  animation: vcIn 640ms var(--ease) both;
}
@media (min-width: 900px) { .config-out.is-secret { margin-top: 1.4rem; } }
@media (max-width: 899px) { .config-out.is-secret { padding: 1rem 0 2.3rem; } }
.config-out.is-secret > * { position: relative; z-index: 1; }
.config-out.is-secret #cfgLabel {
  color: #7ff6ff; letter-spacing: 0.3em;
  text-shadow: 0 0 12px rgba(0,240,255,.8);
}
.config-out.is-secret #cfgTitle {
  color: #fff; font-weight: 300; font-style: italic;
  font-size: clamp(1.8rem, 1.1rem + 2.8vw, 3.6rem); line-height: 1.02;
  letter-spacing: -0.015em; margin: 0.8rem 0 0.9rem; max-width: 12ch;
  text-shadow: 0 0 10px rgba(255,46,136,.95), 0 0 34px rgba(255,46,136,.6), 0 0 70px rgba(255,46,136,.35);
  animation: vcNeon 4.8s steps(1, end) infinite;
}
@keyframes vcNeon {
  0%, 100% { opacity: 1; }
  87% { opacity: 1; } 88% { opacity: .55; } 89% { opacity: 1; }
  93% { opacity: 1; } 94% { opacity: .7; }  95% { opacity: 1; }
}
.config-out.is-secret #cfgBody { color: #ffe9f4; max-width: 34ch; text-shadow: 0 1px 12px rgba(8,2,26,.95), 0 0 2px rgba(8,2,26,1); }
.config-out.is-secret .config-hint { display: none; }

/* off-screen: nothing moves for nobody */
.config.is-live.is-off .vc *, .config.is-live.is-off .vc-lights *, .config.is-live.is-off .config-out.is-secret #cfgTitle { animation-play-state: paused; }

/* Reduced motion: the whole scene, composed, standing still. The cars park
   where --p puts them, the sun is up, the grid is drawn, the windows are on. */
@media (prefers-reduced-motion: reduce) {
  .vc, .vc *, .vc-lights *, .config-out.is-secret, .config-out.is-secret #cfgTitle { animation: none !important; }
  .config-fig img, .vc-wash, .vc-lights { transition: none; }
  .vc-pose .pb { opacity: 0; }
  .vc-sun { transform: translateX(-50%); opacity: 1; }
}


/* "Tab to them, or hover" is nonsense on a phone. */
.coarse-pointer { display: none; }
@media (pointer: coarse) {
  .fine-pointer { display: none; }
  .coarse-pointer { display: inline; }
}


/* Act 05's only image, and it carries the act's whole argument: a maker's
   name and a place, engraved on the object. Sits between the masthead and
   the roadmap so the act does not run as an unbroken column of text. */
.plate-band { margin-block: clamp(2rem, 4vw, 3.2rem) clamp(2rem, 4vw, 3rem); }
.plate-band { max-width: 800px; }          /* its own pixel width — never stretched */
.plate-band img { width: 100%; height: auto; }

/* ── THE TEASER — the real film, self-hosted, full-bleed ──────────────── */
.film { background: #000; }
.film-video { display: block; width: 100%; height: auto; max-height: 84vh; background: #000; }
.film-note { padding-block: 0.9rem 1.1rem; }

/* ── THE OBJECT, OPENED — the bridge between the proof and the price ─────
   Founder, three times: the band of paper above act 04 was empty and wanted
   an infographic or illustration about the product. A side cutaway of the
   Ox1 in the page's own grammar: hairlines that stay hairlines at every
   size, paper ground, tracked capitals, and a numbered key beside it.
   The drawing carries short words only; the key carries the sentences, so
   it is legible at 320px and at 3440px without two drawings. */
.inside { padding-block: clamp(3rem, 2rem + 4vw, 6rem) clamp(1rem, 0.5rem + 2vw, 2.5rem); }
#price { padding-top: clamp(3rem, 2rem + 4vw, 6rem); }
.inside-grid {
  display: grid; gap: clamp(1.5rem, 3vw, 3.5rem); align-items: center;
  margin-top: clamp(1.6rem, 3vw, 2.6rem);
}
@media (min-width: 900px) { .inside-grid { grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); } }
.inside-fig { margin: 0; }
.inside-svg { width: 100%; height: auto; color: var(--ink); font-family: inherit; overflow: visible; }
.inside-svg path, .inside-svg rect, .inside-svg circle, .inside-svg line {
  fill: none; stroke: currentColor; stroke-width: 1.25;
  stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke;
}
.inside-svg .thick  { stroke-width: 2.5; }
.inside-svg .fine   { stroke: var(--ink-faint); }
.inside-svg .body   { fill: var(--paper-raise); }
.inside-svg .solid  { fill: var(--ink); stroke: none; }
.inside-svg .board  { fill: var(--paper-edge); stroke: none; }
.inside-svg .perf   { fill: url(#perf); stroke: none; }
.inside-svg #perf circle { fill: var(--ink-faint); stroke: none; }
.inside-svg #arr path { fill: currentColor; stroke: none; }
.inside-svg .ghost  { stroke: var(--ink-faint); stroke-dasharray: 3 4; }
.inside-svg .air path { stroke: var(--ink-faint); stroke-dasharray: 2 5; }
.inside-svg .gap    { stroke: var(--oxon-amber); stroke-dasharray: 2 4; stroke-width: 1.5; }
.inside-svg .fan    { stroke: var(--ink-faint); }
.inside-svg .gpu-fan { stroke: var(--paper); }
.inside-svg text {
  fill: var(--ink-faint); stroke: none; font-size: 14px; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase;
}
.inside-svg .nc { fill: var(--paper); stroke: var(--ink); r: 13px; transition: fill 160ms var(--ease); }
.inside-svg .n  { fill: var(--ink); font-size: 13px; letter-spacing: 0; text-anchor: middle; dominant-baseline: central; transition: fill 160ms var(--ease); }
.inside-svg .num.lit .nc { fill: var(--ink); }
.inside-svg .num.lit .n  { fill: var(--paper); }
/* The drawing scales with its column, so the label size is set in viewBox
   units per tier to land at 10-15 screen pixels from 320px to 3440px. */
@media (max-width: 1199px) { .inside-svg text { font-size: 16px; } .inside-svg .nc { r: 14px; } .inside-svg .n { font-size: 14px; } }
@media (max-width: 899px) {
  .inside-fig { max-width: 520px; margin-inline: auto; width: 100%; }
  .inside-svg text { font-size: 15px; } .inside-svg .nc { r: 14px; } .inside-svg .n { font-size: 14px; }
}
@media (max-width: 560px) { .inside-svg text { font-size: 17px; } .inside-svg .nc { r: 16px; } .inside-svg .n { font-size: 16px; } }
@media (max-width: 420px) { .inside-svg text { font-size: 22px; } .inside-svg .nc { r: 18px; } .inside-svg .n { font-size: 20px; } }

.inside-key { list-style: none; margin: 0; padding: 0; border-top: var(--hair) solid var(--alu); }
.inside-key li {
  display: grid; grid-template-columns: 1.7rem minmax(0, 1fr); gap: 0 0.9rem; align-items: start;
  padding: 0.85rem 0; border-bottom: var(--hair) solid var(--paper-edge);
  font-size: var(--t-small); color: var(--ink-soft); line-height: 1.5;
}
.inside-key li strong { color: var(--ink); font-weight: 500; }
.inside-key .k {
  width: 1.6rem; height: 1.6rem; border: var(--hair) solid var(--ink); border-radius: 50%;
  display: grid; place-items: center; font-size: var(--t-micro); color: var(--ink);
  font-variant-numeric: tabular-nums; margin-top: 0.05rem;
  transition: background 160ms var(--ease), color 160ms var(--ease);
}
.inside-key li.lit .k { background: var(--ink); color: var(--paper); }

/* "Tab to them, or hover" is nonsense on a phone. */
.coarse-pointer { display: none; }
@media (pointer: coarse) {
  .fine-pointer { display: none; }
  .coarse-pointer { display: inline; }
}


/* Act 05's only image, and it carries the act's whole argument: a maker's
   name and a place, engraved on the object. Sits between the masthead and
   the roadmap so the act does not run as an unbroken column of text. */
.plate-band { margin-block: clamp(2rem, 4vw, 3.2rem) clamp(2rem, 4vw, 3rem); }
.plate-band { max-width: 800px; }          /* its own pixel width — never stretched */
.plate-band img { width: 100%; height: auto; }

/* ============================================================================
   THE TEASER — full-bleed, and it makes a sound.

   ⛔ v1 was a 16:9 box inset in the page with the object floating small inside
   it. Founder: "images look poor in those boxes... why didn't you use full
   screen effects? it looks like a mistake." He is right — a bordered rectangle
   with letterboxed stills is a slideshow frame, not a film. This runs edge to
   edge, the detail shots FILL the frame, and the machine is large on black.

   ⭐ Still not an mp4: the site makes zero third-party requests and proves it
   in the viewer's browser. Sound is synthesised in the page with Web Audio, so
   there is no audio file either — which also means the silence at the cut is
   real silence, not a quiet passage.
   ========================================================================= */

.film { background: #000; padding: 0; position: relative; }
.film-stage {
  position: relative; width: 100%;
  height: min(82vh, 860px); min-height: 420px;
  background: #000; overflow: hidden; isolation: isolate;
}
.film-shot { position: absolute; inset: 0; opacity: 0; display: grid; place-items: center; }
/* ⛔ NEVER UPSCALED. The source render is 1149px wide and the machine inside
   it is 929px, so a full-bleed stage stretched to 1440 (2880 on a retina
   screen) was a 3x upscale — which is exactly why it looked fuzzy and cheap.
   The stage stays full-bleed; the OBJECT sits at its own resolution in the
   black field, which is how a product film does it anyway. */
.film-shot img {
  max-width: 100%; max-height: 100%;
  width: auto; height: auto;
  object-fit: contain;
}

.film-cap {
  position: absolute; inset: auto 0 12%; text-align: center;
  font-weight: 300; letter-spacing: -0.015em; color: #fff;
  font-size: clamp(1.4rem, 0.9rem + 2.4vw, 3.4rem);
  opacity: 0; padding-inline: 6vw; z-index: 4;
  text-shadow: 0 2px 44px rgba(0,0,0,.95);
}
.film-cap.micro {
  font-size: clamp(0.72rem, 0.66rem + 0.3vw, 0.9rem);
  letter-spacing: 0.34em; text-transform: uppercase; font-weight: 500;
  color: rgba(255,255,255,.72); inset: auto 0 50%;
}
.film-cap.price { inset: auto 0 14%; }
.film-cap.price::before {
  content: ""; position: absolute; inset: -1.6em -50% -2em;
  background: linear-gradient(to top, rgba(0,0,0,.82), transparent); z-index: -1;
}
.film-black { position: absolute; inset: 0; background: #000; opacity: 0; z-index: 5; }

@keyframes filmIn  { 0%,100% { opacity: 0 } 8%,88% { opacity: 1 } }
@keyframes filmPush{ 0% { transform: scale(1.02) } 100% { transform: scale(1.16) } }
@keyframes filmPull{ 0% { transform: scale(1.15) } 100% { transform: scale(1.01) } }
@keyframes filmCut { 0%,100% { opacity: 0 } 4%,96% { opacity: 1 } }

.film.playing .film-shot { animation: filmIn var(--d) both; animation-delay: var(--t); }
.film.playing .film-shot img { animation: filmPush var(--d) linear both; animation-delay: var(--t); }
.film.playing .film-shot.pull img { animation-name: filmPull; }
.film.playing .film-cap { animation: filmIn var(--d) both; animation-delay: var(--t); }
.film.playing .film-black { animation: filmCut 1.2s steps(1) both; animation-delay: 16s; }

/* controls sit ON the film, bottom-left, out of the way of the type */
.film-bar {
  position: absolute; inset: auto auto 1.6rem 0; z-index: 6;
  display: flex; align-items: center; gap: 0.7rem;
  padding-inline: clamp(1.25rem, 4vw, 3rem);
}
.film-btn {
  font: inherit; font-size: var(--t-micro); letter-spacing: var(--track-label);
  text-transform: uppercase; font-weight: 500;
  background: rgba(255,255,255,.07); color: rgba(255,255,255,.82);
  border: var(--hair) solid rgba(255,255,255,.28); border-radius: 100px;
  padding: 0.72em 1.25em; cursor: pointer; backdrop-filter: blur(8px);
}
.film-btn:hover { color: #fff; border-color: rgba(255,255,255,.7); }
.film-btn[aria-pressed="true"] { background: #fff; color: #000; border-color: #fff; }

@media (prefers-reduced-motion: reduce) {
  .film.playing .film-shot, .film.playing .film-shot img,
  .film.playing .film-cap, .film.playing .film-black { animation: none; }
  .film .film-shot { opacity: 0; }
  .film .film-shot.poster { opacity: 1; }
  .film .film-cap.poster-cap { opacity: 1; }
}

/* ── The honeypot. A person never sees this; a bot fills every field it finds.
   Off-screen rather than display:none, because some bots skip hidden inputs. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ── PHOTOGRAPHS OF THE MACHINE IN USE ──────────────────────────────────────
   ⛔ Juno's ruling, 2026-09-04: a photograph must NOT wear the hairline and
   radius that `.figure img` gives a drawing. The OS screenshot has a border
   BECAUSE it is a screenshot; put one on a photograph and the photograph
   reads as a screenshot too.
   They sit inside .wrap at full column width — never full-bleed. The film is
   the page's only full-bleed element and stays the only one; the photographs
   belong in the same column as the words. */
figure.photo { margin: 0; }
figure.photo img {
  display: block; width: 100%; aspect-ratio: 3 / 2; object-fit: cover;
  border: 0; border-radius: 0;
}
figure.photo figcaption {
  display: flex; justify-content: space-between; gap: 1.5rem;
  margin-top: 0.7rem;
}
figure.photo figcaption .label:last-child { text-align: right; }
@media (max-width: 620px) {
  figure.photo figcaption { display: block; }
  figure.photo figcaption .label:last-child { display: block; text-align: left; margin-top: 0.25rem; }
}
.photo-pair { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1rem, 2.5vw, 2rem); }
/* the same breakpoint the two demonstration windows use, so the page folds once */
@media (max-width: 820px) { .photo-pair { grid-template-columns: 1fr; } }
