/* ============================================================================
   css/howvex.css — "How VEX works" (sections/15-how-vex-works.html · js/howvex.js)
   Concept C, ported to the site. Semantic tokens only (tokens.css Part 2).
   No hex, no shadows, no gradients. Playfair is the section head's job (site.css);
   everything here is Geist body / Roboto Mono labels.

   DEFAULT = the static layout (no JS · prefers-reduced-motion · #noanim): the
   five beats stack as readable cards under their mono step labels —
     01 the export table · 02 the five stages and their metrics ·
     03 the three check lines · 04 the hub, the five drivers, the ranked panel
     and the lever · 05 the briefing card.
   Every word of that comes from the section markup, so the fallback needs no JS
   and no data file. JS adds .howvex--live, which pins the stage inside the
   laptop, turns the same elements into an absolutely-placed artboard and drives
   all five beats from scroll progress.

   THE ARTBOARD IS 1:1. js/howvex.js measures the laptop screen and lays the
   composition out at that exact size — there is no scale() anywhere — so every
   size below is the size it is on screen. Nothing here is under 11 px.

   THE DEPTH LADDER is the whole filtering system, and it is four numbers. They
   are read by JS (getComputedStyle) and used on the canvas too, which is why
   they are tokens and not literals in the script.
     --hv-o-cleared   a checked-and-cleared chip: still plainly there
     --hv-o-ghost     the field, once it has been checked
     --hv-o-recede    everything, behind the briefing card
     --hv-o-quiet     the hub, once the story has moved past it
   ============================================================================ */

.howvex {
  --hv-o-cleared: 0.28;
  --hv-o-ghost: 0.095;
  --hv-o-ghost-link: 0.085;
  --hv-o-recede: 0.13;
  --hv-o-quiet: 0.62;
}
[data-theme="dark"] .howvex {
  --hv-o-cleared: 0.34;
  --hv-o-ghost: 0.145;
  --hv-o-ghost-link: 0.075;
  --hv-o-recede: 0.17;
  --hv-o-quiet: 0.66;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) .howvex,
  [data-theme="system"] .howvex {
    --hv-o-cleared: 0.34;
    --hv-o-ghost: 0.145;
    --hv-o-ghost-link: 0.075;
    --hv-o-recede: 0.17;
    --hv-o-quiet: 0.66;
  }
}

.howvex__anchor { display: block; height: 0; }
.howvex__rail { display: none; }                     /* live only */
.howvex__say { display: none; }                      /* live only, narrow only */

/* ============================================================================
   THE ARTBOARD — shared components. Static geometry here, live geometry below.
   ============================================================================ */
.hvc { position: relative; }
.hvc p { max-width: none; }                          /* the artboard sets its own measure */
.hvc-b + .hvc-b { margin-top: var(--spacing-48); }
.hvc-b__k { margin: 0 0 var(--spacing-16); text-align: center; color: var(--muted); }
.hvc-field { display: none; }

/* --- 01 · the raw export --------------------------------------------------- */
.hvc-tbl {
  position: relative; width: min(100%, 760px); margin: 0 auto;
  color: var(--ink-2); font-variant-numeric: tabular-nums;
}
.hvc-tt { margin: 0 0 var(--spacing-8); color: var(--muted); white-space: nowrap; }
.hvc-tt--r { text-align: right; }
.hvc-tbl__grid { position: relative; }
.hvc-tr {
  display: grid; grid-template-columns: var(--hvc-cols, 8.5fr 13fr 8.5fr 10fr 13fr 16.5fr 14.5fr 16fr);
  align-items: center; column-gap: var(--spacing-8);
  height: var(--hvc-rowh, 30px); box-sizing: border-box;
  border-top: 1px solid var(--hair);
  font-size: var(--hvc-fs, 12.5px); line-height: 1;
  color: var(--ink-2); white-space: nowrap;
}
.hvc-tr > span { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.hvc-tr > span.r { text-align: right; color: var(--ink); }
.hvc-tr--h {
  height: var(--hvc-headh, 30px);
  border-top: 1px solid var(--hair-2); border-bottom: 1px solid var(--hair-2);
  color: var(--muted); font-size: var(--fs-label);
  letter-spacing: 0.1em; text-transform: uppercase;
}
.hvc-tr--h > span.r { color: var(--muted); }
.hvc-tbl__grid::after { content: ""; display: block; height: 1px; background: var(--hair-2); opacity: var(--hvc-chr, 1); }
.hvc-tbl > .hvc-tt:nth-of-type(3) { margin: var(--spacing-8) 0 0; }
.hvc-tt--count { display: none; }
.hvc-tr.is-off { display: none; }

/* --- 02 · the five stages -------------------------------------------------- */
.hvc-stages { list-style: none; margin: 0; padding: 0; }
.hvc-stages > li { max-width: none; }
.hvc-stages > li + li { margin-top: var(--spacing-24); }
.hvc-stage__k {
  position: relative; margin: 0 0 var(--spacing-8); padding-bottom: var(--spacing-8);
  color: var(--muted); font-size: var(--text-caption); letter-spacing: 0.12em;
  text-transform: uppercase; white-space: nowrap;
}
.hvc-stage__k i { font-style: normal; color: var(--hair-2); }
.hvc-stage__rule { position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: var(--hair); }
.hvc-stages ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--spacing-8) var(--spacing-24); }
.hvc-stages ul li {
  max-width: none; font-family: var(--font-mono); font-size: var(--text-caption);
  color: var(--muted); font-variant-numeric: tabular-nums;
}
.hvc-stages ul li::after { content: " " attr(data-dv); color: var(--ink-2); }
.hvc-stages ul li:not([data-dv])::after { content: ""; }
.hvc-stages ul li[data-surv] { color: var(--accent-blue); }
.hvc-stages ul li[data-surv]::after { color: var(--accent-blue); }
.hvc-legend { display: none; }

/* --- 03 · the three check lines -------------------------------------------- */
.hvc-caps { text-align: center; color: var(--muted); font-family: var(--font-mono); font-size: 12.5px; line-height: 1.55; letter-spacing: 0.01em; }
.hvc-caps span { display: block; }
.hvc-caps b { font-weight: var(--font-weight-regular); color: var(--ink); }

/* --- 04 · the chips, the ranked panel and the lever ------------------------ */
.hvc-edges { display: none; }
.hvc-nodes { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--spacing-12); }
.obj { position: relative; width: 220px; }
.obj > .inner { position: relative; transform-origin: 0 50%; }
.chip .inner {
  box-sizing: border-box; min-height: 44px; padding: 6px 12px 7px;
  display: flex; flex-direction: column; justify-content: center;
  background: var(--bg); border: 1px solid var(--hair); border-radius: var(--radius-md);
}
.chip .lab {
  font-size: 13px; font-weight: var(--font-weight-medium); line-height: 1.2;
  letter-spacing: -0.15px; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.chip .sub {
  margin-top: 3px; font-size: 11px; line-height: 1.28; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.chip .lab { max-width: var(--labw, 100%); }
.chip .sub { max-width: var(--txtw, 100%); }
.chip .tag {
  position: absolute; right: 11px; top: 50%; transform: translateY(-50%);
  font-family: var(--font-mono); font-size: var(--fs-label); letter-spacing: 0.04em;
  color: var(--ink); opacity: 0; pointer-events: none;
}
/* a cleared chip keeps its structure — at 28 % (34 % dark) it is still plainly
   a box that was looked at, which is the whole point of beat 4 */
.chip.done .inner { border-color: var(--hair-2); }
.chip.done .sub { opacity: 0; }

.chip.lit .inner { border-color: transparent; outline: 1.5px solid var(--accent-blue); outline-offset: -1.5px; }
.chip.lit .inner::before {
  content: ""; position: absolute; left: -4px; top: 50%; width: 8px; height: 8px;
  margin-top: -4px; border-radius: 50%; background: var(--accent-blue);
}
.chip.hub .inner {
  border-color: transparent; outline: 1.5px solid var(--ink); outline-offset: -1.5px;
  padding: 9px 14px 10px; min-height: 56px;
}
.chip.hub .lab { font-size: 20px; letter-spacing: -0.4px; }
.chip.hub .sub { font-size: var(--text-caption); margin-top: 3px; }
.chip.hub.lit .inner { outline-color: var(--accent-blue); }
.chip.hub.lit .inner::before { display: none; }

/* the lever — lemon is a MARKER, never text, never a hairline */
.chip.lever .inner { border-color: transparent; outline: 1.5px solid var(--ink); outline-offset: -1.5px; }
.chip.lever .inner::after {
  content: "LEVER"; position: absolute; right: -6px; top: -9px;
  font-family: var(--font-mono); font-size: var(--fs-label); letter-spacing: 0.1em;
  line-height: 1; padding: 3px 6px 4px; border-radius: 2px;
  background: var(--accent-lemon); color: var(--accent-lemon-ink);
}
.chip.lever .mark {
  position: absolute; left: -5px; top: 50%; width: 10px; height: 10px; margin-top: -5px;
  border-radius: 2px; background: var(--accent-lemon);
}

/* the ranked panel: ONE object, not five chips */
.hvc-rank .inner { background: var(--bg); border: 1px solid var(--hair); border-radius: var(--radius-md); padding: 10px 0 6px; }
.hvc-rank .rh {
  margin: 0; padding: 0 13px 8px; border-bottom: 1px solid var(--hair);
  color: var(--muted); letter-spacing: 0.12em;
}
.hvc-rank .row {
  position: relative; display: flex; align-items: center; justify-content: space-between;
  gap: var(--spacing-8); padding: 0 13px; height: 26px; font-size: 13px; color: var(--ink);
}
.hvc-rank .row .n { position: relative; }
.hvc-rank .row .v { font-family: var(--font-mono); font-size: var(--fs-label); color: var(--muted); font-variant-numeric: tabular-nums; }
.hvc-rank .row.pick.on { background: var(--accent-blue-wash); }
.hvc-rank .row.pick.on .n { font-weight: var(--font-weight-medium); padding-left: 13px; }
.hvc-rank .row.pick.on .v { color: var(--accent-blue); }
.hvc-rank .row.pick.on .n::before {
  content: ""; position: absolute; left: 0; top: 50%; width: 7px; height: 7px;
  margin-top: -3.5px; border-radius: 50%; background: var(--accent-blue);
}

.hvc-chain { margin: var(--spacing-16) 0 0; color: var(--muted); line-height: 1.9; text-transform: none; letter-spacing: 0.04em; }
.hvc-chain b { font-weight: var(--font-weight-regular); color: var(--ink); }
.hvc-chain i { font-style: normal; color: var(--accent-blue); }
.hvc-chain u { text-decoration: none; color: var(--on-lemon-quiet); background: var(--accent-lemon-quiet); padding: 1px 5px; border-radius: 2px; }
.hvc-chain em { font-style: normal; color: var(--hair-2); padding: 0 4px; }
.hvc-chain b, .hvc-chain i, .hvc-chain u { white-space: nowrap; }

/* static: beat 4 has to say what the animation says — four drivers carry their
   "cleared" tag, and the one that survives carries the blue ring */
.howvex:not(.howvex--live) .obj[data-obj^="f"]:not([data-surv]) .tag { opacity: 1; color: var(--muted); }
.howvex:not(.howvex--live) .obj[data-obj^="f"]:not([data-surv]) .inner { border-color: var(--hair-2); }
.howvex:not(.howvex--live) .obj[data-surv] .inner { border-color: transparent; outline: 1.5px solid var(--accent-blue); outline-offset: -1.5px; }

/* --- 05 · the briefing card (24 / 16 / 14 + mono 11) ----------------------- */
.hvc-card { width: min(100%, 620px); margin: 0 auto; }
.hvc-card .inner {
  background: var(--surface); border: 1px solid var(--hair-2); border-radius: var(--radius-xl);
  padding: 20px 24px 18px; transform-origin: 50% 50%;
}
.hvc-card .hd { display: flex; align-items: center; gap: 9px; margin: 0 0 14px; color: var(--muted); }
.hvc-card .hd .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--st-critical); flex: none; }
.hvc-card .hd .sev { color: var(--st-critical); margin-left: auto; }
.hvc-card .money {
  margin: 0 0 10px; font-size: var(--card-money); font-weight: var(--font-weight-medium);
  line-height: var(--leading-card-money); letter-spacing: var(--tracking-card-money);
  color: var(--ink); font-variant-numeric: tabular-nums; text-wrap: balance;
}
.hvc-card .money span { color: var(--ink-2); font-weight: var(--font-weight-regular); }
.hvc-card .lede2 { margin: 0 0 9px; font-size: var(--card-base); line-height: var(--leading-card); color: var(--ink); }
.hvc-card .why { margin: 0 0 14px; font-size: var(--card-small); line-height: var(--leading-card); color: var(--ink-2); }
.hvc-card .act {
  margin: 0 0 14px; padding: 11px 14px; border-radius: var(--radius-lg);
  background: var(--accent-lemon-quiet); color: var(--on-lemon-quiet);
  font-size: var(--card-base); line-height: 1.45;
}
.hvc-card .act b { display: block; margin-bottom: 4px; font-weight: var(--font-weight-regular); color: var(--ink-2); }
.hvc-card .ft { margin: 0; padding-top: 11px; border-top: 1px solid var(--hair); color: var(--muted); }

/* ============================================================================
   LIVE — the pinned stage, inside a laptop.
   The stage is sticky under the nav pill and SHORTER than the small viewport
   (100svh), so a mobile URL bar sliding in never moves the pin and never
   changes the document height. js/howvex.js writes .howvex__track's height in
   px: trackHeight = stageHeight + travel. Nothing inside the stage may change
   its own box while p runs — every beat is an absolute layer, and only
   transform / opacity / a handful of custom properties are written per frame.
   ============================================================================ */
.howvex--live {
  --hv-top: 84px;      /* the nav pill is 56 tall at top:16 → 72; +12 of air */
  --hv-gap: 16px;      /* air under the stage                                */
  --hv-pad: 10px;      /* the bezel                                          */
  --hv-deck: 22px;     /* hinge + deck under the lid                         */
  /* the widest lid whose 16:10 screen still fits the box; cqw / cqh are the
     .hv-laptop container, so this is exact at every stage size (no JS needed) */
  --hv-lid-w: min(96cqw, (100cqh - var(--hv-deck) - 2 * var(--hv-pad) - 2px) * 1.6 + 2 * var(--hv-pad) + 2px);
}
.howvex--live .howvex__track { height: var(--hv-track, 300svh); }
.howvex--live .howvex__stage {
  position: sticky; top: var(--hv-top);
  height: calc(100vh - var(--hv-top) - var(--hv-gap));
  height: calc(100svh - var(--hv-top) - var(--hv-gap));
}
/* the stage runs a touch wider than the reading wrap: every extra pixel of
   width is a wider laptop screen, and the composition wants the room */
.howvex--live .howvex__grid {
  display: grid; grid-template-columns: 210px minmax(0, 1fr);
  gap: var(--spacing-40); height: 100%; align-items: center; max-width: 1320px;
}
.howvex--live .howvex__rail { display: flex; flex-direction: column; gap: var(--spacing-20); list-style: none; margin: 0; padding: 0; }
.howvex--live .hvc-b__k { display: none; }

/* --- the laptop: a flat bezel, a hairline screen edge, a camera dot, a hinge
       and a hint of a deck. Borders and two flat surfaces only. --- */
.howvex--live .hv-laptop {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 100%; height: 100%; min-height: 0;
  container: hvlaptop / size; perspective: 1400px;
}
.howvex--live .hv-laptop__lid {
  display: block; position: relative; box-sizing: border-box; flex: 0 0 auto;
  width: var(--hv-lid-w); padding: var(--hv-pad);
  background: var(--surface-stage); border: 1px solid var(--hair-2); border-radius: 12px 12px 3px 3px;
  transform-origin: 50% 100%; transform: rotateX(var(--hv-lid-r, 0deg));
  will-change: transform;
}
.howvex--live .hv-laptop__cam { display: block; position: absolute; top: 3px; left: 50%; width: 3px; height: 3px; margin-left: -1.5px; border-radius: 50%; background: var(--hair-2); }
.howvex--live .hv-laptop__screen {
  display: block; position: relative; box-sizing: border-box; width: 100%; aspect-ratio: 16 / 10;
  background: var(--bg); border: 1px solid var(--hair-2); border-radius: 3px; overflow: hidden;
}
.howvex--live .hv-laptop__hinge { display: block; flex: 0 0 auto; width: 16%; height: 4px; box-sizing: border-box; background: var(--surface-stage); border: 1px solid var(--hair-2); border-top: 0; border-radius: 0 0 2px 2px; }
.howvex--live .hv-laptop__deck {
  display: block; position: relative; flex: 0 0 auto; box-sizing: border-box;
  width: calc(var(--hv-lid-w) + 4cqw); height: calc(var(--hv-deck) - 4px);
  background: var(--surface-stage); border: 1px solid var(--hair-2); border-top: 0; border-radius: 2px 2px 9px 9px;
}
.howvex--live .hv-laptop__deck::after { content: ""; position: absolute; left: 50%; bottom: 3px; width: 22%; height: 1px; margin-left: -11%; background: var(--hair-2); }
[data-theme="dark"] .howvex--live { --hv-shell: var(--surface-2); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) .howvex--live,
  [data-theme="system"] .howvex--live { --hv-shell: var(--surface-2); }
}
.howvex--live .hv-laptop__lid,
.howvex--live .hv-laptop__hinge,
.howvex--live .hv-laptop__deck { background: var(--hv-shell, var(--surface-stage)); }

/* --- the artboard: five absolute layers on one 1:1 canvas ----------------- */
.howvex--live .hvc { position: absolute; inset: 0; contain: layout paint; }
.howvex--live .hvc-b { position: absolute; inset: 0; margin: 0; pointer-events: none; }
.howvex--live .hvc-b--1 { z-index: 1; }
.howvex--live .hvc-b--2 { z-index: 2; }
.howvex--live .hvc-b--4 { z-index: 4; }
.howvex--live .hvc-b--3 { z-index: 5; }
.howvex--live .hvc-b--5 { z-index: 7; }

/* 01 · the table, absolutely placed from the same numbers the dots launch from */
.howvex--live .hvc-tbl { position: absolute; width: auto; margin: 0; }
.howvex--live .hvc-tt { position: absolute; margin: 0; top: -26px; left: 0; }
.howvex--live .hvc-tt--r { left: auto; right: 0; }
.howvex--live .hvc-tbl > .hvc-tt:nth-of-type(3),
.howvex--live .hvc-tbl > .hvc-tt:nth-of-type(4) { top: calc(var(--hvc-fy, 0px) + 11px); }
.howvex--live .hvc-tt--count { display: block; }
.howvex--live .hvc-tbl__grid { position: absolute; inset: 0; }
.howvex--live .hvc-tr { position: absolute; left: 0; right: 0; column-gap: 0; }
.howvex--live .hvc-tbl__grid::after { position: absolute; left: 0; right: 0; top: var(--hvc-fy, 0px); }

/* 02 · the field, and the five stage heads over it */
.howvex--live .hvc-field { display: block; position: absolute; left: 0; top: 0; }
.howvex--live .hvc-stages { position: absolute; inset: 0; }
.howvex--live .hvc-stages > li { position: absolute; margin: 0; }
.howvex--live .hvc-stages > li > ul { display: none; }
.howvex--live .hvc-stage__k { margin: 0; padding: 0; }
.howvex--live .hvc-stage__rule { top: var(--rt, 22px); bottom: auto; }
.howvex--live .hvc-legend {
  display: flex; align-items: center; gap: var(--spacing-8); position: absolute;
  margin: 0; color: var(--muted); opacity: 0; z-index: 3;
}
.howvex--live .hvc-legend .sw { width: 22px; height: 0; border-top: 1.5px dashed var(--hair-2); flex: none; }

/* 03 · the three check lines, cross-fading in place */
.howvex--live .hvc-caps { position: absolute; left: 0; right: 0; box-sizing: border-box; }
.howvex--live .hvc-caps span { position: absolute; left: 0; right: 0; top: 0; opacity: 0; }

/* 04 · the causal world */
.howvex--live .hvc-world { position: absolute; inset: 0; }
.howvex--live .hvc-edges { display: block; position: absolute; inset: 0; overflow: visible; pointer-events: none; z-index: 3; }
.howvex--live .hvc-nodes { display: block; position: absolute; inset: 0; z-index: 4; }
.howvex--live .obj { position: absolute; width: auto; transform: translateY(-50%); }
.howvex--live .obj > .inner { will-change: transform, opacity; }
.howvex--live .hvc-chain { position: absolute; margin: 0; opacity: 0; z-index: 5; }
.hvc-edge { fill: none; stroke: var(--hair-2); stroke-width: 1.4; stroke-dasharray: 3.5 5; stroke-linecap: round; }
.hvc-edge.on { stroke: var(--accent-blue); stroke-width: 1.75; stroke-dasharray: 4 4; }
.hvc-pulse { fill: none; stroke: var(--ink-2); stroke-width: 2.25; stroke-linecap: round; }

/* 05 · the card */
.howvex--live .hvc-card { position: absolute; width: auto; margin: 0; transform: translateY(-50%); opacity: 0; }
.howvex--live .hvc-card .inner { will-change: transform, opacity; }

/* the artboard sheds by height, exactly like a short window would. JS measures
   the screen and sets these — no container query can see the px the layout
   maths already knows. Three steps, and each one gives up the least it can:
     is-h1  compact — tighter boxes, the card's reasoning step goes
     is-h2  pinched — the chips lose their sub-line, the chain and footer go
     is-h3  extreme (a landscape phone) — the card's type steps down */
.howvex--live .hvc.is-h1 .chip .inner { min-height: 40px; padding: 4px 11px 5px; }
.howvex--live .hvc.is-h1 .chip.hub .inner { min-height: 48px; padding: 6px 13px 7px; }
.howvex--live .hvc.is-h1 .hvc-rank .inner { padding: 8px 0 5px; }
.howvex--live .hvc.is-h1 .hvc-rank .row { height: 23px; }
.howvex--live .hvc.is-h1 .hvc-card .inner { padding: 15px 18px 13px; }
.howvex--live .hvc.is-h1 .hvc-card .hd { margin-bottom: 10px; }
.howvex--live .hvc.is-h1 .hvc-card .why { display: none; }
.howvex--live .hvc.is-h1 .hvc-card .act { margin-bottom: 10px; padding: 9px 12px; }

.howvex--live .hvc.is-h2 .chip .sub { display: none; }
.howvex--live .hvc.is-h2 .chip .inner { min-height: 34px; padding: 4px 10px 5px; }
.howvex--live .hvc.is-h2 .chip.hub .inner { min-height: 42px; padding: 5px 12px 6px; }
.howvex--live .hvc.is-h2 .chip .tag { right: 8px; }
.howvex--live .hvc.is-h2 .chip.hub .lab { font-size: 17px; }
.howvex--live .hvc.is-h2 .hvc-rank .row { height: 21px; }
.howvex--live .hvc.is-h2 .hvc-card .ft { display: none; }
.howvex--live .hvc.is-h2 .hvc-chain { display: none; }

.howvex--live .hvc.is-h3 .hvc-card .inner { padding: 11px 14px 10px; }
.howvex--live .hvc.is-h3 .hvc-card .hd { margin-bottom: 7px; }
.howvex--live .hvc.is-h3 .hvc-card .money { font-size: 18px; margin-bottom: 7px; }
.howvex--live .hvc.is-h3 .hvc-card .lede2 { font-size: 13px; margin-bottom: 7px; }
.howvex--live .hvc.is-h3 .hvc-card .act { margin-bottom: 0; padding: 8px 11px; font-size: 13px; }
.howvex--live .hvc.is-h3 .hvc-card .act b { margin-bottom: 2px; }

/* --- the rail (live): five mono steps, a hairline bar under each fills ----- */
.howvex__rail li { max-width: none; }
.hv-step { position: relative; display: block; width: 100%; text-align: left; padding: 0 0 var(--spacing-12); color: var(--muted); transition: color var(--ui-duration) var(--ui-ease); }
.hv-step__k, .hv-step__t { font-family: var(--font-mono); font-size: var(--fs-label); letter-spacing: var(--tracking-label); text-transform: uppercase; line-height: var(--leading-label); }
.hv-step__k { margin-right: var(--spacing-8); }
.hv-step__t--s { display: none; }
.hv-step__d { display: block; margin-top: 6px; font-size: 13px; line-height: 1.45; letter-spacing: 0; color: var(--muted); max-width: 24ch; }
.hv-step.is-on { color: var(--ink); }
.hv-step.is-on .hv-step__d { color: var(--ink-2); }
.hv-step__bar { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--hair); overflow: hidden; }
.hv-step__bar::after { content: ""; position: absolute; inset: 0; background: var(--ink); transform: scaleX(var(--hv-fill, 0)); transform-origin: left center; }

/* the active beat's line, for the widths where the rail has no room for it */
.howvex--live .howvex__say {
  display: none; margin: 0; text-align: center; color: var(--ink-2);
  font-size: 15px; line-height: 1.35; letter-spacing: -0.2px;
  min-height: 1.35em; text-wrap: balance;
}
.howvex--live .howvex__say b { font-weight: var(--font-weight-medium); color: var(--ink); }

/* the rail tracks scroll exactly in live mode — a 180 ms colour transition at a
   beat boundary is both a lag and a repaint chain we do not need while scrubbing */
.howvex--live .hv-step { transition: none; }

/* --- the laptop wrappers are inert until live: the static stack is untouched --- */
.hv-laptop, .hv-laptop__lid, .hv-laptop__screen { display: contents; }
.hv-laptop__cam, .hv-laptop__hinge, .hv-laptop__deck { display: none; }

/* ============================================================================
   RESPONSIVE
   ============================================================================ */
/* the rail goes horizontal above the laptop below 1280: at 1024 that is worth
   about 230 px of extra screen width, which is the whole composition */
@media (max-width: 1279px) {
  .howvex--live .howvex__grid { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto minmax(0, 1fr); align-items: stretch; row-gap: var(--spacing-12); }
  .howvex--live .howvex__rail { grid-row: 1; }
  .howvex--live .howvex__say { grid-row: 2; }
  .howvex--live .hv-laptop { grid-row: 3; }
  .howvex--live .howvex__rail { flex-direction: row; gap: var(--spacing-12); }
  .howvex--live .howvex__rail li { flex: 1 1 0; }
  .howvex--live .hv-step__d { display: none; }
  .howvex--live .hv-step { padding-bottom: 8px; }
  .howvex--live .howvex__say { display: block; }
}

/* static stack, narrow: the export drops to five columns, same as the phone artboard */
@media (max-width: 719px) {
  .hvc-tr { grid-template-columns: 15.5fr 23.5fr 22.5fr 17fr 21.5fr; column-gap: var(--spacing-4); font-size: 12px; }
  .hvc-tr > span:nth-child(3), .hvc-tr > span:nth-child(4), .hvc-tr > span:nth-child(5) { display: none; }
  .hvc-card .inner { padding: 16px 18px 14px; }
  .hvc-chain { line-height: 2.1; }

  .howvex--live { --hv-top: 76px; --hv-gap: 12px; --hv-pad: 5px; --hv-deck: 14px; --hv-lid-w: 94cqw; }
  .howvex--live .howvex__grid { row-gap: var(--spacing-8); }
  .howvex--live .howvex__rail { gap: 6px; }
  .howvex--live .hv-step { padding-bottom: 6px; }
  /* five steps have to sit inside 342 px (≈ 64 px each): the number over a
     short title that is allowed to wrap onto two lines. Nothing shrinks below
     11 px — the long titles simply step aside, and the line under the rail
     always names the beat in full. */
  .howvex--live .hv-step__k, .howvex--live .hv-step__t { display: block; letter-spacing: 0.02em; line-height: 1.3; }
  .howvex--live .hv-step__t { display: none; }
  .howvex--live .hv-step__t--s { display: block; }
  .howvex--live .hv-step__k { margin: 0 0 2px; }
  .howvex--live .howvex__say { font-size: 13.5px; line-height: 1.3; }
  /* the lid fills the portrait box — a 16:10 letterbox here would be 175 px tall */
  .howvex--live .hv-laptop__lid { flex: 1 1 auto; min-height: 0; border-radius: 8px 8px 2px 2px; }
  .howvex--live .hv-laptop__screen { height: 100%; aspect-ratio: auto; border-radius: 2px; }
  .howvex--live .hv-laptop__cam { top: 1px; width: 2px; height: 2px; margin-left: -1px; }
  .howvex--live .hv-laptop__deck { border-radius: 2px 2px 6px 6px; }
}

/* the artboard's own five-column export (phone shape), set by JS */
.howvex--live .hvc.is-c5 .hvc-tr > span:nth-child(3),
.howvex--live .hvc.is-c5 .hvc-tr > span:nth-child(4),
.howvex--live .hvc.is-c5 .hvc-tr > span:nth-child(5) { display: none; }

/* short and wide (landscape phones, short laptop windows): the 16:10 screen
   would be a postage stamp in a tall empty band, so the lid fills the box */
@media (min-width: 720px) and (max-height: 620px) {
  .howvex--live { --hv-pad: 5px; --hv-deck: 10px; --hv-lid-w: 96cqw; --hv-top: 72px; --hv-gap: 10px; }
  .howvex--live .hv-laptop__lid { flex: 1 1 auto; min-height: 0; border-radius: 8px 8px 2px 2px; }
  .howvex--live .hv-laptop__screen { height: 100%; aspect-ratio: auto; }
  .howvex--live .hv-laptop__cam { top: 1px; width: 2px; height: 2px; margin-left: -1px; }
  /* every px of a 390 px-tall viewport counts: thinner chrome, tighter rail */
  .howvex--live .howvex__grid { row-gap: 6px; }
  .howvex--live .hv-step { padding-bottom: 5px; }
  .howvex--live .howvex__say { display: none; }
}

/* --- reduced motion / #noanim: no live mode (JS never adds the class), and
       nothing waits on a transition --- */
@media (prefers-reduced-motion: reduce) { .hv-step { transition: none; } }
.no-anim .hv-step { transition: none; }
