/* =========================================================================
   Instruments — added 2026-08-29.

   The writing on this page stays exactly as it was. What was missing is that
   every claim was described and none of it could be operated: "one store
   failing does not bring down the other three" is a sentence nobody
   remembers, and a store you can switch off is something people press.

   So each section gains an apparatus, and the apparatus sits in the open —
   not behind "Read the case". The button still opens the full writing; the
   instrument is what makes anyone want to press it.

   Every instrument borrows the chapter's own colour (--ch) or the card's
   (--oc), so nothing here introduces a palette. Two states are new, because
   the page had no vocabulary for a system reporting on itself:
   ========================================================================= */
:root {
  --i-stop: #F0685C;   /* refused, failed, offline */
  --i-live: #5CBF8A;   /* serving, verified */
}

/* the frame. a field of the chapter's paper with a mono caption bar, so it
   reads as apparatus rather than as another content card */
.i-rig {
  border: 1px solid var(--hair);
  background: var(--plate);
  margin-top: clamp(20px, 3vh, 30px);
}
.builds .object .i-rig { grid-column: 2; }


.i-rig__bar,
.i-rig__foot {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 8px 18px;
  padding: 9px 14px;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: 0.14em; text-transform: uppercase;
}
.i-rig__bar  { border-bottom: 1px solid var(--hair-2); color: var(--ch); }
.i-rig__foot { border-top: 1px solid var(--hair-2); }
.i-rig__note { color: var(--faint); }
.i-rig__body { padding: clamp(16px, 2.6vw, 26px); }

/* the readout is where the instrument says what just happened. it is the
   only place on the page that changes its own words. */
.i-read {
  font-family: var(--sc-font-mono); font-size: 10.5px; letter-spacing: 0.06em;
  line-height: 1.75; color: var(--ink-2); text-transform: none;
  max-width: 78ch; margin: 0;
}
.i-read b { color: var(--sc-ink); font-weight: 700; }
.i-read.is-stop, .i-read.is-stop b { color: var(--i-stop); }

/* controls reuse the page's existing expand button language */
.i-btn {
  appearance: none; background: none; border: 0; border-bottom: 1px solid var(--hair);
  padding: 4px 0; margin-left: 18px;
  font-family: var(--sc-font-mono); font-size: 10px;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-2); cursor: pointer;
  transition: color .2s, border-color .2s;
}
.i-btn:hover:not([disabled]) { color: var(--ch); border-bottom-color: var(--ch); }
.i-btn[disabled] { opacity: .35; cursor: default; }


/* the expand button was inside the narrow third column; now that the
   instrument sits between the card and the writing, the button belongs
   under the instrument */



/* placement of the two added children, in breakpoint order. the card is three
   columns wide, then two, then one — and at one column nothing may ask for a
   second, or the real track collapses to nothing. */
.object > .i-rig,
.object > .expand { grid-column: 1; justify-self: start; }
.object > .i-rig  { justify-self: stretch; }
@media (min-width: 620px) {
  .object > .i-rig, .object > .expand { grid-column: 2; }
}
@media (min-width: 900px) {
  .object > .i-rig, .object > .expand { grid-column: 2 / -1; }
  .object > .expand { justify-self: start; }
  .object .case { grid-column: 1 / -1; }
}

/* ------------------------------------------------------ 01 · break a store */
.i-fan { display: grid; gap: 16px; }
@media (min-width: 720px) {
  /* the wire column touches both sides: a diagram with gaps in its wiring
     reads as decoration, not as a circuit */
  .i-fan { grid-template-columns: 120px 70px minmax(0, 1fr); align-items: center; column-gap: 0; row-gap: 16px; }
}
.i-auth {
  border: 1px solid var(--oc, var(--ch)); color: var(--oc, var(--ch));
  padding: 11px 8px; text-align: center;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: 0.12em; text-transform: uppercase; line-height: 1.7;
}
.i-wires { display: none; }
@media (min-width: 720px) { .i-wires { display: block; height: 100%; min-height: 176px; } }
.i-wire { fill: none; stroke: var(--oc, var(--ch)); stroke-width: 1.1; opacity: .8; transition: stroke .3s, opacity .3s, stroke-dasharray .3s; }
.i-wire.is-down { stroke: var(--i-stop); stroke-dasharray: 3 4; opacity: .5; }

.i-stores { display: grid; gap: 1px; }
.i-store {
  appearance: none; border: 0; width: 100%; text-align: left; cursor: pointer;
  display: grid; grid-template-columns: 10px 1fr auto auto; align-items: center;
  gap: 12px; padding: 10px 12px;
  background: var(--elev); color: var(--sc-ink);
  transition: background .22s, opacity .22s;
}
.i-store:hover { background: color-mix(in oklab, var(--oc, var(--ch)) 12%, var(--elev)); }
.i-store__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--i-live); transition: background .22s; }
.i-store__name { font-family: var(--sc-font-mono); font-weight: 700; font-size: 11px; letter-spacing: 0.12em; }
.i-store__tools, .i-store__state {
  font-family: var(--sc-font-mono); font-size: 10px; letter-spacing: 0.06em;
  color: var(--faint); font-variant-numeric: tabular-nums;
}
.i-store__state { min-width: 7ch; text-align: right; }
.i-store.is-down { opacity: .48; }
.i-store.is-down .i-store__dot { background: var(--i-stop); }
.i-store.is-down .i-store__state { color: var(--i-stop); }

.i-spec { display: flex; flex-wrap: wrap; gap: 6px 26px; margin: 18px 0 0; padding-top: 14px; border-top: 1px solid var(--hair-2); }
.i-spec div { display: flex; gap: 8px; align-items: baseline; }
.i-spec dt { margin: 0; font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--faint); }
.i-spec dd { margin: 0; font-family: var(--sc-font-mono); font-weight: 700; font-size: 11.5px; color: var(--sc-ink); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------- 02 · run it, break it */
.i-pipe { display: grid; gap: 14px; }
@media (min-width: 900px) {
  .i-pipe { grid-template-columns: minmax(0,1fr) 88px 152px 88px minmax(0,140px); align-items: center; column-gap: 0; row-gap: 14px; }
}
.i-feeds { display: grid; gap: 1px; }
.i-feed {
  display: flex; align-items: center; gap: 10px; padding: 6px 10px;
  background: var(--elev); color: var(--faint);
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: 0.1em; text-transform: uppercase;
  transition: background .2s, color .2s;
}
.i-feed::before { content: ''; width: 5px; height: 5px; flex: none; background: var(--hair); transition: background .2s; }
.i-feed.is-hot { color: var(--sc-ink); }
.i-feed.is-hot::before { background: var(--ch); }

.i-link { position: relative; height: 26px; align-self: stretch; }
.i-link svg { display: none; }
.i-link::before {
  content: ''; position: absolute; left: 50%; top: 0; bottom: 0; width: 1px;
  background: var(--hair); transition: background .25s;
}
.i-link.is-hot::before  { background: var(--ch); }
.i-link.is-stop::before { background: var(--i-stop); }
@media (min-width: 900px) {
  .i-link { height: 100%; min-height: 118px; }
  .i-link::before { display: none; }
  .i-link svg { display: block; width: 100%; height: 100%; }
  .i-link path { fill: none; stroke: var(--hair); stroke-width: 1.1; transition: stroke .25s; }
  .i-link.is-hot path  { stroke: var(--ch); }
  .i-link.is-stop path { stroke: var(--i-stop); }
}

.i-gate {
  border: 1px solid var(--hair); padding: 16px 10px; text-align: center;
  transition: border-color .25s, background .25s, color .25s;
}
.i-gate__label { font-family: var(--sc-font-mono); font-weight: 700; font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--sc-ink); }
.i-gate__sub { display: block; margin-top: 5px; font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: 0.06em; color: var(--faint); }
.i-gate.is-hot  { border-color: var(--ch); }
.i-gate.is-hot .i-gate__sub { color: var(--ch); }
.i-gate.is-stop { border-color: var(--i-stop); background: color-mix(in oklab, var(--i-stop) 16%, transparent); }
.i-gate.is-stop .i-gate__label, .i-gate.is-stop .i-gate__sub { color: var(--i-stop); }

.i-out {
  border: 1px solid var(--hair); padding: 16px 10px; text-align: center;
  font-family: var(--sc-font-mono); font-size: 10px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--faint);
  transition: border-color .25s, color .25s;
}
.i-out.is-hot  { border-color: var(--ch); color: var(--sc-ink); }
.i-out.is-stop { border-color: var(--i-stop); color: var(--i-stop); text-transform: none; letter-spacing: 0.01em; font-size: 11.5px; line-height: 1.45; }

/* ------------------------------------------------------- 03 · scrub it */
.i-ab__panes { position: relative; overflow: hidden; background: var(--g0); }
.i-ab__pane { display: block; width: 100%; }
.i-ab__pane--after { position: absolute; inset: 0; }
.i-ab__handle { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--ch); pointer-events: none; }
.i-ab__handle::after {
  content: ''; position: absolute; top: 50%; left: 50%; width: 30px; height: 30px;
  transform: translate(-50%,-50%); border: 1px solid var(--ch); background: var(--plate);
}
.i-ab__range { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: ew-resize; }
.i-ab__tags {
  display: flex; justify-content: space-between; margin: 10px 0 0;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--faint);
}

/* ============================================== 03 · thinking, as a tuner

   The four essays were four identical rows, so nothing asked to be stopped
   at. They are not really a list: they are four positions of one move —
   replacing the question everyone asks with a better one. A dial says that;
   a stack of rows says only "there are four".

   Every word here is the existing copy, re-paced. Nothing was rewritten.
   ============================================================== */
.i-tuner { margin-top: clamp(2rem, 5vh, 3.5rem); }
.i-tuner__frame {
  border-top: 1px solid var(--ch);
  display: grid; gap: clamp(20px, 4vw, 48px);
  padding-top: clamp(22px, 4vh, 34px);
}
@media (min-width: 860px) { .i-tuner__frame { grid-template-columns: 158px minmax(0, 1fr); } }

/* the detents. four positions, and the reader can feel where they are */
.i-detents { display: grid; gap: 1px; align-content: start; }
.i-detent {
  appearance: none; border: 0; cursor: pointer; width: 100%; text-align: left;
  display: flex; align-items: baseline; gap: 12px; padding: 10px 12px;
  background: transparent; color: var(--faint);
  font-family: var(--sc-font-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase;
  border-left: 1px solid var(--hair); white-space: nowrap;
  transition: color .22s, border-color .22s, background .22s;
}
.i-detent:hover { color: var(--ink-2); }
.i-detent.is-on { color: var(--ch); border-left-color: var(--ch); background: color-mix(in oklab, var(--ch) 8%, transparent); }
.i-detent__n { font-weight: 700; font-variant-numeric: tabular-nums; }
.i-detent__k { font-size: 9px; letter-spacing: 0.1em; }

.i-claim { min-height: clamp(210px, 30vh, 300px); display: grid; align-content: start; }
.i-claim__ex {
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1.3rem, 1rem + 1.9vw, 2.6rem); line-height: 1.18; letter-spacing: -0.03em;
  color: var(--sc-ink); max-width: 24ch; margin: 0;
}
/* the turn arrives a beat after the assumption, because that is how the
   sentence is built */
.i-claim__ex + .i-claim__ex { margin-top: 0.4em; color: var(--ink-2); }
.i-claim__title {
  margin: clamp(20px, 3vh, 30px) 0 0;
  font-family: var(--sc-font-mono); font-size: 10.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ch); max-width: 48ch; line-height: 1.8;
}
.i-claim [data-turn] { opacity: 0; transform: translateY(10px); transition: opacity .5s var(--sc-ease-out, ease), transform .5s var(--sc-ease-out, ease); }
.i-claim.is-turned [data-turn] { opacity: 1; transform: none; }
.i-claim.is-turned [data-turn="2"] { transition-delay: .09s; }

/* ============================================== 06 · about, as a journey

   The longest piece of writing on the site had no way in and no way to
   measure progress. The rail is not decoration: it is the essay's own
   structure, and it is the only place the reader can see how far the story
   has travelled — which is the story.
   ============================================================== */
.i-about { display: grid; gap: clamp(20px, 4vw, 56px); }
@media (min-width: 900px) { .i-about { grid-template-columns: 168px minmax(0, 1fr); align-items: start; } }

.i-rail { display: none; }
@media (min-width: 900px) {
  .i-rail { display: block; position: sticky; top: calc(var(--bar) + 28px); }
}
.i-rail ol { list-style: none; margin: 0; padding: 0; border-left: 1px solid var(--hair); }
.i-rail li {
  position: relative; padding: 9px 0 9px 18px;
  font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--faint);
  transition: color .3s;
}
.i-rail li::before {
  content: ''; position: absolute; left: -3px; top: 50%; transform: translateY(-50%);
  width: 5px; height: 5px; background: var(--hair); transition: background .3s, transform .3s;
}
.i-rail li.is-here { color: var(--sc-ink); }
.i-rail li.is-here::before { background: var(--ch); transform: translateY(-50%) scale(1.7); }
.i-rail li.is-past { color: var(--ink-2); }
.i-rail li.is-past::before { background: var(--ink-2); }

/* the translator. her thesis, stated in her own four lines, made operable:
   the raw thing on one side and what it becomes on the other */
.i-xlate { margin: 1.8em 0; border: 1px solid var(--hair); background: var(--plate); }
.i-xlate__bar {
  padding: 9px 14px; border-bottom: 1px solid var(--hair-2);
  font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ch);
}
.i-xlate__body { padding: clamp(14px, 2.4vw, 22px); display: grid; gap: 1px; }
.i-xlate__row {
  appearance: none; border: 0; width: 100%; text-align: left; cursor: pointer;
  display: grid; grid-template-columns: minmax(0,1fr) auto minmax(0,1fr);
  align-items: center; gap: 10px; padding: 12px 10px;
  background: transparent; color: var(--ink-2);
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(0.95rem, 0.9rem + 0.35vw, 1.15rem); line-height: 1.3; letter-spacing: -0.02em;
  transition: background .22s, color .22s;
}
.i-xlate__row:hover { background: var(--elev); }
.i-xlate__row.is-on { background: var(--elev); color: var(--sc-ink); }
.i-xlate__to { color: var(--ink-2); }
.i-xlate__row.is-on .i-xlate__to { color: var(--ch); }
.i-xlate__arrow {
  justify-self: center; padding: 0 14px;
  font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--faint);
  transition: color .22s, transform .3s var(--sc-ease-out, ease);
}
.i-xlate__row.is-on .i-xlate__arrow { color: var(--ch); }
@media (max-width: 560px) {
  .i-xlate__row { grid-template-columns: minmax(0,1fr); gap: 4px; }
  .i-xlate__arrow { justify-self: start; padding: 2px 0; }
}

@media (prefers-reduced-motion: reduce) {
  .i-claim [data-turn] { opacity: 1; transform: none; transition: none; }
  .i-rig *, .i-tuner *, .i-about * { transition-duration: .001ms !important; }
}

/* =========================================================================
   Layout corrections — 2026-08-29

   Three things the added instruments exposed rather than caused:
   the opened case study used barely a third of the screen, the control that
   opens it had become the quietest thing on a loud card, and the About essay
   sat in one narrow column with all of its slack dumped on the right.
   ========================================================================= */

/* ------------------------------------------------ the opened case study
   The writing was set at 62ch inside a 945px block inside a 1440px page,
   which is a third of the width and 2,253px of height for a single case.
   Reclaiming the numeral gutter and moving the section labels into a
   left-hand spine roughly halves the scroll and puts the prose on a proper
   measure instead of a column of three-word lines. */

.case__row {
  display: grid;
  grid-template-columns: clamp(96px, 10vw, 152px) minmax(0, 1fr);
  column-gap: clamp(20px, 3vw, 48px);
  align-items: start;
  padding-top: clamp(20px, 2.6vh, 30px);
}
.case__row + .case__row { border-top: 1px solid var(--hair-2); }
.case .case__row h4 { margin: 0; padding-top: 2px; line-height: 1.6; }
.case__rowbody { min-width: 0; }

/* a longer measure now that there is width to spend, and the staccato
   one-line paragraphs sit as a stanza rather than as separate blocks */
.case p, .case ul { max-width: 74ch; }
.case .case__rowbody p + p { margin-top: 0.42em; }
.case .lede { max-width: 30ch; margin-bottom: 0.3em; }
.case__note { max-width: 74ch; }

/* the wide passages — lists of specs and the figure rows — can run in two
   columns once the block is this wide, because each item is one line */
@media (min-width: 1040px) {
  .case__rowbody ul { columns: 2; column-gap: clamp(24px, 3vw, 52px); }
  .case__rowbody ul li { break-inside: avoid; }
}
@media (max-width: 719px) {
  .case__row { grid-template-columns: minmax(0, 1fr); }
  .case .case__row h4 { margin-bottom: 8px; }
}

/* ------------------------------------------------------- the open control
   Same glass pane the top bar and the footer already use. On a card that now
   carries an instrument, a hairline-underlined caption was invisible. */
.expand.btn {
  border: 1px solid var(--ch);
  height: 42px; padding: 0 24px; margin-top: 22px;
  color: var(--ch); font-size: 10px;
}
.expand.btn:hover, .expand.btn:focus-visible { color: #0B0B0A; border-bottom-color: var(--ch); }
.expand.btn[aria-expanded="true"] > span::after { content: ' ×'; }

/* =========================================================================
   Corner consistency — 2026-08-29

   The system's radius tokens are all 0, and every button on the page is
   square: Say hello, Email me, LinkedIn, Read the case. The discipline
   filters and the card chips were the only pills on the site, so they were
   the exception rather than the rule — squaring them settles it in the
   direction the rest of the page already went.
   ========================================================================= */
/* Corners, settled as a rule rather than a blanket: square is for things
   that do something (Say hello, Read the case), the pill is for things that
   name something (a discipline filter, a card's tags). That keeps actions and
   taxonomy visually separate, which is worth more than one shared shape. */
.disc, .object__chips b { border-radius: var(--sc-r-pill); }

/* and the filters are coloured before they are touched — the four words under
   the wordmark already are, and a row of identical grey chips says "one
   control" where four disciplines were meant */
.disc { color: var(--wc); border-color: color-mix(in oklab, var(--wc) 32%, transparent); }
.disc:hover { border-color: var(--wc); }
.disc .ct { opacity: .6; }
.disc-clear { --wc: var(--sc-accent); }

/* =========================================================================
   03 · the route, not the contents — 2026-08-29

   The first version of this instrument compared two pictures of a page and
   the "after" was the busier one, which reads as "we added things" and,
   worse, as less considered. The finding was never about what went onto the
   page. It was about how much work was left to the customer.

   So both states show the same page, and what changes is the line drawn
   over it: before, the route keeps leaving the collection for a product page
   and coming back; after, it stays inside and is short. The improvement is
   the emptier picture, which is the only way this can look like a decision
   rather than an addition.
   ========================================================================= */
.i-path svg { display: block; width: 100%; height: auto; }

.i-path__frame { fill: none; stroke: var(--hair); stroke-width: 1; }
.i-path__title { fill: var(--sc-ink); opacity: .55; }
.i-path__cards rect { fill: var(--elev); }

/* the added guidance is deliberately quiet: it is not the point */
.i-path__added rect { fill: var(--ch); opacity: 0; transition: opacity .45s var(--sc-ease-out, ease); }
.i-path.is-after .i-path__added rect { opacity: .34; }

.i-path__away rect { fill: none; stroke: var(--hair); stroke-width: 1; stroke-dasharray: 3 4; transition: opacity .45s; }
.i-path__away text {
  fill: var(--faint); font-family: var(--sc-font-mono); font-size: 9px;
  letter-spacing: .12em; text-transform: uppercase; text-anchor: middle;
  transition: opacity .45s;
}
.i-path.is-after .i-path__away { opacity: .18; }

.i-path__line {
  fill: none; stroke: var(--ch); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.i-path__stops circle { fill: var(--sc-canvas); stroke: var(--ch); stroke-width: 1.5; }
.i-path__stops text {
  fill: var(--ch); font-family: var(--sc-font-mono); font-weight: 700; font-size: 9px;
  text-anchor: middle; dominant-baseline: middle;
}

.i-path__legend { display: flex; gap: 2px; margin: 14px 0 0; }
.i-path__tab {
  appearance: none; border: 1px solid var(--hair); background: none; cursor: pointer;
  padding: 7px 16px;
  font-family: var(--sc-font-mono); font-size: 10px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-2);
  transition: color .22s, border-color .22s, background .22s;
}
.i-path__tab:hover { color: var(--ch); border-color: var(--ch); }
.i-path__tab.is-on { color: var(--sc-accent-ink); background: var(--ch); border-color: var(--ch); }



/* =========================================================================
   The three questions — 2026-08-29

   The figures this case used to print were the business's, so they came out.
   What replaced them is better than a redaction: the questions the team could
   answer each week once the system existed. A question is methodology, and it
   carries the weight the numbers were carrying without disclosing anything.
   ========================================================================= */
.asks { list-style: none; counter-reset: ask; margin: 18px 0; padding: 0; display: grid; gap: 1px; max-width: 68ch; }
.asks li {
  counter-increment: ask;
  display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 0 14px;
  padding: 14px 14px 15px; background: var(--plate);
}
.asks li::before {
  content: counter(ask, decimal-leading-zero);
  grid-row: 1 / span 2;
  font-family: var(--sc-font-mono); font-weight: 700; font-size: 10px;
  letter-spacing: .1em; color: var(--ch); padding-top: 3px;
  font-variant-numeric: tabular-nums;
}
.asks__q {
  margin: 0 0 5px;
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1rem, .95rem + .45vw, 1.22rem); line-height: 1.25;
  letter-spacing: -.02em; color: var(--sc-ink);
}
.asks__a { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ink-2); max-width: 62ch; }
@media (max-width: 560px) {
  .asks li { grid-template-columns: minmax(0, 1fr); }
  .asks li::before { grid-row: auto; padding-top: 0; margin-bottom: 6px; }
}

/* the disclosure note is a condition of the work, not an apology for it */
.case__guard {
  margin-top: 14px; padding-left: 14px;
  border-left: 1px solid var(--hair);
  font-size: 13px; color: var(--sc-ink-soft); max-width: 62ch;
}

/* =========================================================================
   Analytical thinking — the rail scrolls sideways — 2026-08-29

   The strip was laid out horizontally but driven by vertical scroll: the
   section pinned for nearly three screens and panned as you went down.
   Watching people use it settled the question — a horizontal row is read as
   an invitation to swipe sideways, and the gesture did nothing.

   It is now a real horizontal scroller. Every native gesture works because
   nothing is intercepted: trackpad sideways, shift-wheel, touch swipe, the
   scrollbar, tab. Drag and the two arrows exist for a plain mouse, which has
   no sideways gesture at all. Vertical scrolling is left completely alone —
   the previous version's problem was hijacking, and replacing one hijack
   with another would not be a fix.
   ========================================================================= */
.railstage {
  height: auto;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;   /* no accidental browser back-swipe */
  scroll-snap-type: x proximity;
  padding-block: clamp(48px, 9vh, 96px);
  cursor: grab;
  scrollbar-width: thin;
  scrollbar-color: var(--hair) transparent;
}
.railstage.is-dragging { cursor: grabbing; scroll-snap-type: none; scroll-behavior: auto; }
.railstage::-webkit-scrollbar { height: 6px; }
.railstage::-webkit-scrollbar-track { background: transparent; }
.railstage::-webkit-scrollbar-thumb { background: var(--hair); }
.railstage::-webkit-scrollbar-thumb:hover { background: var(--ch); }

.chartrail { align-items: stretch; }
.chartrail__lead, .plate, .chartrail__trail { scroll-snap-align: center; }
.chartrail__lead { scroll-snap-align: start; }
/* while dragging, a click on a plate would be an accident */
.railstage.is-dragging .plate { pointer-events: none; }

.railbar {
  max-width: var(--pagew); margin-inline: auto;
  padding-inline: var(--sc-gutter); padding-bottom: clamp(32px, 7vh, 72px);
  display: grid; gap: 14px;
}
.railbar__meter { height: 1px; background: var(--hair); position: relative; overflow: hidden; }
.railbar__meter span {
  position: absolute; inset: 0; transform-origin: left; transform: scaleX(0);
  background: var(--ch); transition: transform .18s linear;
}
.railbar__ctrl { display: flex; align-items: center; gap: 10px; }
.railbar__hint { color: var(--faint); margin-right: auto; }
.railbar__btn {
  appearance: none; cursor: pointer; background: none;
  border: 1px solid var(--hair); border-radius: 0;
  width: 42px; height: 34px; color: var(--ink-2); font-size: 14px; line-height: 1;
  transition: color .2s, border-color .2s;
}
.railbar__btn:hover:not([disabled]) { color: var(--ch); border-color: var(--ch); }
.railbar__btn[disabled] { opacity: .3; cursor: default; }

@media (prefers-reduced-motion: reduce) { .railstage { scroll-behavior: auto; } }

/* =========================================================================
   About, set as a book — 2026-08-29

   This is the only piece of writing on the site that is a story rather than
   an argument, and it was running as one narrow column down a wide page.
   Setting it as spreads the reader turns gives it the pacing a story wants,
   and gives the reader a sense of how far they have come — which, in an
   essay about leaving somewhere, is not decoration.

   The pagination is CSS multi-column: the browser breaks the text into
   columns of its own accord, so it reflows at any size and nothing is ever
   clipped. Turning a page translates the flow by exactly one spread.

   Pagination is a real preference, not a universal improvement, so the
   switch back to one continuous page is a first-class control rather than
   an accessibility afterthought.
   ========================================================================= */
.book {
  margin-top: clamp(20px, 4vh, 34px);
  border: 1px solid var(--hair);
  background: var(--plate);
}
.book__head, .book__foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px 20px; flex-wrap: wrap;
  padding: 11px clamp(14px, 2.4vw, 26px);
}
.book__head { border-bottom: 1px solid var(--hair-2); color: var(--faint); }
.book__title { color: var(--ch); }
.book__foot { border-top: 1px solid var(--hair-2); }

.book__leaf { overflow: hidden; padding: clamp(22px, 4vw, 44px); }
.book__flow {
  height: clamp(420px, 62vh, 660px);
  columns: 2;
  column-gap: clamp(28px, 5vw, 72px);
  column-fill: auto;
  column-rule: 1px solid var(--hair-2);
  transition: transform .62s cubic-bezier(.22, 1, .36, 1);
  will-change: transform;
}
@media (max-width: 760px) { .book__flow { columns: 1; height: clamp(400px, 66vh, 560px); } }

/* inside the book the essay is plain running text again — the two-track
   treatment was solving the problem this replaces */
.book .about__body { max-width: none; margin-top: 0; }
.book .about__body > p { max-width: none; }
.book .about__body .about__beat { max-width: none; margin: 1.2em 0; border: 0; padding: 0; }
.book .i-xlate { margin: 1.4em 0; break-inside: avoid; }

/* a page break should never cut a heading-ish line from what follows it */
.book .about__beat, .book .i-xlate__row { break-inside: avoid; }

.book__index { display: flex; flex-wrap: wrap; gap: 2px; margin-right: auto; }
.book__index button {
  appearance: none; background: none; border: 0; cursor: pointer;
  padding: 5px 9px;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
  border-bottom: 1px solid transparent;
  transition: color .22s, border-color .22s;
}
.book__index button:hover { color: var(--ink-2); }
.book__index button.is-here { color: var(--ch); border-bottom-color: var(--ch); }

.book__ctrl { display: flex; align-items: center; gap: 8px; }
.book__btn {
  appearance: none; cursor: pointer; background: none;
  border: 1px solid var(--hair); border-radius: 0;
  width: 40px; height: 32px; color: var(--ink-2); font-size: 13px; line-height: 1;
  transition: color .2s, border-color .2s;
}
.book__btn:hover:not([disabled]) { color: var(--ch); border-color: var(--ch); }
.book__btn[disabled] { opacity: .3; cursor: default; }
.book__flat {
  appearance: none; cursor: pointer; background: none; border: 0;
  border-bottom: 1px solid var(--hair); padding: 4px 0; margin-left: 10px;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
  transition: color .2s, border-color .2s;
}
.book__flat:hover { color: var(--ch); border-bottom-color: var(--ch); }

/* one continuous page: the book stops being a book */
.book.is-flat .book__leaf { overflow: visible; }
.book.is-flat .book__flow { height: auto; columns: 1; transform: none !important; column-rule: 0; }
.book.is-flat .book__ctrl .book__btn { display: none; }
.book.is-flat .about__body { max-width: 66ch; }
.book.is-flat .book__flat { color: var(--ch); border-bottom-color: var(--ch); }

@media (prefers-reduced-motion: reduce) { .book__flow { transition: none; } }

/* ============================================== 03 · thinking, as a tuner

   The four essays were four identical rows, so nothing asked to be stopped
   at. They are not really a list: they are four positions of one move —
   replacing the question everyone asks with a better one. A dial says that;
   a stack of rows says only "there are four".

   Every word here is the existing copy, re-paced. Nothing was rewritten.
   ============================================================== */
.i-tuner { margin-top: clamp(2rem, 5vh, 3.5rem); }
.i-tuner__frame {
  border-top: 1px solid var(--ch);
  display: grid; gap: clamp(20px, 4vw, 48px);
  padding-top: clamp(22px, 4vh, 34px);
}
@media (min-width: 860px) { .i-tuner__frame { grid-template-columns: 158px minmax(0, 1fr); } }

/* the detents. four positions, and the reader can feel where they are */
.i-detents { display: grid; gap: 1px; align-content: start; }
.i-detent {
  appearance: none; border: 0; cursor: pointer; width: 100%; text-align: left;
  display: flex; align-items: baseline; gap: 12px; padding: 10px 12px;
  background: transparent; color: var(--faint);
  font-family: var(--sc-font-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase;
  border-left: 1px solid var(--hair); white-space: nowrap;
  transition: color .22s, border-color .22s, background .22s;
}
.i-detent:hover { color: var(--ink-2); }
.i-detent.is-on { color: var(--ch); border-left-color: var(--ch); background: color-mix(in oklab, var(--ch) 8%, transparent); }
.i-detent__n { font-weight: 700; font-variant-numeric: tabular-nums; }
.i-detent__k { font-size: 9px; letter-spacing: 0.1em; }

.i-claim { min-height: clamp(210px, 30vh, 300px); display: grid; align-content: start; }
.i-claim__ex {
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1.3rem, 1rem + 1.9vw, 2.6rem); line-height: 1.18; letter-spacing: -0.03em;
  color: var(--sc-ink); max-width: 24ch; margin: 0;
}
/* the turn arrives a beat after the assumption, because that is how the
   sentence is built */
.i-claim__ex + .i-claim__ex { margin-top: 0.4em; color: var(--ink-2); }
.i-claim__title {
  margin: clamp(20px, 3vh, 30px) 0 0;
  font-family: var(--sc-font-mono); font-size: 10.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ch); max-width: 48ch; line-height: 1.8;
}
.i-claim [data-turn] { opacity: 0; transform: translateY(10px); transition: opacity .5s var(--sc-ease-out, ease), transform .5s var(--sc-ease-out, ease); }
.i-claim.is-turned [data-turn] { opacity: 1; transform: none; }
.i-claim.is-turned [data-turn="2"] { transition-delay: .09s; }

/* ============================================== 06 · about, as a journey

   The longest piece of writing on the site had no way in and no way to
   measure progress. The rail is not decoration: it is the essay's own
   structure, and it is the only place the reader can see how far the story
   has travelled — which is the story.
   ============================================================== */
.i-about { display: grid; gap: clamp(20px, 4vw, 56px); }
@media (min-width: 900px) { .i-about { grid-template-columns: 168px minmax(0, 1fr); align-items: start; } }

.i-rail { display: none; }
@media (min-width: 900px) {
  .i-rail { display: block; position: sticky; top: calc(var(--bar) + 28px); }
}
.i-rail ol { list-style: none; margin: 0; padding: 0; border-left: 1px solid var(--hair); }
.i-rail li {
  position: relative; padding: 9px 0 9px 18px;
  font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--faint);
  transition: color .3s;
}
.i-rail li::before {
  content: ''; position: absolute; left: -3px; top: 50%; transform: translateY(-50%);
  width: 5px; height: 5px; background: var(--hair); transition: background .3s, transform .3s;
}
.i-rail li.is-here { color: var(--sc-ink); }
.i-rail li.is-here::before { background: var(--ch); transform: translateY(-50%) scale(1.7); }
.i-rail li.is-past { color: var(--ink-2); }
.i-rail li.is-past::before { background: var(--ink-2); }

/* the translator. her thesis, stated in her own four lines, made operable:
   the raw thing on one side and what it becomes on the other */
.i-xlate { margin: 1.8em 0; border: 1px solid var(--hair); background: var(--plate); }
.i-xlate__bar {
  padding: 9px 14px; border-bottom: 1px solid var(--hair-2);
  font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ch);
}
.i-xlate__body { padding: clamp(14px, 2.4vw, 22px); display: grid; gap: 1px; }
.i-xlate__row {
  appearance: none; border: 0; width: 100%; text-align: left; cursor: pointer;
  display: grid; grid-template-columns: minmax(0,1fr) auto minmax(0,1fr);
  align-items: center; gap: 10px; padding: 12px 10px;
  background: transparent; color: var(--ink-2);
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(0.95rem, 0.9rem + 0.35vw, 1.15rem); line-height: 1.3; letter-spacing: -0.02em;
  transition: background .22s, color .22s;
}
.i-xlate__row:hover { background: var(--elev); }
.i-xlate__row.is-on { background: var(--elev); color: var(--sc-ink); }
.i-xlate__to { color: var(--ink-2); }
.i-xlate__row.is-on .i-xlate__to { color: var(--ch); }
.i-xlate__arrow {
  justify-self: center; padding: 0 14px;
  font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--faint);
  transition: color .22s, transform .3s var(--sc-ease-out, ease);
}
.i-xlate__row.is-on .i-xlate__arrow { color: var(--ch); }
@media (max-width: 560px) {
  .i-xlate__row { grid-template-columns: minmax(0,1fr); gap: 4px; }
  .i-xlate__arrow { justify-self: start; padding: 2px 0; }
}

@media (prefers-reduced-motion: reduce) {
  .i-claim [data-turn] { opacity: 1; transform: none; transition: none; }
  .i-rig *, .i-tuner *, .i-about * { transition-duration: .001ms !important; }
}

/* =========================================================================
   Layout corrections — 2026-08-29

   Three things the added instruments exposed rather than caused:
   the opened case study used barely a third of the screen, the control that
   opens it had become the quietest thing on a loud card, and the About essay
   sat in one narrow column with all of its slack dumped on the right.
   ========================================================================= */

/* ------------------------------------------------ the opened case study
   The writing was set at 62ch inside a 945px block inside a 1440px page,
   which is a third of the width and 2,253px of height for a single case.
   Reclaiming the numeral gutter and moving the section labels into a
   left-hand spine roughly halves the scroll and puts the prose on a proper
   measure instead of a column of three-word lines. */

.case__row {
  display: grid;
  grid-template-columns: clamp(96px, 10vw, 152px) minmax(0, 1fr);
  column-gap: clamp(20px, 3vw, 48px);
  align-items: start;
  padding-top: clamp(20px, 2.6vh, 30px);
}
.case__row + .case__row { border-top: 1px solid var(--hair-2); }
.case .case__row h4 { margin: 0; padding-top: 2px; line-height: 1.6; }
.case__rowbody { min-width: 0; }

/* a longer measure now that there is width to spend, and the staccato
   one-line paragraphs sit as a stanza rather than as separate blocks */
.case p, .case ul { max-width: 74ch; }
.case .case__rowbody p + p { margin-top: 0.42em; }
.case .lede { max-width: 30ch; margin-bottom: 0.3em; }
.case__note { max-width: 74ch; }

/* the wide passages — lists of specs and the figure rows — can run in two
   columns once the block is this wide, because each item is one line */
@media (min-width: 1040px) {
  .case__rowbody ul { columns: 2; column-gap: clamp(24px, 3vw, 52px); }
  .case__rowbody ul li { break-inside: avoid; }
}
@media (max-width: 719px) {
  .case__row { grid-template-columns: minmax(0, 1fr); }
  .case .case__row h4 { margin-bottom: 8px; }
}

/* ------------------------------------------------------- the open control
   Same glass pane the top bar and the footer already use. On a card that now
   carries an instrument, a hairline-underlined caption was invisible. */
.expand.btn {
  border: 1px solid var(--ch);
  height: 42px; padding: 0 24px; margin-top: 22px;
  color: var(--ch); font-size: 10px;
}
.expand.btn:hover, .expand.btn:focus-visible { color: #0B0B0A; border-bottom-color: var(--ch); }
.expand.btn[aria-expanded="true"] > span::after { content: ' ×'; }

/* =========================================================================
   Corner consistency — 2026-08-29

   The system's radius tokens are all 0, and every button on the page is
   square: Say hello, Email me, LinkedIn, Read the case. The discipline
   filters and the card chips were the only pills on the site, so they were
   the exception rather than the rule — squaring them settles it in the
   direction the rest of the page already went.
   ========================================================================= */
/* Corners, settled as a rule rather than a blanket: square is for things
   that do something (Say hello, Read the case), the pill is for things that
   name something (a discipline filter, a card's tags). That keeps actions and
   taxonomy visually separate, which is worth more than one shared shape. */
.disc, .object__chips b { border-radius: var(--sc-r-pill); }

/* and the filters are coloured before they are touched — the four words under
   the wordmark already are, and a row of identical grey chips says "one
   control" where four disciplines were meant */
.disc { color: var(--wc); border-color: color-mix(in oklab, var(--wc) 32%, transparent); }
.disc:hover { border-color: var(--wc); }
.disc .ct { opacity: .6; }
.disc-clear { --wc: var(--sc-accent); }

/* =========================================================================
   03 · the route, not the contents — 2026-08-29

   The first version of this instrument compared two pictures of a page and
   the "after" was the busier one, which reads as "we added things" and,
   worse, as less considered. The finding was never about what went onto the
   page. It was about how much work was left to the customer.

   So both states show the same page, and what changes is the line drawn
   over it: before, the route keeps leaving the collection for a product page
   and coming back; after, it stays inside and is short. The improvement is
   the emptier picture, which is the only way this can look like a decision
   rather than an addition.
   ========================================================================= */
.i-path svg { display: block; width: 100%; height: auto; }

.i-path__frame { fill: none; stroke: var(--hair); stroke-width: 1; }
.i-path__title { fill: var(--sc-ink); opacity: .55; }
.i-path__cards rect { fill: var(--elev); }

/* the added guidance is deliberately quiet: it is not the point */
.i-path__added rect { fill: var(--ch); opacity: 0; transition: opacity .45s var(--sc-ease-out, ease); }
.i-path.is-after .i-path__added rect { opacity: .34; }

.i-path__away rect { fill: none; stroke: var(--hair); stroke-width: 1; stroke-dasharray: 3 4; transition: opacity .45s; }
.i-path__away text {
  fill: var(--faint); font-family: var(--sc-font-mono); font-size: 9px;
  letter-spacing: .12em; text-transform: uppercase; text-anchor: middle;
  transition: opacity .45s;
}
.i-path.is-after .i-path__away { opacity: .18; }

.i-path__line {
  fill: none; stroke: var(--ch); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.i-path__stops circle { fill: var(--sc-canvas); stroke: var(--ch); stroke-width: 1.5; }
.i-path__stops text {
  fill: var(--ch); font-family: var(--sc-font-mono); font-weight: 700; font-size: 9px;
  text-anchor: middle; dominant-baseline: middle;
}

.i-path__legend { display: flex; gap: 2px; margin: 14px 0 0; }
.i-path__tab {
  appearance: none; border: 1px solid var(--hair); background: none; cursor: pointer;
  padding: 7px 16px;
  font-family: var(--sc-font-mono); font-size: 10px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-2);
  transition: color .22s, border-color .22s, background .22s;
}
.i-path__tab:hover { color: var(--ch); border-color: var(--ch); }
.i-path__tab.is-on { color: var(--sc-accent-ink); background: var(--ch); border-color: var(--ch); }



/* =========================================================================
   The three questions — 2026-08-29

   The figures this case used to print were the business's, so they came out.
   What replaced them is better than a redaction: the questions the team could
   answer each week once the system existed. A question is methodology, and it
   carries the weight the numbers were carrying without disclosing anything.
   ========================================================================= */
.asks { list-style: none; counter-reset: ask; margin: 18px 0; padding: 0; display: grid; gap: 1px; max-width: 68ch; }
.asks li {
  counter-increment: ask;
  display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 0 14px;
  padding: 14px 14px 15px; background: var(--plate);
}
.asks li::before {
  content: counter(ask, decimal-leading-zero);
  grid-row: 1 / span 2;
  font-family: var(--sc-font-mono); font-weight: 700; font-size: 10px;
  letter-spacing: .1em; color: var(--ch); padding-top: 3px;
  font-variant-numeric: tabular-nums;
}
.asks__q {
  margin: 0 0 5px;
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1rem, .95rem + .45vw, 1.22rem); line-height: 1.25;
  letter-spacing: -.02em; color: var(--sc-ink);
}
.asks__a { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ink-2); max-width: 62ch; }
@media (max-width: 560px) {
  .asks li { grid-template-columns: minmax(0, 1fr); }
  .asks li::before { grid-row: auto; padding-top: 0; margin-bottom: 6px; }
}

/* the disclosure note is a condition of the work, not an apology for it */
.case__guard {
  margin-top: 14px; padding-left: 14px;
  border-left: 1px solid var(--hair);
  font-size: 13px; color: var(--sc-ink-soft); max-width: 62ch;
}

/* =========================================================================
   Analytical thinking — the rail scrolls sideways — 2026-08-29

   The strip was laid out horizontally but driven by vertical scroll: the
   section pinned for nearly three screens and panned as you went down.
   Watching people use it settled the question — a horizontal row is read as
   an invitation to swipe sideways, and the gesture did nothing.

   It is now a real horizontal scroller. Every native gesture works because
   nothing is intercepted: trackpad sideways, shift-wheel, touch swipe, the
   scrollbar, tab. Drag and the two arrows exist for a plain mouse, which has
   no sideways gesture at all. Vertical scrolling is left completely alone —
   the previous version's problem was hijacking, and replacing one hijack
   with another would not be a fix.
   ========================================================================= */
.railstage {
  height: auto;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;   /* no accidental browser back-swipe */
  scroll-snap-type: x proximity;
  padding-block: clamp(48px, 9vh, 96px);
  cursor: grab;
  scrollbar-width: thin;
  scrollbar-color: var(--hair) transparent;
}
.railstage.is-dragging { cursor: grabbing; scroll-snap-type: none; scroll-behavior: auto; }
.railstage::-webkit-scrollbar { height: 6px; }
.railstage::-webkit-scrollbar-track { background: transparent; }
.railstage::-webkit-scrollbar-thumb { background: var(--hair); }
.railstage::-webkit-scrollbar-thumb:hover { background: var(--ch); }

.chartrail { align-items: stretch; }
.chartrail__lead, .plate, .chartrail__trail { scroll-snap-align: center; }
.chartrail__lead { scroll-snap-align: start; }
/* while dragging, a click on a plate would be an accident */
.railstage.is-dragging .plate { pointer-events: none; }

.railbar {
  max-width: var(--pagew); margin-inline: auto;
  padding-inline: var(--sc-gutter); padding-bottom: clamp(32px, 7vh, 72px);
  display: grid; gap: 14px;
}
.railbar__meter { height: 1px; background: var(--hair); position: relative; overflow: hidden; }
.railbar__meter span {
  position: absolute; inset: 0; transform-origin: left; transform: scaleX(0);
  background: var(--ch); transition: transform .18s linear;
}
.railbar__ctrl { display: flex; align-items: center; gap: 10px; }
.railbar__hint { color: var(--faint); margin-right: auto; }
.railbar__btn {
  appearance: none; cursor: pointer; background: none;
  border: 1px solid var(--hair); border-radius: 0;
  width: 42px; height: 34px; color: var(--ink-2); font-size: 14px; line-height: 1;
  transition: color .2s, border-color .2s;
}
.railbar__btn:hover:not([disabled]) { color: var(--ch); border-color: var(--ch); }
.railbar__btn[disabled] { opacity: .3; cursor: default; }

@media (prefers-reduced-motion: reduce) { .railstage { scroll-behavior: auto; } }

/* =========================================================================
   About, set as a book — 2026-08-29

   This is the only piece of writing on the site that is a story rather than
   an argument, and it was running as one narrow column down a wide page.
   Setting it as spreads the reader turns gives it the pacing a story wants,
   and gives the reader a sense of how far they have come — which, in an
   essay about leaving somewhere, is not decoration.

   The pagination is CSS multi-column: the browser breaks the text into
   columns of its own accord, so it reflows at any size and nothing is ever
   clipped. Turning a page translates the flow by exactly one spread.

   Pagination is a real preference, not a universal improvement, so the
   switch back to one continuous page is a first-class control rather than
   an accessibility afterthought.
   ========================================================================= */
.book {
  margin-top: clamp(20px, 4vh, 34px);
  border: 1px solid var(--hair);
  background: var(--plate);
}
.book__head, .book__foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px 20px; flex-wrap: wrap;
  padding: 11px clamp(14px, 2.4vw, 26px);
}
.book__head { border-bottom: 1px solid var(--hair-2); color: var(--faint); }
.book__title { color: var(--ch); }
.book__foot { border-top: 1px solid var(--hair-2); }

.book__leaf { overflow: hidden; padding: clamp(22px, 4vw, 44px); }
.book__flow {
  height: clamp(420px, 62vh, 660px);
  columns: 2;
  column-gap: clamp(28px, 5vw, 72px);
  column-fill: auto;
  column-rule: 1px solid var(--hair-2);
  transition: transform .62s cubic-bezier(.22, 1, .36, 1);
  will-change: transform;
}
@media (max-width: 760px) { .book__flow { columns: 1; height: clamp(400px, 66vh, 560px); } }

/* inside the book the essay is plain running text again — the two-track
   treatment was solving the problem this replaces */
.book .about__body { max-width: none; margin-top: 0; }
.book .about__body > p { max-width: none; }
.book .about__body .about__beat { max-width: none; margin: 1.2em 0; border: 0; padding: 0; }
.book .i-xlate { margin: 1.4em 0; break-inside: avoid; }

/* a page break should never cut a heading-ish line from what follows it */
.book .about__beat, .book .i-xlate__row { break-inside: avoid; }

.book__index { display: flex; flex-wrap: wrap; gap: 2px; margin-right: auto; }
.book__index button {
  appearance: none; background: none; border: 0; cursor: pointer;
  padding: 5px 9px;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
  border-bottom: 1px solid transparent;
  transition: color .22s, border-color .22s;
}
.book__index button:hover { color: var(--ink-2); }
.book__index button.is-here { color: var(--ch); border-bottom-color: var(--ch); }

.book__ctrl { display: flex; align-items: center; gap: 8px; }
.book__btn {
  appearance: none; cursor: pointer; background: none;
  border: 1px solid var(--hair); border-radius: 0;
  width: 40px; height: 32px; color: var(--ink-2); font-size: 13px; line-height: 1;
  transition: color .2s, border-color .2s;
}
.book__btn:hover:not([disabled]) { color: var(--ch); border-color: var(--ch); }
.book__btn[disabled] { opacity: .3; cursor: default; }
.book__flat {
  appearance: none; cursor: pointer; background: none; border: 0;
  border-bottom: 1px solid var(--hair); padding: 4px 0; margin-left: 10px;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
  transition: color .2s, border-color .2s;
}
.book__flat:hover { color: var(--ch); border-bottom-color: var(--ch); }

/* one continuous page: the book stops being a book */
.book.is-flat .book__leaf { overflow: visible; }
.book.is-flat .book__flow { height: auto; columns: 1; transform: none !important; column-rule: 0; }
.book.is-flat .book__ctrl .book__btn { display: none; }
.book.is-flat .about__body { max-width: 66ch; }
.book.is-flat .book__flat { color: var(--ch); border-bottom-color: var(--ch); }

@media (prefers-reduced-motion: reduce) { .book__flow { transition: none; } }

/* =========================================================================
   04 · the narrowing — 2026-08-30

   The first instrument here drew first purchase to second, which implied a
   finding the analysis did not actually license. What the work produced was
   discipline: several plausible hypotheses went in, each was held to the same
   threshold, and none was promoted into a planning rule. That is a valuable
   outcome and it should look like one.

   The narrowing is the geometry — each band is narrower than the one above —
   so the diagram states its own argument without a caption explaining it.
   One accent, on the threshold, because the threshold is the point.

   No figures appear here and none are implied. Every state is qualitative.
   ========================================================================= */
.narrow { display: grid; justify-items: center; }
.narrow__stage { width: 100%; }
.narrow__stage--2 { width: 84%; }
.narrow__stage--3 { width: 66%; }
.narrow__stage--4 { width: 52%; }
@media (max-width: 720px) {
  .narrow__stage--2, .narrow__stage--3, .narrow__stage--4 { width: 100%; }
}

.narrow__h {
  margin: 0 0 10px;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .15em; text-transform: uppercase; color: var(--faint);
}
.narrow__h span { color: var(--oc, var(--ch)); font-weight: 700; margin-right: 8px; }

.narrow__rows { display: grid; gap: 1px; }
.hyp {
  appearance: none; border: 0; width: 100%; text-align: left; cursor: pointer;
  display: grid; grid-template-columns: 26px minmax(0, 1fr); align-items: baseline; gap: 12px;
  padding: 13px 14px; background: var(--elev); color: var(--sc-ink);
  transition: background .22s, opacity .22s, color .22s;
}
.hyp__n { font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: .1em; color: var(--faint); }
.hyp__t { font-family: var(--sc-font-display); font-weight: 500; font-size: clamp(.98rem, .92rem + .4vw, 1.14rem); line-height: 1.3; letter-spacing: -.02em; }
.hyp:hover { background: color-mix(in oklab, var(--oc, var(--ch)) 12%, var(--elev)); }
.hyp.is-on { background: color-mix(in oklab, var(--oc, var(--ch)) 22%, var(--elev)); }
.hyp.is-on .hyp__n { color: var(--oc, var(--ch)); }
.hyp.is-dim { opacity: .32; }

/* the connectors: four strands in, one out */
.narrow__link { display: flex; justify-content: center; gap: 46px; margin: 0; height: 26px; }
.narrow__link span { width: 1px; background: var(--hair); transition: background .25s, opacity .25s; }
.narrow__link span.is-on { background: var(--oc, var(--ch)); }
.narrow__link span.is-off { opacity: .25; }

.narrow__chips, .narrow__gate, .narrow__out { display: flex; flex-wrap: wrap; gap: 1px; }
.narrow__chips span, .narrow__out span {
  flex: 1 1 auto; padding: 10px 12px; background: var(--elev);
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2);
}

/* the one accent on the page belongs to the threshold */
.narrow__gate { border: 1px solid var(--oc, var(--ch)); gap: 0; }
.narrow__gate span {
  flex: 1 1 auto; padding: 12px; text-align: center;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--oc, var(--ch));
}
.narrow__gate span + span { border-left: 1px solid color-mix(in oklab, var(--oc, var(--ch)) 34%, transparent); }
@media (max-width: 720px) {
  .narrow__gate span + span { border-left: 0; border-top: 1px solid color-mix(in oklab, var(--oc, var(--ch)) 34%, transparent); }
  .narrow__gate span, .narrow__chips span, .narrow__out span { flex: 1 1 100%; text-align: left; }
}
.narrow__out span { color: var(--sc-ink); background: transparent; border: 1px solid var(--hair); }

/* the detail panel: four questions, the last one set apart because it is the
   instruction the rest of the panel exists to justify */
.detail { margin-top: 26px; padding-top: 20px; border-top: 1px solid var(--hair); }
.detail__title {
  margin: 0 0 16px;
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1.05rem, .98rem + .5vw, 1.32rem); line-height: 1.25;
  letter-spacing: -.025em; color: var(--sc-ink);
}
.detail__grid { display: grid; gap: 16px; margin: 0; }
@media (min-width: 820px) { .detail__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 40px; } }
.detail__grid dt {
  margin: 0 0 5px;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
}
.detail__grid dd { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ink-2); max-width: 56ch; }
.detail__imp { grid-column: 1 / -1; padding-top: 14px; border-top: 1px solid var(--hair-2); }
.detail__imp dd { color: var(--oc, var(--ch)); font-family: var(--sc-font-mono); font-size: 11px; letter-spacing: .06em; }

/* ============================================== 03 · thinking, as a tuner

   The four essays were four identical rows, so nothing asked to be stopped
   at. They are not really a list: they are four positions of one move —
   replacing the question everyone asks with a better one. A dial says that;
   a stack of rows says only "there are four".

   Every word here is the existing copy, re-paced. Nothing was rewritten.
   ============================================================== */
.i-tuner { margin-top: clamp(2rem, 5vh, 3.5rem); }
.i-tuner__frame {
  border-top: 1px solid var(--ch);
  display: grid; gap: clamp(20px, 4vw, 48px);
  padding-top: clamp(22px, 4vh, 34px);
}
@media (min-width: 860px) { .i-tuner__frame { grid-template-columns: 158px minmax(0, 1fr); } }

/* the detents. four positions, and the reader can feel where they are */
.i-detents { display: grid; gap: 1px; align-content: start; }
.i-detent {
  appearance: none; border: 0; cursor: pointer; width: 100%; text-align: left;
  display: flex; align-items: baseline; gap: 12px; padding: 10px 12px;
  background: transparent; color: var(--faint);
  font-family: var(--sc-font-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase;
  border-left: 1px solid var(--hair); white-space: nowrap;
  transition: color .22s, border-color .22s, background .22s;
}
.i-detent:hover { color: var(--ink-2); }
.i-detent.is-on { color: var(--ch); border-left-color: var(--ch); background: color-mix(in oklab, var(--ch) 8%, transparent); }
.i-detent__n { font-weight: 700; font-variant-numeric: tabular-nums; }
.i-detent__k { font-size: 9px; letter-spacing: 0.1em; }

.i-claim { min-height: clamp(210px, 30vh, 300px); display: grid; align-content: start; }
.i-claim__ex {
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1.3rem, 1rem + 1.9vw, 2.6rem); line-height: 1.18; letter-spacing: -0.03em;
  color: var(--sc-ink); max-width: 24ch; margin: 0;
}
/* the turn arrives a beat after the assumption, because that is how the
   sentence is built */
.i-claim__ex + .i-claim__ex { margin-top: 0.4em; color: var(--ink-2); }
.i-claim__title {
  margin: clamp(20px, 3vh, 30px) 0 0;
  font-family: var(--sc-font-mono); font-size: 10.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ch); max-width: 48ch; line-height: 1.8;
}
.i-claim [data-turn] { opacity: 0; transform: translateY(10px); transition: opacity .5s var(--sc-ease-out, ease), transform .5s var(--sc-ease-out, ease); }
.i-claim.is-turned [data-turn] { opacity: 1; transform: none; }
.i-claim.is-turned [data-turn="2"] { transition-delay: .09s; }

/* ============================================== 06 · about, as a journey

   The longest piece of writing on the site had no way in and no way to
   measure progress. The rail is not decoration: it is the essay's own
   structure, and it is the only place the reader can see how far the story
   has travelled — which is the story.
   ============================================================== */
.i-about { display: grid; gap: clamp(20px, 4vw, 56px); }
@media (min-width: 900px) { .i-about { grid-template-columns: 168px minmax(0, 1fr); align-items: start; } }

.i-rail { display: none; }
@media (min-width: 900px) {
  .i-rail { display: block; position: sticky; top: calc(var(--bar) + 28px); }
}
.i-rail ol { list-style: none; margin: 0; padding: 0; border-left: 1px solid var(--hair); }
.i-rail li {
  position: relative; padding: 9px 0 9px 18px;
  font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--faint);
  transition: color .3s;
}
.i-rail li::before {
  content: ''; position: absolute; left: -3px; top: 50%; transform: translateY(-50%);
  width: 5px; height: 5px; background: var(--hair); transition: background .3s, transform .3s;
}
.i-rail li.is-here { color: var(--sc-ink); }
.i-rail li.is-here::before { background: var(--ch); transform: translateY(-50%) scale(1.7); }
.i-rail li.is-past { color: var(--ink-2); }
.i-rail li.is-past::before { background: var(--ink-2); }

/* the translator. her thesis, stated in her own four lines, made operable:
   the raw thing on one side and what it becomes on the other */
.i-xlate { margin: 1.8em 0; border: 1px solid var(--hair); background: var(--plate); }
.i-xlate__bar {
  padding: 9px 14px; border-bottom: 1px solid var(--hair-2);
  font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ch);
}
.i-xlate__body { padding: clamp(14px, 2.4vw, 22px); display: grid; gap: 1px; }
.i-xlate__row {
  appearance: none; border: 0; width: 100%; text-align: left; cursor: pointer;
  display: grid; grid-template-columns: minmax(0,1fr) auto minmax(0,1fr);
  align-items: center; gap: 10px; padding: 12px 10px;
  background: transparent; color: var(--ink-2);
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(0.95rem, 0.9rem + 0.35vw, 1.15rem); line-height: 1.3; letter-spacing: -0.02em;
  transition: background .22s, color .22s;
}
.i-xlate__row:hover { background: var(--elev); }
.i-xlate__row.is-on { background: var(--elev); color: var(--sc-ink); }
.i-xlate__to { color: var(--ink-2); }
.i-xlate__row.is-on .i-xlate__to { color: var(--ch); }
.i-xlate__arrow {
  justify-self: center; padding: 0 14px;
  font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--faint);
  transition: color .22s, transform .3s var(--sc-ease-out, ease);
}
.i-xlate__row.is-on .i-xlate__arrow { color: var(--ch); }
@media (max-width: 560px) {
  .i-xlate__row { grid-template-columns: minmax(0,1fr); gap: 4px; }
  .i-xlate__arrow { justify-self: start; padding: 2px 0; }
}

@media (prefers-reduced-motion: reduce) {
  .i-claim [data-turn] { opacity: 1; transform: none; transition: none; }
  .i-rig *, .i-tuner *, .i-about * { transition-duration: .001ms !important; }
}

/* =========================================================================
   Layout corrections — 2026-08-29

   Three things the added instruments exposed rather than caused:
   the opened case study used barely a third of the screen, the control that
   opens it had become the quietest thing on a loud card, and the About essay
   sat in one narrow column with all of its slack dumped on the right.
   ========================================================================= */

/* ------------------------------------------------ the opened case study
   The writing was set at 62ch inside a 945px block inside a 1440px page,
   which is a third of the width and 2,253px of height for a single case.
   Reclaiming the numeral gutter and moving the section labels into a
   left-hand spine roughly halves the scroll and puts the prose on a proper
   measure instead of a column of three-word lines. */

.case__row {
  display: grid;
  grid-template-columns: clamp(96px, 10vw, 152px) minmax(0, 1fr);
  column-gap: clamp(20px, 3vw, 48px);
  align-items: start;
  padding-top: clamp(20px, 2.6vh, 30px);
}
.case__row + .case__row { border-top: 1px solid var(--hair-2); }
.case .case__row h4 { margin: 0; padding-top: 2px; line-height: 1.6; }
.case__rowbody { min-width: 0; }

/* a longer measure now that there is width to spend, and the staccato
   one-line paragraphs sit as a stanza rather than as separate blocks */
.case p, .case ul { max-width: 74ch; }
.case .case__rowbody p + p { margin-top: 0.42em; }
.case .lede { max-width: 30ch; margin-bottom: 0.3em; }
.case__note { max-width: 74ch; }

/* the wide passages — lists of specs and the figure rows — can run in two
   columns once the block is this wide, because each item is one line */
@media (min-width: 1040px) {
  .case__rowbody ul { columns: 2; column-gap: clamp(24px, 3vw, 52px); }
  .case__rowbody ul li { break-inside: avoid; }
}
@media (max-width: 719px) {
  .case__row { grid-template-columns: minmax(0, 1fr); }
  .case .case__row h4 { margin-bottom: 8px; }
}

/* ------------------------------------------------------- the open control
   Same glass pane the top bar and the footer already use. On a card that now
   carries an instrument, a hairline-underlined caption was invisible. */
.expand.btn {
  border: 1px solid var(--ch);
  height: 42px; padding: 0 24px; margin-top: 22px;
  color: var(--ch); font-size: 10px;
}
.expand.btn:hover, .expand.btn:focus-visible { color: #0B0B0A; border-bottom-color: var(--ch); }
.expand.btn[aria-expanded="true"] > span::after { content: ' ×'; }

/* =========================================================================
   Corner consistency — 2026-08-29

   The system's radius tokens are all 0, and every button on the page is
   square: Say hello, Email me, LinkedIn, Read the case. The discipline
   filters and the card chips were the only pills on the site, so they were
   the exception rather than the rule — squaring them settles it in the
   direction the rest of the page already went.
   ========================================================================= */
/* Corners, settled as a rule rather than a blanket: square is for things
   that do something (Say hello, Read the case), the pill is for things that
   name something (a discipline filter, a card's tags). That keeps actions and
   taxonomy visually separate, which is worth more than one shared shape. */
.disc, .object__chips b { border-radius: var(--sc-r-pill); }

/* and the filters are coloured before they are touched — the four words under
   the wordmark already are, and a row of identical grey chips says "one
   control" where four disciplines were meant */
.disc { color: var(--wc); border-color: color-mix(in oklab, var(--wc) 32%, transparent); }
.disc:hover { border-color: var(--wc); }
.disc .ct { opacity: .6; }
.disc-clear { --wc: var(--sc-accent); }

/* =========================================================================
   03 · the route, not the contents — 2026-08-29

   The first version of this instrument compared two pictures of a page and
   the "after" was the busier one, which reads as "we added things" and,
   worse, as less considered. The finding was never about what went onto the
   page. It was about how much work was left to the customer.

   So both states show the same page, and what changes is the line drawn
   over it: before, the route keeps leaving the collection for a product page
   and coming back; after, it stays inside and is short. The improvement is
   the emptier picture, which is the only way this can look like a decision
   rather than an addition.
   ========================================================================= */
.i-path svg { display: block; width: 100%; height: auto; }

.i-path__frame { fill: none; stroke: var(--hair); stroke-width: 1; }
.i-path__title { fill: var(--sc-ink); opacity: .55; }
.i-path__cards rect { fill: var(--elev); }

/* the added guidance is deliberately quiet: it is not the point */
.i-path__added rect { fill: var(--ch); opacity: 0; transition: opacity .45s var(--sc-ease-out, ease); }
.i-path.is-after .i-path__added rect { opacity: .34; }

.i-path__away rect { fill: none; stroke: var(--hair); stroke-width: 1; stroke-dasharray: 3 4; transition: opacity .45s; }
.i-path__away text {
  fill: var(--faint); font-family: var(--sc-font-mono); font-size: 9px;
  letter-spacing: .12em; text-transform: uppercase; text-anchor: middle;
  transition: opacity .45s;
}
.i-path.is-after .i-path__away { opacity: .18; }

.i-path__line {
  fill: none; stroke: var(--ch); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.i-path__stops circle { fill: var(--sc-canvas); stroke: var(--ch); stroke-width: 1.5; }
.i-path__stops text {
  fill: var(--ch); font-family: var(--sc-font-mono); font-weight: 700; font-size: 9px;
  text-anchor: middle; dominant-baseline: middle;
}

.i-path__legend { display: flex; gap: 2px; margin: 14px 0 0; }
.i-path__tab {
  appearance: none; border: 1px solid var(--hair); background: none; cursor: pointer;
  padding: 7px 16px;
  font-family: var(--sc-font-mono); font-size: 10px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-2);
  transition: color .22s, border-color .22s, background .22s;
}
.i-path__tab:hover { color: var(--ch); border-color: var(--ch); }
.i-path__tab.is-on { color: var(--sc-accent-ink); background: var(--ch); border-color: var(--ch); }



/* =========================================================================
   The three questions — 2026-08-29

   The figures this case used to print were the business's, so they came out.
   What replaced them is better than a redaction: the questions the team could
   answer each week once the system existed. A question is methodology, and it
   carries the weight the numbers were carrying without disclosing anything.
   ========================================================================= */
.asks { list-style: none; counter-reset: ask; margin: 18px 0; padding: 0; display: grid; gap: 1px; max-width: 68ch; }
.asks li {
  counter-increment: ask;
  display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 0 14px;
  padding: 14px 14px 15px; background: var(--plate);
}
.asks li::before {
  content: counter(ask, decimal-leading-zero);
  grid-row: 1 / span 2;
  font-family: var(--sc-font-mono); font-weight: 700; font-size: 10px;
  letter-spacing: .1em; color: var(--ch); padding-top: 3px;
  font-variant-numeric: tabular-nums;
}
.asks__q {
  margin: 0 0 5px;
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1rem, .95rem + .45vw, 1.22rem); line-height: 1.25;
  letter-spacing: -.02em; color: var(--sc-ink);
}
.asks__a { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ink-2); max-width: 62ch; }
@media (max-width: 560px) {
  .asks li { grid-template-columns: minmax(0, 1fr); }
  .asks li::before { grid-row: auto; padding-top: 0; margin-bottom: 6px; }
}

/* the disclosure note is a condition of the work, not an apology for it */
.case__guard {
  margin-top: 14px; padding-left: 14px;
  border-left: 1px solid var(--hair);
  font-size: 13px; color: var(--sc-ink-soft); max-width: 62ch;
}

/* =========================================================================
   Analytical thinking — the rail scrolls sideways — 2026-08-29

   The strip was laid out horizontally but driven by vertical scroll: the
   section pinned for nearly three screens and panned as you went down.
   Watching people use it settled the question — a horizontal row is read as
   an invitation to swipe sideways, and the gesture did nothing.

   It is now a real horizontal scroller. Every native gesture works because
   nothing is intercepted: trackpad sideways, shift-wheel, touch swipe, the
   scrollbar, tab. Drag and the two arrows exist for a plain mouse, which has
   no sideways gesture at all. Vertical scrolling is left completely alone —
   the previous version's problem was hijacking, and replacing one hijack
   with another would not be a fix.
   ========================================================================= */
.railstage {
  height: auto;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;   /* no accidental browser back-swipe */
  scroll-snap-type: x proximity;
  padding-block: clamp(48px, 9vh, 96px);
  cursor: grab;
  scrollbar-width: thin;
  scrollbar-color: var(--hair) transparent;
}
.railstage.is-dragging { cursor: grabbing; scroll-snap-type: none; scroll-behavior: auto; }
.railstage::-webkit-scrollbar { height: 6px; }
.railstage::-webkit-scrollbar-track { background: transparent; }
.railstage::-webkit-scrollbar-thumb { background: var(--hair); }
.railstage::-webkit-scrollbar-thumb:hover { background: var(--ch); }

.chartrail { align-items: stretch; }
.chartrail__lead, .plate, .chartrail__trail { scroll-snap-align: center; }
.chartrail__lead { scroll-snap-align: start; }
/* while dragging, a click on a plate would be an accident */
.railstage.is-dragging .plate { pointer-events: none; }

.railbar {
  max-width: var(--pagew); margin-inline: auto;
  padding-inline: var(--sc-gutter); padding-bottom: clamp(32px, 7vh, 72px);
  display: grid; gap: 14px;
}
.railbar__meter { height: 1px; background: var(--hair); position: relative; overflow: hidden; }
.railbar__meter span {
  position: absolute; inset: 0; transform-origin: left; transform: scaleX(0);
  background: var(--ch); transition: transform .18s linear;
}
.railbar__ctrl { display: flex; align-items: center; gap: 10px; }
.railbar__hint { color: var(--faint); margin-right: auto; }
.railbar__btn {
  appearance: none; cursor: pointer; background: none;
  border: 1px solid var(--hair); border-radius: 0;
  width: 42px; height: 34px; color: var(--ink-2); font-size: 14px; line-height: 1;
  transition: color .2s, border-color .2s;
}
.railbar__btn:hover:not([disabled]) { color: var(--ch); border-color: var(--ch); }
.railbar__btn[disabled] { opacity: .3; cursor: default; }

@media (prefers-reduced-motion: reduce) { .railstage { scroll-behavior: auto; } }

/* =========================================================================
   About, set as a book — 2026-08-29

   This is the only piece of writing on the site that is a story rather than
   an argument, and it was running as one narrow column down a wide page.
   Setting it as spreads the reader turns gives it the pacing a story wants,
   and gives the reader a sense of how far they have come — which, in an
   essay about leaving somewhere, is not decoration.

   The pagination is CSS multi-column: the browser breaks the text into
   columns of its own accord, so it reflows at any size and nothing is ever
   clipped. Turning a page translates the flow by exactly one spread.

   Pagination is a real preference, not a universal improvement, so the
   switch back to one continuous page is a first-class control rather than
   an accessibility afterthought.
   ========================================================================= */
.book {
  margin-top: clamp(20px, 4vh, 34px);
  border: 1px solid var(--hair);
  background: var(--plate);
}
.book__head, .book__foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px 20px; flex-wrap: wrap;
  padding: 11px clamp(14px, 2.4vw, 26px);
}
.book__head { border-bottom: 1px solid var(--hair-2); color: var(--faint); }
.book__title { color: var(--ch); }
.book__foot { border-top: 1px solid var(--hair-2); }

.book__leaf { overflow: hidden; padding: clamp(22px, 4vw, 44px); }
.book__flow {
  height: clamp(420px, 62vh, 660px);
  columns: 2;
  column-gap: clamp(28px, 5vw, 72px);
  column-fill: auto;
  column-rule: 1px solid var(--hair-2);
  transition: transform .62s cubic-bezier(.22, 1, .36, 1);
  will-change: transform;
}
@media (max-width: 760px) { .book__flow { columns: 1; height: clamp(400px, 66vh, 560px); } }

/* inside the book the essay is plain running text again — the two-track
   treatment was solving the problem this replaces */
.book .about__body { max-width: none; margin-top: 0; }
.book .about__body > p { max-width: none; }
.book .about__body .about__beat { max-width: none; margin: 1.2em 0; border: 0; padding: 0; }
.book .i-xlate { margin: 1.4em 0; break-inside: avoid; }

/* a page break should never cut a heading-ish line from what follows it */
.book .about__beat, .book .i-xlate__row { break-inside: avoid; }

.book__index { display: flex; flex-wrap: wrap; gap: 2px; margin-right: auto; }
.book__index button {
  appearance: none; background: none; border: 0; cursor: pointer;
  padding: 5px 9px;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
  border-bottom: 1px solid transparent;
  transition: color .22s, border-color .22s;
}
.book__index button:hover { color: var(--ink-2); }
.book__index button.is-here { color: var(--ch); border-bottom-color: var(--ch); }

.book__ctrl { display: flex; align-items: center; gap: 8px; }
.book__btn {
  appearance: none; cursor: pointer; background: none;
  border: 1px solid var(--hair); border-radius: 0;
  width: 40px; height: 32px; color: var(--ink-2); font-size: 13px; line-height: 1;
  transition: color .2s, border-color .2s;
}
.book__btn:hover:not([disabled]) { color: var(--ch); border-color: var(--ch); }
.book__btn[disabled] { opacity: .3; cursor: default; }
.book__flat {
  appearance: none; cursor: pointer; background: none; border: 0;
  border-bottom: 1px solid var(--hair); padding: 4px 0; margin-left: 10px;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
  transition: color .2s, border-color .2s;
}
.book__flat:hover { color: var(--ch); border-bottom-color: var(--ch); }

/* one continuous page: the book stops being a book */
.book.is-flat .book__leaf { overflow: visible; }
.book.is-flat .book__flow { height: auto; columns: 1; transform: none !important; column-rule: 0; }
.book.is-flat .book__ctrl .book__btn { display: none; }
.book.is-flat .about__body { max-width: 66ch; }
.book.is-flat .book__flat { color: var(--ch); border-bottom-color: var(--ch); }

@media (prefers-reduced-motion: reduce) { .book__flow { transition: none; } }

/* ============================================== 03 · thinking, as a tuner

   The four essays were four identical rows, so nothing asked to be stopped
   at. They are not really a list: they are four positions of one move —
   replacing the question everyone asks with a better one. A dial says that;
   a stack of rows says only "there are four".

   Every word here is the existing copy, re-paced. Nothing was rewritten.
   ============================================================== */
.i-tuner { margin-top: clamp(2rem, 5vh, 3.5rem); }
.i-tuner__frame {
  border-top: 1px solid var(--ch);
  display: grid; gap: clamp(20px, 4vw, 48px);
  padding-top: clamp(22px, 4vh, 34px);
}
@media (min-width: 860px) { .i-tuner__frame { grid-template-columns: 158px minmax(0, 1fr); } }

/* the detents. four positions, and the reader can feel where they are */
.i-detents { display: grid; gap: 1px; align-content: start; }
.i-detent {
  appearance: none; border: 0; cursor: pointer; width: 100%; text-align: left;
  display: flex; align-items: baseline; gap: 12px; padding: 10px 12px;
  background: transparent; color: var(--faint);
  font-family: var(--sc-font-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase;
  border-left: 1px solid var(--hair); white-space: nowrap;
  transition: color .22s, border-color .22s, background .22s;
}
.i-detent:hover { color: var(--ink-2); }
.i-detent.is-on { color: var(--ch); border-left-color: var(--ch); background: color-mix(in oklab, var(--ch) 8%, transparent); }
.i-detent__n { font-weight: 700; font-variant-numeric: tabular-nums; }
.i-detent__k { font-size: 9px; letter-spacing: 0.1em; }

.i-claim { min-height: clamp(210px, 30vh, 300px); display: grid; align-content: start; }
.i-claim__ex {
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1.3rem, 1rem + 1.9vw, 2.6rem); line-height: 1.18; letter-spacing: -0.03em;
  color: var(--sc-ink); max-width: 24ch; margin: 0;
}
/* the turn arrives a beat after the assumption, because that is how the
   sentence is built */
.i-claim__ex + .i-claim__ex { margin-top: 0.4em; color: var(--ink-2); }
.i-claim__title {
  margin: clamp(20px, 3vh, 30px) 0 0;
  font-family: var(--sc-font-mono); font-size: 10.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ch); max-width: 48ch; line-height: 1.8;
}
.i-claim [data-turn] { opacity: 0; transform: translateY(10px); transition: opacity .5s var(--sc-ease-out, ease), transform .5s var(--sc-ease-out, ease); }
.i-claim.is-turned [data-turn] { opacity: 1; transform: none; }
.i-claim.is-turned [data-turn="2"] { transition-delay: .09s; }

/* ============================================== 06 · about, as a journey

   The longest piece of writing on the site had no way in and no way to
   measure progress. The rail is not decoration: it is the essay's own
   structure, and it is the only place the reader can see how far the story
   has travelled — which is the story.
   ============================================================== */
.i-about { display: grid; gap: clamp(20px, 4vw, 56px); }
@media (min-width: 900px) { .i-about { grid-template-columns: 168px minmax(0, 1fr); align-items: start; } }

.i-rail { display: none; }
@media (min-width: 900px) {
  .i-rail { display: block; position: sticky; top: calc(var(--bar) + 28px); }
}
.i-rail ol { list-style: none; margin: 0; padding: 0; border-left: 1px solid var(--hair); }
.i-rail li {
  position: relative; padding: 9px 0 9px 18px;
  font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--faint);
  transition: color .3s;
}
.i-rail li::before {
  content: ''; position: absolute; left: -3px; top: 50%; transform: translateY(-50%);
  width: 5px; height: 5px; background: var(--hair); transition: background .3s, transform .3s;
}
.i-rail li.is-here { color: var(--sc-ink); }
.i-rail li.is-here::before { background: var(--ch); transform: translateY(-50%) scale(1.7); }
.i-rail li.is-past { color: var(--ink-2); }
.i-rail li.is-past::before { background: var(--ink-2); }

/* the translator. her thesis, stated in her own four lines, made operable:
   the raw thing on one side and what it becomes on the other */
.i-xlate { margin: 1.8em 0; border: 1px solid var(--hair); background: var(--plate); }
.i-xlate__bar {
  padding: 9px 14px; border-bottom: 1px solid var(--hair-2);
  font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ch);
}
.i-xlate__body { padding: clamp(14px, 2.4vw, 22px); display: grid; gap: 1px; }
.i-xlate__row {
  appearance: none; border: 0; width: 100%; text-align: left; cursor: pointer;
  display: grid; grid-template-columns: minmax(0,1fr) auto minmax(0,1fr);
  align-items: center; gap: 10px; padding: 12px 10px;
  background: transparent; color: var(--ink-2);
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(0.95rem, 0.9rem + 0.35vw, 1.15rem); line-height: 1.3; letter-spacing: -0.02em;
  transition: background .22s, color .22s;
}
.i-xlate__row:hover { background: var(--elev); }
.i-xlate__row.is-on { background: var(--elev); color: var(--sc-ink); }
.i-xlate__to { color: var(--ink-2); }
.i-xlate__row.is-on .i-xlate__to { color: var(--ch); }
.i-xlate__arrow {
  justify-self: center; padding: 0 14px;
  font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--faint);
  transition: color .22s, transform .3s var(--sc-ease-out, ease);
}
.i-xlate__row.is-on .i-xlate__arrow { color: var(--ch); }
@media (max-width: 560px) {
  .i-xlate__row { grid-template-columns: minmax(0,1fr); gap: 4px; }
  .i-xlate__arrow { justify-self: start; padding: 2px 0; }
}

@media (prefers-reduced-motion: reduce) {
  .i-claim [data-turn] { opacity: 1; transform: none; transition: none; }
  .i-rig *, .i-tuner *, .i-about * { transition-duration: .001ms !important; }
}

/* =========================================================================
   Layout corrections — 2026-08-29

   Three things the added instruments exposed rather than caused:
   the opened case study used barely a third of the screen, the control that
   opens it had become the quietest thing on a loud card, and the About essay
   sat in one narrow column with all of its slack dumped on the right.
   ========================================================================= */

/* ------------------------------------------------ the opened case study
   The writing was set at 62ch inside a 945px block inside a 1440px page,
   which is a third of the width and 2,253px of height for a single case.
   Reclaiming the numeral gutter and moving the section labels into a
   left-hand spine roughly halves the scroll and puts the prose on a proper
   measure instead of a column of three-word lines. */

.case__row {
  display: grid;
  grid-template-columns: clamp(96px, 10vw, 152px) minmax(0, 1fr);
  column-gap: clamp(20px, 3vw, 48px);
  align-items: start;
  padding-top: clamp(20px, 2.6vh, 30px);
}
.case__row + .case__row { border-top: 1px solid var(--hair-2); }
.case .case__row h4 { margin: 0; padding-top: 2px; line-height: 1.6; }
.case__rowbody { min-width: 0; }

/* a longer measure now that there is width to spend, and the staccato
   one-line paragraphs sit as a stanza rather than as separate blocks */
.case p, .case ul { max-width: 74ch; }
.case .case__rowbody p + p { margin-top: 0.42em; }
.case .lede { max-width: 30ch; margin-bottom: 0.3em; }
.case__note { max-width: 74ch; }

/* the wide passages — lists of specs and the figure rows — can run in two
   columns once the block is this wide, because each item is one line */
@media (min-width: 1040px) {
  .case__rowbody ul { columns: 2; column-gap: clamp(24px, 3vw, 52px); }
  .case__rowbody ul li { break-inside: avoid; }
}
@media (max-width: 719px) {
  .case__row { grid-template-columns: minmax(0, 1fr); }
  .case .case__row h4 { margin-bottom: 8px; }
}

/* ------------------------------------------------------- the open control
   Same glass pane the top bar and the footer already use. On a card that now
   carries an instrument, a hairline-underlined caption was invisible. */
.expand.btn {
  border: 1px solid var(--ch);
  height: 42px; padding: 0 24px; margin-top: 22px;
  color: var(--ch); font-size: 10px;
}
.expand.btn:hover, .expand.btn:focus-visible { color: #0B0B0A; border-bottom-color: var(--ch); }
.expand.btn[aria-expanded="true"] > span::after { content: ' ×'; }

/* =========================================================================
   Corner consistency — 2026-08-29

   The system's radius tokens are all 0, and every button on the page is
   square: Say hello, Email me, LinkedIn, Read the case. The discipline
   filters and the card chips were the only pills on the site, so they were
   the exception rather than the rule — squaring them settles it in the
   direction the rest of the page already went.
   ========================================================================= */
/* Corners, settled as a rule rather than a blanket: square is for things
   that do something (Say hello, Read the case), the pill is for things that
   name something (a discipline filter, a card's tags). That keeps actions and
   taxonomy visually separate, which is worth more than one shared shape. */
.disc, .object__chips b { border-radius: var(--sc-r-pill); }

/* and the filters are coloured before they are touched — the four words under
   the wordmark already are, and a row of identical grey chips says "one
   control" where four disciplines were meant */
.disc { color: var(--wc); border-color: color-mix(in oklab, var(--wc) 32%, transparent); }
.disc:hover { border-color: var(--wc); }
.disc .ct { opacity: .6; }
.disc-clear { --wc: var(--sc-accent); }

/* =========================================================================
   03 · the route, not the contents — 2026-08-29

   The first version of this instrument compared two pictures of a page and
   the "after" was the busier one, which reads as "we added things" and,
   worse, as less considered. The finding was never about what went onto the
   page. It was about how much work was left to the customer.

   So both states show the same page, and what changes is the line drawn
   over it: before, the route keeps leaving the collection for a product page
   and coming back; after, it stays inside and is short. The improvement is
   the emptier picture, which is the only way this can look like a decision
   rather than an addition.
   ========================================================================= */
.i-path svg { display: block; width: 100%; height: auto; }

.i-path__frame { fill: none; stroke: var(--hair); stroke-width: 1; }
.i-path__title { fill: var(--sc-ink); opacity: .55; }
.i-path__cards rect { fill: var(--elev); }

/* the added guidance is deliberately quiet: it is not the point */
.i-path__added rect { fill: var(--ch); opacity: 0; transition: opacity .45s var(--sc-ease-out, ease); }
.i-path.is-after .i-path__added rect { opacity: .34; }

.i-path__away rect { fill: none; stroke: var(--hair); stroke-width: 1; stroke-dasharray: 3 4; transition: opacity .45s; }
.i-path__away text {
  fill: var(--faint); font-family: var(--sc-font-mono); font-size: 9px;
  letter-spacing: .12em; text-transform: uppercase; text-anchor: middle;
  transition: opacity .45s;
}
.i-path.is-after .i-path__away { opacity: .18; }

.i-path__line {
  fill: none; stroke: var(--ch); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.i-path__stops circle { fill: var(--sc-canvas); stroke: var(--ch); stroke-width: 1.5; }
.i-path__stops text {
  fill: var(--ch); font-family: var(--sc-font-mono); font-weight: 700; font-size: 9px;
  text-anchor: middle; dominant-baseline: middle;
}

.i-path__legend { display: flex; gap: 2px; margin: 14px 0 0; }
.i-path__tab {
  appearance: none; border: 1px solid var(--hair); background: none; cursor: pointer;
  padding: 7px 16px;
  font-family: var(--sc-font-mono); font-size: 10px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-2);
  transition: color .22s, border-color .22s, background .22s;
}
.i-path__tab:hover { color: var(--ch); border-color: var(--ch); }
.i-path__tab.is-on { color: var(--sc-accent-ink); background: var(--ch); border-color: var(--ch); }



/* =========================================================================
   The three questions — 2026-08-29

   The figures this case used to print were the business's, so they came out.
   What replaced them is better than a redaction: the questions the team could
   answer each week once the system existed. A question is methodology, and it
   carries the weight the numbers were carrying without disclosing anything.
   ========================================================================= */
.asks { list-style: none; counter-reset: ask; margin: 18px 0; padding: 0; display: grid; gap: 1px; max-width: 68ch; }
.asks li {
  counter-increment: ask;
  display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 0 14px;
  padding: 14px 14px 15px; background: var(--plate);
}
.asks li::before {
  content: counter(ask, decimal-leading-zero);
  grid-row: 1 / span 2;
  font-family: var(--sc-font-mono); font-weight: 700; font-size: 10px;
  letter-spacing: .1em; color: var(--ch); padding-top: 3px;
  font-variant-numeric: tabular-nums;
}
.asks__q {
  margin: 0 0 5px;
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1rem, .95rem + .45vw, 1.22rem); line-height: 1.25;
  letter-spacing: -.02em; color: var(--sc-ink);
}
.asks__a { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ink-2); max-width: 62ch; }
@media (max-width: 560px) {
  .asks li { grid-template-columns: minmax(0, 1fr); }
  .asks li::before { grid-row: auto; padding-top: 0; margin-bottom: 6px; }
}

/* the disclosure note is a condition of the work, not an apology for it */
.case__guard {
  margin-top: 14px; padding-left: 14px;
  border-left: 1px solid var(--hair);
  font-size: 13px; color: var(--sc-ink-soft); max-width: 62ch;
}

/* =========================================================================
   Analytical thinking — the rail scrolls sideways — 2026-08-29

   The strip was laid out horizontally but driven by vertical scroll: the
   section pinned for nearly three screens and panned as you went down.
   Watching people use it settled the question — a horizontal row is read as
   an invitation to swipe sideways, and the gesture did nothing.

   It is now a real horizontal scroller. Every native gesture works because
   nothing is intercepted: trackpad sideways, shift-wheel, touch swipe, the
   scrollbar, tab. Drag and the two arrows exist for a plain mouse, which has
   no sideways gesture at all. Vertical scrolling is left completely alone —
   the previous version's problem was hijacking, and replacing one hijack
   with another would not be a fix.
   ========================================================================= */
.railstage {
  height: auto;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;   /* no accidental browser back-swipe */
  scroll-snap-type: x proximity;
  padding-block: clamp(48px, 9vh, 96px);
  cursor: grab;
  scrollbar-width: thin;
  scrollbar-color: var(--hair) transparent;
}
.railstage.is-dragging { cursor: grabbing; scroll-snap-type: none; scroll-behavior: auto; }
.railstage::-webkit-scrollbar { height: 6px; }
.railstage::-webkit-scrollbar-track { background: transparent; }
.railstage::-webkit-scrollbar-thumb { background: var(--hair); }
.railstage::-webkit-scrollbar-thumb:hover { background: var(--ch); }

.chartrail { align-items: stretch; }
.chartrail__lead, .plate, .chartrail__trail { scroll-snap-align: center; }
.chartrail__lead { scroll-snap-align: start; }
/* while dragging, a click on a plate would be an accident */
.railstage.is-dragging .plate { pointer-events: none; }

.railbar {
  max-width: var(--pagew); margin-inline: auto;
  padding-inline: var(--sc-gutter); padding-bottom: clamp(32px, 7vh, 72px);
  display: grid; gap: 14px;
}
.railbar__meter { height: 1px; background: var(--hair); position: relative; overflow: hidden; }
.railbar__meter span {
  position: absolute; inset: 0; transform-origin: left; transform: scaleX(0);
  background: var(--ch); transition: transform .18s linear;
}
.railbar__ctrl { display: flex; align-items: center; gap: 10px; }
.railbar__hint { color: var(--faint); margin-right: auto; }
.railbar__btn {
  appearance: none; cursor: pointer; background: none;
  border: 1px solid var(--hair); border-radius: 0;
  width: 42px; height: 34px; color: var(--ink-2); font-size: 14px; line-height: 1;
  transition: color .2s, border-color .2s;
}
.railbar__btn:hover:not([disabled]) { color: var(--ch); border-color: var(--ch); }
.railbar__btn[disabled] { opacity: .3; cursor: default; }

@media (prefers-reduced-motion: reduce) { .railstage { scroll-behavior: auto; } }

/* =========================================================================
   About, set as a book — 2026-08-29

   This is the only piece of writing on the site that is a story rather than
   an argument, and it was running as one narrow column down a wide page.
   Setting it as spreads the reader turns gives it the pacing a story wants,
   and gives the reader a sense of how far they have come — which, in an
   essay about leaving somewhere, is not decoration.

   The pagination is CSS multi-column: the browser breaks the text into
   columns of its own accord, so it reflows at any size and nothing is ever
   clipped. Turning a page translates the flow by exactly one spread.

   Pagination is a real preference, not a universal improvement, so the
   switch back to one continuous page is a first-class control rather than
   an accessibility afterthought.
   ========================================================================= */
.book {
  margin-top: clamp(20px, 4vh, 34px);
  border: 1px solid var(--hair);
  background: var(--plate);
}
.book__head, .book__foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px 20px; flex-wrap: wrap;
  padding: 11px clamp(14px, 2.4vw, 26px);
}
.book__head { border-bottom: 1px solid var(--hair-2); color: var(--faint); }
.book__title { color: var(--ch); }
.book__foot { border-top: 1px solid var(--hair-2); }

.book__leaf { overflow: hidden; padding: clamp(22px, 4vw, 44px); }
.book__flow {
  height: clamp(420px, 62vh, 660px);
  columns: 2;
  column-gap: clamp(28px, 5vw, 72px);
  column-fill: auto;
  column-rule: 1px solid var(--hair-2);
  transition: transform .62s cubic-bezier(.22, 1, .36, 1);
  will-change: transform;
}
@media (max-width: 760px) { .book__flow { columns: 1; height: clamp(400px, 66vh, 560px); } }

/* inside the book the essay is plain running text again — the two-track
   treatment was solving the problem this replaces */
.book .about__body { max-width: none; margin-top: 0; }
.book .about__body > p { max-width: none; }
.book .about__body .about__beat { max-width: none; margin: 1.2em 0; border: 0; padding: 0; }
.book .i-xlate { margin: 1.4em 0; break-inside: avoid; }

/* a page break should never cut a heading-ish line from what follows it */
.book .about__beat, .book .i-xlate__row { break-inside: avoid; }

.book__index { display: flex; flex-wrap: wrap; gap: 2px; margin-right: auto; }
.book__index button {
  appearance: none; background: none; border: 0; cursor: pointer;
  padding: 5px 9px;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
  border-bottom: 1px solid transparent;
  transition: color .22s, border-color .22s;
}
.book__index button:hover { color: var(--ink-2); }
.book__index button.is-here { color: var(--ch); border-bottom-color: var(--ch); }

.book__ctrl { display: flex; align-items: center; gap: 8px; }
.book__btn {
  appearance: none; cursor: pointer; background: none;
  border: 1px solid var(--hair); border-radius: 0;
  width: 40px; height: 32px; color: var(--ink-2); font-size: 13px; line-height: 1;
  transition: color .2s, border-color .2s;
}
.book__btn:hover:not([disabled]) { color: var(--ch); border-color: var(--ch); }
.book__btn[disabled] { opacity: .3; cursor: default; }
.book__flat {
  appearance: none; cursor: pointer; background: none; border: 0;
  border-bottom: 1px solid var(--hair); padding: 4px 0; margin-left: 10px;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
  transition: color .2s, border-color .2s;
}
.book__flat:hover { color: var(--ch); border-bottom-color: var(--ch); }

/* one continuous page: the book stops being a book */
.book.is-flat .book__leaf { overflow: visible; }
.book.is-flat .book__flow { height: auto; columns: 1; transform: none !important; column-rule: 0; }
.book.is-flat .book__ctrl .book__btn { display: none; }
.book.is-flat .about__body { max-width: 66ch; }
.book.is-flat .book__flat { color: var(--ch); border-bottom-color: var(--ch); }

@media (prefers-reduced-motion: reduce) { .book__flow { transition: none; } }

/* =========================================================================
   04 · the narrowing — 2026-08-30

   The first instrument here drew first purchase to second, which implied a
   finding the analysis did not actually license. What the work produced was
   discipline: several plausible hypotheses went in, each was held to the same
   threshold, and none was promoted into a planning rule. That is a valuable
   outcome and it should look like one.

   The narrowing is the geometry — each band is narrower than the one above —
   so the diagram states its own argument without a caption explaining it.
   One accent, on the threshold, because the threshold is the point.

   No figures appear here and none are implied. Every state is qualitative.
   ========================================================================= */
.narrow { display: grid; justify-items: center; }
.narrow__stage { width: 100%; }
.narrow__stage--2 { width: 84%; }
.narrow__stage--3 { width: 66%; }
.narrow__stage--4 { width: 52%; }
@media (max-width: 720px) {
  .narrow__stage--2, .narrow__stage--3, .narrow__stage--4 { width: 100%; }
}

.narrow__h {
  margin: 0 0 10px;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .15em; text-transform: uppercase; color: var(--faint);
}
.narrow__h span { color: var(--oc, var(--ch)); font-weight: 700; margin-right: 8px; }

.narrow__rows { display: grid; gap: 1px; }
.hyp {
  appearance: none; border: 0; width: 100%; text-align: left; cursor: pointer;
  display: grid; grid-template-columns: 26px minmax(0, 1fr); align-items: baseline; gap: 12px;
  padding: 13px 14px; background: var(--elev); color: var(--sc-ink);
  transition: background .22s, opacity .22s, color .22s;
}
.hyp__n { font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: .1em; color: var(--faint); }
.hyp__t { font-family: var(--sc-font-display); font-weight: 500; font-size: clamp(.98rem, .92rem + .4vw, 1.14rem); line-height: 1.3; letter-spacing: -.02em; }
.hyp:hover { background: color-mix(in oklab, var(--oc, var(--ch)) 12%, var(--elev)); }
.hyp.is-on { background: color-mix(in oklab, var(--oc, var(--ch)) 22%, var(--elev)); }
.hyp.is-on .hyp__n { color: var(--oc, var(--ch)); }
.hyp.is-dim { opacity: .32; }

/* the connectors: four strands in, one out */
.narrow__link { display: flex; justify-content: center; gap: 46px; margin: 0; height: 26px; }
.narrow__link span { width: 1px; background: var(--hair); transition: background .25s, opacity .25s; }
.narrow__link span.is-on { background: var(--oc, var(--ch)); }
.narrow__link span.is-off { opacity: .25; }

.narrow__chips, .narrow__gate, .narrow__out { display: flex; flex-wrap: wrap; gap: 1px; }
.narrow__chips span, .narrow__out span {
  flex: 1 1 auto; padding: 10px 12px; background: var(--elev);
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2);
}

/* the one accent on the page belongs to the threshold */
.narrow__gate { border: 1px solid var(--oc, var(--ch)); gap: 0; }
.narrow__gate span {
  flex: 1 1 auto; padding: 12px; text-align: center;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--oc, var(--ch));
}
.narrow__gate span + span { border-left: 1px solid color-mix(in oklab, var(--oc, var(--ch)) 34%, transparent); }
@media (max-width: 720px) {
  .narrow__gate span + span { border-left: 0; border-top: 1px solid color-mix(in oklab, var(--oc, var(--ch)) 34%, transparent); }
  .narrow__gate span, .narrow__chips span, .narrow__out span { flex: 1 1 100%; text-align: left; }
}
.narrow__out span { color: var(--sc-ink); background: transparent; border: 1px solid var(--hair); }

/* the detail panel: four questions, the last one set apart because it is the
   instruction the rest of the panel exists to justify */
.detail { margin-top: 26px; padding-top: 20px; border-top: 1px solid var(--hair); }
.detail__title {
  margin: 0 0 16px;
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1.05rem, .98rem + .5vw, 1.32rem); line-height: 1.25;
  letter-spacing: -.025em; color: var(--sc-ink);
}
.detail__grid { display: grid; gap: 16px; margin: 0; }
@media (min-width: 820px) { .detail__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 40px; } }
.detail__grid dt {
  margin: 0 0 5px;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
}
.detail__grid dd { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ink-2); max-width: 56ch; }
.detail__imp { grid-column: 1 / -1; padding-top: 14px; border-top: 1px solid var(--hair-2); }
.detail__imp dd { color: var(--oc, var(--ch)); font-family: var(--sc-font-mono); font-size: 11px; letter-spacing: .06em; }

/* =========================================================================
   04 · the gate — 2026-08-30

   The previous version of this was a diagram made of paragraphs. It came from
   a brief written for a combined visual-and-copy piece, but on this page the
   reading lives behind "Read the case" and the instrument in front of it
   should be something you operate, the way the other three are: a store you
   switch off, a pipeline you run, a route you scrub.

   So it is a sorting gate. Four candidates, one standard, two trays. Send any
   of them through and it comes to rest in the upper tray. The lower tray has
   a name, a place, and stays empty however many you send — that empty tray is
   the finding, and it needs no sentence to explain it.

   No figures, and none implied. Nothing here says a relationship was absent;
   only that none met the standard required to plan on.
   ========================================================================= */
.gw { display: grid; gap: 16px; align-items: stretch; }
@media (min-width: 860px) { .gw { grid-template-columns: minmax(0,1.25fr) 58px minmax(0,1fr); gap: 0; } }

.gw__h {
  margin: 0 0 8px;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--faint);
}
.gw__cands { display: grid; gap: 1px; }

.cand {
  appearance: none; border: 0; width: 100%; text-align: left; cursor: pointer;
  display: grid; grid-template-columns: 24px minmax(0,1fr); align-items: baseline; gap: 12px;
  padding: 13px 14px; background: var(--elev); color: var(--sc-ink);
  transition: background .22s, opacity .3s, transform .42s var(--sc-ease-out, cubic-bezier(.22,1,.36,1));
}
.cand__n { font-family: var(--sc-font-mono); font-size: 9.5px; letter-spacing: .1em; color: var(--faint); }
.cand__t { font-family: var(--sc-font-display); font-weight: 500; font-size: clamp(.95rem,.9rem + .35vw,1.1rem); line-height: 1.3; letter-spacing: -.02em; }
.cand:hover:not([disabled]) { background: color-mix(in oklab, var(--oc, var(--ch)) 14%, var(--elev)); }
.cand[disabled] { cursor: default; opacity: .3; }
.cand.is-going { transform: translateX(14px); background: color-mix(in oklab, var(--oc, var(--ch)) 26%, var(--elev)); }

/* the standard everything is held to: the one accent in the frame */
.gw__gate {
  position: relative;
  border-left: 1px solid var(--oc, var(--ch));
  border-right: 1px solid var(--oc, var(--ch));
  display: grid; place-items: center;
  transition: background .3s;
}
.gw__gate span {
  font-family: var(--sc-font-mono); font-size: 9px; letter-spacing: .2em;
  text-transform: uppercase; color: var(--oc, var(--ch));
  white-space: nowrap;
}
@media (min-width: 860px) { .gw__gate span { writing-mode: vertical-rl; } }
@media (max-width: 859px) {
  .gw__gate { border: 1px solid var(--oc, var(--ch)); padding: 9px; }
}
.gw__gate.is-live { background: color-mix(in oklab, var(--oc, var(--ch)) 16%, transparent); }

.gw__out { display: grid; gap: 12px; align-content: start; }
@media (min-width: 860px) { .gw__out { padding-left: 18px; } }

.tray { border: 1px solid var(--hair); padding: 12px 14px 14px; }
.tray__slots { display: flex; flex-wrap: wrap; gap: 4px; min-height: 34px; align-items: center; }

/* the tray that never fills is drawn as a place, not as an absence */
.tray--void { border-style: dashed; }
.tray--void .tray__slots::after {
  content: '—';
  font-family: var(--sc-font-mono); font-size: 12px; color: var(--hair);
}

.chip {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  border: 1px solid var(--oc, var(--ch));
  color: var(--oc, var(--ch));
  font-family: var(--sc-font-mono); font-weight: 700; font-size: 10px;
  animation: chip-land .34s var(--sc-ease-out, cubic-bezier(.22,1,.36,1)) both;
}
@keyframes chip-land {
  from { opacity: 0; transform: translateX(-16px) scale(.86); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .chip { animation: none; }
  .cand { transition: none; }
}

/* =========================================================================
   Places — 2026-08-30

   Two words in the essay are places, and a reader who has never been to
   either is reading a name rather than seeing somewhere. Hovering lifts the
   photograph up beside the word; leaving puts it away. The word stays a word.

   The card leans toward the pointer rather than tracking it, so it reads as
   something being held up rather than something following you around.

   Both photographs are properly licensed and the credit is part of the card,
   not a footnote elsewhere — a caption under a plate, which is what the page
   is already set as.
   ========================================================================= */
/* At rest the word already carries a faded marker stroke, so a reader can see
   there is something here without being told. Hovering fills it left to right
   — the gesture of drawing a line under a word you want to come back to,
   which is exactly what the page is inviting.

   Built as two background layers rather than pseudo-elements: a gradient
   painted on the element is always behind its own glyphs, with no stacking
   context to get wrong, and the fill is one transition on background-size.

   The chapter's own colour here is a soft grey, too quiet to read as an
   invitation, so these use the site accent instead — the one warm colour on
   the page, and it appears nowhere else in this chapter. */
.plc {
  color: var(--sc-ink);
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  padding: 0 .12em;
  /* a multi-word phrase must be allowed to wrap; the gradient repaints per
     line fragment, which is what we want */
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
  background-image:
    linear-gradient(color-mix(in oklab, var(--sc-accent) 88%, transparent),
                    color-mix(in oklab, var(--sc-accent) 88%, transparent)),
    linear-gradient(color-mix(in oklab, var(--sc-accent) 30%, transparent),
                    color-mix(in oklab, var(--sc-accent) 30%, transparent));
  background-repeat: no-repeat;
  background-position: 0 92%, 0 92%;
  background-size: 0% .46em, 100% .46em;
  transition: background-size .36s var(--sc-ease-out, cubic-bezier(.22,1,.36,1)),
              color .28s var(--sc-ease-out, ease);
}
.plc:hover, .plc:focus-visible {
  color: #0B0B0A;
  background-size: 100% .46em, 100% .46em;
}
.plc:focus-visible { outline: 2px solid var(--sc-accent); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) { .plc { transition: none; } }

.plccard {
  position: fixed; z-index: 90; margin: 0;
  width: clamp(190px, 22vw, 268px);
  padding: 6px 6px 0;
  background: var(--elev);
  border: 1px solid var(--hair);
  box-shadow: 0 16px 40px rgba(0,0,0,.55);
  opacity: 0; visibility: hidden;
  transform: translate3d(0, 10px, 0) scale(.94);
  transform-origin: 50% 100%;
  transition: opacity .22s var(--sc-ease-out, ease),
              transform .32s var(--sc-ease-out, cubic-bezier(.22,1,.36,1)),
              visibility .22s;
  pointer-events: none;
}
.plccard.is-up { opacity: 1; visibility: visible; transform: translate3d(0,0,0) scale(1); }
.plccard img { display: block; width: 100%; height: auto; aspect-ratio: 8 / 5; object-fit: cover; }
.plccard figcaption {
  display: grid; gap: 2px; padding: 8px 4px 9px;
  font-family: var(--sc-font-mono); font-size: 9px;
  letter-spacing: .1em; text-transform: uppercase; line-height: 1.5;
}
.plccard figcaption span:first-child { color: var(--ink-2); }
.plccard figcaption span:last-child { color: var(--faint); }

@media (prefers-reduced-motion: reduce) { .plccard { transition: opacity .01ms, visibility .01ms; transform: none; } }
@media (max-width: 620px) { .plccard { width: 62vw; } }

/* =========================================================================
   04 · the same data, cut two ways — 2026-08-30

   Three attempts at this case failed the same way: each was a diagram of a
   conclusion, and a diagram of a conclusion is never surprising, because the
   answer arrives before the reader has any stake in it.

   So the reader is asked to make the call first. The pooled view shows a
   clean trend and a fair question — would you plan on this? Then the same
   points are split by market and each market's own line disagrees with the
   pooled one. Whichever answer they gave, they have now felt the thing the
   analysis caught, which is the only way this case is interesting.

   The points are generated, not measured, and the frame says so. What is
   being demonstrated is a way of checking, not a company's numbers — the
   same status as the ten charts in Ways of looking.
   ========================================================================= */
.split { display: grid; gap: 20px; }
@media (min-width: 900px) { .split { grid-template-columns: minmax(0,1fr) 250px; gap: 32px; align-items: center; } }

.split__plot svg { display: block; width: 100%; height: auto; }
.split__axes line { stroke: var(--hair); stroke-width: 1; }
.split__ax { fill: var(--faint); font-family: var(--sc-font-mono); font-size: 9px; letter-spacing: .12em; text-transform: uppercase; text-anchor: middle; }

.dot { transition: fill .5s var(--sc-ease-out, ease), opacity .5s; }
.fit { stroke-width: 2; fill: none; stroke-linecap: round;
       transition: opacity .5s var(--sc-ease-out, ease), stroke .5s; }
.fit--pooled { stroke: var(--sc-ink); }
.fit--market { stroke-width: 1.6; }

.split__legend {
  display: flex; flex-wrap: wrap; gap: 4px 18px; margin: 12px 0 0;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .12em; text-transform: uppercase;
}
.split__legend[hidden] { display: none; }
.split__legend span { display: inline-flex; align-items: center; gap: 7px; color: var(--ink-2); }
.split__legend span::before { content: ''; width: 14px; height: 2px; background: currentColor; }
.split__legend span[data-m="0"] { color: var(--c-marketing); }
.split__legend span[data-m="1"] { color: var(--c-product); }
.split__legend span[data-m="2"] { color: var(--c-technology); }

.split__ask { border-left: 1px solid var(--hair); padding-left: 20px; }
@media (max-width: 899px) { .split__ask { border-left: 0; border-top: 1px solid var(--hair); padding: 18px 0 0; } }
.split__q {
  margin: 0 0 16px;
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1rem, .95rem + .45vw, 1.2rem); line-height: 1.3; letter-spacing: -.02em;
  color: var(--sc-ink);
}
.split__btns { display: flex; flex-wrap: wrap; gap: 4px 20px; }
.split__btns .i-btn { margin-left: 0; }
.split__verdict {
  margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ink-2);
  animation: split-in .4s var(--sc-ease-out, ease) both;
}
.split__verdict b { color: var(--sc-ink); font-weight: 600; }
@keyframes split-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .dot, .fit, .split__verdict { transition: none; animation: none; }
}

/* =========================================================================
   03 · testability — 2026-08-30

   This chapter replaces four essays that were parked because they were four
   observations of equal weight and nothing asked to be stopped at. What
   sits here instead is the one piece of method she has actually built: the
   check that runs before an idea is allowed onto a roadmap.

   The industry figure is used once, as a benchmark rather than as content.
   Three per cent of programmes run a power analysis before prioritising;
   she is in the three per cent, and the point of quoting it is to say so
   without saying so.

   The instrument is the check itself, live. Put in a metric and the traffic
   you have and it answers the only question that matters first — can this
   be decided at all, and by when. Switching the metric is the demonstration:
   the same idea goes from unanswerable to a fortnight.
   ========================================================================= */
.method { display: grid; gap: clamp(24px, 4vw, 56px); margin-top: clamp(2rem, 5vh, 3.25rem); }
@media (min-width: 900px) { .method { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); align-items: start; } }

.method__stat { margin: 0; display: grid; gap: 10px; }
.method__stat b {
  font-family: var(--sc-font-mono); font-weight: 700;
  font-size: clamp(3rem, 2rem + 4vw, 5rem); line-height: .9;
  letter-spacing: -.04em; color: var(--ch);
  font-variant-numeric: tabular-nums;
}
.method__stat span { font-size: 15px; line-height: 1.6; color: var(--ink-2); max-width: 34ch; }
.method__src {
  margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--hair);
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
}
.method__body p { font-size: 16.5px; line-height: 1.7; color: var(--ink-2); max-width: 58ch; }
.method__body p + p { margin-top: 1em; }
.method__close {
  margin: clamp(2rem, 5vh, 3.5rem) 0 0; padding-top: clamp(1.4rem, 3vh, 2rem);
  border-top: 1px solid var(--ch);
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1.2rem, 1rem + 1.3vw, 2rem); line-height: 1.25;
  letter-spacing: -.03em; color: var(--sc-ink); max-width: 30ch;
}

/* ------------------------------------------------------------ the gate */
.pw { display: grid; gap: 24px; }
@media (min-width: 860px) { .pw { grid-template-columns: minmax(0,1fr) minmax(0,.85fr); gap: clamp(28px,4vw,56px); align-items: center; } }

.pw__dials { display: grid; gap: 18px; }
.pw__d { display: grid; gap: 8px; }
.pw__k {
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
}
.pw__k b { color: var(--ch); font-weight: 700; font-variant-numeric: tabular-nums; }

.pw__d select {
  appearance: none; width: 100%;
  background: var(--elev); color: var(--sc-ink);
  border: 1px solid var(--hair); border-radius: 0;
  padding: 10px 12px; cursor: pointer;
  font-family: var(--sc-font-mono); font-size: 11px; letter-spacing: .06em;
}
.pw__d select:focus-visible { outline: 2px solid var(--ch); outline-offset: 2px; }

.pw__d input[type="range"] { appearance: none; width: 100%; height: 22px; background: none; cursor: pointer; }
.pw__d input[type="range"]::-webkit-slider-runnable-track { height: 1px; background: var(--hair); }
.pw__d input[type="range"]::-moz-range-track { height: 1px; background: var(--hair); }
.pw__d input[type="range"]::-webkit-slider-thumb {
  appearance: none; width: 12px; height: 22px; margin-top: -10px;
  background: var(--ch); border: 0; border-radius: 0;
}
.pw__d input[type="range"]::-moz-range-thumb { width: 12px; height: 22px; background: var(--ch); border: 0; border-radius: 0; }
.pw__d input[type="range"]:focus-visible { outline: 2px solid var(--ch); outline-offset: 4px; }

.pw__out { display: grid; gap: 6px; align-content: center; }
.pw__verdict {
  margin: 0; min-height: 1.4em;
  font-family: var(--sc-font-mono); font-size: 9.5px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--i-live, #5CBF8A);
}
.pw__verdict.is-stop { color: var(--i-stop, #F0685C); }
.pw__weeks { margin: 0; display: flex; align-items: baseline; gap: 12px; }
.pw__weeks b {
  font-family: var(--sc-font-mono); font-weight: 700;
  font-size: clamp(2.6rem, 2rem + 3.2vw, 4.4rem); line-height: .9;
  letter-spacing: -.045em; color: var(--sc-ink);
  font-variant-numeric: tabular-nums;
  transition: color .3s;
}
.pw__weeks b.is-stop { color: var(--i-stop, #F0685C); }
.pw__weeks span { font-family: var(--sc-font-mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--faint); }
.pw__n { margin: 2px 0 0; font-family: var(--sc-font-mono); font-size: 10.5px; letter-spacing: .08em; color: var(--faint); font-variant-numeric: tabular-nums; }
.pw__bar { height: 2px; background: var(--hair); margin-top: 12px; overflow: hidden; }
.pw__bar span { display: block; height: 100%; width: 0; background: var(--ch); transition: width .35s var(--sc-ease-out, ease), background .3s; }
.pw__bar span.is-stop { background: var(--i-stop, #F0685C); }

/* the three ways out, which only appear once the gate has actually refused */
.pw__pivots { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--hair); }
.pw__ph { margin: 0 0 16px; font-size: 15px; line-height: 1.6; color: var(--sc-ink); max-width: 62ch; }
.pw__list { list-style: none; counter-reset: pv; margin: 0; padding: 0; display: grid; gap: 1px; }
.pw__list li {
  counter-increment: pv;
  display: grid; grid-template-columns: 26px minmax(0,1fr); gap: 0 14px;
  padding: 14px; background: var(--plate);
}
.pw__list li::before {
  content: counter(pv, decimal-leading-zero); grid-row: 1 / span 2;
  font-family: var(--sc-font-mono); font-weight: 700; font-size: 10px;
  letter-spacing: .1em; color: var(--ch); padding-top: 3px;
}
.pw__t { margin: 0 0 5px; font-family: var(--sc-font-display); font-weight: 500; font-size: 1.05rem; letter-spacing: -.02em; color: var(--sc-ink); }
.pw__list p:not(.pw__t) { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ink-2); max-width: 62ch; }
.pw__try {
  appearance: none; background: none; border: 0; border-bottom: 1px solid var(--ch);
  padding: 0; margin-left: 4px; cursor: pointer;
  font-family: var(--sc-font-mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ch);
}
@media (max-width: 560px) {
  .pw__list li { grid-template-columns: minmax(0,1fr); }
  .pw__list li::before { grid-row: auto; margin-bottom: 6px; }
}

/* =========================================================================
   Six pages instead of one — 2026-08-30

   The single page carried the whole site until it stopped being readable at
   eleven screens and five instruments. Her own copy master called this:
   one long-form editorial homepage first, then Work / Thinking / Make move
   into pages of their own as the site earns them. It has earned them.

   The index is the way in, not a summary of what is behind it: hero, six
   cards, and how to reach her. Each card carries its chapter's colour, so
   the palette that already ran down the long page now runs across the grid.
   ========================================================================= */
.idxgrid { display: grid; gap: 2px; margin-top: clamp(2rem, 5vh, 3.25rem); }
@media (min-width: 780px)  { .idxgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1180px) { .idxgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.idx {
  position: relative;
  display: grid;
  grid-template-areas: 'n k' 't t' 'd d' 'go go';
  grid-template-columns: auto 1fr;
  align-content: start; gap: 0 12px;
  padding: clamp(20px, 2.6vw, 30px);
  background: var(--plate);
  text-decoration: none; color: inherit;
  border: 1px solid transparent;
  transition: background .28s var(--sc-ease-out, ease), border-color .28s;
}
.idx:hover, .idx:focus-visible { background: var(--elev); border-color: color-mix(in oklab, var(--ic) 55%, transparent); }
.idx:focus-visible { outline: 2px solid var(--ic); outline-offset: -2px; }

.idx__n {
  grid-area: n;
  font-family: var(--sc-font-mono); font-weight: 700; font-size: 11px;
  letter-spacing: .1em; color: var(--ic); font-variant-numeric: tabular-nums;
}
.idx__k {
  grid-area: k;
  font-family: var(--sc-font-mono); font-size: 10px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--faint);
}
.idx__t {
  grid-area: t; margin-top: 20px;
  font-family: var(--sc-font-display); font-weight: 600;
  font-size: clamp(1.2rem, 1rem + .9vw, 1.62rem); line-height: 1.12;
  letter-spacing: -.03em; color: var(--sc-ink); max-width: 20ch;
}
.idx__d {
  grid-area: d; margin-top: 12px;
  font-size: 14px; line-height: 1.6; color: var(--ink-2); max-width: 42ch;
}
.idx__go {
  grid-area: go; margin-top: 22px;
  font-family: var(--sc-font-mono); font-size: 15px; color: var(--ic);
  transform: translateX(0);
  transition: transform .3s var(--sc-ease-out, cubic-bezier(.22,1,.36,1));
}
.idx:hover .idx__go, .idx:focus-visible .idx__go { transform: translateX(7px); }

/* The bar is links now. The chapter styling was written against `button`,
   so the anchors inherit the same rules rather than a second set of values
   that would drift from them. */
.topbar__nav a {
  display: inline-block; white-space: nowrap; text-decoration: none;
  padding: 6px 10px;
  font-family: var(--sc-font-mono); font-size: 10px;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--faint);
  transition: color var(--sc-d-fast) var(--sc-ease-out);
}
.topbar__nav a i { font-style: normal; color: var(--faint); opacity: .75; margin-right: 7px; transition: color var(--sc-d-fast) var(--sc-ease-out); }
.topbar__nav a:hover, .topbar__nav a:focus-visible { color: var(--ink-2); }
.topbar__nav a[aria-current="page"] { color: var(--nc, var(--sc-ink)); }
.topbar__nav a[aria-current="page"] i { color: var(--nc, var(--sc-ink)); opacity: 1; }
.topbar__mark { text-decoration: none; }

.wavefoot__right a { text-decoration: none; }
.wavefoot__right a[aria-current="page"] { color: var(--sc-ink); }

/* a chapter page has no hero to fall past, so it starts below the bar */
body.page-chapter main > section:first-child { padding-top: var(--bar); }
