/* ================================================================
   COMPONENT: CASE VISUALS (Pindo + shared metrics)
   Teal-on-paper artifacts that make the Pindo case SHOW. Rebuilt for
   restraint: ink + ONE teal accent, the --pindo-rose pulled back to a
   true whisper (a faint tint, never saturated text), precise
   alignment, generous space, NO box-shadow at rest. No scattered
   marks, no filler glyphs. Static by default with one reveal-keyed
   draw-on (the pool fill); full reduced-motion / no-JS fallback to the
   finished state. Diagrams carry role="img" + aria-label; meaning
   never rides on color alone.

   Linked on work/pindo.html and work/dev-studio.html, never on Japan.
   Elements: .case-clock  .case-address  .case-guide  .case-loop  .case-metrics
   plus the page's two detail crops (.case-shot--join-sheet /
   --pool-card), which are captured UI rather than drawn artifacts.

   `.case-metrics` is the ONE piece here that is not Pindo-specific — it
   is the big-numeral outcome row, and any case page can wear it. Its
   grid offset therefore lists every page that uses it; the Pindo-only
   artifacts above keep their own scope.
   ================================================================ */

/* ================================================================
   PINDO DRAWS ITS GRID — the rail, plus a scroll-pressed crease
   ================================================================
   The other three case pages hang a 220px label margin left of the
   reading column, and blocks choose between two left edges: the column
   (rail + gap = 268 in) for prose and most plates, or the section edge
   for the two `--wide` ones. That works while `--wide` is rare.
   Chapter 2 pushed it past that: with a POC board AND a media stepper
   on the canvas, the left edge crossed 192 ↔ 460 four times inside one
   chapter, and the page read as though it could not decide where it
   started.

   Deleting the rail was tried first and reverted — it fixed the zigzag
   by having less structure rather than by making the structure legible,
   and it cost the chapter labels their margin. What ships keeps both
   axes and DRAWS the boundary between them, so a block starting left of
   the line reads as a deliberate breakout instead of a near-miss.

   The crease is a real element (`.case-crease`), the first child of each
   section, pressed down as the section arrives by
   `js/modules/case-crease.js`. Without GSAP it simply sits at full length.

   IT NOW LIVES IN `case.css`, ON `.case-page` — all four case pages draw
   their grid, not just this one. What is left in this file is only what is
   genuinely Pindo's: the body's track pin (this page deleted its empty
   rails) and the page-local plate offsets.
   ================================================================ */

@media (min-width: 1025px) {
  /* PINDO HAS NO EMPTY RAIL DIVS — its ten unused ones were deleted, so a
     `.case-grid` row often holds only a body. Pinning the body to track 2
     keeps it on the column axis without a filler element. The other three
     pages still carry real `.case-rail` divs and need nothing here.

     The vertical crease itself now lives in `case.css`, on `.case-page`:
     every case page draws its grid, not just this one. */
  .case-pindo .case-body { grid-column: 2; }

  /* Plates return to the reading column; `--wide` blocks (the POC board,
     the media stepper) keep their own `margin-left: 0` and cross the
     crease, which passes behind them. */
  .case-pindo .case-thesis,
  .case-pindo .case-stats,
  .case-pindo .case-clock,
  .case-pindo .case-address,
  .case-pindo .case-guide,
  .case-pindo .case-loop,
  .case-pindo .case-metrics,
  .case-devstudio .case-metrics {
    margin-left: calc(var(--case-rail) + var(--sp-12));
    max-width: var(--case-column);
  }

  /* The next-project card is not part of the reading grid — a single
     full-width control leaving the page, no rail beside it and no column to
     announce. It gets no crease element at all (see the markup), so there is
     nothing to hide here. The cover is excluded the same way. */
}

/* --- The chip override is GONE (2026-08-19) ---------------------
   `.case-pindo .cn-label` used to re-mute the chips to 9% ground / 48% ink,
   under the old rule that the saturated brand red was reserved for captured
   product screens. That rule died when the case took the product's colour as
   its page accent, and the override outlived it — so the corrected base rule
   in `case.css` was being cancelled by a page scope written for a world that
   no longer existed. **An override survives its own reason silently; a token
   change does not go looking for them.** After re-pointing an accent, grep
   for scoped overrides of it before assuming the page updated.

   Measured, the stale override was the wrong colour twice: 48% into
   `--gray-900` is saturation 0.61 against the brand's 0.75, so the chips read
   maroon rather than Pindo red, and the 9% ground sat at 1.16:1 against paper
   — a chip you had to be told was there. The base rule is 15% / 82%. */

/* ── THE CASE WEARS THE PRODUCT'S ACCENT, NOT THE SITE'S ──────────
   Pindo's teal highlights are now rose. This is the eyebrow lesson taken
   to its conclusion: **when two accent systems meet, the one describing
   the subject wins and the one describing the container gives way.** A
   case study is a piece about a product; its accents should be that
   product's. Teal remains the portfolio's own colour and still owns the
   homepage, the navbar and the hero.

   IT IS A TOKEN RE-POINT, NOT A SET OF COLOUR EDITS. Every component here
   already reads `--accent` / `--accent-dk` / `--text-accent-ink`, so
   remapping those three inside the case's scope recolours the kicker, the
   `.case-em` heading word, `.case-link`, the clock fill and its live stage
   dot, the chosen-option verdict, stat terms and the next-project label in
   one place. Never hard-code a rose into a component — add it here, or the
   next page that wants its own colour has to hunt.

   SCOPE IS `main.case` PLUS `.chapter-nav`, DELIBERATELY. Both belong to
   the case. The site navbar sits outside `<main>` and keeps teal, because
   chrome that appears on every page must not change colour per page — that
   is the difference between a branded article and a re-skinned site.

   ONE VALUE COVERS ALL THREE STEPS, WHICH TEAL COULD NOT. The teal ladder
   exists because `--teal-accent` is 2.74:1 and fails text; rose starts at
   **5.16:1 on paper** — above even the small-text teal step (4.94:1) — so
   the same value is legal for body text, for large serif and for a fill.
   If a lighter rose is ever introduced for graphics, it needs its own step
   and its own contrast check; do not lighten this one in place.

   `--pindo-rose` IS THE BRAND'S OWN `#cb1d45`, not a muted draw from it. It
   was #c0304f while a rule reserved the real red for captured product
   screens; once the page took the product's colour as its accent that rule
   had nothing left to protect, and the muted value was measurably worse —
   13% less chroma for 0.03 of contrast. See `tokens.css`. The chips keep
   their quiet by mixing (`.cn-label`, `case.css`), which is where muting
   belongs: in the derivation, never in the source value. */
.case-pindo main.case,
.case-pindo .chapter-nav {
  --accent:          var(--pindo-rose);
  --accent-dk:       var(--pindo-rose);
  --text-accent-ink: var(--pindo-rose);
}

/* ── THE TWO FISERV CASES TAKE FISERV ORANGE ──────────────────────
   Same mechanism, same scope rule: the case's own content and its chapter
   nav, never the site navbar.

   THESE TAKE THREE VALUES WHERE PINDO TOOK ONE, and the reason is
   measured rather than stylistic. `--fiserv-orange` (#FF6600, the
   published brand value, Pantone 1505 C) is **2.74:1 on paper — the exact
   twin of `--teal-accent`** — so like teal it can fill a bar and cannot
   set a word. `--pindo-rose` starts at 5.16:1 and needed no ladder at all.
   **A brand colour's contrast decides how many steps it needs; the number
   of steps is not a house style.** See `tokens.css` for the full ladder.

   Japan is deliberately absent: it stays on the site's teal (see
   `DESIGN.md → A case page wears the product's accent`), which is also why
   it carries no `case-` modifier on `<body>`. */
.case-devstudio main.case,
.case-devstudio .chapter-nav,
.case-vision main.case,
.case-vision .chapter-nav {
  --accent:          var(--fiserv-orange);   /* fills and marks only */
  --accent-dk:       var(--fiserv-dk);       /* large serif — `.case-em` */
  --text-accent-ink: var(--fiserv-ink);      /* every small label and link */
}

/* Shared mat + caption (matches .case-figure). */
.case-clock,
.case-address,
.case-guide,
.case-loop {
  margin: var(--sp-8) 0;
}
.case-clock__mat,
.case-address__mat,
.case-guide__mat,
.case-loop__mat {
  background: var(--surface-alt);
  border-radius: var(--radius-card);
  corner-shape: squircle;
  padding: var(--sp-10);
}
.case-clock figcaption,
.case-address figcaption,
.case-guide figcaption,
.case-loop figcaption {
  font-size: var(--type-body2-size);
  color: var(--text-tertiary);
}

/* Same rule as `.case-figure__mat figcaption` — the caption sits INSIDE the
   card and runs its full width. These mats are flex columns, so the
   caption is simply the last item and needs no grid placement; it only needs
   the 560 cap lifted and a gap that reads as "belonging to" rather than
   "next to". */
.case-clock__mat figcaption,
.case-address__mat figcaption,
.case-guide__mat figcaption,
.case-loop__mat figcaption {
  max-width: none;
  margin-top: var(--sp-2);
}

.viz-label {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/* ================================================================
   1 · DUAL-CLOCK — two clean rows, one teal accent
   Top: the pool bar, filling toward a single ship mark.
   Bottom: the order, stepping through four stages.
   The "one box" lives in the caption, not a glyph.
   ================================================================ */
.case-clock__mat { display: flex; flex-direction: column; gap: var(--sp-10); }
.case-clock__row { display: flex; flex-direction: column; gap: var(--sp-4); }
.case-clock__label {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-secondary);
}

/* Pool bar */
.case-clock__bar { position: relative; }
.case-clock__track {
  position: relative;
  height: 6px;
  border-radius: 999px;
  background: var(--paper-tint-3);
}
.case-clock__fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 60%;
  border-radius: 999px;
  background: var(--accent);
}
.case-clock__mark { position: absolute; top: -7px; bottom: -7px; width: 0; }
.case-clock__mark::before {
  content: "";
  position: absolute;
  inset: 0;
  left: -1px;
  width: 2px;
  border-radius: 2px;
  background: var(--text-secondary);
}
/* THE MARK SITS AT THE TRACK'S END, AND THE LABEL HANGS OFF ITS RIGHT EDGE.
   It used to stand at 82% with the track running on past it, which asks a
   question the figure cannot answer: what is the last 18% for? A pool ships
   when it reaches its weight — there is nothing beyond that point to draw.
   The product agrees: the group-buy card reads `23kg/50kg` and its bar ends
   at the target. **A progress track's end IS its goal; a threshold drawn
   short of the end invents a quantity nobody defined.**

   Right-aligned rather than centred because a centred label at 100% would
   hang half its width past the plate. */
.case-clock__mark span {
  position: absolute;
  bottom: calc(100% + 6px);
  right: 0;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/* Order stepper — four even stages, hairline connector */
.case-clock__stages {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  padding-top: 2px;
}
.case-clock__stages::before {
  content: "";
  position: absolute;
  top: 7px;
  left: 12.5%;
  right: 12.5%;
  height: 1px;
  background: var(--paper-tint-4);
}
.case-clock__stage {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  text-align: center;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.case-clock__dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--paper-tint-1);
  box-shadow: inset 0 0 0 1.5px var(--paper-tint-5);
}
.case-clock__stage.is-done { color: var(--text-secondary); }
.case-clock__stage.is-done .case-clock__dot { background: var(--text-secondary); box-shadow: none; }
.case-clock__stage.is-now { color: var(--text-primary); }
.case-clock__stage.is-now .case-clock__dot { background: var(--accent); box-shadow: none; }

/* Draw-on — the pool fill grows to its mark when revealed.

   THIS SHIPPED BROKEN AND THE FAILURE IS INSTRUCTIVE. The collapsed start
   state was written as `body.js-ready …{ transform: scaleX(0) }` with the
   release keyed to `.case-clock.is-visible` — but **`.is-visible` is added
   only by `scroll-reveal.js`'s `initFallback()`**, the branch taken when the
   GSAP CDN fails or motion is reduced. On every normal visit GSAP drives the
   reveals, that class never lands, and the bar sat at `scaleX(0)` forever: a
   figure captioned *the pool fills toward its weight* rendering an empty
   track. It was invisible to us because a hidden preview tab and a
   reduced-motion check both take the fallback path, where it works.

   THE RULE: a start state must be gated by the SAME condition as its
   release. This one was gated on `body.js-ready` (always true) and released
   on a fallback-only class (usually false), so the two could never meet.
   Anything that hides content must be written as `html:not(.gsap-motion)` —
   the house gate — or written by the module that also unhides it.

   Grows via `scaleX`, not `width`: `width` is a LAYOUT property and 1.2s of
   it relayouts the bar on every frame. The bar is laid out at its final 60%
   and scaled in from the left edge. */
.case-clock__fill { width: 60%; }

/* Fallback path only. Under GSAP the bar is drawn by `case-clock.js`, which
   writes its own start state and can therefore also clear it. */
html:not(.gsap-motion) body.js-ready .case-clock__fill {
  transform: scaleX(0);
  transform-origin: 0% 50%;
  transition: transform 1.2s var(--ease-out);
}
html:not(.gsap-motion) body.js-ready .case-clock.is-visible .case-clock__fill {
  transform: scaleX(1);
}
@media (prefers-reduced-motion: reduce) {
  html:not(.gsap-motion) body.js-ready .case-clock__fill { transform: none; transition: none; }
}

/* ================================================================
   2 · SELF-NAMING ADDRESS — the flagship anatomy
   The address you copy, then the code split into its three parts.
   Rose appears only as a faint underlay in the code (it IS the
   mechanism).
   ================================================================ */
.case-address__mat { display: flex; flex-direction: column; gap: var(--sp-6); }

.case-address__card {
  background: var(--paper-tint-1);
  border-radius: var(--radius-sm);
  corner-shape: squircle;
  padding: var(--sp-6);
  font-family: var(--font-body);
  font-weight: var(--weight-book);
  font-size: var(--type-body1-size);
  line-height: 1.8;
  color: var(--text-primary);
}
.case-address__card .viz-label { display: block; margin-bottom: var(--sp-4); }
.case-address__code { font-family: var(--font-mono); letter-spacing: var(--tracking-code); }
.case-address__code b { font-weight: inherit; padding: 2px 3px; border-radius: 3px; }
.case-address__code .seg--transport { background: color-mix(in srgb, var(--pindo-rose) 10%, var(--paper)); }
.case-address__code .seg--pool      { background: color-mix(in srgb, var(--pindo-rose) 17%, var(--paper)); }
.case-address__code .seg--user      { background: color-mix(in srgb, var(--pindo-rose) 25%, var(--paper)); }

.case-address__anatomy { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-4); }
.case-address__seg-block { display: flex; flex-direction: column; gap: var(--sp-3); }
.case-address__seg {
  font-family: var(--font-mono);
  font-size: 22px;
  letter-spacing: var(--tracking-code);
  color: var(--text-primary);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-sm);
  corner-shape: squircle;
  text-align: center;
}
.case-address__seg-block:nth-child(1) .case-address__seg { background: color-mix(in srgb, var(--pindo-rose) 10%, var(--paper)); }
.case-address__seg-block:nth-child(2) .case-address__seg { background: color-mix(in srgb, var(--pindo-rose) 17%, var(--paper)); }
.case-address__seg-block:nth-child(3) .case-address__seg { background: color-mix(in srgb, var(--pindo-rose) 25%, var(--paper)); }
.case-address__cap {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
  text-align: center;
  line-height: 1.5;
}
.case-address__cap b { color: var(--text-secondary); font-weight: var(--weight-book); }

.case-address__hint {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/* ================================================================
   3 · THE POOL CARD CROP — Chapter 1's evidence
   Replaces `.case-poolbar`, a pair of STYLISED before/after bars that
   sat in a fold-compare. Two reasons they went. The chapter's argument
   moved: it is no longer "the bar's arithmetic was wrong" but "we
   designed the input that lets the bar run ahead of the parcels", and
   an input flow cannot be drawn as two bars. And once the real screens
   were available, an illustrated bar next to a captured one is the
   weaker of the two — it also quoted weights (18/60, 47/60) that the
   real screen contradicts (23/50).

   Geometry: the source is 590x2115 and only its top card argues this
   chapter — Active, the 23/50 kg bar, and the editable estimate row
   under it. Everything below is the shipping address, which belongs to
   Chapter 2. Slice = y 180..630 of 590 wide.
   ================================================================ */
.case-shot--pool-card { aspect-ratio: 590 / 450; }
.case-shot--pool-card img { margin-top: -30.5%; }

/* The join sheet, cropped the same way and for a sharper reason: the two
   captures are IDENTICAL above the sheet — same blurred group-progress screen
   behind both — so shown whole, the pair spent ~450px per column proving they
   are the same screen, and the one thing the figure exists to show (range vs
   exact) arrived below the fold of the figure itself. Cropped from y=700 of
   1704, which keeps enough of the blurred screen above the sheet's top edge to
   read as an overlay rising over a flow, and starts the pair on the difference. */
.case-shot--join-sheet { aspect-ratio: 786 / 1004; }
.case-shot--join-sheet img { margin-top: -89.1%; }

/* ================================================================
   4 · THE INTAKE LOOP'S SIX SCREENS — no slice offsets any more
   Every step used to be cropped to the stepper's declared ratio, with a
   per-step starting line stated here (`margin-top`, later
   `object-position`). The rail now stands the WHOLE phone on a dark ground,
   so the box matches each capture's own ratio and there is nothing left to
   crop — those five rules were deleted rather than left sitting inert, and
   the `.cs-shot--*` classes went with them.

   What the crops were protecting is worth recording, because it is the
   reason not to reintroduce them casually: `admin-test.pindo.info` in the
   merchant screens' URL bar was the proof of the chapter's product argument
   — that the warehouse tool is a web page on a phone the merchant already
   owns, not a ¥10,000 scanner-gun terminal. Standing the whole phone in the
   well renders that domain at 41% of its design size, which is a smear on a
   desktop. THE LIGHTBOX IS WHAT PAYS THAT BACK: every screen on a case page
   opens at full size on click, so the evidence is one tap away instead of
   cropped into the thumbnail. See `css/components/lightbox.css`.

   THE PROOF IS GONE AS OF THE 1179×2556 RE-EXPORT (2026-08-18). The three
   warehouse captures were redrawn with a native title bar — `Scan label`,
   `Check-in result`, `Weigh and classify` — in place of the Safari chrome, so
   there is no URL on the page any more. Step 02's copy dropped *"look at the
   URL"* with them and states the claim plainly instead. That is a real loss:
   a demonstrated claim went back to being an asserted one, and no crop,
   lightbox or sizing change can recover it. **If the warehouse screens are
   ever re-exported again, export them from Safari with the address bar
   visible** — it is the cheapest evidence in the case study.
   ================================================================ */

/* ================================================================
   4 · BIG-NUMBER METRICS — replaces the plain stat row
   ================================================================ */
/* Segmented by tone, not by lines — matches `.case-stats` exactly (same slot
   in the page). The per-column toppers are gone; the plate and the gap carry
   the separation. See case.css → `.case-stats` for the reasoning. */
.case-metrics {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-8);
  margin-top: var(--sp-8);
  background: var(--surface-alt);
  border-radius: var(--radius-card);
  corner-shape: squircle;
  padding: var(--sp-6);
}
/* Dev Studio reports TWO measures, not three. The row is sized to the
   numbers that exist rather than padded to fill the grid — a third
   column here would either invent a metric or leave a hole. */
.case-devstudio .case-metrics { grid-template-columns: repeat(2, 1fr); }
.case-metric {
  min-width: 0;
}
.case-metric__label {
  display: block;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-accent-ink);
  margin-bottom: var(--sp-4);
}
/* THE NUMERAL REGISTER. Statistics get to be big and expressive — but
   `--type-case-numeral` is deliberately capped below `--type-case-chapter`,
   so a number never outranks the heading of the section it sits in. At 56px
   this read as the largest thing on the page after the cover: bigger than
   every chapter heading (52px), and at 769–1024px exactly equal to the cover
   title itself. */
.case-metric__value {
  display: block;
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  font-size: var(--type-case-numeral);
  line-height: var(--leading-none);
  letter-spacing: -0.01em;
  color: var(--text-primary);
}
.case-metric__value .unit { font-size: 20px; color: var(--text-tertiary); margin-left: 5px; letter-spacing: 0; }
.case-metric__note { display: block; margin-top: var(--sp-4); font-size: var(--type-body2-size); line-height: 1.45; color: var(--text-tertiary); }

/* ================================================================
   5 · THE COPY GUIDE — the judgment, quoted
   "I wrote my judgment down where the tools could use it" is the case's
   differentiating claim, and it was the one strong claim on the page with
   nothing to look at. There is no product SCREEN for a rules file, which is
   exactly the condition under which a drawn artifact is allowed (see the
   deleted `.case-push` note below): this quotes a real document rather than
   inventing a fictional interface.

   IT WEARS THE SAME TWO-LAYER SKIN AS `.case-address` — `--surface-alt` mat
   holding a `--paper-tint-1` card — because that is this page's artifact
   idiom, not a new one. Rule: change an artifact's CONTENT, never its stock.

   NO RULES BETWEEN THE ROWS. Four key/value pairs separated by padding alone,
   the way `.case-meta` is. A hairline here would be the fifth line on a page
   whose whole separation ladder is crease → air → tone → space.
   ================================================================ */
.case-guide__file {
  background: var(--paper-tint-1);
  border-radius: var(--radius-sm);
  corner-shape: squircle;
  padding: var(--sp-6);
}
.case-guide__file .viz-label { display: block; margin-bottom: var(--sp-5); }

.case-guide__rules { margin: 0; }

/* The term column is fixed so all four values start on one axis — a rules
   file reads as a spec because its right-hand edge is a column, not a ragged
   run. 108px fits "Tiebreak" at the label size with room to spare. */
.case-guide__rule {
  display: grid;
  grid-template-columns: 108px minmax(0, 1fr);
  gap: var(--sp-5);
  align-items: baseline;
  padding: var(--sp-3) 0;
}
.case-guide__rule dt {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.case-guide__rule dd {
  margin: 0;
  font-family: var(--font-body);
  font-weight: var(--weight-book);
  font-size: var(--type-body1-size);
  line-height: 1.5;
  color: var(--text-primary);
}
/* The one focal mark in the plate. 22px matches `.case-address__seg` — the
   sibling artifact's own numeral step — so the two agree, and it stays far
   below `--type-case-beat` (32px) so a number never outranks the heading it
   sits under (DESIGN.md → nothing outranks its section's heading). */
.case-guide__num {
  font-family: var(--font-mono);
  font-weight: var(--weight-book);
  font-size: 22px;
  letter-spacing: var(--tracking-code);
  color: var(--text-primary);
  margin-right: 2px;
}

/* ================================================================
   5 · THE BUILD LOOP — the six phases every feature runs
   Same two-layer skin as `.case-guide` (`--surface-alt` mat holding a
   `--paper-tint-1` card) because the plate is this page's one artifact
   idiom. WHAT DIFFERS IS CONTENT, NOT STOCK: a numbered path instead of a
   key/value spec. Do not give it a skin of its own to "vary" the page —
   that is the mistake DESIGN.md → Two plate families rules out.

   THE NUMERALS LEAD AND STAY SMALL. 12px mono against `.case-guide`'s 22px
   focal numeral is deliberate: there are six of them here and one there, so
   at feature size they would read as the loudest thing in the chapter and
   outrank the heading. A sequence is stated by ORDER, not by size.

   IT IS A DRAWN GRAPH, NOT A LIST (rebuilt 2026-08-19). It shipped as six rows
   of text — phase names, then phase names plus their outputs — and both were a
   table of contents drawn as an artifact, which is what made this chapter read
   as thin. A list can only ever restate the prose beside it.

   SO IT CHANGED IDIOM, AND THAT MOVES IT TO THE OTHER FAMILY. `.case-guide`
   quotes a document, so it keeps the `--paper-tint-1` inner card — the card IS
   the "quoted page" layer. A diagram quotes nothing, so this now sits DIRECTLY
   ON THE MAT exactly as `.case-clock` does, with no inner card. That is the
   readable difference between the page's two artifact families; do not put the
   card back, and do not give `.case-clock` one.

   THE RETURN ARCS ARE THE WHOLE POINT. The playbook states that the order holds
   but work goes backward as a matter of course: phase 5 returns a screen to 4
   for a state nobody drew, 4 returns it to 3 for a sentence that stopped being
   true. A straight 1→6 row asserts the opposite. Those two dashed arcs are the
   only part of this artifact a text list could not have carried — which is the
   test for whether a diagram earns its place. Dashed because the return is
   conditional, not scheduled.

   PHASE 5 IS THE ONE MARKED NODE — filled ink at r=7 against r=4.5 tertiary
   dots — because that is where the loop hands back to a person. INK, never
   teal: the accent is budgeted and a phase is not a label. The single non-ink
   value in the drawing is the spine, which borrows `--paper-tint-3` from
   `.case-clock__track`, so both diagrams on this page draw a baseline the same
   way.

   TWO SVGs, ONE PER AXIS — NOT ONE THAT SCALES. A 600-unit horizontal viewBox
   squeezed into the 295px mobile card renders its 13px labels at ~6px, so
   mobile gets a vertical variant rather than an unreadable squeeze. Toggled
   with `display:none`, which also drops the inactive one out of the a11y tree,
   so each SVG can carry its own `role="img"` + `aria-label` without the two
   announcing twice. Height is intrinsic to the viewBox — never set one here.
   ================================================================ */
.case-loop__mat { display: flex; flex-direction: column; gap: var(--sp-6); }
.case-loop__mat .viz-label { display: block; }

.case-loop__graph { display: block; width: 100%; height: auto; }
.case-loop__graph--v { display: none; }

/* ================================================================
   6 · LOCK-SCREEN PUSH — DELETED 2026-08-18, AND IT SHOULD STAY DELETED
   A drawn lock-screen card (teal-tinted screen, fake 9:41 clock, one
   notification reading "Your pool shipped") closed Chapter 3. It went for the
   same reason `.case-poolbar` did: **a drawn artifact is a stand-in for a
   screen you don't have, and a real one now exists.** The stepper's step 05
   carries `user-notification.jpg` — a real Pindo push on a real lock screen —
   one chapter earlier, so the drawn card was the weaker of two lock screens
   sitting a screen apart, which only asks why the real one isn't shown here.

   Two things worth keeping, because they are why it can't simply be redrawn:
   A STILL IMAGE CANNOT DEMONSTRATE A DEEP LINK — the claim is about what
   happens after the tap, so the card was reduced to asserting it in its own
   notification copy ("Tap to open the pickup group"), which is the paragraph
   restated, not evidence. And the chapter's real argument was the notification
   BUDGET — exactly three pushes earn a buzz — which one card cannot state.

   MOOT NOW: the pickup chapter itself was replaced (2026-08-18) by the design
   system chapter. It was 194 words on one routing change, the page's thinnest
   act, and the budget rule was the only part worth keeping — it survives as a
   clause in Chapter 2's close, where the notification already lives. So there
   is no longer a chapter for this artifact to close. Do not rebuild it, and do
   not restore the chapter to give it somewhere to sit.
   ================================================================ */

/* ================================================================
   Responsive
   ================================================================ */
@media (max-width: 768px) {
  .case-clock__mat,
  .case-address__mat,
  .case-guide__mat,
  .case-loop__mat { padding: 24px; }

  .case-address__anatomy { grid-template-columns: 1fr; gap: 12px; }
  .case-address__seg-block { flex-direction: row; align-items: center; gap: 14px; }
  .case-address__seg { min-width: 92px; }
  .case-address__cap { text-align: left; }

  /* THE TERM COLUMN STOPS BEING A COLUMN. 108px of label beside a value on a
     343px card leaves the longest rule ~28 characters of measure, which wraps
     to four lines. Stacked, each rule reads term-then-value down the card and
     the values keep the full width. */
  .case-guide__file { padding: 20px; }
  .case-guide__rule {
    grid-template-columns: 1fr;
    gap: 6px;
    padding: 10px 0;
  }

  /* The loop SWAPS AXIS rather than scaling. The horizontal viewBox is 600
     units wide; inside a 295px card that is a 0.49 scale, which renders its
     13px labels at ~6px. Swapping to the vertical SVG keeps type at full size
     and costs nothing but markup. Never solve this with a smaller viewBox or
     an overflow-x scroller — a diagram a reader has to drag is not a diagram. */
  .case-loop__graph--h { display: none; }
  .case-loop__graph--v { display: block; }

  /* Size comes from `--type-case-numeral`, which the case ladder re-points
     at this breakpoint — a local override here would escape the cap. */
  .case-metrics,
  .case-devstudio .case-metrics { grid-template-columns: 1fr; gap: 28px; padding: 24px; }

  .case-clock__stage { font-size: var(--text-2xs); }
}
