/* StepOne - steponeapp.com
   The world: a drafting sheet. Warm paper, ink, and the dimension line as the
   recurring mark, because that is what both programs actually draw. Palette
   sampled from the two programs themselves, not from a stock ramp.

   Motion thesis (2026-09-17): the page drafts itself. Lines draw, dimension
   chains extend from their centre and the number lands in the gap - the gesture
   both programs perform all day. Every hidden start state lives behind
   [data-motion='on'] AND prefers-reduced-motion: no-preference, so a dead
   script or a reduced-motion visitor gets a complete, still page. */

@font-face { font-family: 'Barlow'; src: url('../fonts/barlow-400.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Barlow'; src: url('../fonts/barlow-500.woff2') format('woff2'); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'Barlow'; src: url('../fonts/barlow-600.woff2') format('woff2'); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: 'Barlow Condensed'; src: url('../fonts/barlow-condensed-700.woff2') format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: 'JetBrains Mono'; src: url('../fonts/jetbrains-mono-400.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }

:root {
  /* paper and ink */
  --paper:      #F3EFE6;
  --paper-2:    #EAE5D9;
  --paper-line: #DCD5C5;
  --sheet:      #FAF7F0;   /* a clean sheet lying on the desk */
  --ink:        #16181B;
  --ink-2:      #4A4E55;
  --ink-3:      #63676E;   /* 4.95:1 on --paper. #6E727A was 4.21:1 - under AA. */
  --rule:       rgba(22, 24, 27, 0.16);

  /* the plate - the programs' own chrome */
  --plate:      #22262B;
  --plate-2:    #2C3138;
  --plate-line: #3A4048;
  --plate-ink:  #E8E6E1;
  --plate-ink2: #9AA0A8;   /* 5.8:1 on --plate */

  /* the dimension red both programs draw their chains in */
  --red:        #B23A2B;
  --red-soft:   #C8503F;   /* lines only on the dark plate - 3.2:1, not for text */

  --measure: 68ch;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --shell: 76rem;
  --r: 4px;                /* one corner for everything: a drafting world is nearly square */
  --mast-h: 3.75rem;

  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);

  color-scheme: light;
}

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

html { -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--mast-h) + 1rem); }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 clamp(1rem, 0.96rem + 0.2vw, 1.0625rem)/1.6 'Barlow', system-ui, -apple-system, 'Segoe UI', sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

/* Browser surfaces belong to the design too. */
::selection { background: var(--red); color: #fff; }
:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 3px;
  border-radius: 2px;
}
:root { scrollbar-color: var(--paper-line) var(--paper); }
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: var(--paper); }
::-webkit-scrollbar-thumb { background: var(--paper-line); border: 3px solid var(--paper); border-radius: 99px; }
::-webkit-scrollbar-thumb:hover { background: #C9C0AC; }

img, svg { max-width: 100%; display: block; }
img { height: auto; }
[hidden] { display: none !important; }

h1, h2, h3 {
  font-family: 'Barlow Condensed', 'Barlow', system-ui, sans-serif;
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.01em;
  text-wrap: balance;
  margin: 0;
}

p { margin: 0; max-width: var(--measure); text-wrap: pretty; }

a { color: inherit; text-underline-offset: 0.18em; }

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

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

/* ---- masthead ------------------------------------------------------------- */
.masthead {
  position: sticky; top: 0; z-index: 20;
  border-bottom: 1px solid var(--paper-line);
  background: rgba(243, 239, 230, 0.95);
  -webkit-backdrop-filter: blur(10px) saturate(1.3);
          backdrop-filter: blur(10px) saturate(1.3);
}
.masthead .shell {
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 3vw, 2.25rem);
  min-height: var(--mast-h);
}
.wordmark {
  font-family: 'Barlow Condensed', sans-serif;
  font-weight: 700;
  font-size: 1.5rem;
  letter-spacing: 0.01em;
  text-decoration: none;
  margin-right: auto;
  white-space: nowrap;
}
.wordmark b { color: var(--red); font-weight: 700; }
.nav { display: flex; gap: clamp(0.9rem, 2.5vw, 1.75rem); }
.nav a {
  text-decoration: none;
  font-weight: 500;
  color: var(--ink-2);
  white-space: nowrap;
  padding: 0.85rem 0 0.75rem;                /* 44px tall: a nav link is a target */
  border-bottom: 1.5px solid transparent;
  transition: color 160ms ease, border-color 160ms ease;
}
@media (hover: hover) and (pointer: fine) {
  .nav a:hover { color: var(--ink); border-bottom-color: var(--red); }
}
.nav a[aria-current='page'] { color: var(--ink); border-bottom-color: var(--red); }
/* Both programs carry the full name (Ryan, 2026-09-17: "more uniformity across the board").
   On a phone both drop the prefix together, so the pair still matches. */
@media (max-width: 36rem) { .nav a .pre { display: none; } }

/* A real status, stated once. The dot is still: "in beta testing" is a state,
   not live data, so nothing about it should pulse. */
.status {
  display: none;
  align-items: center;
  gap: 0.55rem;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.75rem;
  letter-spacing: 0.03em;
  color: var(--red);
  white-space: nowrap;
}
@media (min-width: 46rem) { .status { display: inline-flex; } }
.status::before {
  content: '';
  width: 7px; height: 7px;
  background: var(--red);
  border-radius: 50%;
  flex: none;
}

/* ---- buttons and links ---------------------------------------------------- */
.actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 2rem; }
.btn {
  display: inline-flex; align-items: center; gap: 0.55rem;
  font: 600 1rem/1 'Barlow', system-ui, sans-serif;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
  padding: 0.95rem 1.25rem;
  border: 1.5px solid var(--ink);
  border-radius: var(--r);
  transition: background-color 180ms ease, color 180ms ease, border-color 180ms ease, transform 160ms var(--ease-out);
}
.btn .arr { transition: transform 200ms var(--ease-out); }
.btn--ink { background: var(--ink); color: var(--paper); }
@media (hover: hover) and (pointer: fine) {
  .btn:hover { background: var(--red); border-color: var(--red); color: #fff; }
  .btn:hover .arr { transform: translateX(3px); }
}
.btn:active { transform: scale(0.97); }

.link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
  color: inherit;
  text-decoration: none;
  border-bottom: 1.5px solid var(--red);
  padding-bottom: 1px;
  transition: color 160ms ease;
}
.link .arr { color: var(--red); transition: transform 200ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .link:hover { color: var(--red); }
  .link:hover .arr { transform: translateX(4px); }
}
.link:active { transform: scale(0.98); }
.band--plate .link { border-bottom-color: var(--red-soft); }
.band--plate .link .arr { color: var(--plate-ink); }
@media (hover: hover) and (pointer: fine) { .band--plate .link:hover { color: #fff; } }

.mailto {
  display: inline-block;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.9rem;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1.5px solid var(--red);
  padding-bottom: 2px;
  transition: color 160ms ease;
}
@media (hover: hover) and (pointer: fine) { .mailto:hover { color: var(--red); } }

/* ---- hero ----------------------------------------------------------------- */
.hero { padding: clamp(2.5rem, 5vw, 5rem) 0 clamp(3rem, 6vw, 5.5rem); }
.hero-grid { display: grid; gap: clamp(2.25rem, 5vw, 4rem); align-items: center; }
@media (min-width: 64rem) {
  .hero-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }     /* 5/7 squeezed the headline to four lines under 1190 */
  .hero-grid--even { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
@media (min-width: 75rem) { .hero-grid:not(.hero-grid--even) { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); } }
.hero h1 {
  font-size: clamp(2.85rem, 1.5rem + 3.8vw, 4.75rem);
  letter-spacing: -0.02em;
  max-width: 17ch;
}
.hero--long h1 { font-size: clamp(2.6rem, 1.4rem + 4.2vw, 4.1rem); max-width: 20ch; }
.hero--stack h1 { max-width: none; }
.nb { display: inline-block; }           /* a sentence breaks between sentences, not inside one */
.hero .lede {
  margin-top: 1.5rem;
  font-size: clamp(1.1rem, 1.02rem + 0.4vw, 1.3rem);
  color: var(--ink-2);
  max-width: 50ch;
}
.hero--stack .hero-copy { max-width: 58rem; }
.hero--stack .lede { max-width: 60ch; }
.hero--stack .views { margin-top: clamp(2.25rem, 5vw, 3.5rem); }

/* ---- the drawing: the program's own screen, drafting -----------------------
   Ryan, 2026-09-17: "Even in the animations we're supposed to be representing
   the exact product." So these are not ink-on-paper illustrations any more. The
   colours below were sampled from his screenshots of the two programs:
   StepOne CAD      canvas #1B1E23, grid #252A31, cut lines red #F23C37,
                     dimensions and text white #E8E8E8, "Command:" yellow #FED640
   Cabinet Designer  canvas #1C1C1B, wall #FFFFFF, cabinets #FBF9F2, appliances
                     #EDF0FA, codes blue #4D6FDB, chains red #BB655E with the
                     number on a dark pill, the overall run in grey */
.drawing {
  --canvas: #1B1E23;
  --grid: rgba(255, 255, 255, 0.045);
  color: #E8E8E8;              /* what the screen's text is painted in; SVG labels take it through currentColor */
  margin: 0;
  position: relative;
  background-color: var(--canvas);
  background-image:
    linear-gradient(to right, var(--grid) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid) 1px, transparent 1px);
  background-size: 24px 24px;
  /* no hairline: a dark screen on paper is its own edge, and a 1px border under a wide shadow is a generated-UI tell */
  border-radius: var(--r);
  box-shadow: 0 2px 3px rgba(20, 18, 14, 0.10), 0 22px 40px -22px rgba(20, 18, 14, 0.5);
  overflow: hidden;
}
.drawing--cd { --canvas: #1C1C1B; --grid: rgba(255, 255, 255, 0.07); }
.drawing svg { width: 100%; height: auto; }
.drawing figcaption, .drawing .cmdline {
  border-top: 1px solid var(--plate-line);
  background: #23272E;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.75rem; line-height: 1.55;
  color: var(--plate-ink2);
  padding: 0.7rem 0.95rem;
  margin: 0; max-width: none;
}

/* StepOne CAD's pens */
.dw-top   { fill: none; stroke: #F23C37; stroke-width: 1.5; stroke-linejoin: round; }   /* the cut path is red */
.dw-cut   { fill: none; stroke: #F23C37; stroke-width: 1.5; }
.dw-dim   { fill: none; stroke: #E8E8E8; stroke-width: 1; }                              /* measurements are white */
.dw-arrow { fill: #E8E8E8; }
.dw-num   { font: 400 12px Arial, Helvetica, sans-serif; fill: currentColor; text-anchor: middle;
            dominant-baseline: central;          /* a number sits ON its dimension line at any size */
            paint-order: stroke; stroke: var(--canvas); stroke-width: 7px; stroke-linejoin: round; }
.dw-num--lg { font-size: 16px; }
.dw-frac  { font-size: 10.5px; }

/* Cabinet Designer's pens */
.drawing--cd .dw-wall { fill: #FFFFFF; stroke: none; }
.drawing--cd .dw-win  { fill: #FFFFFF; stroke: #8A8F98; stroke-width: 0.8; }
.drawing--cd .dw-cab  { fill: #FBF9F2; stroke: #B9B3A4; stroke-width: 0.8; }
.drawing--cd .dw-app  { fill: #EDF0FA; stroke: #9FB0E8; }
/* the program's label blue is #4D6FDB, 4.34:1 on the cream cabinets; a shade deeper clears AA on both the cabinets (5.2:1) and the appliances (4.8:1) */
.drawing--cd .dw-code { font: 500 11px Arial, Helvetica, sans-serif; fill: #3F61CF; text-anchor: middle; }
.drawing--cd .dw-top  { stroke: #8F8D88; stroke-width: 1.1; }
.drawing--cd .dw-fix  { fill: #EDF0FA; stroke: #8E97B5; stroke-width: 0.9; }
.drawing--cd .dw-dim  { stroke: #BB655E; }
.drawing--cd .dw-dim--over { stroke: #A9A7A2; }
.drawing--cd .dw-num  { color: #E6E4DF; stroke: #242423; stroke-width: 8px; }             /* the number rides on a dark pill */

.only-narrow { display: none; }
/* Between 64 and 82rem the two-column hero draws the screen at about 0.6 scale: bump the small labels. */
@media (min-width: 64rem) and (max-width: 82rem) {
  .drawing--cd .dw-code { font-size: 13.5px; }
  .drawing .dw-num:not(.dw-num--lg) { font-size: 14.5px; }
  .drawing .dw-num--lg { font-size: 19px; }
}
/* On a phone the screen is ~335px wide and a 12px label would print at 5px. Keep
   the dimensions that carry the drawing, large, and drop the ones nobody could read. */
@media (max-width: 40rem) {
  .drawing .dw-code, .drawing .dw-num:not(.dw-key):not(.dw-num--lg) { display: none; }
  .drawing .dw-key, .drawing .dw-num--lg { font-size: 24px; stroke-width: 12px; }
  .drawing .only-wide { display: none; }
  .drawing .only-narrow { display: inline; }
}

/* The square-cornered outline exists only so the fillet step has something to
   replace. In the finished (still, no-script, reduced-motion) drawing it is gone. */
.swap-out { opacity: 0; }

/* the command line under the CAD drawing, in the program's own colours */
.cmdline { display: flex; align-items: center; gap: 0.6rem; min-height: 2.6rem; }
.cmdline .prompt { color: #FED640; }
.cmdline .typed { color: #E8E8E8; font-weight: 400; }
.cmdline .name { color: var(--plate-ink2); }
.cmdline .caret { width: 0.55em; height: 1.05em; background: #E8E8E8; flex: none; margin-left: -0.35rem; }
.cmdline .replay {
  margin-left: auto;
  font: inherit; color: var(--plate-ink);
  background: var(--plate-2); border: 1px solid var(--plate-line); border-radius: var(--r);
  padding: 0.3rem 0.6rem; cursor: pointer; position: relative;
  transition: background-color 160ms ease, border-color 160ms ease, transform 160ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) { .cmdline .replay:hover { background: var(--red); border-color: var(--red); } }
.cmdline .replay:active { transform: scale(0.97); }
/* On a phone the command's name gets a row of its own, reserved, so the bar never changes
   height while the sequence types and nothing below the drawing jumps. */
@media (max-width: 40rem) {
  .cmdline { flex-wrap: wrap; row-gap: 0.1rem; }
  .cmdline .name { order: 1; flex: 0 0 100%; min-height: 1.55em; white-space: nowrap; }
}

/* ---- sections ------------------------------------------------------------- */
.sec { padding: clamp(3.5rem, 8vw, 6.5rem) 0; }
.sec--ruled { border-top: 1px solid var(--paper-line); }
.sec-head { margin-bottom: clamp(2rem, 4vw, 3rem); }
.sec-head h2 { font-size: clamp(2rem, 1.4rem + 2.6vw, 3.25rem); max-width: 26ch; }
.sec-head p { margin-top: 1.1rem; color: var(--ink-2); font-size: 1.1rem; max-width: 58ch; }

.prose { color: var(--ink-2); }
.prose p + p { margin-top: 1.1rem; }
.prose b, .prose strong { color: var(--ink); font-weight: 600; }
.cols { display: grid; gap: 1.25rem clamp(2rem, 5vw, 4.5rem); }
@media (min-width: 56rem) { .cols { grid-template-columns: 1fr 1fr; } }
.prose.cols > p + p { margin-top: 0; }      /* side by side, both start on the same line */

/* prose on the left, its evidence on the right */
.split { display: grid; gap: clamp(2rem, 5vw, 4.5rem); align-items: start; }
@media (min-width: 60rem) { .split { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); } }
.split .term { margin-top: 0; max-width: none; }

/* ---- product bands -------------------------------------------------------- */
.band {
  border-top: 1px solid var(--paper-line);
  padding: clamp(3rem, 7vw, 5.5rem) 0 clamp(3.5rem, 8vw, 6rem);
  position: relative;
}
.band-grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(120, 108, 84, 0.07) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(120, 108, 84, 0.07) 1px, transparent 1px);
  background-size: 28px 28px;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
          mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
}
.band > .shell { position: relative; }

/* The CAD band is the program's own chrome colour, owning the whole region:
   the one deliberate theme switch on the page. */
.band--plate { background: var(--plate); color: var(--plate-ink); border-top: 0; }
.band--plate .band-grid {
  background-image:
    linear-gradient(to right, rgba(232, 230, 225, 0.045) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(232, 230, 225, 0.045) 1px, transparent 1px);
}
.band--plate ::selection { background: var(--red-soft); }
/* The red ring is 2.5:1 on the dark surfaces; a light one is 12:1. The second selector out-ranks
   the plate's own 1px outline, which was silently replacing the focus ring altogether. */
.band--plate :focus-visible, .band--plate .sheet button.open:focus-visible,
.drawing :focus-visible, .term :focus-visible, dialog.lb :focus-visible { outline: 2px solid var(--plate-ink); outline-offset: 3px; }

.band-head { margin-bottom: clamp(2rem, 4vw, 2.75rem); }
.band-head h2 { font-size: clamp(2.3rem, 1.4rem + 3.6vw, 4.1rem); }
.replaces {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.78rem;
  color: var(--ink-3);
  margin-top: 0.9rem;
}
.band-head .blurb { margin-top: 1.4rem; color: var(--ink-2); font-size: 1.1rem; max-width: 62ch; }
.band--plate .replaces, .band--plate .band-head .blurb { color: var(--plate-ink2); }

/* drawing notes under the sheet: one rule over the group, none between rows */
.notes {
  list-style: none; margin: clamp(2rem, 4vw, 2.75rem) 0 0; padding: 1.4rem 0 0;
  display: grid; gap: 1.6rem clamp(1.75rem, 4vw, 3.5rem);
  border-top: 1px solid var(--rule);
}
@media (min-width: 40rem) { .notes { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 72rem) { .notes { grid-template-columns: repeat(4, 1fr); } }
.notes .k {
  display: block;
  font-family: 'Barlow Condensed', sans-serif; font-weight: 700;
  font-size: 1.3rem; line-height: 1.1; color: var(--ink);
  margin-bottom: 0.4rem;
}
.notes .v { color: var(--ink-2); font-size: 0.97rem; line-height: 1.5; }
.notes .v b { color: var(--ink); font-weight: 600; }
.band--plate .notes { border-top-color: var(--plate-line); }
.band--plate .notes .k { color: var(--plate-ink); }
.band--plate .notes .v { color: var(--plate-ink2); }
.band--plate .notes .v b { color: var(--plate-ink); }
.band-more { margin-top: 2.5rem; }

/* ---- the sheet: a screenshot you can actually open ------------------------ */
.sheet { margin: 0; position: relative; }
.sheet button.open {
  position: relative;      /* the zoom chip rides with the plate when it tilts */
  display: block; width: 100%; padding: 0; border: 0; background: var(--plate);
  cursor: zoom-in; border-radius: var(--r); overflow: hidden;
  box-shadow: 0 2px 3px rgba(20, 18, 14, 0.10), 0 22px 40px -22px rgba(20, 18, 14, 0.42);
  transition: transform 240ms var(--ease-out), box-shadow 240ms var(--ease-out);
}
.sheet button.open img { display: block; width: 100%; }
@media (hover: hover) and (pointer: fine) {
  .sheet button.open:hover {
    transform: translateY(-3px);
    box-shadow: 0 3px 5px rgba(20, 18, 14, 0.12), 0 30px 50px -22px rgba(20, 18, 14, 0.48);
  }
}
.sheet button.open:active { transform: scale(0.995); }
.band--plate .sheet button.open {
  outline: 1px solid var(--plate-line); outline-offset: -1px;
  box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.7);
}

.zoom {
  position: absolute; right: 0.7rem; top: 0.7rem;
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.75rem;
  color: var(--plate-ink); background: rgba(16, 18, 21, 0.82);
  border: 1px solid var(--plate-line);
  padding: 0.35rem 0.55rem; border-radius: var(--r);
  pointer-events: none;
  transition: background-color 180ms ease, border-color 180ms ease;
}
@media (hover: hover) and (pointer: fine) {
  .sheet button.open:hover .zoom { background: var(--red); border-color: var(--red); }
}
/* on a phone the plate is small; the chip must not cover a fifth of it */
@media (max-width: 40rem) { .zoom { right: 0.4rem; top: 0.4rem; padding: 0.25rem 0.4rem; } }
.sheet figcaption {
  margin-top: 0.85rem;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.8rem; line-height: 1.6; color: var(--ink-3);
  max-width: 78ch;
}
.sheet figcaption b { color: var(--ink-2); font-weight: 400; }
.band--plate .sheet figcaption { color: var(--plate-ink2); }
.band--plate .sheet figcaption b { color: var(--plate-ink); }

/* ---- the view switcher: the same job, one click apart ---------------------
   Without the script the three figures simply stack. With it they share one
   stage and a tab bar swaps them, the way the program's own view buttons do. */
.views-bar { display: none; }
[data-motion='on'] .views-bar { display: block; min-height: 54px; margin-bottom: 1.1rem; }
.views .view + .view { margin-top: clamp(1.5rem, 3vw, 2.25rem); }
.views.is-tabbed .views-bar {
  display: inline-flex; position: relative;
  padding: 4px; margin-bottom: 1.1rem;
  background: var(--paper-2);
  border: 1px solid var(--paper-line);
  border-radius: calc(var(--r) + 3px);
}
.views-bar button {
  position: relative; z-index: 1;
  font: 600 0.95rem/1 'Barlow', system-ui, sans-serif;
  color: var(--ink-2);
  background: none; border: 0; border-radius: var(--r);
  padding: 0.7rem 1.15rem; min-height: 44px; cursor: pointer;
  transition: color 200ms ease;
}
.views-bar button[aria-selected='true'] { color: var(--paper); }
@media (hover: hover) and (pointer: fine) { .views-bar button[aria-selected='false']:hover { color: var(--ink); } }
.views-pill {
  position: absolute; z-index: 0; top: 4px; left: 0; bottom: 4px; width: 10px;
  background: var(--ink); border-radius: var(--r);
  transform-origin: left center;
  transition: transform 300ms var(--ease-out);
}
.views.is-tabbed .views-stage { display: grid; }
.views.is-tabbed .view { grid-area: 1 / 1; margin-top: 0; }
.views.is-tabbed .view {
  opacity: 0; visibility: hidden; filter: blur(8px); transform: scale(0.992);
  transition: opacity 320ms ease, filter 320ms ease, transform 420ms var(--ease-out), visibility 0s linear 320ms;
}
.views.is-tabbed .view.is-active {
  opacity: 1; visibility: visible; filter: none; transform: none;
  transition: opacity 320ms ease, filter 320ms ease, transform 420ms var(--ease-out), visibility 0s;
}

/* two plates side by side; the second hangs a little lower, like sheets on a desk */
.pair { display: grid; gap: clamp(1.5rem, 3vw, 2.5rem); margin-bottom: clamp(2.5rem, 5vw, 4rem); }
@media (min-width: 56rem) {
  .pair { grid-template-columns: 1fr 1fr; }
  .pair > :nth-child(2) { margin-top: 2.5rem; }
}

/* ---- spec grid: what it does ---------------------------------------------- */
.specgrid {
  margin: 0; padding: 1.75rem 0 0;
  border-top: 1px solid var(--rule);
  display: grid; gap: 2rem clamp(2rem, 5vw, 4.5rem);
}
@media (min-width: 48rem) { .specgrid { grid-template-columns: 1fr 1fr; } .specgrid .wide { grid-column: 1 / -1; } }
.specgrid dt {
  font-family: 'Barlow Condensed', sans-serif; font-weight: 700;
  font-size: 1.5rem; line-height: 1.1; margin-bottom: 0.45rem;
}
.specgrid dd { margin: 0; color: var(--ink-2); max-width: 60ch; }
.specgrid .wide dd { max-width: 90ch; }
.specgrid dd b { color: var(--ink); font-weight: 600; }
.aside-note { margin-top: 2.25rem; color: var(--ink-2); font-size: 0.97rem; }

/* ---- the dimension chain: proof, measured ---------------------------------
   Four numbers the programs' own checks produce, strung on a dimension line
   the way a run of cabinets is. */
.chain {
  list-style: none; margin: clamp(2.5rem, 5vw, 4rem) 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, 1fr); row-gap: 2.25rem;
}
@media (min-width: 60rem) { .chain { grid-template-columns: repeat(4, 1fr); } }
.chain { position: relative; }
.chain::after {                          /* the closing tick at the far end of the chain */
  content: ''; position: absolute; right: 0; top: -6px; width: 1px; height: 13px;
  background: var(--red); transform: rotate(35deg);
}
.chain li { position: relative; padding: 1.6rem 1.25rem 0 0; }
.chain li::before {                      /* the dimension line, one segment per number */
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: var(--red); transform-origin: left center;
}
.chain li::after {                       /* the tick at each station */
  content: ''; position: absolute; left: 0; top: -6px; width: 1px; height: 13px;
  background: var(--red); transform: rotate(35deg);
}
.chain b {
  display: block;
  font-family: 'Barlow Condensed', sans-serif; font-weight: 700;
  font-size: clamp(2.75rem, 1.8rem + 3.4vw, 4.5rem); line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.chain span { display: block; margin-top: 0.6rem; color: var(--ink-2); font-size: 0.97rem; line-height: 1.45; max-width: 24ch; }

/* ---- the round trip ------------------------------------------------------- */
.trip {
  display: grid; grid-template-columns: minmax(5.5rem, 13rem) minmax(0, 1fr) minmax(5.5rem, 13rem);
  align-items: start; gap: clamp(0.5rem, 2vw, 1.5rem);
  margin: clamp(2rem, 4vw, 3rem) 0; max-width: 58rem;
}
.trip-mid { align-self: center; }
/* On a phone the sheets shrink to thumbnails so the two arrows keep their room;
   minmax() would otherwise hand the sheets everything and leave the middle 0px. */
@media (max-width: 40rem) { .trip { grid-template-columns: 5.25rem minmax(0, 1fr) 5.25rem; } }
.trip-sheet { margin: 0; }
.trip-sheet .drawing { box-shadow: 0 1px 2px rgba(20, 18, 14, 0.1), 0 12px 22px -14px rgba(20, 18, 14, 0.45); }
.trip-sheet figcaption {
  margin-top: 0.6rem; text-align: center;
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.75rem; color: var(--ink-2);
}
.trip-mid { display: grid; gap: 0.5rem; text-align: center; font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.75rem; color: var(--ink-3); }
.trip-arrow { position: relative; height: 1px; background: var(--red); margin: 0.35rem 0.4rem; }
.trip-arrow::after {
  content: ''; position: absolute; top: -4px; right: -1px; width: 8px; height: 9px;
  background: var(--red); clip-path: polygon(0 0, 100% 50%, 0 100%);
}
.trip-arrow--out { transform-origin: left center; }
.trip-arrow--back { transform-origin: right center; }
.trip-arrow--back::after { right: auto; left: -1px; clip-path: polygon(100% 0, 0 50%, 100% 100%); }
.trip-eq { font-family: 'Barlow Condensed', sans-serif; font-weight: 700; font-size: clamp(1.15rem, 0.9rem + 1.2vw, 1.7rem); color: var(--ink); line-height: 1.1; }

/* ---- the check output ----------------------------------------------------- */
.term {
  margin: clamp(2rem, 4vw, 2.75rem) 0 0; max-width: 46rem;
  background: var(--plate); color: var(--plate-ink2);
  border-radius: var(--r);
  box-shadow: 0 2px 3px rgba(20, 18, 14, 0.10), 0 22px 40px -22px rgba(20, 18, 14, 0.42);
  overflow: hidden;
}
.term pre {
  margin: 0; padding: 1.25rem 1.4rem 1.4rem;
  font: 400 0.8rem/1.7 'JetBrains Mono', ui-monospace, monospace;
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.term .ln { display: block; min-height: 1.7em; }
.term .ok { color: var(--plate-ink); }
.term .cmd { color: var(--plate-ink); }
.term .pass { color: #fff; font-weight: 400; letter-spacing: 0.04em; }
.term figcaption {
  border-top: 1px solid var(--plate-line); background: var(--plate-2);
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.75rem;
  color: var(--plate-ink2); padding: 0.6rem 1.4rem;
}

/* ---- the big count -------------------------------------------------------- */
.tally { display: grid; gap: clamp(1.5rem, 4vw, 4rem); align-items: center; }
@media (min-width: 56rem) { .tally { grid-template-columns: auto minmax(0, 1fr); } }
.tally-num {
  font-family: 'Barlow Condensed', sans-serif; font-weight: 700;
  font-size: clamp(4rem, 2rem + 9vw, 6rem); line-height: 0.95;
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
  white-space: nowrap; max-width: none;
}
.tally-num [data-count] { display: inline-block; min-width: 3ch; text-align: right; }
.tally-num i { font-style: normal; color: var(--red); padding: 0 0.12em; }

/* ---- the close ------------------------------------------------------------ */
.close h2 { font-size: clamp(2.2rem, 1.4rem + 3.2vw, 3.75rem); max-width: 18ch; }
.close p { margin-top: 1.25rem; color: var(--ink-2); font-size: 1.1rem; max-width: 56ch; }

/* ---- footer: the drawing's title block ------------------------------------ */
.foot { padding: 0 0 clamp(2rem, 4vw, 3rem); color: var(--ink-2); font-size: 0.92rem; }
.tb { display: grid; border: 1px solid var(--rule); border-radius: var(--r); background: var(--sheet); }
.tb-cell { padding: 1.2rem 1.35rem; border-top: 1px solid var(--rule); }
.tb-cell:first-child { border-top: 0; }
@media (min-width: 52rem) {
  .tb { grid-template-columns: 2fr 1fr 1.35fr 1.25fr; }
  .tb-cell { border-top: 0; border-left: 1px solid var(--rule); }
  .tb-cell:first-child { border-left: 0; }
  .tb-fine { grid-column: 1 / -1; border-left: 0; border-top: 1px solid var(--rule); }
}
.tb-k {
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.75rem;
  color: var(--ink-3); margin-bottom: 0.5rem;
}
.tb-main .wordmark { font-size: 1.9rem; display: inline-block; }
.tb-main p { margin-top: 0.35rem; color: var(--ink-2); max-width: 34ch; }
.tb-links a { display: block; width: fit-content; padding: 0.65rem 0; }   /* 45px, as the 09-09 footer was */
.foot a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--paper-line); transition: color 160ms ease, border-color 160ms ease; }
.foot a.wordmark, .foot a.mailto { border-bottom: 0; }
.foot a.mailto { border-bottom: 1.5px solid var(--red); padding: 0.35rem 0 2px; position: relative; }
.foot a.mailto::after, .cmdline .replay::after { content: ''; position: absolute; inset: -9px -4px; }   /* the hit area, not the look */
@media (hover: hover) and (pointer: fine) { .foot a:hover { color: var(--red); border-bottom-color: var(--red); } }
.tb-fine p { max-width: 88ch; color: var(--ink-3); line-height: 1.55; }
.tb-fine p + p { margin-top: 0.7rem; }
.credit { margin-top: 1.25rem; color: var(--ink-3); max-width: none; }

/* ---- lightbox -------------------------------------------------------------
   The stage is the scroll container, so the bar (and Close) stays put while a
   shot is panned in any direction. The image is centred with auto margins, NOT
   with justify-content: a flex item wider than its container that is centred
   that way overflows to the LEFT, where no scrollbar can ever reach it - the
   2560px shots lost their left 300px on a 1920 screen that way. */
dialog.lb {
  padding: 0; border: 0; background: transparent;
  max-width: 100vw; max-height: 100vh; width: 100%; height: 100%;
  overflow: hidden;
  scrollbar-color: #57524a #0e0d0b;
}
dialog.lb::backdrop { background: rgba(14, 13, 11, 0.965); }
.lb-inner { height: 100%; display: flex; flex-direction: column; }
.lb-bar {
  flex: none;
  display: flex; align-items: center; gap: 1rem;
  padding: 0.5rem clamp(0.75rem, 3vw, 1.5rem);
  background: #0e0d0b;
  border-bottom: 1px solid #35322c;
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.78rem;
  color: #c4bfb5;
}
.lb-bar .t { margin-right: auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-bar button {
  flex: none; white-space: nowrap;
  font: inherit; color: #f0ece4; background: #2a2723;
  border: 1px solid #45413a; border-radius: var(--r);
  padding: 0.45rem 0.85rem; cursor: pointer; min-height: 44px;
  transition: background-color 150ms ease, transform 150ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) { .lb-bar button:hover { background: var(--red); border-color: var(--red); } }
.lb-bar button:active { transform: scale(0.97); }
.lb-stage {
  flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain;
  display: flex; align-items: flex-start; justify-content: flex-start;
  padding: clamp(0.5rem, 2vw, 1.5rem);
}
/* Wider than the glass on purpose: panning round a drawing is the right gesture,
   rather than shrinking it back to the size the visitor just clicked to escape. */
.lb-stage img { flex: none; max-width: none; width: 1600px; height: auto; margin-inline: auto; border-radius: var(--r); }
.lb-hint { flex: none; white-space: nowrap; }
@media (max-width: 40rem) { .lb-hint { display: none; } }

/* ==========================================================================
   MOTION
   Everything above is the finished, still page. The start states below exist
   only while the head script's data-motion flag is up and the visitor has not
   asked for reduced motion. The flag is dropped after 3s if site.js never
   reports in, so a blocked or broken script cannot leave anything hidden.
   ========================================================================== */
@media screen and (prefers-reduced-motion: no-preference) {

  /* hero copy arrives once, on load - pure CSS, no script needed to finish it */
  [data-motion='on'] .hero-copy > * { animation: rise 700ms var(--ease-out) both; }
  [data-motion='on'] .hero-copy > :nth-child(2) { animation-delay: 80ms; }
  [data-motion='on'] .hero-copy > :nth-child(3) { animation-delay: 160ms; }
  [data-motion='on'] .hero .drawing, [data-motion='on'] .hero--stack .views { animation: rise 800ms var(--ease-out) 120ms both; }
  @keyframes rise { from { opacity: 0; transform: translateY(16px); } }

  /* plain arrivals: headings, prose, notes */
  [data-motion='on'] [data-reveal] { opacity: 0; transform: translateY(14px); }
  [data-motion='on'] [data-reveal].is-in {
    opacity: 1; transform: none;
    transition: opacity 600ms var(--ease-out), transform 600ms var(--ease-out);
  }
  /* a list arriving as a list: children, capped stagger */
  [data-motion='on'] [data-reveal='stagger'] { opacity: 1; transform: none; }
  [data-motion='on'] [data-reveal='stagger'] > * { opacity: 0; transform: translateY(12px); }
  [data-motion='on'] [data-reveal='stagger'].is-in > * {
    opacity: 1; transform: none;
    transition: opacity 520ms var(--ease-out), transform 520ms var(--ease-out);
    transition-delay: calc(var(--i, 0) * 60ms);
  }

  /* plates unroll from the top edge. The clip sits on the IMAGE, never on the
     observed figure: a fully clipped element reports zero intersection forever. */
  [data-motion='on'] .sheet[data-plate] img { clip-path: inset(0 0 100% 0); transform: scale(1.05); }
  [data-motion='on'] .sheet[data-plate] .zoom, [data-motion='on'] .sheet[data-plate] figcaption { opacity: 0; }
  [data-motion='on'] .sheet[data-plate].is-in img {
    clip-path: inset(0 0 0 0); transform: none;
    transition: clip-path 1000ms var(--ease-in-out), transform 1400ms var(--ease-out);
  }
  [data-motion='on'] .sheet[data-plate].is-in figcaption { opacity: 1; transition: opacity 500ms ease 700ms; }
  /* the chip keeps its hover properties in the list, or this rule would make its colour change snap for good */
  [data-motion='on'] .sheet[data-plate].is-in .zoom {
    opacity: 1; transition: opacity 500ms ease 700ms, background-color 180ms ease, border-color 180ms ease;
  }

  /* where the browser can tie it to the scroll, the CAD plate tips up off the
     desk as it arrives instead */
  @supports (animation-timeline: view()) {
    [data-motion='on'] .sheet[data-plate='tilt'] { perspective: 1600px; }
    [data-motion='on'] .sheet[data-plate='tilt'] img { clip-path: none; transform: none; }
    [data-motion='on'] .sheet[data-plate='tilt'] .zoom, [data-motion='on'] .sheet[data-plate='tilt'] figcaption { opacity: 1; }
    [data-motion='on'] .sheet[data-plate='tilt'] button.open {
      transform-origin: 50% 100%;
      animation: tip-up linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 38%;
    }
    @keyframes tip-up { from { transform: rotateX(16deg) scale(0.93); opacity: 0.35; } }
  }

  /* --- the drafting: strokes draw, parts drop, dimensions extend ---------- */
  [data-motion='on'] [data-draft] .ink { stroke-dasharray: 1; stroke-dashoffset: 1; }
  [data-motion='on'] [data-draft] .fillin { fill-opacity: 0; }
  [data-motion='on'] [data-draft] .drop { opacity: 0; transform: translateY(-9px); }
  [data-motion='on'] [data-draft] .fade { opacity: 0; }
  [data-motion='on'] [data-draft] .pop { opacity: 0; transform: scale(0.6); transform-box: fill-box; transform-origin: center; }

  [data-motion='on'] [data-draft] .on .ink, [data-motion='on'] [data-draft] .ink.on {
    stroke-dashoffset: 0;
    transition: stroke-dashoffset var(--dur, 800ms) var(--ease-in-out) var(--t, 0ms);
  }
  [data-motion='on'] [data-draft] .on .fillin, [data-motion='on'] [data-draft] .fillin.on {
    fill-opacity: 1; transition: fill-opacity 500ms ease calc(var(--t, 0ms) + 350ms);
  }
  /* a shape that both draws and fills needs both in ONE transition list, or the
     later rule silently replaces the earlier one and the stroke just appears */
  [data-motion='on'] [data-draft] .on .ink.fillin, [data-motion='on'] [data-draft] .ink.fillin.on {
    transition: stroke-dashoffset var(--dur, 800ms) var(--ease-in-out) var(--t, 0ms),
                fill-opacity 500ms ease calc(var(--t, 0ms) + 350ms);
  }
  [data-motion='on'] [data-draft] .on .drop, [data-motion='on'] [data-draft] .drop.on {
    opacity: 1; transform: none;
    transition: opacity 260ms ease var(--t, 0ms), transform 420ms var(--ease-out) var(--t, 0ms);
  }
  [data-motion='on'] [data-draft] .on .fade, [data-motion='on'] [data-draft] .fade.on {
    opacity: 1; transition: opacity 320ms ease var(--t, 0ms);
  }
  [data-motion='on'] [data-draft] .on .pop, [data-motion='on'] [data-draft] .pop.on {
    opacity: 1; transform: none;
    transition: opacity 200ms ease var(--t, 0ms), transform 320ms var(--ease-out) var(--t, 0ms);
  }
  /* a fillet replaces a square corner: the square one leaves as the round one lands */
  [data-motion='on'] [data-draft] .swap-out { opacity: 1; }
  [data-motion='on'] [data-draft] .swap-out.off { opacity: 0; transition: opacity 260ms ease; }

  /* four blinks, then it rests solid: nothing on the page moves for more than five seconds unasked */
  [data-motion='on'] .cmdline .caret { animation: blink 1.05s steps(1, end) 4; }
  @keyframes blink { 50% { opacity: 0; } }

  /* the chain extends station by station, then each number lands */
  [data-motion='on'] .chain li::before { transform: scaleX(0); }
  [data-motion='on'] .chain li::after  { opacity: 0; }
  [data-motion='on'] .chain li > * { opacity: 0; transform: translateY(10px); }
  [data-motion='on'] .chain.is-in li::before {
    transform: none; transition: transform 520ms var(--ease-in-out) calc(var(--i, 0) * 200ms);
  }
  [data-motion='on'] .chain.is-in li::after {
    opacity: 1; transition: opacity 200ms ease calc(var(--i, 0) * 200ms);
  }
  [data-motion='on'] .chain.is-in li > * {
    opacity: 1; transform: none;
    transition: opacity 480ms var(--ease-out) calc(var(--i, 0) * 200ms + 220ms),
                transform 480ms var(--ease-out) calc(var(--i, 0) * 200ms + 220ms);
  }

  /* the round trip: out, back, and the count that matches */
  [data-motion='on'] .trip .trip-arrow { transform: scaleX(0); }
  [data-motion='on'] .trip .trip-eq, [data-motion='on'] .trip .trip-lbl { opacity: 0; }
  [data-motion='on'] .trip .trip-sheet--b { opacity: 0.25; }
  [data-motion='on'] .trip.is-in .trip-arrow--out  { transform: none; transition: transform 700ms var(--ease-in-out) 200ms; }
  [data-motion='on'] .trip.is-in .trip-sheet--b    { opacity: 1; transition: opacity 500ms ease 800ms; }
  [data-motion='on'] .trip.is-in .trip-arrow--back { transform: none; transition: transform 700ms var(--ease-in-out) 1200ms; }
  [data-motion='on'] .trip.is-in .trip-lbl { opacity: 1; transition: opacity 400ms ease 300ms; }
  [data-motion='on'] .trip.is-in .trip-lbl--back { transition-delay: 1300ms; }
  [data-motion='on'] .trip.is-in .trip-eq { opacity: 1; transition: opacity 500ms ease 1900ms; }

  /* the check prints its lines */
  [data-motion='on'] .term .ln { opacity: 0; }
  [data-motion='on'] .term.is-in .ln { opacity: 1; transition: opacity 120ms linear calc(var(--i, 0) * 85ms + 250ms); }

  /* the lightbox opens from just under full size, not from nothing */
  dialog.lb[open] { animation: lb-in 260ms var(--ease-out); }
  dialog.lb[open]::backdrop { animation: lb-fade 260ms ease; }
  @keyframes lb-in { from { opacity: 0; transform: scale(0.985); } }
  @keyframes lb-fade { from { opacity: 0; } }
}

/* Reduced motion: no travel, no drawing-in. State changes keep a short fade. */
@media (prefers-reduced-motion: reduce) {
  .views.is-tabbed .view { filter: none; transform: none; transition: opacity 160ms ease, visibility 0s linear 160ms; }
  .views.is-tabbed .view.is-active { transition: opacity 160ms ease, visibility 0s; }
  .views-pill { transition: none; }
  .sheet button.open, .btn, .link .arr, .btn .arr { transition: none; }
}

/* ---- print ----------------------------------------------------------------
   The motion block is screen-only, so nothing is hidden on paper. The tabbed
   stage un-stacks so both views print. */
@media print {
  .masthead { position: static; }
  .views-bar, .zoom, .cmdline .replay { display: none !important; }
  .views.is-tabbed .views-stage { display: block; }
  .views.is-tabbed .view { opacity: 1; visibility: visible; filter: none; transform: none; margin-top: 1.5rem; }
}
