/* ============================================================================
   THE JUNK DRAWER — /about/ : the walkthrough's layout (PLAN-PORTFOLIO v3).

   A sticky-graphic scrollytelling page. ONE pinned visual pane holding four
   scenes (drawer, instrument, report card, analysis) and a column of steps
   that scrolls beside it; about-scenes.js switches the pane as each step
   arrives. This file places the two columns, teaches the two modal cards
   (the turn card, the report card) to flow INLINE in the pane instead of
   covering the screen, and sets the analysis — the page's own charts and
   records table since 2026-09-27 — on the report card's paper.

   Every rule is scoped to .jd-about, the page wrapper, except where the
   thing styled is not inside it: the html-level overrides (html.jd-about-
   page, which must outrank rules the cards set on the root element, and
   html.jd-poster-on), a card's scrim while it is still on <body>, the
   timeline's own parts (.jd-tl-*) and the prompt card (.jd-prompt-tip,
   which lives on <body>). Nothing here re-skins the drawer, the card or
   the turn.

   In order: the shared numbers, the steps (and the title), the pane and its
   scenes, the timeline, the poster (scene 1), the cards inline, the
   instrument, the report card, the analysis, then the two layouts —
   desktop (>=769px wide and >=501px tall: pane ~66%, steps ~34%, a 40px
   timeline) and the phone (anything else: each scene's graphic above its
   own steps, the held ones sticky — "STICKY SECTIONS").
   ========================================================================== */

/* TWO NUMBERS THIS FILE SHARES WITH about-scenes.js (2026-10-01), which
   reads them once per resize with these same values as its fallback: the
   focus line, where a step is read (the stepper's focusLine(), the step's
   sticky top and every margin measured from it), and the air between the
   outgoing graphic's foot and the incoming one's head in a handoff (the
   script's GAP; the runway margin below). Change them here, not there. */
.jd-about {
  --jd-focus: 45vh;
  --jd-gap: 28px;
}

/* ---- the steps ---------------------------------------------------------- */
/* Each step is a block of prose tall enough to own a stretch of the scroll.
   Not a full viewport: a step that fills the screen makes the reader scroll
   blind between ideas, and this page is read fast or not at all. */
.jd-about .jd-step {
  margin: 0 0 var(--s-6);
  transition: opacity 0.3s ease;
}
.jd-about--live .jd-step { opacity: 0.42; }
.jd-about--live .jd-step.is-on { opacity: 1; }
/* no eyebrow (owner, 2026-09-26): a step is its heading and its prose. The
   scene a step belongs to is on the timeline, and the pane shows it. */
/* the demo notice — under the drawing, beside the controls, stated plainly */
/* (owner, 2026-09-28) italic fine print under the prose — no box.
   Selector at (0,3,1): the step's paragraph rule below is (0,2,1) and used
   to outrank this one's margin, size and line-height, so the note printed
   at body size until 2026-10-01. */
.jd-about .jd-step p.jd-demo-note {
  margin: var(--s-3) 0 0;
  font-style: italic;
  font-size: var(--fs-xs); line-height: 1.5;
  color: var(--ink-soft);
}

/* ============================================================================
   THE STEP TYPE (owner, 2026-09-23). The steps inherited .jd-notes from the
   art page: Courier Prime at 13px, the drawer's chrome. But the steps are
   prose, and the site's rule is "mono is the chrome, Spectral is the voice"
   (css/style.css). So: Spectral for the step body and headings. (The demo
   note under the instrument's step is a <p> of the step, so it takes this
   face too.)

   Three heading treatments were tried side by side with ?type=a|b|c on the
   URL (2026-09-23): a, Spectral semibold headings in sentence case, is the
   one everything since was built on; b (the drawer's mono uppercase label
   style) and c (Spectral italic, a looser body) were deleted on 2026-10-01,
   as this note asked once one was picked. A ?type= URL renders as a.
   ========================================================================== */
.jd-about .jd-step,
.jd-about .jd-step p {
  font-family: var(--font-body);
  font-size: var(--fs-md);
  line-height: var(--lh-base);
}
.jd-about .jd-step p { margin: 0 0 var(--s-2); }
/* a list in a step (the taxonomy's categories and grades, owner 2026-10-06):
   the paragraphs' type, a plain bullet, tight rows */
.jd-about .jd-step-body ul { margin: 0 0 var(--s-2); padding-left: 1.4em; }
.jd-about .jd-step-body li {
  font-family: var(--font-body); font-size: var(--fs-md); line-height: var(--lh-base);
}
.jd-about .jd-step h2 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--fs-xl);
  line-height: var(--lh-tight);
  letter-spacing: 0;
  text-transform: none;
  border-bottom: 0;
  padding-bottom: 0;
  margin: 0 0 var(--s-2);
}
.jd-about .jd-step em { font-family: var(--font-voice); font-style: italic; }

/* links in a step's prose */
.jd-about .jd-step-body a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.15em; }

/* THE CATEGORIES AS A BULLETED LIST (owner, 2026-09-27). On this page the
   taxonomy step introduces the four categories in a sentence ending "They
   are:" — so they read as a plain list in the step's own type: the name,
   a dash, the one-line question. The drawer's small-caps label style is
   for its field notes, not for prose. */
.jd-about .jd-axes--list {
  margin: var(--s-2) 0 0;
  padding-left: 1.2em;
  list-style: disc;
}
.jd-about .jd-axes--list .jd-axis-row { margin: 0 0 var(--s-1); padding-left: 0.2em; }
.jd-about .jd-axes--list .jd-axis-label {
  display: inline;
  font-size: inherit;
  letter-spacing: normal;
  text-transform: none;
  font-weight: 600;
  color: var(--ink);
}
/* the space after the dash is an escape (\0020): a literal space straight
   after the \2014 escape is read as the escape's terminator and dropped.
   The space before is non-breaking, so the dash never starts a line. */
.jd-about .jd-axes--list .jd-axis-label::after {
  content: "\00a0\2014\0020"; white-space: pre-wrap; font-weight: 400;
}
.jd-about .jd-axes--list .jd-axis-desc { color: inherit; font-style: italic; }   /* italic: owner, 2026-09-29 */

/* THE PAGE TITLE (owner, 2026-09-28, third pass). A title block at the
   head of the opening step, so it scrolls away with the opening paragraphs.
   "About the" is part of the title — on its own line, in the same type — over
   the name in the page's heading face at display size (sentence case; the
   site's h1 caps are for section labels), closed by a double rule, heavy
   over hairline. On desktop the block reaches from 17vh down to the focus
   line: the title sits high in the column, near the top of the drawer,
   and the opening heading still lands where every later step is read. */
.jd-about .jd-about-head { margin: 0 0 var(--s-4); }
/* (owner, 2026-09-29) "About the" is set exactly like the name — same
   face, size, weight and ink — on its own line, so the title reads as one
   phrase across two lines */
.jd-about .jd-about-kicker { display: block; }
.jd-about .jd-about-title {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: clamp(2.2rem, 1.7rem + 1.1vw, 2.8rem);
  line-height: 1.02;
  letter-spacing: -0.02em;
  text-transform: none;
  color: var(--ink);
}
.jd-about .jd-about-title::after {
  content: "";
  display: block;
  width: 4.5rem;
  height: 7px;
  margin-top: 1.1rem;
  background: linear-gradient(var(--ink) 0 3px, transparent 3px 6px, var(--ink) 6px 7px);
}

/* ---- reduced motion ----------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .jd-about .jd-step { transition: none; }
  .jd-about--live .jd-step { opacity: 1; }
}

/* ---- the pane and its scenes -------------------------------------------- */
/* SCROLL ANCHORING OFF. The browser re-anchors the scroll position when
   content resizes, which is right for a growing comment thread and wrong for
   a page whose pinned pane swaps a whole card on every scene change. Traced
   on desktop: the page jumped BACKWARD by exactly 505px each time a card
   mounted (document height constant at 12377, so not a reflow), the stepper
   re-ran at the earlier position, re-activated an earlier step, and drove the
   turn card's rail back to the wrong drawing — the prose said Gemini while
   the card showed A. The page's scroll position is the story's playhead
   here; nothing may move it but the reader. */
.jd-about .jd-about-grid,
.jd-about .jd-about-pane,
.jd-about .jd-about-notes { overflow-anchor: none; }
.jd-about .jd-about-pane { position: relative; }
/* SCENES TRAVEL WITH THE TEXT. A cross-fade made the graphic dissolve in
   place, which reads as a swap rather than movement. Each scene now LEAVES
   the way the page is going — scrolling down, the outgoing graphic rides up
   and off while the next arrives from below, the same direction the prose
   beside it is moving; scrolling back up, both reverse.

   THE POSITION IS A FUNCTION OF THE SCROLL OFFSET, set from about-scenes.js
   on every scroll tick — not a transition, not a keyframe, not a WAAPI
   animation. Two CSS approaches were tried and neither ran (a transition
   needs a previously-rendered start value, and these scenes are display:none
   until they come on), but the deeper reason is that a clock-driven version
   of this is the wrong thing: "the image should scroll up with the text" is
   a position, not a tween that fires at a boundary. Nothing here may declare
   a transition on transform or opacity — it would fight the scroll, lagging
   the graphic behind the reader's own hand.

   The resting state below is what matters to CSS: a scene that is on is
   visible, full stop, so a page with the script disabled is still correct. */
.jd-about--live .jd-scene {
  display: none;
  /* the card is scaled by a transform, which does NOT shrink its layout box —
     about-scenes.js sets the host's height to the scaled size, so the host
     has to clip what the untransformed box still claims */
  overflow: hidden;
  will-change: transform;
}
.jd-about--live .jd-scene.is-on { display: block; position: relative; z-index: 1; }
/* GHOSTS (2026-09-15): a static clone of a card, kept in the card's own
   host, shown while the real card is closed (leaving) or not yet rendered
   (arriving). It carries the real card's own transform, so it sits exactly
   where the real one sat; the real card is hidden under it until fitted. */
.jd-about--live .jd-scene-ghost {
  position: absolute; top: 0; left: 0;
  pointer-events: none;
  visibility: visible;
}
.jd-about--live .jd-scene.has-ghost > .jd-inline-card:not(.jd-scene-ghost) { visibility: hidden; }
/* a ghost is a still picture: nothing in it may animate or transition. A
   clone restarts every animation its original had finished (a card's
   entrance, a drawing's draw-on), so without this the stand-in itself moved
   for a frame or two as it went up */
.jd-about--live .jd-scene-ghost,
.jd-about--live .jd-scene-ghost * { animation: none !important; transition: none !important; }
/* the instrument's preview DRAWS ITSELF ON as the reader arrives (about-scenes.js,
   _drawPreview), so its picture in the handoff shows the plates bare — a
   finished set flashing up and then being erased read as a glitch */
.jd-about--live [data-scene-pane="instrument"]:not(.is-drawn) .jd-scene-ghost .jd-preview .jd-turn-art-in svg { visibility: hidden; }
/* THE RELAY (2026-09-27): the report card for the NEXT drawing, rising
   behind the one riding out — a change of drawing is a scroll, like a
   change of scene. */
.jd-about--live .jd-scene-relay { z-index: 2; }
/* the pre-render: a host laid out but invisible, so a card can be opened,
   fitted and cloned before the reader ever reaches it */
.jd-about--live .jd-scene.is-prerender {
  display: block; position: absolute; top: 0; left: 0; right: 0;
  visibility: hidden; pointer-events: none; z-index: 0;
}
/* the cards' own entrance animations (a rise-and-settle on every open)
   would play under the ghost swap and read as a stutter; here a card
   arrives on the scroll, not on a spring */
.jd-about .jd-inline-card .jd-record.is-enter,
.jd-about .jd-inline-card .jd-folder-card.is-enter { animation: none; }
/* THE OUTGOING SCENE LEAVES THE FLOW. Both scenes are display:block for the
   length of the handover, and the pane is a centring flex column — in flow
   they both claimed height, so the incoming card was shoved down the pane
   (and clipped by the pane's own overflow) for a quarter of a second on
   every single scene change. about-scenes.js captures the outgoing scene's
   position in the pane before adding this class, so going absolute moves it
   by nothing at all; it then keeps travelling on the scroll. */
.jd-about--live .jd-scene.is-out {
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  z-index: 0;
  pointer-events: none;
}
/* without the engine there is no pane to switch: the drawer stands alone and
   every step reads as ordinary prose beneath it */
.jd-about:not(.jd-about--live) .jd-scene:not([data-scene-pane="drawer"]) {
  display: none;
}

/* ---- the timeline -------------------------------------------------------
   A metro line, and nothing else: one station per step on a single
   continuous rule, with the four scenes told apart by SPACING alone. No
   scene names, no station labels — the rail's whole job is to say "this
   scrolls, here is where you are, press to go back", and every word it
   carried was width taken from the prose beside it. 112px of column became
   40px, and the text got the difference. */
.jd-timeline { display: none; }
.jd-about--live .jd-timeline {
  display: block;
  position: relative;
  padding: 4px 0;
}
/* THE THROUGH LINE. Drawn once on the container, from the first station to
   the last, so it runs unbroken behind every dot and straight through the
   gaps that separate the scenes — the gaps group the stations without
   cutting the line. */
.jd-about--live .jd-timeline::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 10px;
  bottom: 10px;
  width: 1px;
  margin-left: -0.5px;
  background: currentColor;
  opacity: 0.22;
}
.jd-tl-scene {
  position: relative;
  padding: 0;
  margin: 0 0 15px;          /* the gap that reads as a scene break */
}
.jd-tl-scene:last-child { margin-bottom: 0; }
.jd-tl-name { display: none; }

.jd-tl-stop {
  position: relative;
  display: block;
  width: 100%;
  height: 17px;              /* the stations were nearly touching at 7px */
  padding: 0;
  margin: 0;
  border: 0; background: none; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.jd-tl-dot {
  position: absolute; left: 50%; top: 50%;
  width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px;
  border-radius: 50%;
  border: 1px solid currentColor;
  background: var(--paper, #fff);
  opacity: 0.4;
  transition: opacity 0.18s ease, transform 0.18s ease, background-color 0.18s ease;
}
.jd-tl-stop:hover .jd-tl-dot { opacity: 0.85; transform: scale(1.3); }
.jd-tl-stop:focus-visible { outline: 2px solid var(--red, #b02a24); outline-offset: 1px; }
.jd-tl-stop.is-done .jd-tl-dot { opacity: 0.55; background: currentColor; }
.jd-tl-stop.is-on .jd-tl-dot {
  opacity: 1; background: currentColor; transform: scale(1.7);
}

/* ============================================================================
   THE POSTER (owner, 2026-09-26). Scene 1's pile is a picture of the real
   drawer, captured by scripts/capture-drawer-poster.js and laid in as the
   well's floor (index.php sets html.jd-poster-on and --jd-poster-url only
   when the capture is on disk; ?live turns it off). The pile is still BUILT —
   the cards read the same payload — but only the specimen is ever painted:
   one live drawing, one drop-shadow, one real tag, instead of the whole
   collection re-compositing inside a pane the page scrolls past.
   The live wall shade, varnish and vignette stay on top of the picture; the
   capture is taken without them so nothing is doubled.
   ========================================================================== */
/* AWAKE (2026-09-27): once the reader reaches for the drawer, the live pile
   takes over from the picture — every rule that stands in for the pile
   applies only while html lacks .jd-drawer-awake. The live pile lands on the
   picture's own layout (the capture's scatter), so nothing moves. */
html.jd-poster-on:not(.jd-drawer-awake) .jd-about .jd-well {
  background: #8d6537 var(--jd-poster-url) center / 100% 100% no-repeat;
}
/* (every pictured drawing but the specimen stays unpainted: that rule names
   the specimen's id, so index.php prints it beside --jd-poster-url, from
   drawer-poster.json — the one place the id is kept) */
/* a pick dims the rest of the pile (brightness .68 on every other item); with
   the rest of the pile in the picture, the shade falls on the picture */
html.jd-poster-on:not(.jd-drawer-awake) .jd-about .jd-well::before {
  content: '';
  position: absolute; inset: 0; z-index: 1;
  pointer-events: none;
  background: rgba(24, 12, 4, 0.34);
  opacity: 0;
  transition: opacity 0.25s ease;
}
html.jd-poster-on:not(.jd-drawer-awake) .jd-about .jd-well.jd-has-pick::before { opacity: 1; }


/* the craquelure is the floor's aging and lies UNDER the objects. Over the
   floor it is baked into the picture beneath them; left live across the whole
   stage it would crack the pictured objects too. So the live layer keeps only
   the frame: its padding is the wall, and the mask cuts the well out of it. */
html.jd-poster-on:not(.jd-drawer-awake) .jd-about .jd-craquelure {
  padding: var(--wall);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}

/* ---- the three cards, flowed inline -------------------------------------
   Each card normally mounts as a fixed, full-screen scrim over a dark
   backdrop. In the pane it becomes an ordinary block: no fixed position, no
   backdrop, no z-index of its own, no reserved band for the site banner.

   THE CARDS RENDER AT FULL SIZE, THEN SCALE.
   First attempt re-armed the cards' PHONE layouts against the pane width
   (container queries), because the pane was 770px and the report card's
   two-column grid wants 924px. That fixed the clipping and broke the point
   of the page: the phone layout is one column with full-width artwork, so
   the succulent came out enormous, the card grew too tall to see at once,
   and the survey's labels were cut — none of it looking like the instrument
   the drawer actually shows.

   Measured on the live drawer: the report card is 924x496 in two columns of
   420px + 436px, and the turn card's bench is `min(960px, 100%)`. So the
   card is given its full 960px to lay out in — exactly the desktop layout a
   visitor sees — and about-scenes.js then scales the whole thing to fit the
   pane. Same card, same proportions, just smaller. (The hosts below narrow
   it to 740px, 700px for the charts.) */
.jd-about .jd-inline-card {
  position: static;
  inset: auto;
  z-index: auto;
  padding: 0;
  background: none;
  display: block;
  max-height: none;
  width: 960px;
  transform-origin: top left;
  will-change: transform;
  /* ONE SPACING SCALE FOR BOTH CARDS. The two-column band was arrived at by
     moving pieces around rather than by designing it, and it showed: the
     filmstrip sat 8px under the plate, close enough to read as touching the
     artwork's grid. These are the three gaps the layout actually has —
     between the columns, between blocks stacked in a column, and between
     the band and the full-width rows under it — set once and referred to
     everywhere below, so a change lands in one place. */
  --ab-gap-col: 22px;
  /* the step between blocks stacked in a column — and specifically the air
     ABOVE the filmstrip. At 14px the scrubber's top all but touched the box
     holding the drawing while 40px of nothing sat under it: the control read
     as belonging to whatever came next instead of to the picture it scrubs.
     It wants more room above than it had and less below than the seam gave
     it, so the two numbers move toward each other. */
  --ab-gap-row: 15px;
  /* the seam. Going from two columns to full width is the single biggest
     structural change on the card, and at 20px it read as just another gap —
     the eye had no stop before the table. It gets its own, larger step. */
  --ab-gap-band: 26px;
  --ab-pad: 18px;
}
/* the cards' own close controls point at a modal that isn't one here */
.jd-about .jd-inline-card .jd-turn-close,
.jd-about .jd-inline-card .jd-record-close,
.jd-about .jd-inline-card .jd-folder-close { display: none; }

/* THE COLLAPSE. `.jd-record` and `.jd-folder-card` are `max-height: 100%`
   column flexboxes whose scroll area is `flex: 1 1 auto; min-height: 0`.
   Against a fixed, full-screen scrim that resolves to the viewport and the
   card fills it; against an auto-height block it resolves to nothing and the
   card measures 0. Inline, the cards flow at their natural height and
   about-scenes.js scales them to the pane (fitCard). */
.jd-about .jd-inline-card .jd-record,
.jd-about .jd-inline-card .jd-folder-card,
.jd-about .jd-inline-card .jd-turn {
  max-height: none;
  height: auto;
  width: 100%;
  margin: 0;
}
.jd-about .jd-inline-card .rc-scroll,
.jd-about .jd-inline-card .jd-folder-scroll,
/* the turn card's scroller belongs on the list too: `flex: 1 1 auto;
   min-height: 0; overflow-y: auto` resolves to the content height against an
   auto-height card and is harmless — until the card acquires a definite
   height for any reason, at which point it quietly SCROLLS its own contents
   instead of growing. The host would then be cut to a card that never
   changed size, no observer would fire, and the reader would be looking at
   the top of a card with no way to reach the rest of it: the exact failure
   this page has to make impossible. */
.jd-about .jd-inline-card .jd-turn-scroll {
  flex: 0 0 auto;
  min-height: 0;
  max-height: none;
  overflow: visible;
}

/* NO BLUEPRINT SWITCH ON THIS PAGE (owner, 2026-09-29) — about-scenes.js
   pins the paper to graph; the drawer proper keeps the switch */
.jd-about .rc-paper,
.jd-about .jd-turn-paper { display: none !important; }

/* THE SCROLL LOCK. Opening the turn card sets html.jd-turn-open { overflow:
   hidden } so a modal turn cannot be scrolled behind — correct everywhere
   else, fatal here, where the card IS the page's furniture and the page must
   keep scrolling. Scoped to this page by a class set on <html> before the
   modules load, so no other page is affected. */
html.jd-about-page.jd-turn-open,
html.jd-about-page.jd-record-open,
html.jd-about-page.jd-folder-open { overflow: visible; }

/* a card's scrim lands on <body> as a full-screen modal before about-scenes.js
   carries it into the pane. The script moves it before the next paint; this
   makes sure a scrim that is on <body> for any reason never paints over the
   walkthrough (the page opens no modal of its own — the tag's REPORT CARD
   button opens the full drawer in a new tab). */
html.jd-about-page body > .jd-turn-scrim,
html.jd-about-page body > .jd-record-scrim,
html.jd-about-page body > .jd-folder-scrim { visibility: hidden !important; }

/* THE INSTRUMENT (owner, 2026-09-15 to 09-29). In the drawer the turn card
   is landscape at 960px; here it is 740px and laid out as ONE grid — see
   "THE INSTRUMENT, RE-LAID", next, which places every piece. Three
   earlier layouts led there (a portrait stack, 09-15; the drawer's own
   landscape grid back, 09-17; only the prompt beside the drawing, 09-17);
   what they leave standing is below: the card's width, the scroller's
   padding, the seam above the ratings, the filmstrip's step under the
   drawing, and the two column wrappers flattened to display:contents so
   that their children are items of that grid.

   Two things the earlier layouts learned and the drawer's own rules now
   carry, which must not be undone here: the plate needs a DEFINITE width
   (junk-drawer.css gives `.jd-turn-pin .jd-turn-plate` 100% of the pin, and
   RE-LAID gives the pin var(--plate)) — `width: auto` with a max-width makes
   it content-sized around an svg that sizes off the plate, and the circle
   collapsed to 2x2px, the artwork gone; and NO aspect-ratio on the plate —
   .jd-turn-art carries its own 1/1, and the plate also holds the filmstrip
   under the art, which a forced square left hanging off its bottom edge. */
.jd-about [data-scene-pane="instrument"] .jd-inline-card { width: 740px; }
.jd-about .jd-inline-card .jd-turn[data-view="bench"] .jd-turn-scroll {
  padding: var(--ab-pad);
}
/* NO row-gap on the grid. Every piece of the question is a grid row of its
   own, so a row-gap is not the band's seam — it would be inserted between
   every pair of rows ("way too tall and awkward", the owner, of the select
   rows this card carried before 0.18.0). The seam is a margin on the one
   element that starts the full-width zone: the first thing after the
   question's progress line, which takes no space since 0.19.19 (its words
   are the options' hidden name): */
.jd-about .jd-inline-card .jd-bench-r > .jd-q-step + * { margin-top: var(--ab-gap-band); }
/* the bench keeps its control INSIDE the plate, under the artwork — same
   step away from the picture as the record card's */
.jd-about .jd-inline-card .jd-turn-plate > .jd-filmstrip {
  margin-top: var(--ab-gap-row);
  margin-bottom: 2px;      /* a floor: the strip stopped flush on the edge */
}
.jd-about .jd-inline-card .jd-bench-l,
.jd-about .jd-inline-card .jd-bench-r { display: contents; }

/* THE INSTRUMENT, RE-LAID (owner, 2026-09-29): the prompt ABOVE the drawing,
   the drawing and its filmstrip centred and a size larger, the ratings under
   them, and the rail (DRAWING A … RANKING) moved from the top of the card
   down to the last row, to the left of the button, which reads just "next"
   (about-scenes.js). The scroller becomes the one grid: the bench and its two
   column wrappers go display:contents so every piece is an item of it, and
   `order` puts the prompt first and the rail with the actions last — auto
   placement then sets the rail in column 1 and the button in column 2 of the
   same final row. Bench view only: the ranking keeps its own layout. */
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn[data-view="bench"] {
  --plate: 440px;
}
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn[data-view="bench"] .jd-turn-scroll {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: var(--ab-gap-col);
  row-gap: 0;
  align-items: start;
}
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn[data-view="bench"] .jd-bench { display: contents; }
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn[data-view="bench"] .jd-bench-l > *,
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn[data-view="bench"] .jd-bench-r > * {
  grid-column: 1 / -1; grid-row: auto; order: 3;
}
/* (B3: the prompt panel rides the drawing's column in the drawer's frame) */
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn[data-view="bench"] .jd-bench-l > .jd-turn-assign,
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn[data-view="bench"] .jd-bench-r > .jd-turn-assign {
  order: 1; align-self: stretch; margin: 0 0 var(--ab-gap-row);
}
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn[data-view="bench"] .jd-bench-l > .jd-turn-pin {
  order: 2; width: var(--plate); max-width: 100%; justify-self: center;
  align-self: start;
}
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn[data-view="bench"] .jd-rail {
  order: 4; grid-column: 1; align-self: center; justify-content: flex-start;
  margin: var(--ab-gap-band) 0 0;
}
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn[data-view="bench"] .jd-bench-r > .jd-turn-actions {
  order: 4; grid-column: 2; align-self: center;
  margin: var(--ab-gap-band) 0 0; padding-top: 0;
}

/* THE QUESTION CARDS STAND SIDE BY SIDE (about rework, 2026-10-06). Since
   0.18 each drawing is rated one question a card, and a question is a
   heading, a line and four or five ballot lines of ~48px: stacked under a
   440px drawing (RE-LAID, above) the card stood ~1100px tall and was scaled
   to ~0.6 in the pane — type at 9px. Here, on the question cards only (the
   preview, the podium and the margins keep their own layouts), the drawing
   and its replay take the left column and the question the right, as the
   instrument's own desk card has them: the prompt and the question strip
   across the top, the rail and the buttons across the foot. The card then
   stands ~650px and fits the pane at full size or nearly. (:has() picks the
   question card; a browser without it keeps the stacked layout, which
   still works, smaller.) */
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn[data-view="bench"] .jd-turn-scroll:has(> .jd-bench--q) {
  grid-template-columns: 300px minmax(0, 1fr);
  column-gap: 26px;
}
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn-scroll:has(> .jd-bench--q) > .jd-qstrip { grid-column: 1 / -1; grid-row: 1; }
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn-scroll:has(> .jd-bench--q) .jd-bench-l > .jd-turn-assign { grid-column: 1 / -1; grid-row: 2; margin-top: 12px; }
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn-scroll:has(> .jd-bench--q) .jd-bench-l > .jd-turn-pin {
  grid-column: 1; grid-row: 3; width: 100%; justify-self: stretch;
}
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn-scroll:has(> .jd-bench--q) .jd-bench-r > .jd-q-step,
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn-scroll:has(> .jd-bench--q) .jd-bench-r > .jd-q-main {
  grid-column: 2; grid-row: 3; margin-top: 0; align-self: start;
}
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn-scroll:has(> .jd-bench--q) > .jd-rail { grid-column: 1; grid-row: 4; }
.jd-about [data-scene-pane="instrument"] .jd-inline-card .jd-turn-scroll:has(> .jd-bench--q) .jd-bench-r > .jd-turn-actions {
  grid-column: 2; grid-row: 4; justify-self: end;
}

/* THE DOCKET WEARS RINGS HERE (2026-10-01). From 769px the drawer's turn
   card dresses each rail node as a pill wearing its word — sized for the
   bench's 960 measure, where seven pills (A-D, ranking, head to head,
   size) hold one line. This card stands 740px wide with the "next" button
   sharing the rail's row, leaving the rail ~610px: the pills (~760px for
   six) ran past the card's right edge and under the button. Inline, the
   docket keeps the phone's bare rings instead — seven fit in ~340px — at
   every desktop width and in every view (bench, ranking, head to head).
   The drawer's own modal is untouched: everything is scoped to this page's
   .jd-inline-card. */
@media (min-width: 769px) {
  .jd-about .jd-inline-card .jd-turn .jd-rail .jd-rail-step {
    min-height: 0; padding: 0;
    background: none; border: 0; border-radius: 0;
  }
  .jd-about .jd-inline-card .jd-turn .jd-rail .jd-rail-step.is-done { color: var(--tink-2); }
  .jd-about .jd-inline-card .jd-turn .jd-rail .jd-rail-word { display: none; }
  .jd-about .jd-inline-card .jd-turn .jd-rail .jd-rail-ring {
    display: flex; width: 26px; height: 26px;
    background: rgba(255, 250, 232, 0.35);
    border: 1px solid var(--trule); border-radius: 50%;
  }
  .jd-about .jd-inline-card .jd-turn .jd-rail .jd-rail-step.is-done .jd-rail-ring {
    background: var(--graphite); border-color: var(--graphite);
    color: var(--tpaper-hi);
  }
  .jd-about .jd-inline-card .jd-turn .jd-rail .jd-rail-step.is-current .jd-rail-ring {
    border: 2px solid var(--tred); background: var(--tpaper-hi);
  }
}
/* (a coarse pointer grows the rings toward the touch floor, as the drawer's
   own docket does — junk-drawer.css, any-pointer: coarse) */
@media (min-width: 769px) and (any-pointer: coarse) {
  .jd-about .jd-inline-card .jd-turn .jd-rail .jd-rail-ring { width: 34px; height: 34px; }
}

/* THE REPORT CARD TAKES THE SAME PORTRAIT (owner, 2026-09-15). In the
   drawer the record is landscape at 960px — the photograph in a 420px
   column, the paperwork beside it. Here it stands the way the instrument
   stands: the same 660px card, the photograph centred on top, the prompt
   beneath it, then the grades table and the sibling strip. The drawer's
   own phone layout is the source of the move (the column wrappers go
   display:contents, source order is the portrait order), keyed to this
   page instead of to a narrow viewport. */
.jd-about [data-scene-pane="record"] .jd-inline-card { width: 740px; }
/* SIDE BY SIDE AGAIN (owner, 2026-09-17) — same move as the bench above: the
   flex column and the display:contents wrappers are dropped, and the record
   gets its own landscape grid back ("mast mast" / "left right", the plate
   column beside the paperwork). The prompt opens the right column, so it
   lands beside the drawing; the grades and the sibling strip follow it down
   that column exactly as they do in the drawer. */
.jd-about .jd-inline-card .rc-scroll {
  padding: var(--ab-pad) var(--ab-pad) var(--ab-pad);
  display: grid;
  grid-template-columns: var(--plate) minmax(0, 1fr);
  column-gap: var(--ab-gap-col);
}
/* same shape as the bench above: ONE grid, the plate and its filmstrip in
   column 1, the prompt (its rule and its text) in column 2 beside them, and
   the grades table and the sibling strip back to the card's full width
   underneath. The plate spans the prompt's two rows so the filmstrip can sit
   under it on a row of its own; align-self keeps the plate its natural
   height rather than stretching it to whatever the prompt needs. */
/* THE DRAWING COLUMN IS A BOX AGAIN, not display:contents. With the plate
   and the filmstrip as separate grid items on rows 2 and 3, their spacing
   was at the mercy of how the grid sized those tracks — and it got it wrong:
   the plate (a 1/1 square whose height the row did not fully account for)
   ran 2px PAST its track and the filmstrip, sitting at the top of the next
   one, landed on top of it. The two belong together, so they go in one cell
   and stack in ordinary flow, where a margin means what it says.
   .rc-col-r stays display:contents — its children are placed individually. */
.jd-about .jd-inline-card .rc-col-l {
  grid-column: 1; grid-row: 2; align-self: start;
  display: flex; flex-direction: column; min-width: 0;
}
.jd-about .jd-inline-card .rc-col-r { display: contents; }

/* THE PLATE'S BOTTOM BAND IS FREE NOW. junk-drawer.css insets the artwork
   `6% 8% 20%` — "the artwork yields its bottom band to the margin notes" —
   and on this page those notes have moved off the photograph into the
   specimen block. The reservation stayed behind: a fifth of the plate, 38px
   of empty graph paper under every drawing, which is what pushed the
   scrubber down to the plate's edge. Given back to the artwork, which is
   also the larger drawing the owner has been asking for. */
.jd-about .jd-inline-card .rc-col-l > .rc-plate .rc-plate-art { inset: 7% 8%; }
/* the default: anything not explicitly placed spans the card. .rc-col-l is
   excluded by name — it IS explicitly placed (column 1, above) and at equal
   specificity this later rule would otherwise win and hand the drawing
   column the full width, collapsing the card to one column. Its children are
   no longer grid items at all, so they are out of the list too. */
.jd-about .jd-inline-card .rc-scroll > *:not(.rc-col-l),
.jd-about .jd-inline-card .rc-col-r > * { grid-column: 1 / -1; }
.jd-about .jd-inline-card .rc-masthead { grid-row: 1; margin-bottom: 8px; }
.jd-about .jd-inline-card .rc-col-l > .rc-plate {
  flex: 0 0 auto; width: 100%; margin: 0;
}
.jd-about .jd-inline-card .rc-col-l > .jd-filmstrip {
  flex: 0 0 auto;
  margin-top: var(--ab-gap-row);
}
/* the band's own floor: the full-width rows start a clear step below it */
.jd-about .jd-inline-card .rc-col-r > .rc-head:not(:first-of-type) {
  margin-top: var(--ab-gap-band);
}
/* ONE COLUMN GRID FOR THE WHOLE CARD. The grades table splits itself 47/53
   inline, which put its GRADE column ~12px off the prompt's left edge — two
   things stacked in the same region of the card, not quite lining up. Pinned
   to the band's own column instead so the card has ONE vertical seam. */
.jd-about .jd-inline-card .rc-subj th:first-child,
.jd-about .jd-inline-card .rc-subj td:first-child {
  width: calc(var(--plate) + var(--ab-gap-col)) !important;
}

/* ---- THE SCRUBBER, A SIZE DOWN (owner, 2026-09-17) ---------------------
   On this page the control is a label on a specimen, not a working transport
   — nobody is scrubbing through a drawing here the way they would in the
   drawer — so it can afford to be quieter. The cells come down from 26px to
   22 and the play button from 28 to 24 (it was the taller of the two, so
   shrinking the cells alone would have changed nothing: the button set the
   row's height).

   And the caret's flag comes DOWN into the strip. It used to float clear
   above it — flag bottom 2px shy of the strip's top edge — which read as a
   marker hovering over the timeline rather than a pen resting on it. Now it
   overlaps the top by 2px, so the point and the thing it points at touch.
   All of it scoped to this page; the drawer's control is untouched. */
.jd-about .jd-inline-card .jd-filmstrip { --fs-h: 22px; }
.jd-about .jd-inline-card .fs-play { width: 24px; height: 24px; padding: 4px; }
.jd-about .jd-inline-card .fs-play svg { width: 14px; height: 14px; }
.jd-about .jd-inline-card .fs-caret { top: -2px; bottom: -2px; }
.jd-about .jd-inline-card .fs-caret::before { top: -1px; }

/* ---- THE RATING ROWS, COMPACTED (owner, 2026-09-17) --------------------
   "They're way too tall and it's kind of awkward." In the drawer these rows
   are a working form — you are filling them in, one drawing at a time, and
   the 28px scale boxes are sized for that. On this page the card is a
   SPECIMEN being shown, not a form being used: nobody picks a grade here, and
   at 46px a row the ratings stood nearly twice the pitch of the report card's
   own grades table (~26px) sitting on the facing page. The two are meant to
   read as one system, so here they are brought to the same rhythm.

   EVERY RULE IN THIS BLOCK IS SCOPED TO .jd-about .jd-inline-card, which
   exists on this page and nowhere else. The drawer's instrument keeps its
   working height untouched — that is the whole point of the scoping, and it
   is why the compaction is done here rather than on .jd-row itself. */
/* ONE ROW RHYTHM ACROSS THE TWO CARDS. The first pass overshot: the
   instrument came down to ~24px a row while the record's grades table sat at
   ~31px, so the compaction swapped one mismatch for its mirror image. Both
   are brought to the same pitch instead — the instrument loosened a little,
   the record's table tightened a little, meeting in the middle. */
/* (the instrument's half — its select rows at 25px — retired with the
   selects in 0.18.0: the card now asks one question at a time) */
.jd-about .jd-inline-card table.rc-subj td { padding: 0.16em 0.5em 0.2em; }

/* ---- THE SIBLING STRIP, SMALLER (owner, 2026-09-17) --------------------
   In the drawer the strip is the paperwork column's width and each thumbnail
   flexes to fill it. Here the strip spans the whole 740px card, so five
   siblings came out ~140px wide and the row stood taller than the grades
   table above it — the loudest thing on the card, for the least important.
   Fixed-width thumbnails instead: they stay the plate's 84:74 scale model,
   at a size that reads as a reference strip rather than a gallery. */
.jd-about .jd-inline-card .rc-alt {
  /* wide enough that "Claude Opus 5" sets on one line — at 76px it broke
     after "Opus" and the caption went to three lines while the row had
     room to spare */
  flex: 0 0 auto; width: 104px;
  padding: 4px 4px 5px;
}
.jd-about .jd-inline-card .rc-alts,
.jd-about .jd-inline-card .rc-alt-port { gap: 6px; }

/* the aside about-scenes.js builds: the prompt, then the specimen block */
/* THE VOID BESIDE THE DRAWING. The prompt is three lines and the drawing is
   tall, so the right column ran out ~150px before the left one did and left a
   dangling gap just above the seam — the last thing the eye met before the
   grades table was empty paper. The column is stretched to the band's height
   and its two blocks pushed to the ends instead: the prompt opens the column,
   the specimen closes it level with the filmstrip, and the slack sits BETWEEN
   them where it reads as breathing room rather than as a run-out. */
.jd-about .jd-inline-card .rc-col-r > .jd-about-aside {
  grid-column: 2; grid-row: 2; align-self: stretch; min-width: 0;
  display: flex; flex-direction: column; justify-content: space-between;
  gap: var(--ab-gap-band);
}

/* ---- THE SPECIMEN BLOCK ------------------------------------------------
   Model / Date / Tokens / Cost, the file number and the DOWNLOAD button. In
   the drawer these are printed ON the photograph, absolutely placed in its
   corners with a paper glow behind the type so they read over artwork. Off
   the plate they are ordinary text in a column, so every one of those
   devices is undone here: no absolute placement, no glow, no ellipsis, and
   the label column can be narrower because nothing is dodging a button. */
/* the specimen block reads ACROSS (owner, 2026-09-17): the notes on the
   left, the download on the right of the same band, the file number under
   them. Stacked, the three cost three lines of height for two lines of
   content; side by side the block is as short as its tallest part. */
.jd-about .jd-inline-card .jd-about-specimen-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  column-gap: 10px; row-gap: 4px;
}
.jd-about .jd-inline-card .jd-about-specimen .rc-notes {
  grid-column: 1; grid-row: 1;
  position: static; max-width: none; left: auto; bottom: auto;
  pointer-events: auto; gap: 2px; width: 100%;
}
.jd-about .jd-inline-card .jd-about-specimen .rc-note-l {
  min-width: 4.2em; text-shadow: none;
}
.jd-about .jd-inline-card .jd-about-specimen .rc-note-v {
  white-space: normal; overflow: visible; text-overflow: clip;
  text-shadow: none;
}
.jd-about .jd-inline-card .jd-about-specimen .rc-note-no {
  grid-column: 1 / -1; grid-row: 2;
  position: static; right: auto; bottom: auto; max-width: none;
  pointer-events: auto; text-shadow: none; opacity: 0.75;
}
/* the ↻ comes back when the buttons leave the plate: junk-drawer.css hides
   it with `.rc-col-l > .rc-plate .rc-draw`, and these are no longer inside a
   plate. The filmstrip's play button is the replay on this page, so the same
   reasoning applies wherever the row ends up. */
.jd-about .jd-inline-card .jd-about-specimen .rc-draw { display: none; }
.jd-about .jd-inline-card .jd-about-specimen .rc-plate-btns {
  grid-column: 2; grid-row: 1; align-self: start;
  position: static; right: auto; bottom: auto;
  justify-content: flex-start; flex-wrap: wrap;
  margin-top: 2px;
}
.jd-about .jd-inline-card .rc-col-r > .rc-head:first-child { margin-top: 0; }
/* the plate column's width: --plate is what .rc-scroll's grid is built on,
   and what .rc-plate-art's 8% inset (and so the filmstrip's alignment) is
   measured inside. 330px against the card's 740 leaves the paperwork ~330. */
.jd-about [data-scene-pane="record"] .jd-inline-card .jd-record { --plate: 330px; }
/* the drawer's LANDSCAPE fold rule (min-width 701px: the prompt as the
   right column's springy row) would apply here because the viewport is
   wide; in a stacked column there is no slack to spring into, so the prompt
   goes back to its plain fold — three lines, the cut over the last one,
   SHOW FULL PROMPT to unfold */
.jd-about .jd-inline-card .rc-col-r > .rc-assign.rc-can-fold:not(.is-open) {
  display: block;
  flex: 0 0 auto;
}
.jd-about .jd-inline-card .rc-col-r > .rc-assign.rc-can-fold:not(.is-open) p {
  flex: none;
  min-height: 0;
  max-height: 4.5em;
}
/* (a restatement of the drawer's own 0.55rem head margin used to sit here,
   at the same specificity as the band seam above and later in the file, so
   the 26px --ab-gap-band never rendered; gone 2026-10-01 — the seam is the
   intent, see its token) */

/* ============================================================================
   THE FILMSTRIP, on the walkthrough. The control itself — markup, tokens and
   every .fs-* part — lives in junk-drawer.css and jd-filmstrip.js, shared
   with the drawer proper since 2026-09-16. All that is page-specific is where
   it sits and how wide: the inline cards are transform-scaled copies of the
   real ones, so the control takes the plate's drawn width rather than the
   column's. Mounted by about-scenes.js (see ensureFilmstrip).
   ========================================================================== */
/* NO SPACING HERE, DELIBERATELY (2026-09-17). Two rules stood here, what
   was left of the stacked-portrait layout, where the filmstrip was a
   centred 380px block under a centred plate — hence `auto` side margins,
   and `-0.15rem` above to close the gap that centring left. In the
   two-column layout the column sets the width and the spacing scale sets the
   air, and this block — sitting LATER in the file than those rules, at equal
   specificity — was quietly winning: every attempt to give the scrubber room
   above it was overridden back to a NEGATIVE margin, which is why the control
   kept landing on the plate's bottom edge however often the gap was "fixed".
   Width and margin belong to the layout (the cards' own rules, above). */

/* ============================================================================
   THE CHARTS (owner, 2026-09-27). Scene 4 no longer mounts the analytics
   folder: about-scenes.js draws three charts of its own from the folder's
   endpoint, and the pane shows them on the page itself — no manila, no
   card, no frame. Tufte's rules, in this site's type: the only ink is the
   data (a dot or a bar per model), a hairline per row to carry the eye,
   and faint ticks at the scale's points (the scale's words under the last
   row gave way to each value's n, below). Names and values sit on the
   marks, so there is no legend and no axis of numbers. Titles are set like
   the step headings, a size down; values are mono; the subtitle is the
   page's own text voice, muted.
   ========================================================================== */
/* the analysis cards' width (the sheet's own is 740px, below) */
.jd-about [data-scene-pane="analytics"] .jd-inline-card { width: 700px; }
.jd-about .jd-charts {
  --jdc-name: 10.5rem;         /* the model-name column */
  --jdc-val: 5.4rem;           /* the value column (value + its n) */
  /* THE PAPER (owner, 2026-09-27: "give them a container … that fits the
     theme"). The report card's stock, so the analysis reads as one more
     document from the same file: the cream card, its grain and mottle
     (junk-drawer.css's shared :root textures, --jd-grain-url and
     --jd-mottle-url, the very bytes the report card's scrim aliases), the
     double hairline border, the drop shadow, and the card's slate ink. The
     charts inside keep their plain marks. */
  --jdc-card: #efe4c6;
  --jdc-ink: #37414f;
  --jdc-hair: rgba(55, 65, 79, 0.22);
  --jdc-ground: var(--jdc-card); /* the dots' rings, cut from the paper */
  position: relative;
  box-sizing: border-box;
  padding: 30px 34px 28px;
  color: var(--jdc-ink);
  background: var(--jdc-card) var(--jd-grain-url);
  border: 1px solid rgba(48, 38, 20, 0.55);
  box-shadow: 14px 22px 34px -10px rgba(6, 3, 0, 0.5),
              3px 6px 12px -4px rgba(6, 3, 0, 0.4);
}
/* the inner hairline of the double border, and the paper's mottle */
.jd-about .jd-charts::before {
  content: ""; position: absolute; inset: 5px; z-index: 1; pointer-events: none;
  border: 1px solid rgba(55, 65, 79, 0.42);
}
.jd-about .jd-charts::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: var(--jd-mottle-url);
  background-size: 420px 420px;
}
.jd-about .jd-charts > .jdc { position: relative; z-index: 2; }
.jd-about .jd-charts-wrap { box-sizing: border-box; padding: 2px 30px 40px 4px; }
/* one chart per card since 2026-09-27 (each view its own card) */
.jd-about .jd-charts .jdc { display: block; margin: 0; }
.jd-about .jdc figcaption {
  margin: 0 0 20px; padding-bottom: 12px;
  border-bottom: 1px solid rgba(55, 65, 79, 0.35);
  text-align: center;
}
/* the chart titles in the page's own text face (owner, 2026-09-27), set
   like the step headings beside them, a size down: not the drawer's mono */
.jd-about .jdc-title {
  display: block;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.22rem; line-height: 1.25;
  letter-spacing: 0; text-transform: none;
  color: #1f2530;
}
.jd-about .jdc-sub {
  display: block; margin-top: 6px;
  font-size: 0.98rem; line-height: 1.35; font-style: italic;
  color: rgba(55, 65, 79, 0.85);
}
/* a figure with nothing filed yet (dataset v2 before its first sitting,
   2026-10-01): one line in the subtitle's voice, tall enough (200px) for the
   card fitter and the warm-up's settle test to treat it as a card */
.jd-about .jdc-empty {
  display: flex; align-items: center; justify-content: center;
  box-sizing: border-box; min-height: 200px; margin: 0; padding: 24px;
  font-size: 0.98rem; line-height: 1.35; font-style: italic; text-align: center;
  color: rgba(55, 65, 79, 0.85);
}
.jd-about .jdc-row {
  display: grid;
  grid-template-columns: var(--jdc-name) 1fr var(--jdc-val);
  align-items: center;
  column-gap: 14px;
  min-height: 34px;
}
.jd-about .jdc-name {
  font-family: var(--font-mono); font-size: 0.9rem;
  text-align: right; color: var(--jdc-ink);
  white-space: nowrap;
}
.jd-about .jdc-val {
  font-family: var(--font-mono); font-size: 0.9rem;
  font-variant-numeric: tabular-nums; color: #1f2530;
}
.jd-about .jdc-track { position: relative; height: 14px; }
/* the row's hairline, and the scale's points as faint ticks on it */
.jd-about .jdc-rule {
  position: absolute; left: 0; right: 0; top: 50%;
  height: 1px; background: var(--jdc-hair);
}
.jd-about .jdc-tick {
  position: absolute; top: 50%; width: 1px; height: 7px; margin: -3px 0 0;
  background: var(--jdc-hair);
}
/* the mark: a dot with a ring of page around it, so a dot on a tick reads
   as sitting on the line, not merged into it */
.jd-about .jdc-dot {
  position: absolute; top: 50%;
  width: 11px; height: 11px; margin: -5.5px 0 0 -5.5px;
  border-radius: 50%;
  box-shadow: 0 0 0 2px var(--jdc-ground);
}
/* the multiples: two by two, each panel titled, the name column narrower */
.jd-about .jdc-multiples {
  display: grid; grid-template-columns: 1.45fr 1fr; gap: 30px 26px;
}
.jd-about .jdc-panel { --jdc-name: 8.6rem; --jdc-val: 2.2rem; }
.jd-about .jdc-panel.is-right { --jdc-name: 0px; }
.jd-about .jdc-panel .jdc-row { column-gap: 10px; min-height: 30px; }
.jd-about .jdc-panel.is-right .jdc-row { grid-template-columns: 0 1fr var(--jdc-val); }
.jd-about .jdc-panel.is-right .jdc-name { visibility: hidden; overflow: hidden; }
.jd-about .jdc-panel .jdc-name,
.jd-about .jdc-panel .jdc-val { font-size: 0.82rem; }
.jd-about .jdc-ptitle {
  margin: 0 0 8px calc(var(--jdc-name) + 10px);
  font-size: 1.05rem; color: #1f2530; white-space: nowrap;
}
.jd-about .jdc-panel.is-right .jdc-ptitle { margin-left: 0; }
/* each issue-rate panel's own key (taxonomy v35): which levels its pale and
   dark segments count, from the axis's value labels — under the panel's
   title, on the same left edge */
.jd-about .jdc-pkey {
  display: flex; flex-wrap: wrap; gap: 2px 12px;
  margin: -4px 0 8px calc(var(--jdc-name) + 10px);
  font-size: 0.74rem; color: #5b6472;
}
.jd-about .jdc-panel.is-right .jdc-pkey { margin-left: 0; }
.jd-about .jdc-pkey .jdc-key i { width: 12px; height: 6px; }
/* the bar: a length from zero, thin, the data end rounded */
.jd-about .jdc-bar {
  position: absolute; left: 0; top: 50%;
  height: 10px; margin-top: -5px;
  border-radius: 0 4px 4px 0;
}
.jd-about .jdc-barrow .jdc-track { height: 14px; }
.jd-about .jdc-endval { position: absolute; top: 50%; transform: translateY(-50%); line-height: 1; white-space: nowrap; }

/* THE CATEGORIES AS ISSUE RATES (owner, 2026-09-30): one 0-100% ruler per
   panel, a severity-split bar (dark = big problem / has it, pale = small
   problem / a hint), the data end rounded like the cost bars, and a thin
   whisker for the 95% interval, grey and unhaloed (owner, 2026-10-01) */
.jd-about .jdc-rates .jdc-panel { --jdc-val: 2.7rem; }
.jd-about .jdc-multiples.jdc-rates, .jd-about .jdc-legend { --jdc-ci: #7a746a; }
.jd-about .jdc-rtrack {
  position: absolute; left: 0; right: 0; top: 50%;
  height: 10px; margin-top: -5px; background: rgba(55, 65, 79, 0.07);
}
.jd-about .jdc-mid {
  position: absolute; left: 50%; top: 0; bottom: 0; width: 1px;
  background: var(--jdc-hair);
}
.jd-about .jdc-seg { position: absolute; top: 50%; height: 10px; margin-top: -5px; }
.jd-about .jdc-seg-end { border-radius: 0 3px 3px 0; }
.jd-about .jdc-ci {
  position: absolute; top: 50%; height: 9px; margin-top: -4.5px;
  box-sizing: border-box;
  border-left: 1.2px solid var(--jdc-ci); border-right: 1.2px solid var(--jdc-ci);
  background: linear-gradient(var(--jdc-ci), var(--jdc-ci)) center / 100% 1.2px no-repeat;
}
.jd-about .jdc-legend {
  display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 0 0 18px;
  font-size: 0.8rem; color: var(--jdc-ink);
}
.jd-about .jdc-multiples > .jdc-legend--cell { margin: 0; align-self: end; justify-self: end; }
.jd-about .jdc-key { display: inline-flex; align-items: center; gap: 6px; }
.jd-about .jdc-key i { display: inline-block; width: 16px; height: 8px; }
.jd-about .jdc-key i.jdc-key-ci {
  height: 9px; box-sizing: border-box;
  border-left: 1.2px solid var(--jdc-ci); border-right: 1.2px solid var(--jdc-ci);
  background: linear-gradient(var(--jdc-ci), var(--jdc-ci)) center / 100% 1.2px no-repeat;
}

/* HEAD-TO-HEAD STRENGTH (owner, 2026-10-05): the dot on its 95% interval,
   the interval a 2px line in the model's ink; the 50% tick (an even chance)
   firmer than the rest, and the scale's points named once under the rows */
.jd-about .jdc-btci {
  position: absolute; top: 50%; height: 2px; margin-top: -1px;
  border-radius: 1px; opacity: 0.85;
}
.jd-about .jdc-tick.is-mid { height: 13px; margin-top: -6px; background: rgba(55, 65, 79, 0.45); }
.jd-about .jdc-axisrow { min-height: 22px; }
.jd-about .jdc-axis { position: relative; height: 14px; }
.jd-about .jdc-axis span {
  position: absolute; top: 0; transform: translateX(-50%);
  font-family: var(--font-mono); font-size: 0.72rem; color: #5b6472;
  font-variant-numeric: tabular-nums;
}
.jd-about .jdc-key i.jdc-key-level { background: rgba(55, 65, 79, 0.18); }
/* each row's n to the right of its chance (owner, 2026-10-05): the value
   column wide enough for "64%" and "n = 128" on one line */
.jd-about .jdc-strength { --jdc-val: 7.6rem; }
.jd-about .jdc-strength .jdc-val { white-space: nowrap; }
.jd-about .jdc-strength .jdc-n { font-size: 0.76rem; color: #4a5361; }

/* THE SIX MATCHUPS (owner, 2026-10-05): one row per pair, the left model's
   wins running left from the centre line and the right model's right,
   shaded by margin, the even results ("About the same") straddling the centre; each side's
   share at its end, the names in the outer columns */
.jd-about .jdc-matchups { display: flex; flex-direction: column; }
.jd-about .jdc-mrow {
  display: grid; grid-template-columns: 8.8rem 1fr 8.8rem;
  align-items: center; column-gap: 12px; min-height: 40px;
  border-bottom: 1px solid rgba(55, 65, 79, 0.1);
}
.jd-about .jdc-mrow:last-child { border-bottom: 0; }
/* THE TWO NEAR-TIES (owner, 2026-10-06): on the `ties` step (data-focus
   "ties" on the charts' pane host) the matchups' top and bottom rows — the
   top pair against each other, the bottom pair against each other — stay
   lit and the four between dim. The rows are in the charts' strength order,
   so those two are first and last. Desk only: the phone has no focus. */
.jd-about .jdc-matchups > .jdc-mrow { transition: opacity 0.45s ease; }
.jd-about [data-scene-pane="analytics"][data-focus="ties"] .jdc-matchups > .jdc-mrow:not(:first-child):not(:last-child) { opacity: 0.22; }
@media (prefers-reduced-motion: reduce) { .jd-about .jdc-matchups > .jdc-mrow { transition: none; } }
.jd-about .jdc-mrow .jdc-name { white-space: nowrap; }
.jd-about .jdc-mrow .jdc-name.is-right { text-align: left; }
.jd-about .jdc-mtrack { position: relative; height: 22px; }
.jd-about .jdc-mcentre {
  position: absolute; left: 50%; top: -6px; bottom: -6px; width: 1px;
  background: rgba(55, 65, 79, 0.45);
}
.jd-about .jdc-mseg { position: absolute; top: 50%; height: 12px; margin-top: -6px; }
.jd-about .jdc-mlevel { background: rgba(55, 65, 79, 0.18); }
.jd-about .jdc-mval {
  position: absolute; top: 50%; transform: translateY(-50%); line-height: 1;
  font-family: var(--font-mono); font-size: 0.82rem; color: #1f2530;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* WHERE EACH MODEL DOES BETTER OR WORSE (owner, 2026-10-05; redrawn the
   same day: "I still just don't love the design of this heat map", "it has a
   vertical scroll bar"). A heat map on the card's paper, with no scrolling
   box around it: the heading column (the probe, its count small at the
   right), then four equal columns of tiles. REDRAWN 2026-10-08: each tile
   is the model's real average grade, its signed gap small beside it, shaded
   by that gap on one diverging scale (--c, set per cell) over a pale tile
   ground that lets the paper's grain through; the column is titled over the
   probes it names; each model's overall average closes the table as an
   "All prompts" totals row under a double rule, unshaded, the baseline the
   shades are measured from. The key and a footnote under the grid. */
.jd-about .jdc-btfig figcaption { margin-bottom: 8px; }
.jd-about .jdc-bt-key {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin: 10px 4px 0;
  font-size: 0.8rem; font-style: italic; line-height: 1.2;
  color: rgba(55, 65, 79, 0.85); white-space: nowrap;
}
.jd-about .jdc-bt-ramp {
  display: block; flex: none; width: 112px; height: 9px; border-radius: 1px;
  box-shadow: inset 0 0 0 1px rgba(55, 65, 79, 0.12);
}
.jd-about .jdc-bt {
  width: 100%; table-layout: fixed;
  border-collapse: separate; border-spacing: 4px;
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--jdc-ink);
}
.jd-about .jdc-bt col.jdc-bt-hcol { width: 11.5rem; }
.jd-about .jdc-bt th, .jd-about .jdc-bt td { padding: 0; }
/* the heading column: the probe on the left, its count small on the right,
   on one baseline */
.jd-about .jdc-bt th.jdc-bt-kind,
.jd-about .jdc-bt th.jdc-bt-toth,
.jd-about .jdc-bt th.jdc-bt-corner { text-align: left; font-weight: 400; white-space: nowrap; }
.jd-about .jdc-bt .jdc-bt-hd {
  display: flex; align-items: baseline; justify-content: space-between; gap: 6px;
  padding: 0 10px 0 2px;
}
.jd-about .jdc-bt .jdc-bt-n { font-size: 0.7rem; color: rgba(55, 65, 79, 0.62); }
.jd-about .jdc-bt th.jdc-bt-kind .jdc-bt-label {
  font-family: var(--font-body); font-size: 1rem; line-height: 1.1; color: #1f2530;
}
/* a title and its gloss under it, stacked: the column's head ("Probe /
   what the prompt tests") and the totals row's ("All prompts / each
   model's overall average") */
.jd-about .jdc-bt .jdc-bt-ttl { display: flex; flex-direction: column; min-width: 0; }
.jd-about .jdc-bt .jdc-bt-gloss {
  font-family: var(--font-body); font-style: italic; font-size: 0.78rem; line-height: 1.15;
  color: rgba(55, 65, 79, 0.78); white-space: nowrap;
}
/* the head: the column's title over the probes, the model names over their
   tiles, set on the tiles' baseline, a hairline under it */
.jd-about .jdc-bt thead th {
  vertical-align: bottom; padding-bottom: 5px;
  border-bottom: 1px solid rgba(55, 65, 79, 0.35);
}
.jd-about .jdc-bt th.jdc-bt-corner .jdc-bt-hd { align-items: flex-end; }
.jd-about .jdc-bt th.jdc-bt-corner .jdc-bt-label {
  font-family: var(--font-body); font-size: 1rem; font-weight: 700; line-height: 1.1;
  color: #1f2530;
}
.jd-about .jdc-bt th.jdc-bt-corner .jdc-bt-n { font-style: italic; padding-bottom: 1px; }
.jd-about .jdc-bt th.jdc-bt-model {
  font-size: 0.8rem; font-weight: 700; line-height: 1.2; color: #1f2530;
  text-align: center; text-wrap: balance; overflow-wrap: normal;
}
.jd-about .jdc-bt .jdc-bt-w { white-space: nowrap; }
.jd-about .jdc-btfig .jdc-title, .jd-about .jdc-btfig .jdc-sub { text-wrap: balance; }
/* the tiles: the grade, and its gap from the model's usual small beside it */
.jd-about .jdc-bt td.jdc-bt-c {
  height: 30px; text-align: center; vertical-align: middle;
  background: var(--c, rgba(250, 245, 230, 0.6));
  border-radius: 2px;
  box-shadow: inset 0 0 0 1px rgba(55, 65, 79, 0.07);
  line-height: 1; color: #1f2530; white-space: nowrap;
}
.jd-about .jdc-bt .jdc-bt-g { font-size: 0.86rem; letter-spacing: -0.01em; }
.jd-about .jdc-bt .jdc-bt-d {
  margin-left: 7px; font-size: 0.64rem; letter-spacing: -0.03em; opacity: 0.68;
}
.jd-about .jdc-bt td.jdc-bt-c.is-deep { color: #f6eed8; box-shadow: none; }
.jd-about .jdc-bt td.jdc-bt-c.is-deep .jdc-bt-d { opacity: 0.82; }
.jd-about .jdc-bt td.jdc-bt-c.is-none { color: rgba(55, 65, 79, 0.5); }
/* THE TOTALS ROW: a double rule across the table, then each model's average
   on every prompt, unshaded in an ink outline, the figure in bold */
.jd-about .jdc-bt tr.jdc-bt-rulerow td { height: 6px; vertical-align: middle; }
.jd-about .jdc-bt .jdc-bt-rule {
  display: block; height: 4px; margin: 2px 0 0;
  border-top: 1.5px solid rgba(31, 37, 48, 0.78);
  border-bottom: 0.75px solid rgba(31, 37, 48, 0.78);
}
.jd-about .jdc-bt th.jdc-bt-toth .jdc-bt-label {
  font-family: var(--font-body); font-size: 1rem; font-weight: 700; line-height: 1.1; color: #1f2530;
}
.jd-about .jdc-bt th.jdc-bt-toth .jdc-bt-hd { align-items: center; }
.jd-about .jdc-bt td.jdc-bt-tot {
  height: 32px; text-align: center; vertical-align: middle;
  background: rgba(250, 245, 230, 0.32);
  border-radius: 2px;
  box-shadow: inset 0 0 0 1.5px rgba(31, 37, 48, 0.62);
  font-size: 0.86rem; font-weight: 700; line-height: 1; color: #1f2530;
}

/* THE CHARTS ON A PHONE. The phone's column is ~360px wide, and a 700px
   chart scaled into it came out at half size. Here the chart lays out at the
   column's own width instead: a narrower name column, and the four category
   panels in one column with the names on every panel (a single column has
   no left-hand panel to carry them). The dots' rings stay cut from the
   card's paper. (The phone block at the foot of the file has the rest.) */
@media (max-width: 768px) {
  .jd-about [data-scene-pane="analytics"] .jd-inline-card { width: 100%; }
  .jd-about .jd-charts { --jdc-name: 7.2rem; }
  .jd-about .jd-charts-wrap { padding: 4px 14px 22px 8px; }
  .jd-about .jdc-row { column-gap: 8px; min-height: 28px; }
  .jd-about .jdc-name, .jd-about .jdc-val { font-size: 0.78rem; }
  .jd-about .jdc-sub { font-size: 0.9rem; }
  .jd-about .jdc-multiples { grid-template-columns: 1fr; gap: 14px; }
  .jd-about .jdc-panel, .jd-about .jdc-panel.is-right { --jdc-name: 7.2rem; }
  .jd-about .jdc-rates .jdc-panel { --jdc-val: 2.8rem; }
  .jd-about .jdc-legend { font-size: 0.74rem; gap: 3px 12px; margin-bottom: 12px; }
  .jd-about .jdc-panel.is-right .jdc-row { grid-template-columns: var(--jdc-name) 1fr var(--jdc-val); column-gap: 8px; }
  .jd-about .jdc-panel.is-right .jdc-ptitle { margin-left: calc(var(--jdc-name) + 8px); }
  .jd-about .jdc-panel.is-right .jdc-name { visibility: visible; }
  .jd-about .jdc-panel .jdc-row { min-height: 22px; }
  /* every panel the same on a phone (PLAN-MOBILE-ABOUT phase 1): the right
     column's panels kept the desk's clipped name ("Claude Opus 5.!") and a
     key flush left, out of line with the left column's. One name size that
     fits 7.2rem, the name never clipped, every key and title on the bars'
     left edge. */
  .jd-about .jdc-panel .jdc-name, .jd-about .jdc-panel .jdc-val { font-size: 0.78rem; }
  .jd-about .jdc-panel.is-right .jdc-name { overflow: visible; }
  .jd-about .jdc-panel .jdc-ptitle,
  .jd-about .jdc-panel .jdc-pkey,
  .jd-about .jdc-panel.is-right .jdc-pkey { margin-left: calc(var(--jdc-name) + 8px); }
  .jd-about .jdc-ptitle { font-size: 0.92rem; margin-bottom: 2px; }
  /* the names over the bar, the bar the column's full width */
  .jd-about .jdc-mrow { grid-template-columns: 1fr 1fr; grid-template-areas: "a b" "t t"; row-gap: 2px; padding: 6px 0 4px; }
  .jd-about .jdc-mrow .jdc-name { font-size: 0.72rem; white-space: nowrap; }
  .jd-about .jdc-mrow .jdc-name.is-left { grid-area: a; text-align: left; }
  .jd-about .jdc-mrow .jdc-name.is-right { grid-area: b; text-align: right; }
  .jd-about .jdc-mrow .jdc-mtrack { grid-area: t; }
  .jd-about .jdc-mval { font-size: 0.72rem; }
  /* the heat map at the column's width: a narrower heading column, the four
     model columns share the rest, the names on two lines over them; each
     tile's gap goes under its grade */
  .jd-about .jdc-bt { border-spacing: 3px; }
  .jd-about .jdc-bt col.jdc-bt-hcol { width: 7.4rem; }
  .jd-about .jdc-bt th.jdc-bt-kind .jdc-bt-label { font-size: 0.86rem; }
  .jd-about .jdc-bt th.jdc-bt-corner .jdc-bt-label,
  .jd-about .jdc-bt th.jdc-bt-toth .jdc-bt-label { font-size: 0.86rem; }
  .jd-about .jdc-bt .jdc-bt-gloss { font-size: 0.66rem; }
  /* the totals row's gloss wraps ("each model's / overall average")
     rather than run into the count beside it */
  .jd-about .jdc-bt th.jdc-bt-toth .jdc-bt-gloss { white-space: normal; text-wrap: balance; }
  /* the column's count header under its title, not beside it */
  .jd-about .jdc-bt th.jdc-bt-corner .jdc-bt-hd { flex-direction: column; align-items: stretch; gap: 1px; }
  .jd-about .jdc-bt th.jdc-bt-corner .jdc-bt-n { align-self: flex-end; }
  .jd-about .jdc-bt .jdc-bt-hd { padding-right: 4px; }
  .jd-about .jdc-bt .jdc-bt-n { font-size: 0.64rem; }
  .jd-about .jdc-bt th.jdc-bt-model { font-size: 0.68rem; }
  .jd-about .jdc-bt td.jdc-bt-c { height: 34px; }
  .jd-about .jdc-bt .jdc-bt-g { display: block; font-size: 0.76rem; }
  .jd-about .jdc-bt .jdc-bt-d { display: block; margin: 3px 0 0; font-size: 0.58rem; }
  .jd-about .jdc-bt td.jdc-bt-tot { height: 30px; font-size: 0.76rem; }
  .jd-about .jdc-bt-key { justify-content: center; font-size: 0.74rem; gap: 6px; }
  .jd-about .jdc-bt-ramp { width: 64px; }
  /* the strength chart's n under its chance, where a row has no room */
  .jd-about .jdc-strength { --jdc-val: 3.4rem; }
  .jd-about .jdc-strength .jdc-val { line-height: 1.15; }
  .jd-about .jdc-strength .jdc-n { display: block; margin-left: 0; }
}
/* the narrowest phones (360px): the heading column gives a little back, so
   each model's name keeps to two lines over its tiles */
@media (max-width: 374px) {
  .jd-about .jdc-bt col.jdc-bt-hcol { width: 6.6rem; }
  .jd-about .jdc-bt th.jdc-bt-kind .jdc-bt-label { font-size: 0.82rem; }
  .jd-about .jdc-bt th.jdc-bt-model { font-size: 0.6rem; }
  .jd-about .jdc-bt .jdc-bt-gloss { font-size: 0.6rem; }
  .jd-about .jdc-bt .jdc-bt-g { font-size: 0.7rem; letter-spacing: -0.04em; }
  .jd-about .jdc-bt td.jdc-bt-tot { font-size: 0.7rem; letter-spacing: -0.04em; }
  .jd-about .jdc-bt-key { font-size: 0.7rem; }
  .jd-about .jdc-bt-ramp { width: 48px; }
}

/* THE RECORD AS A SPREADSHEET (owner, 2026-09-27): one row per prompt, each
   model's grade and four ratings across the row in a group of columns — raw
   values in a grid, on the same paper as the charts, in the card's slate ink.
   Gridlines on every cell, a two-row shaded head (the models over their
   columns), a numbered row gutter, a firmer rule where each model's group
   begins; one monospaced face, text left and numbers right. A fixed window
   scrolls both ways (the page's own scroll resumes at its ends); the head,
   the row numbers and the prompt column hold still. Sticky cells need an
   opaque ground, and the card's base cream reads as a pale block against
   paper its grain has darkened, so they use the paper as it renders.
   The sheet only ever stands in .jd-sheet-card, and since 2026-09-29 its
   look is IN THE FOLDER'S STYLE (below): what this layer still carries is
   the skeleton — the scrolling window, the sticky heads, the frozen prompt
   column and the column widths that layer does not restate. */
.jd-about .jdc-tablewrap {
  overflow: auto;
  border: 1px solid rgba(55, 65, 79, 0.45);
}
.jd-about .jdc-tablewrap:focus-visible { outline: 2px solid rgba(55, 65, 79, 0.5); outline-offset: 2px; }
.jd-about .jdc-sheet {
  --jdc-h1: 30px;             /* the model row's height: the column row sticks under it */
  border-collapse: separate; border-spacing: 0;
  table-layout: fixed;
  width: max-content;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.jd-about .jdc-sheet th,
.jd-about .jdc-sheet td {
  white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.jd-about .jdc-sheet th {
  position: sticky; top: 0; z-index: 2;
  background: var(--jdc-headfill);
  text-align: left;
  text-overflow: clip;
}
.jd-about .jdc-sheet tr.jdc-h1 th { height: var(--jdc-h1); box-sizing: border-box; }
.jd-about .jdc-sheet tr.jdc-h2 th {
  top: var(--jdc-h1);
  white-space: normal; vertical-align: bottom;
}
/* the prompt holds still as the table scrolls sideways (the row numbers
   that once stood beside it are hidden, below) */
.jd-about .jdc-sheet .jdc-c-prompt {
  position: sticky; z-index: 1;
  width: 12rem; min-width: 12rem; max-width: 12rem;
}
.jd-about .jdc-sheet th.jdc-c-prompt { z-index: 4; }

/* THE SHEET ON ITS OWN (owner, 2026-09-27): the table is the whole visual —
   no card, title or subtitle — straight on the white page, as wide as a
   report card (740px, the record host's width). */
.jd-about [data-scene-pane="analytics"] .jd-inline-card.jd-sheet-card { width: 740px; }
.jd-about .jd-sheet-card {
  --jdc-ink: #37414f;
  --jdc-hair: rgba(55, 65, 79, 0.22);
  color: var(--jdc-ink);
  background: var(--paper);
}
.jd-about .jd-sheet-card .jdc { margin: 0; }
.jd-about .jd-sheet-card .jdc-tablewrap { max-height: 720px; background: var(--jdc-paper, #efe4c6); }
/* the rows keep the drawer's cream (owner: "the same kind of beige … that
   fits the theme"): every body cell, frozen or not, on the report card's
   paper tone, under a deeper head (--jdc-paper / --jdc-headfill, on the
   sheet below) */
.jd-about .jd-sheet-card .jdc-sheet td { background: var(--jdc-paper); }
/* IN THE FOLDER'S STYLE (owner, 2026-09-29: "make it look more like the
   table in the analytics folder"): the spreadsheet grid goes — no vertical
   rules, no row-number gutter — for the folder's turn table's grammar:
   small tracked serif heads on a deeper cream, mono values on hairline
   rows, and the segmented gauge beside every number (about-scenes.js). The
   frozen prompt column and the sticky heads stay, because this sheet
   scrolls both ways and the folder's does not. */
.jd-about .jd-sheet-card .jdc-sheet {
  --jdc-paper: #efe4c6;
  --jdc-headfill: #ddd0ad;
  --jdc-ink: #33240f;
  --jdc-group: rgba(74, 53, 18, 0.28);
  color: var(--jdc-ink);
  font-size: 0.66rem;
}
.jd-about .jd-sheet-card .jdc-sheet th,
.jd-about .jd-sheet-card .jdc-sheet td {
  border-right: 0;
  border-bottom: 1px solid rgba(74, 53, 18, 0.18);
  padding: 4px 9px 4px 8px;
  line-height: 1.45;
}
.jd-about .jd-sheet-card .jdc-sheet th {
  font-family: var(--jd-font-form);
  font-weight: 700; font-size: 0.56rem;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: rgba(51, 36, 15, 0.64);
  vertical-align: bottom;
}
.jd-about .jd-sheet-card .jdc-sheet tr.jdc-h1 th { color: var(--jdc-ink); font-size: 0.6rem; }
.jd-about .jd-sheet-card .jdc-sheet tr.jdc-h2 th {
  font-weight: 700; font-size: 0.52rem; line-height: 1.3;
  border-bottom: 1px solid rgba(74, 53, 18, 0.38);
}
.jd-about .jd-sheet-card .jdc-sheet th[rowspan] { border-bottom: 1px solid rgba(74, 53, 18, 0.38); }
.jd-about .jd-sheet-card .jdc-sheet .jdc-hint {
  font-family: var(--font-body); font-style: italic; font-weight: 400;
  letter-spacing: 0; text-transform: none; color: rgba(51, 36, 15, 0.55);
}
/* the row numbers go, and the prompt column takes the left wall */
.jd-about .jd-sheet-card .jdc-sheet .jdc-rn { display: none; }
.jd-about .jd-sheet-card .jdc-sheet .jdc-c-prompt { left: 0; border-right: 1px solid var(--jdc-group); }
.jd-about .jd-sheet-card .jdc-sheet .jdc-g-head,
.jd-about .jd-sheet-card .jdc-sheet .jdc-g-start { border-left: 1px solid var(--jdc-group); }
.jd-about .jd-sheet-card .jdc-sheet .jdc-c-num,
.jd-about .jd-sheet-card .jdc-sheet th.jdc-c-num { text-align: left; width: 6.6rem; min-width: 6.6rem; max-width: 6.6rem; }
.jd-about .jd-sheet-card .jdc-sheet th.jdc-c-num { white-space: normal; }
.jd-about .jd-sheet-card .jdc-num { display: inline-block; width: 1.1em; font-weight: 700; }
.jd-about .jd-sheet-card .jdc-none { color: rgba(51, 36, 15, 0.5); }
.jd-about .jd-sheet-card .jdc-gauge { width: 41px; height: 9px; vertical-align: -1px; margin-left: 4px; }
.jd-about .jd-sheet-card .jdc-seg { stroke: var(--jdc-paper, #efe4c6); stroke-width: 1.4; }
.jd-about .jd-sheet-card .jdc-seg-out { stroke: rgba(74, 53, 18, 0.18); stroke-width: 1; }

/* the prompt card beside an Item cell (about-scenes.js, "the prompt card"):
   the report card's prompt box in miniature — cream paper, a slate hairline,
   the tracked label over the prompt in the typewriter face */
.jd-prompt-tip {
  position: fixed; z-index: 90;
  max-width: 22rem;
  padding: 10px 12px 11px;
  background: #efe4c6;
  border: 1px solid rgba(55, 65, 79, 0.45);
  box-shadow: 3px 6px 14px -4px rgba(6, 3, 0, 0.45);
  color: #37414f;
  pointer-events: none;
  opacity: 0; visibility: hidden;
  transition: opacity 0.12s ease, visibility 0s linear 0.12s;
}
.jd-prompt-tip.is-on { opacity: 1; visibility: visible; transition: opacity 0.12s ease; }
.jd-prompt-tip-h {
  display: block; margin-bottom: 5px;
  font-family: var(--font-mono); font-size: 0.62rem;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(55, 65, 79, 0.8);
}
.jd-prompt-tip p {
  margin: 0;
  font-family: var(--font-mono); font-size: 0.78rem; line-height: 1.45;
  color: #1f2530;
}
.jd-about .jdc-sheet td.jdc-c-prompt { cursor: help; }

/* the Item head's hint: quiet, a size under the head. Its face, italic and
   colour are the folder-style rule's (above); its SIZE stays here, at this
   weight (0,3,0), on purpose — the touch rule below swaps the words by
   setting font-size 0 at the same weight, later, and a size moved into the
   heavier rule would outrank it and print both hints. */
.jd-about .jdc-sheet .jdc-hint {
  font-size: 0.72rem;
  white-space: nowrap;
}
@media (hover: none) {
  /* a touch screen has no hover: the same hint, in its own words */
  .jd-about .jdc-sheet .jdc-hint { font-size: 0; }
  .jd-about .jdc-sheet .jdc-hint::after { content: "(tap to see prompt)"; font-size: 0.68rem; }
}

/* each value's n (owner, 2026-09-27): how many drawings the average rests
   on, beside it in the muted ink — the scale's words under the axis are gone,
   the ticks carry the scale */
.jd-about .jdc-n {
  margin-left: 0.6em;
  font-size: 0.68rem;
  color: rgba(55, 65, 79, 0.62);
}

/* THE GRADE DISTRIBUTIONS (owner, 2026-09-27): one row of small multiples.
   The grade names once, down the left; each model a column of five
   horizontal bars that line up with them across the row, on one shared
   scale, rising from a hairline at each panel's left edge; the count at the
   bar's end. No gridlines, no value axis — the counts are on the bars. */
.jd-about .jdc-hrow { display: grid; column-gap: 14px; row-gap: 7px; align-items: center; }
.jd-about .jdc-hrow-t { margin: 0 0 4px; font-size: 0.95rem; white-space: nowrap; }
.jd-about .jdc-hrow-lab {
  font-family: var(--font-mono); font-size: 0.74rem;
  text-align: right; color: var(--jdc-ink); white-space: nowrap;
  padding-right: 2px;
}
.jd-about .jdc-hrow-cell {
  display: flex; align-items: center; gap: 5px;
  height: 18px;
  border-left: 1px solid rgba(55, 65, 79, 0.45);
}
.jd-about .jdc-hrow-bar { display: block; height: 11px; min-width: 1px; border-radius: 0 3px 3px 0; }
.jd-about .jdc-hrow-n {
  font-family: var(--font-mono); font-size: 0.7rem; line-height: 1;
  color: #1f2530; font-variant-numeric: tabular-nums;
}
/* (a second max-width: 768px block, and it must stay one: the column heads
   here are `.jdc-ptitle.jdc-hrow-t`, so this block has to come AFTER the
   base .jdc-hrow-t rule — its white-space beats the base's nowrap — while
   the first block's .jdc-ptitle margin-bottom has to come BEFORE it, so the
   base's 4px wins over that 2px. One merged block would flip one of them.
   The type sizes are the phone block's, further down.) */
@media (max-width: 768px) {
  .jd-about .jdc-hrow { column-gap: 8px; row-gap: 5px; }
  .jd-about .jdc-hrow-t { white-space: normal; }
}

/* two charts under one title (the average and the spread): each keeps its
   own subtitle, set as a small left-aligned lead-in, with air between them */
.jd-about .jdc-pair figcaption { margin-bottom: 14px; }
.jd-about .jdc-sec + .jdc-sec { margin-top: 24px; padding-top: 18px; border-top: 1px solid rgba(55, 65, 79, 0.18); }
.jd-about .jdc-sec-sub { margin: 0 0 10px; text-align: left; font-size: 0.92rem; }

/* FOCUS (owner, 2026-09-27; widened 2026-09-29): a step can dim part of its
   card to point at the rest. "spread-lead": the averages recede, and in the
   spread only the top three grades (Prime, Choice, Select) of the three
   leading models (Opus, Gemini, Kimi) stay at full strength — every other
   bar, and GPT-5.1's column head, fade back. Opacity eases, so the emphasis
   moves rather than blinks. */
.jd-about .jdc-sec-avg,
.jd-about .jdc-hrow-t,
.jd-about .jdc-hrow-cell { transition: opacity 0.35s ease; }
.jd-about [data-scene-pane="analytics"][data-focus="spread-lead"] .jdc-sec-avg { opacity: 0.28; }
.jd-about [data-scene-pane="analytics"][data-focus="spread-lead"] .jdc-hrow-t[data-model="gpt-5-1"],
.jd-about [data-scene-pane="analytics"][data-focus="spread-lead"] .jdc-hrow-cell { opacity: 0.22; }
.jd-about [data-scene-pane="analytics"][data-focus="spread-lead"] .jdc-hrow-cell:is([data-model="claude-opus-5"], [data-model="gemini-3-1-pro"], [data-model="kimi-k3"]):is([data-grade="5"], [data-grade="4"], [data-grade="3"]) { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .jd-about .jdc-sec-avg, .jd-about .jdc-hrow-t, .jd-about .jdc-hrow-cell { transition: none; }
}
/* THE PANEL IN FOCUS (owner, 2026-10-05: the paintwork callback). A step
   whose data-focus is an axis id lights that issue-rate panel
   (about-scenes.js axisFocus: .has-focus on the multiples, .is-focus on the
   panel, matched by its data-axis): every other panel fades back, the lit
   panel's highest rate (data-top) is ringed and its value set bold. A
   right-hand panel borrows its row's names from the panel on its left
   (.is-names), so those names stay lit while the rest of that panel fades.
   Opacity eases, so the emphasis moves rather than blinks; the desk only
   (the phone has no focus). */
.jd-about .jdc-multiples > .jdc-panel > *,
.jd-about .jdc-multiples .jdc-row > *,
.jd-about .jdc-multiples .jdc-row,
.jd-about .jdc-multiples + .jdc-legend,
.jd-about .jdc-multiples .jdc-val { transition: opacity 0.45s ease, box-shadow 0.45s ease, background-color 0.45s ease; }
.jd-about .jdc-multiples.has-focus > .jdc-panel:not(.is-focus):not(.is-names) > *,
.jd-about .jdc-multiples.has-focus > .jdc-panel.is-names > .jdc-ptitle,
.jd-about .jdc-multiples.has-focus > .jdc-panel.is-names > .jdc-pkey,
.jd-about .jdc-multiples.has-focus > .jdc-panel.is-names .jdc-row > :not(.jdc-name) { opacity: 0.2; }
.jd-about .jdc-multiples.has-focus > .jdc-panel.is-focus .jdc-row[data-top] {
  background-color: rgba(176, 52, 30, 0.08);
  box-shadow: 0 0 0 1.5px rgba(150, 40, 22, 0.55);
  border-radius: 3px;
}
.jd-about .jdc-multiples.has-focus > .jdc-panel.is-focus .jdc-row[data-top] .jdc-val { font-weight: 700; color: #1f2530; }
@media (prefers-reduced-motion: reduce) {
  .jd-about .jdc-multiples > .jdc-panel > *,
  .jd-about .jdc-multiples .jdc-row > *,
  .jd-about .jdc-multiples .jdc-row,
  .jd-about .jdc-multiples .jdc-val { transition: none; }
}


/* THE FOLDER, INLINE — DORMANT (2026-10-01). Scene 4 has drawn its own
   charts since 2026-09-27 (THE CHARTS, above) and this page never opens the
   analytics folder. These rules stay for the one path that still brings it
   in: with ?live the pile is whole, its folder object opens the real folder
   on a click, and if that happens while the analysis is the scene the page
   wants (its warm-up after load, or a handoff out of scene 4) about-scenes.js
   carries the folder's scrim into the pane as an inline card (SCRIM_SCENE)
   — where this is how it looks. Everywhere else the ?live protections hold
   it: html.jd-folder-open's overflow and the hidden scrim on <body>.

   THE ANALYSIS, THREE CARDS (owner, 2026-09-15). The folder renders every
   card into one 920px sheet — the grade book, the spend, the four axes in
   a row, the turn-by-turn table — and scaled into the pane it read as one
   dense dashboard. Here the folder is the width of the other two cards and
   shows ONE card at a time — the host's data-fx, "grades" in the markup
   (the step-driven cost and axes cards went with the folder) — laid two by
   two instead of in a row, each panel its full box with its own key
   (jd-furniture.js treats this page as it treats a narrow viewport for
   that). The turn-by-turn table is left off. */
.jd-about .jd-inline-card .fx-card { display: none; flex: 0 0 auto; }
.jd-about [data-scene-pane="analytics"][data-fx="grades"] .fx-grades { display: block; }
.jd-about .jd-inline-card .fx-turns { display: none; }
/* one chart, centred in the card, and a little larger than the folder's
   440px cap now that it has the sheet to itself */
.jd-about .jd-inline-card .fx-chart { margin: 0 auto; max-width: 520px; }
.jd-about .jd-inline-card .fx-axgrid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px 20px;
}
.jd-about .jd-inline-card .fx-panel svg { max-width: 270px; margin: 0 auto; }

/* THE FOLDER LOOKS LIKE A FOLDER (owner, 2026-09-16). In the drawer the
   open folder is a card with a slim manila band across its top holding the
   tab and the ✕; scaled into the pane, the band read as a title bar and
   the tab as a label on it — not a folder. Here the band is gone: the tab
   is a raised flag standing on the folder's top edge, joined to it (it
   overlaps the body's top rule by a pixel), and the BODY is the manila —
   grain, edge and shadow moved from the card to the sheet the paper card
   lies in. The sheet is a FIXED HEIGHT, the same for all three cards, and
   closer to square than the strip it was; a card shorter than the sheet
   (the cost chart, the grade book) sits at its vertical centre. */
.jd-about .jd-inline-card .jd-folder-card {
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
/* A REAL TAB (owner, 2026-09-16): bigger, and its word bigger with it, the
   way a manila folder's tab stands proud of the sheet. It reaches DOWN
   INTO the sheet by four pixels — over the sheet's top rule and past it —
   so that at any scale factor the join is covered by the tab's own opaque
   manila: a one-pixel overlap left a hairline of light showing through
   under the word once the card was scaled, and read as the tab sitting on
   the folder rather than being part of it. The inset highlight is gone for
   the same reason. */
.jd-about .jd-inline-card .jd-folder-tab {
  position: relative;
  top: 4px;
  z-index: 1;
  padding: 12px 30px 14px;
  font-size: 0.92rem;
  letter-spacing: 0.3em; text-indent: 0.3em;
  background: var(--fmanila) var(--fgrain);
  border: 1px solid rgba(48, 38, 20, 0.6);
  border-bottom: 0;
  border-radius: 9px 9px 0 0;
  box-shadow: none;
}
.jd-about .jd-inline-card .jd-folder-scroll {
  display: flex;
  flex-direction: column;
  justify-content: center;       /* the paper card at the sheet's centre */
  height: 560px;
  box-sizing: border-box;
  padding: 24px;
  background: var(--fmanila) var(--fgrain);
  border: 1px solid rgba(48, 38, 20, 0.6);
  border-radius: 0 6px 6px 6px;  /* square where the tab stands on it */
  box-shadow: 14px 22px 34px -10px rgba(6, 3, 0, 0.66),
              3px 6px 12px -4px rgba(6, 3, 0, 0.5);
  overflow: hidden;
}

/* ============================================================================
   DESKTOP: PANE LEFT, STEPS RIGHT. Every rule that needs a real desktop —
   (min-width: 769px) and (min-height: 501px); about-scenes.js asks the
   complementary question, PHONE_Q — in one block. It was three until
   2026-10-01, each overriding the one before; this one block stands after
   the base rules it overrides, and its place is load-bearing in one spot:
   `.jd-about--live .jd-about-head` has to come AFTER `.jd-about .jd-about-head`
   (the same weight), or the title block keeps its phone-and-no-JS margin.

   THE STEP TEXT MOVES WITH THE SCROLL (owner, 2026-09-26). It used to be
   pinned: prose at the top of an 82vh step, held at the drawer's midline
   for the rest of the step (2026-09-23, so the words sat beside the drawer
   while their step was on). But a paragraph that stops while the wheel keeps
   turning reads as a broken scroll, and the gap fix that followed only
   moved the stop. So nothing pins: every paragraph travels at the page's
   own speed, and the spacing does the pacing instead.
   The prose sits at the TOP of its step, so it is on the drawer's midline
   (the 45% focus line, --jd-focus) at the moment its step lights; the next
   paragraph arrives on that line just as this one clears the top — one
   paragraph in the middle at a time (since 2026-09-27 a step's height is
   its own prose plus that distance: EVERY STEP CLEARS THE SCREEN, below;
   since 2026-09-28 it holds there briefly: THE HOLD). Desktop only.
   ========================================================================== */
@media (min-width: 769px) and (min-height: 501px) {
  /* the pinned pane's height — the viewport under the banner, less --s-3 —
     and the title block's, which the opening step's margin subtracts */
  .jd-about {
    --jd-pane-h: calc(100vh - var(--banner-h) - var(--s-3));
    --jd-head: max(10rem, 28vh);
  }
  .jd-about .jd-about-grid {
    display: grid;
    /* graphic | prose | timeline. The graphic takes the larger share because
       the cards are 960px at full size and every point of scale costs
       legibility; the timeline is a fixed thin rail, not a column. */
    grid-template-columns: minmax(0, 66fr) minmax(0, 34fr) 40px;
    column-gap: var(--s-4);
    align-items: start;
    width: 100%;
    /* wider than v2's 1480: at 1640 a 1920 monitor renders both cards at
       scale 1, i.e. pixel-identical to the drawer */
    max-width: 1640px;
    margin: 0 auto;
    padding: 0 var(--s-4);
    box-sizing: border-box;
  }
  /* the timeline pins beside the prose */
  .jd-about .jd-timeline {
    position: sticky;
    top: calc(var(--banner-h) + var(--s-4));
    padding: var(--s-2) 0;
  }
  .jd-about .jd-about-pane {
    position: sticky;
    top: calc(var(--banner-h) + var(--s-1));
    container-type: inline-size;
    /* the pinned height is fixed (below) and about-scenes.js scales each
       card to fit it, rather than letting a card push the pane past the
       viewport. The card is CENTRED in the column: left top-aligned, the
       report card ended halfway up a pane twice its height while the prose
       beside it sat vertically centred, and the two never lined up. */
    /* a FIXED height, not a max: with max-height the pane shrank to the
       card, so a short card (the report card is only ~424px scaled) sat at
       the top of the column while the prose beside it stayed centred far
       below — the graphic and the words never lined up. Fixed height plus
       safe centring puts the card's middle on the prose's middle. */
    height: var(--jd-pane-h);
    /* the max-height is READ: about-scenes.js fitCard takes the card's
       available height from it. Its fallback, the computed height, is the
       used height snapped to 1/64px — under page zoom it differs from this
       by up to ~0.014px, enough to move a card's 4-decimal scale. Keep it. */
    max-height: var(--jd-pane-h);
    /* hidden, not auto: a scene mid-travel sits ±52px outside the pane and
       would otherwise arm a scrollbar on the pinned graphic every time the
       scene changed. The card is fitted to the pane, so nothing that belongs
       on screen is ever cut. */
    overflow: hidden;
    display: flex;
    flex-direction: column;
    /* SAFE centring. A card shorter than the pane should sit in the middle,
       beside the prose. A card TALLER than the pane must start at the top —
       plain `center` centres the overflow too, which clipped the report card
       at BOTH ends: the drawing lost its leaves off the top and the sibling
       strip fell off the bottom, with no way to reach either. `safe` keeps
       the centring only while it costs nothing; the flex-start line before
       it is the fallback where `safe` is not understood. */
    justify-content: flex-start;
    justify-content: safe center;
  }
  .jd-about .jd-stage {
    max-width: 100%;
    /* the stage's MARGIN BOX has to fit the pane's max-height, not just its
       border box: --s-1 above and --s-2 below ride outside the height, and
       the pane's height (--jd-pane-h) subtracts --s-3 where this once
       subtracted --s-4. That 16px mismatch was constant at every width and
       turned the pinned graphic into a scroller that ate a wheel notch
       before the page moved. */
    height: min(
      calc(var(--jd-pane-h) - var(--s-1) - var(--s-2) - var(--jd-pull-drop)),
      1000px,
      calc(100cqw * 1.25));
    margin: var(--s-1) auto calc(var(--jd-pull-drop) + var(--s-2));
  }
  /* the drawer scene owns its own overflow: the stage is sized to fit and a
     sub-pixel rounding must not re-arm the pane's scrollbar */
  .jd-about .jd-scene[data-scene-pane="drawer"] { overflow: hidden; }
  .jd-about .jd-about-notes { max-width: none; margin: 0; padding: var(--s-2) 0 var(--s-6); }
  /* EACH STEP OWNS A STRETCH OF THE SCROLL. At their natural prose height
     (106 to 229px) a single wheel-flick crossed five steps, so the pane
     strobed through three scenes and no step ever got its moment; the first
     answer was ~82vh a step, a little less than a viewport.
     EVERY STEP CLEARS THE SCREEN BEFORE THE NEXT ARRIVES (owner, 2026-09-27:
     "by the time [the next step] scrolls in, I can still see the bottom of
     the list"). A fixed 66vh step only works for prose shorter than ~21vh;
     anything longer was still on screen when its successor reached the
     focus line. So a step is now as tall as its prose PLUS the distance from
     the focus line (--jd-focus) up to the banner, plus a little air: when
     the next step's top reaches the line, this one's last line has just
     passed under the banner. Long steps get more scroll, short ones less,
     and none overlaps. */
  .jd-about--live .jd-step {
    --jd-hold: 14vh;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    /* a floor for very short steps (a two-line step left the next heading
       peeking in at the foot of the screen): with border-box sizing this
       only lengthens a step whose prose is shorter than ~16vh */
    min-height: calc(58vh + var(--jd-hold));
    padding-bottom: calc(var(--jd-focus) - var(--banner-h) + var(--s-3));
    margin-bottom: 0;
  }
  /* THE HOLD (owner, 2026-09-28: "a subtle little lock in place … when it
     arrives, and then they scroll a bit … and then it starts to leave").
     The prose pins at the focus line for --jd-hold of scroll, then goes on
     at the page's speed. A sticky element is held until its box's content
     edge reaches it, so the hold is a spacer of exactly that height after
     the prose (inside the content box, above the step's bottom padding,
     which stays the clearance before the next step). Short on purpose: a
     long hold read as a broken scroll (2026-09-26). */
  .jd-about--live .jd-step-body {
    position: sticky;
    top: var(--jd-focus);
  }
  .jd-about--live .jd-step::after {
    content: "";
    display: block;
    height: var(--jd-hold);
    flex: none;
  }
  /* THE TITLE AND THE OPENING LINE LEAVE TOGETHER (owner, 2026-09-28: "it
     should scroll along with the paragraph when the paragraph moves up").
     The title scrolls at the page's speed, so the first step does too: no
     hold on it, and no hold spacer. */
  .jd-about--live .jd-step:first-of-type .jd-step-body { position: static; }
  .jd-about--live .jd-step:first-of-type::after { content: none; }
  /* THE LAST STEP ENDS THE PAGE (owner, 2026-09-28: the outro's text should
     still be on screen when the page bottoms out, with the site footer
     below it — not scroll away into a gap). No clearance below it and no
     hold spacer; its height is set so that, at the very bottom of the page,
     its top has passed the focus line (so it lights) and its prose sits in
     the upper half of the screen above the footer. */
  .jd-about--live .jd-step[data-step="outro"] {
    min-height: 58vh;
    padding-bottom: var(--s-4);
    margin-bottom: 0;           /* was 30vh of runway below the last step */
  }
  .jd-about--live .jd-about-notes { padding-bottom: var(--s-4); }
  .jd-about--live .jd-step[data-step="outro"]::after { content: none; }
  /* THE LAST STEP LEAVES WITH THE DRAWER (owner, 2026-09-29: "once it gets
     in position … it should still move up with the drawer"). In the final
     stretch the pane's sticky run is over — the steps column has run out —
     so the drawer is already scrolling away with the page; prose still
     pinned at the focus line then hangs while the drawer rises, which reads
     as the text moving DOWN against it. So, like the opening step, the
     outro's prose is not sticky at all: it arrives at the page's speed and
     keeps that speed, and the step's height above is what puts its arrival
     at the moment the drawer starts to leave. */
  .jd-about--live .jd-step[data-step="outro"] .jd-step-body { position: static; }
  /* THE HANDOFF'S RUNWAY. A scene change runs over the pane's height of
     scroll (D = --jd-pane-h + --jd-gap, the strip's GAP) that ENDS as the
     new scene's first step reaches the focus line (about-scenes.js,
     handoff). This margin sets when it STARTS relative to the outgoing
     scene's last step: its graphic holds still while that step's prose
     rises from the focus line by its own height plus 15vh, then graphic and
     prose leave together. margin = D - (--jd-focus - banner) + 15vh, the
     banner cancelling out — plus the hold: the outgoing step's prose now
     leaves --jd-hold later. */
  .jd-about--live .jd-step--scene-head {
    margin-top: calc(100vh - var(--jd-focus) + 15vh - var(--s-3) + var(--jd-gap) + var(--jd-hold));
  }
  /* THE OPENING LINE (owner, 2026-09-27; the title above it since
     2026-09-28). The first step began 6vh down, so at load its prose sat
     near the top and the next step's heading showed at the foot of the
     screen. Starting it ON the focus line puts the opening words beside the
     drawer's middle, where every later step is read; the title block that
     opens the step (--jd-head tall) stands above the line, high in the
     column. */
  .jd-about--live .jd-step:first-of-type {
    margin-top: calc(var(--jd-focus) - var(--banner-h) - var(--s-2) - var(--jd-head));
  }
  .jd-about--live .jd-about-head {
    min-height: var(--jd-head); box-sizing: border-box; margin: 0;
    padding-bottom: var(--s-4);
  }
}

/* ---------------- the phone, before STICKY SECTIONS -----------------------
   (History: the pinned-pane phone below was replaced on 2026-09-29 by THE
   PHONE, next. Its lessons stand — a graphic whose height follows the
   active scene moves the page under the reader; nothing may hide the
   prose; the drawer page's scroll-snap stays neutralised.)
   Rebuilt after the phone audit (2026-09-15). The first cut pinned the pane
   at 55vh for scenes 2-4 and made scene 1 an 82vh establishing shot with the
   prose riding over it. Three things broke:

   1. THE FEEDBACK LOOP. A pane whose height depends on the active scene
      makes the DOCUMENT height depend on it too — and the active scene is a
      function of scroll position. Crossing the scene-1 boundary moved the
      page 633px under the reader, which re-ran the stepper at a position
      that could select a drawer step again. Steps oscillated and `premise`
      never activated at all. The pane height is now CONSTANT across all four
      scenes; that is what closes the loop, and it is why scene 2 does not
      get a taller pane of its own however much its card would like one.
   2. The overlay prose rendered BEHIND the pane (opaque, z-index 2), so on a
      phone the h1, the dek and the live tally were invisible. The overlay is
      gone; the steps flow under the pinned graphic like every other scene.
   3. junk-drawer.css's phone scroll-snap put a 250px dead band over scene 1
      that a fling could not cross. Neutralised below.
   ------------------------------------------------------------------------ */

/* ============================================================================
   THE PHONE — "STICKY SECTIONS" (owner, 2026-09-29; Option C of the phone
   study). A phone is (max-width: 768px) OR (max-height: 500px): the second
   brings landscape phones in, and about-scenes.js asks the same question
   (PHONE_Q), so the two can never disagree. Desktop rules above are all
   under (min-width: 769px) and (min-height: 501px) — every real desktop.

   The page is an article: the title, then each scene's graphic above its own
   steps, every card the real component in its OWN phone layout at 1:1 (no
   jd-inline-card, no scale). Three graphics are held while their words
   point at them — the drawer, Gemini's drawing, Kimi's drawing — by plain
   position: sticky inside their own section, never more than 44svh, so the
   words always keep most of the screen. Nothing moves but under the thumb.

   Two states. Before about-scenes.js has run (the drawer modules are large
   and load first), the markup's own order is laid out to look the same at
   the top: the title held in its place above the drawer, the drawer still
   in the pane. Once the script has built the sections, .jd-about--phone.
   ========================================================================== */
@media (max-width: 768px), (max-height: 500px) {
  .jd-about {
    --ph-gut: 16px;
    --ph-head: 142px;            /* the title block's height, both states */
    --ph-chap: 0px;              /* the chapter bar under the banner, once it shows */
    --ph-pin: 44svh;             /* a held graphic's ceiling */
    --ph-paper: var(--paper, #fff);
  }

  /* ---- the column ------------------------------------------------------- */
  .jd-about .jd-about-grid {
    display: block;
    position: relative;
    width: 100%; min-width: 0;
    max-width: 720px;
    margin: 0 auto;
    padding: 0 var(--ph-gut);
    box-sizing: border-box;
  }
  .jd-about .jd-about-notes {
    max-width: none; margin: 0; padding: 0;
  }
  .jd-about--live .jd-timeline { display: none; }
  /* NO IMMERSIVE MODE HERE. On a phone the drawer page hides the site
     banner while the drawer fills the screen (junk-drawer.css "IMMERSIVE
     MODE") and brings it back on scroll. This page's drawer is a pinned
     pane, not the whole screen: the banner painted, then slid away as the
     stylesheet landed and the page jumped up under it (owner, 2026-09-26:
     first-load flashing), and the reader was left without the site's
     navigation until they scrolled. The banner simply stays. */
  html.jd-about-page body { padding-top: var(--banner-h); }
  html.jd-about-page .site-banner { transform: none; transition: none; }
  /* the drawer page's own phone page-snap (junk-drawer.css) is written for
     a drawer that IS the screen; here it would snap the page to the stage */
  html.jd-about-page { scroll-snap-type: none; }
  .jd-about .jd-stage,
  .jd-about #notes,
  html.jd-about-page .site-footer { scroll-snap-align: none; scroll-snap-stop: normal; }

  /* ---- the title leads -------------------------------------------------- */
  .jd-about--live .jd-about-head {
    box-sizing: border-box;
    height: var(--ph-head);
    margin: 0;
    padding: 22px 0 0;
  }
  .jd-about .jd-about-title { font-size: min(2.35rem, 10.4vw); }
  /* before the script: the title sits in its own place above the pane */
  .jd-about--live:not(.jd-about--phone) .jd-about-grid { padding-top: var(--ph-head); }
  .jd-about--live:not(.jd-about--phone) .jd-about-head {
    position: absolute; top: 0; left: var(--ph-gut); right: var(--ph-gut);
  }
  .jd-about--live:not(.jd-about--phone) .jd-about-pane {
    position: static; height: auto; overflow: visible;
    padding: 8px 0 30px;         /* = the held figure's 10px + its 20px margin */
  }
  .jd-about--phone .jd-about-pane { display: none; }

  /* ---- the steps: a long read, nothing dimmed --------------------------- */
  .jd-about--live .jd-step {
    opacity: 1;
    min-height: 0;
    margin: 0 0 40px;
  }
  .jd-about .jd-step-body { max-width: 38rem; margin: 0 auto; }
  .jd-about .jd-step-body p,
  .jd-about .jd-step-body li { font-size: 17px; line-height: 1.6; }
  .jd-about .jd-step h2 {
    font-size: 1.5rem; line-height: 1.2;
    margin: 0 0 0.6rem;
  }
  .jd-about .jd-step-body p.jd-demo-note { font-size: 13px; }   /* outranks the 17px paragraph rule above */

  /* ---- sections --------------------------------------------------------- */
  .jd-about .jd-ph-sec { position: relative; }
  /* a scene break: air and a hairline (the drawer opens the page, and the
     report card's and the charts' later figures follow on without one) */
  .jd-about .jd-about-notes > .jd-ph-sec[data-ph="instrument"],
  .jd-about .jd-about-notes > .jd-ph-sec[data-ph="fable"],
  .jd-about .jd-about-notes > .jd-ph-sec[data-ph="turns"],
  .jd-about .jd-about-notes > .jd-ph-sec[data-ph="outro"] {
    margin-top: 36px;             /* space round: 56 + 28 -> 36 + 20 */
    padding-top: 20px;
    border-top: 1px solid var(--rule-soft, rgba(0, 0, 0, 0.12));
  }
  .jd-about .jd-ph-fig { margin: 0 0 20px; }
  /* in-flow figures take half the gutter back (8px a side; the words keep
     16): cards 361 -> 377px on a 393px phone, no dead margin around them */
  .jd-about .jd-ph-fig:not(.jd-ph-pin) { margin-left: -8px; margin-right: -8px; }
  .jd-about--live .jd-ph-sec > .jd-step:last-child { margin-bottom: 0; }
  /* one section after another within a scene: the step gap, not a break */
  .jd-about .jd-ph-sec + .jd-ph-sec { margin-top: 40px; }
  .jd-about .jd-ph-sec[data-ph="outro"] .jd-step { margin-bottom: 0; padding-bottom: 8px; }

  /* ---- a figure beside its words (PLAN-MOBILE-ABOUT phase 2) ------------
     placeFig (about-scenes.js) sets the figure after the step's heading or
     its first paragraph, and the rest of the step's words after it in a
     .jd-step-more, which reads exactly as the step's own body */
  .jd-about--live .jd-step.jd-step--split { margin-bottom: 0; }
  .jd-about .jd-step--split + .jd-ph-fig--in { margin-top: 6px; margin-bottom: 18px; }
  .jd-about .jd-ph-fig--in + .jd-ph-fig--in { margin-top: -6px; }
  .jd-about .jd-step-more { margin: 0 0 40px; font-family: var(--font-body); }
  .jd-about .jd-step-more p { margin: 0 0 var(--s-2); font-family: var(--font-body); }
  .jd-about .jd-step-more em { font-family: var(--font-voice); font-style: italic; }
  .jd-about--live .jd-ph-sec > .jd-step-more:last-child { margin-bottom: 0; }
  .jd-about .jd-ph-sec > .jd-ph-fig--in:last-child { margin-bottom: 0; }

  /* the glossary's second card (splitGlossary) starts with its sheet */
  .jd-about--phone .jdf-plates--split .jdf-plates-sheet--grade { margin-top: 0; }
  /* the two-drawing table's narrow label column: a long category name
     breaks with a hyphen instead of running into the first gauge */
  .jd-about--phone .jdf-plates-report--2 .jdf-plates-rl { -webkit-hyphens: auto; hyphens: auto; overflow-wrap: break-word; }
  /* a plate about one category shows that row; the rest fold under a button
     (phoneFold) that sits on the plate's paper, under its table */
  .jd-about--phone .jdf-plates-report--lit:not(.is-all) > .jdf-plates-rrow--dim { display: none; }
  .jd-about .jd-ph-fold {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    width: 100%; min-height: 44px; margin: 8px 0 0; padding: 0 2px;
    background: none; border: 0; border-top: 1px solid var(--pl-rule-2, rgba(55, 65, 79, 0.22));
    font-family: var(--pl-mono, var(--font-mono)); font-size: 12px; letter-spacing: 0.08em;
    text-transform: uppercase; text-align: left; color: var(--pl-ink-2, #4d5563);
    cursor: pointer;
  }
  .jd-about .jd-ph-fold:focus-visible { outline: 2px solid var(--pl-ink, #37414f); outline-offset: 2px; }
  .jd-about .jd-ph-fold-c::before { content: "\25BE"; font-size: 14px; }
  .jd-about .jd-ph-fold[aria-expanded="true"] .jd-ph-fold-c::before { content: "\25B4"; }

  /* ---- the grading card: a still, and the way in (phase 5) -------------- */
  /* the card lays itself out at the column's width (its own phone layout)
     and is drawn smaller, a picture of it: zoomed, so its box is the drawn
     size (a transform painted the card ~40px below its box in WebKit). 72%
     of the column at zoom 0.72 is the column's own width inside. */
  .jd-about .jd-ph-fig.jd-ph-still { pointer-events: none; }
  /* the card's scrim is a modal's backdrop, padded to clear the site banner
     once the reader has scrolled (junk-drawer.css html.jd-chrome) — in the
     article that was a 56px blank above the card */
  .jd-about .jd-ph-fig .jd-turn-scrim.jd-ph-card { padding: 0; }
  .jd-about .jd-ph-still > .jd-scene { zoom: 0.72; width: 72%; margin: 0 auto; }
  .jd-about .jd-ph-still .jd-turn-go,
  .jd-about .jd-ph-still .jd-turn-actions { display: none; }
  .jd-about .jd-ph-try {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    min-height: 48px; margin: 6px 0 4px; padding: 0 16px; box-sizing: border-box;
    font-family: var(--font-mono); font-size: 14px; font-weight: 700;
    letter-spacing: 0.1em; text-transform: uppercase; text-decoration: none;
    color: #2a1e08; border: 1px solid #6f5a2c; border-radius: 3px;
    background: linear-gradient(#e2bf62, #c9a24a);
    box-shadow: 0 1px 0 rgba(58, 42, 18, 0.25);
  }
  .jd-about .jd-ph-try::after { content: "\2192"; font-weight: 400; }
  .jd-about .jd-ph-try:focus-visible { outline: 2px solid #1f2530; outline-offset: 3px; }
  .jd-about .jd-step-body .jd-ph-try + p.jd-demo-note { margin-top: 6px; text-align: center; }

  /* ---- held one state at a time (PLAN-MOBILE-ABOUT phase 3) -------------
     phoneHold (about-scenes.js) sets data-ph-state on the figure; each state
     shows the part of the figure its step is about. Without a state (the
     figure did not fit the band) the whole figure stands in the flow. */
  /* the pipeline: the four drawings, then the clerk's card */
  .jd-about .jd-ph-fig[data-ph-state="fanout"] .jdf-pipe-clerk-head,
  .jd-about .jd-ph-fig[data-ph-state="fanout"] .jdf-pipe-filed,
  .jd-about .jd-ph-fig[data-ph-state="fanout"] .jdf-pipe-lane,
  .jd-about .jd-ph-fig[data-ph-state="intake"] .jdf-pipe-models,
  .jd-about .jd-ph-fig[data-ph-state="intake"] .jdf-pipe-note { display: none; }
  .jd-about .jd-ph-fig[data-ph-state] .jdf-pipe { padding-top: 0; padding-bottom: 6px; }
  /* a figure held one state at a time sits close under the banner */
  .jd-about .jd-ph-pin.is-held { padding-top: 4px; padding-bottom: 6px; }
  .jd-about .jd-ph-fig[data-ph-state] .jdf-pipe-paper { padding-top: 14px; padding-bottom: 14px; }
  .jd-about .jd-ph-fig[data-ph-state] .jdf-pipe-q {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
  }
  .jd-about .jd-ph-fig[data-ph-state="intake"] .jdf-pipe-clerk-head { margin-top: 12px; }
  /* the clerk's state: the prompt was read in full a step before, so the
     clerk's card stands alone (the side line goes with the slip), its head
     a row shorter — the card fits the band of a real phone's window
     (390x844 Safari with its toolbars: about 390x664) */
  .jd-about .jd-ph-fig[data-ph-state="intake"] .jdf-pipe-prompt,
  .jd-about .jd-ph-fig[data-ph-state="intake"] .jdf-pipe-lane { display: none; }
  .jd-about .jd-ph-fig[data-ph-state="intake"] .jdf-pipe-stage { grid-template-columns: 0 minmax(0, 1fr); }
  .jd-about .jd-ph-fig[data-ph-state="intake"] .jdf-pipe-clerk-head { margin-top: 0; }
  /* the four's state: the fork's note is the step's own sentence ("identical
     system instructions"), so it gives its row to the drawings */
  .jd-about .jd-ph-fig[data-ph-state="fanout"] .jdf-pipe-note { display: none; }
  .jd-about .jd-ph-fig[data-ph-state="intake"] .jdf-pipe-stage { --head-h: 46px; }
  .jd-about .jd-ph-fig[data-ph-state="intake"] .jdf-pipe-filed { padding-top: 9px; padding-bottom: 11px; }
  .jd-about .jd-ph-fig[data-ph-state="intake"] .jdf-pipe-tagged { margin-top: 7px; }
  .jd-about .jd-ph-fig[data-ph-state="intake"] .jdf-pipe-key { margin-top: 7px; }
  .jd-about .jd-ph-fig[data-ph-state] .jdf-pipe-note { margin-top: 10px; }
  /* the comparison card: the podium; the pills over the pedestals; the
     six scores (the module's own end states, __jdPhoneState) */
  .jd-about .jd-ph-fig[data-ph-state="rank"] .jdf-ped-band-a,
  .jd-about .jd-ph-fig[data-ph-state="rank"] .jdf-ped-band-c,
  .jd-about .jd-ph-fig[data-ph-state="pills"] .jdf-ped-band-c,
  .jd-about .jd-ph-fig[data-ph-state="scores"] .jdf-ped-band-a,
  .jd-about .jd-ph-fig[data-ph-state="scores"] .jdf-ped-pod,
  .jd-about .jd-ph-fig[data-ph-state="scores"] .jdf-ped-q { display: none; }
  .jd-about .jd-ph-fig[data-ph-state="scores"] .jdf-ped-band-c { margin-top: 0; }
  /* held, the card's title row goes: the step's heading names each part */
  .jd-about .jd-ph-fig[data-ph-state] .jdf-ped-head { display: none; }
  .jd-about .jd-ph-fig[data-ph-state] .jdf-ped-body { padding-top: 10px; padding-bottom: 10px; }
  .jd-about .jd-ph-fig[data-ph-state="scores"] .jdf-ped-scores { margin-top: 2px; }
  /* a change of state: the new part comes up out of a short fade */
  .jd-about .jd-ph-fig.is-swap .jd-fig { animation: jd-ph-swap 220ms ease-out; }
  @keyframes jd-ph-swap { from { opacity: 0.35; } to { opacity: 1; } }

  /* ---- THE CHAPTER BAR (PLAN-MOBILE-ABOUT phase 4; phoneChapters) ---------
     (the byline, the short version and the chapter list came off the
     phone's opening, owner 2026-10-12; the list stays in the markup, never
     shown, as the bar's source) */
  .jd-about .jd-ph-chaps-l { list-style: none; margin: 0 0 8px; padding: 0; border-top: 1px solid var(--rule-soft, rgba(0, 0, 0, 0.16)); }
  .jd-about .jd-ph-chaps-l li { margin: 0; border-bottom: 1px solid var(--rule-soft, rgba(0, 0, 0, 0.16)); }
  .jd-about .jd-ph-chaps-l a {
    display: flex; align-items: center; justify-content: flex-start; gap: 12px;
    min-height: 46px; padding: 4px 2px; box-sizing: border-box;
    font-family: var(--font-body); font-size: 17px; line-height: 1.3;
    color: var(--ink, #111); text-decoration: none;
  }
  .jd-about .jd-ph-chaps-l a::before { content: attr(data-n) " \00b7"; flex: 0 0 auto; margin-right: -4px; }
  .jd-about .jd-ph-chaps-l a[aria-current] { font-weight: 600; }
  .jd-about .jd-ph-chaps-l a[aria-current]::after { content: ""; width: 8px; height: 8px; margin-left: auto; border-radius: 50%; background: #9b3a2a; flex: 0 0 auto; }
  /* THE TAKE-A-TURN PLATE ("PUSH 4 MORE JUNK") stays off the phone's drawer
     (owner, 2026-10-12) */
  .jd-about .jd-pile > .jd-item--turn,
  .jd-about .jd-pile > [data-turn] { display: none !important; }

  /* the bar: fixed under the banner, shown once the title has scrolled away */
  .jd-about--phone.has-chap { --ph-chap: 32px; }
  .jd-about .jd-ph-chap {
    position: fixed; left: 0; right: 0; top: var(--banner-h); z-index: 49;
    height: 32px; box-sizing: border-box;
    background: var(--ph-paper); border-bottom: 1px solid var(--rule-soft, rgba(0, 0, 0, 0.16));
    transform: translateY(-100%); visibility: hidden;
    transition: transform 0.2s ease, visibility 0s linear 0.2s;
  }
  .jd-about.is-chap-on .jd-ph-chap { transform: none; visibility: visible; transition: transform 0.2s ease; }
  .jd-about .jd-ph-chap-b {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    width: 100%; height: 100%; padding: 0 var(--ph-gut); box-sizing: border-box;
    background: none; border: 0; cursor: pointer;
    font-family: var(--font-mono); font-size: 11.5px; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--ink-soft, #4a4a4a); text-align: left;
  }
  .jd-about .jd-ph-chap-b:focus-visible { outline: 2px solid var(--ink, #111); outline-offset: -3px; }
  .jd-about .jd-ph-chap-l { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .jd-about .jd-ph-chap-l::after { content: " \25BE"; font-weight: 400; }
  .jd-about .jd-ph-chap-d { display: flex; gap: 4px; flex: 0 0 auto; }
  .jd-about .jd-ph-chap-d i { width: 14px; height: 3px; background: rgba(0, 0, 0, 0.16); }
  .jd-about .jd-ph-chap-d i.is-on { background: var(--ink, #111); }
  .jd-about .jd-ph-chap-p {
    position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
    background: var(--ink, #111); transform: scaleX(0); transform-origin: 0 50%;
  }
  /* the bar carries the progress now: the old hairline stands down */
  .jd-about.has-chap .jd-ph-progress { display: none; }
  /* the sheet: the chapters, under the bar */
  .jd-about .jd-ph-chaps {
    position: fixed; left: 8px; right: 8px; top: calc(var(--banner-h) + 36px); z-index: 60;
    max-height: calc(100svh - var(--banner-h) - 52px); overflow-y: auto;
    padding: 6px 14px 8px; box-sizing: border-box;
    background: var(--ph-paper); border: 1px solid var(--ink, #111);
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.22);
  }
  .jd-about .jd-ph-chaps[hidden] { display: none; }
  .jd-about .jd-ph-chaps-h { display: flex; align-items: center; justify-content: space-between; min-height: 40px; }
  .jd-about .jd-ph-chaps-k { font-family: var(--font-mono); font-size: 12px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
  .jd-about .jd-ph-chaps-x { width: 44px; height: 44px; margin-right: -10px; background: none; border: 0; font-size: 18px; cursor: pointer; color: var(--ink, #111); }

  /* ---- held figures ----------------------------------------------------- */
  .jd-about .jd-ph-pin {
    position: sticky;
    top: calc(var(--banner-h) + var(--ph-chap));
    z-index: 10;
    box-sizing: border-box;
    /* the band spans the gutters too, so nothing passing under it shows at
       the screen's edges */
    margin-left: calc(-1 * var(--ph-gut)); margin-right: calc(-1 * var(--ph-gut));
    padding: 8px var(--ph-gut) 10px;
    display: flex; justify-content: center;
    background: var(--ph-paper);
  }
  /* the words slide under the held band into a short fade, not under the
     edge of a floating slab (round 2: no side shadows) */
  .jd-about .jd-ph-pin::after {
    content: ""; position: absolute; left: 0; right: 0; top: 100%;
    height: 14px; pointer-events: none;
    background: linear-gradient(var(--ph-paper), rgba(255, 255, 255, 0));
  }

  /* ---- scene 1: the drawer, WIDE (owner, 2026-10-12: "wider than it is
     tall just for the mobile version") — 4:3, the shape of the phone's own
     picture (drawer-poster-wide*, the capture's --wide: keep the two in
     step) — and held on every portrait phone: at a phone's width it stands
     ~270px tall, under the 45% a held figure may take ---- */
  .jd-about--live .jd-scene[data-scene-pane="drawer"] {
    display: block; overflow: visible; will-change: auto;
    width: 100%;
  }
  .jd-about--live .jd-stage {
    height: auto;
    aspect-ratio: 4 / 3;
    width: min(100%, calc((var(--ph-pin) - 18px - var(--jd-pull-drop, 0px)) * 4 / 3));
    min-height: 0; max-width: none;
    margin: 0 auto calc(var(--jd-pull-drop, 0px));
    box-shadow: none;
  }
  /* OPEN THE DRAWER — DORMANT (owner, 2026-09-29, main 0.9.165+: the
     button is gone; the prose links to the full drawer). Kept whole so the
     phone can have it back with one switch (PHONE_OPEN_DRAWER in
     about-scenes.js): a real button (44px, 13px type) opening a new tab. */
  .jd-about .jd-open-drawer {
    position: absolute; z-index: 64;
    font-family: var(--font-mono); text-transform: uppercase; text-decoration: none;
    color: #3a2a12;
    background:
      linear-gradient(178deg, rgba(255, 250, 228, 0.55) 0%, rgba(255, 250, 228, 0) 40%),
      #e8d9a8;
    border: 1px solid rgba(74, 53, 18, 0.55); border-radius: 3px;
    box-shadow: 2px 3px 7px rgba(22, 11, 4, 0.5);
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 44px; box-sizing: border-box;
    /* two lines, so it clears the Take-a-Turn plate in the corner beside it */
    width: 6.4rem;
    white-space: normal; text-align: center; line-height: 1.2;
    font-size: 13px; letter-spacing: 0.08em;
    padding: 5px 8px;
    right: calc(var(--wall) + 8px);
    bottom: calc(var(--wall) + 8px);
  }
  /* the pile keeps the picture's sizes: the drawer's phone band (x1.2,
     junk-drawer.css) is for a drawer that fills the screen, and the poster
     was captured at the base size — a woken pile must match it */
  /* — and a swipe that starts on a woken drawing scrolls the page (a
     sideways drag still moves it): the page is for reading first */
  .jd-about .jd-pile > .jd-item { width: calc(var(--w) * 1cqmin); touch-action: pan-y; }
  /* THE SPECIMEN'S TAG ON A PHONE (round 2, P1-2): readable (labels 11px,
     buttons 44px tall, their words on two lines), no wider than the well it
     hangs in (the well is a size container: 100cqw is its width), and one
     line for the name. about-scenes.js keeps it inside the well. And the
     tag lets a vertical swipe through to the page (audit P0-1). */
  .jd-about .jd-itemtag {
    --jd-tag-w: min(17rem, calc(100cqw - 12px));
    padding: 0.5rem 0.6rem 0.55rem 1.6rem;
    touch-action: pan-y;
  }
  .jd-about .jd-itemtag .name {
    font-size: 12px; min-height: 0; -webkit-line-clamp: 2;
    padding-bottom: 0.3rem; margin-bottom: 0.35rem;
  }
  .jd-about .jd-itemtag .lab { font-size: 11px; letter-spacing: 0.06em; flex-basis: 3.3rem; }
  .jd-about .jd-itemtag .val,
  .jd-about .jd-itemtag .val.g { font-size: 11px; }
  .jd-about .jd-itemtag .btns { margin-top: 0.4rem; padding-top: 0.4rem; gap: 0.35rem; }
  .jd-about .jd-itemtag .btn {
    display: flex; align-items: center; justify-content: center;
    min-height: 44px; box-sizing: border-box;
    font-size: 11px; letter-spacing: 0.06em; line-height: 1.15;
    white-space: normal; padding: 3px 4px;
  }

  /* ---- the cards, in their own phone layouts ---------------------------- */
  .jd-about .jd-ph-card {
    /* its own stacking context: the card's paper layers (z 3–5) must never
       paint over a held figure the card scrolls under */
    position: relative; inset: auto; z-index: 0; isolation: isolate;
    display: block;
    width: 100%;
    padding: 0; margin: 0;
    background: none;
  }
  .jd-about .jd-ph-card .jd-record,
  .jd-about .jd-ph-card .jd-turn {
    max-height: none; height: auto;
    width: 100%; margin: 0;
  }
  .jd-about .jd-ph-card .rc-scroll,
  .jd-about .jd-ph-card .jd-turn-scroll {
    flex: 0 0 auto; min-height: 0; max-height: none; overflow: visible;
  }
  .jd-about .jd-ph-card .jd-record.is-enter,
  .jd-about .jd-ph-card .jd-turn.is-enter { animation: none; }
  .jd-about .jd-ph-card .jd-record-close,
  .jd-about .jd-ph-card .jd-turn-close { display: none; }
  .jd-about--live .jd-scene[data-scene-pane="instrument"] {
    overflow: visible; will-change: auto;
  }
  /* the card's small print, brought up to 11px where a reader is meant to
     read it (the grade table's subjects and head, the plate's notes, the
     sibling captions) — the one liberty taken with the drawer's own card */
  .jd-about .jd-ph-card .rc-subj-name,
  .jd-about .jd-ph-card table.rc-subj th,
  .jd-about .jd-ph-card .rc-avg-l,
  .jd-about .jd-ph-card .rc-block.rc-head,
  .jd-about .jd-ph-card .rc-note-v,
  .jd-about .jd-ph-card .rc-note-l,
  .jd-about .jd-ph-card .rc-alt-cap,
  .jd-about .jd-ph-card .rc-assign p { font-size: 11px; }
  /* the table's type, in the folder's style since 0.9.170, at 11px (its
     heads and values run 8-10.5px there) */
  .jd-about .jd-sheet-card .jdc-sheet { font-size: 11px; }
  .jd-about .jd-sheet-card .jdc-sheet th,
  .jd-about .jd-sheet-card .jdc-sheet tr.jdc-h1 th,
  .jd-about .jd-sheet-card .jdc-sheet tr.jdc-h2 th { font-size: 11px; }
  /* the report cards' replay button: a thumb's size (the grading card has
     its own 44px hit pad since 0.9.171, junk-drawer.css) */
  .jd-about .jd-ph-card.jd-record-scrim .jd-filmstrip .fs-play { min-width: 44px; min-height: 44px; }
  /* the plates' replay (the Layering step says "Press the ▶ button"): a
     thumb's 44px, as the report cards' (PLAN-MOBILE-ABOUT phase 1) */
  .jd-about .jd-fig-card .jd-filmstrip .fs-play { width: 44px; height: 44px; padding: 13px; }
  /* a vertical swipe that starts on a scrubber scrolls the page; the
     horizontal scrub still gets its pointer moves */
  .jd-about .fs-strip { touch-action: pan-y; }
  /* the rail's letters, the in-flow card's download and file number */
  .jd-about .jd-ph-card .jd-rail-ring { font-size: 11px; }
  /* the grading card's prompt and its category definitions are content,
     not chrome: at a reading size (the card sets them at 10.2-10.6px) */
  .jd-about .jd-ph-card .jd-turn-assign p,
  .jd-about .jd-ph-card .jd-def span { font-size: 12px; }
  .jd-about .jd-ph-card .jd-turn-assign-tag,
  .jd-about .jd-ph-card .jd-turn-go { font-size: 11px; }
  .jd-about .jd-ph-card .rc-dl { font-size: 11px; }
  .jd-about .jd-ph-card .rc-note-no { display: none; }
  /* THE QUESTION CARD ON A PHONE (about rework, 2026-10-06): the drawing a
     column's width (~340px) put the ballot and the buttons a screen below
     it. Held to a smaller square, centred, and without its replay strip
     (the drawer's own phone card stands it down the same way), the
     question, its ballot and back / next stand on one screen with it at
     390×844. */
  .jd-about .jd-ph-card .jd-bench--q .jd-turn-pin {
    width: min(200px, 56%); margin-left: auto; margin-right: auto;
  }
  .jd-about .jd-ph-card .jd-bench--q .jd-turn-pin .jd-filmstrip { display: none; }

  /* Gemini and Kimi: the drawing is held — masthead, plate, replay — and
     the card is sized so all three fit the held band at 1:1 */
  /* the held card is the drawing: no masthead (the name is in the words and
     on the plate), a trimmed margin, and as wide as the band allows — a
     ~270px drawing on a 393x852 phone (space round, 2026-09-29) */
  .jd-about .jd-ph-card--pin {
    width: min(100%, calc(var(--ph-pin) - 78px));
  }
  /* both copies always take the card's portrait flow (the drawer gives it
     at 700px and under; a tablet or a landscape phone is wider) */
  .jd-about .jd-ph-card--pin .rc-scroll,
  .jd-about .jd-ph-card--under .rc-scroll {
    display: flex; flex-direction: column; padding: 12px 14px 11px;
  }
  .jd-about .jd-ph-card--pin .rc-col-l,
  .jd-about .jd-ph-card--pin .rc-col-r,
  .jd-about .jd-ph-card--under .rc-col-r { display: contents; }
  .jd-about .jd-ph-card--pin .rc-plate { width: 100%; margin: 0 auto 0.55rem; }
  .jd-about .jd-ph-card--pin .rc-masthead { display: none !important; }
  .jd-about .jd-ph-card--pin .rc-scroll { padding: 8px 10px 6px; }
  /* the grades copy: its GRADES label stays, the paper above it trims */
  .jd-about .jd-ph-card--under .rc-scroll { padding-top: 8px; }
  .jd-about .jd-ph-card--pin .rc-scroll > :not(.rc-masthead):not(.rc-col-l):not(.rc-col-r),
  .jd-about .jd-ph-card--pin .rc-col-r > * { display: none !important; }
  /* the plate's download button and file number are chrome the held band
     has no room for (they collided with the date at this width) */
  .jd-about .jd-ph-card--pin .rc-plate-btns,
  .jd-about .jd-ph-card--pin .rc-note-no { display: none; }
  /* and of the plate's notes only the model stays: four lines at a
     readable size covered the foot of the drawing — Gemini's stand, the
     very thing the words ask the reader to find */
  .jd-about .jd-ph-card--pin .rc-note-line:not(:first-child) { display: none; }
  /* a held card sits on the page, not above it: its own deep drop shadow
     read as a slab floating over the words */
  .jd-about .jd-ph-card--pin .jd-record,
  .jd-about .jd-ph-card--under .jd-record { box-shadow: 0 1px 3px rgba(6, 3, 0, 0.28); }
  /* ... and the model's name alone, so it never truncates */
  .jd-about .jd-ph-card--pin .rc-note-l { display: none; }
  /* under it, in the flow: the same card's grades, and nothing else */
  .jd-about .jd-ph-card--under .rc-scroll > :not(.rc-col-r),
  .jd-about .jd-ph-card--under .rc-col-r > :not(:has(> .rc-subj)):not(:has(+ .rc-block > .rc-subj)) { display: none !important; }
  /* (important: the card's own landscape rules, 701px and up, set display
     on the prompt with more specificity than a crop can carry) */

  /* ---- scene 4: the table --------------------------------------------- */
  .jd-about .jdc-sheet .jdc-c-prompt { width: 8.5rem; min-width: 8.5rem; max-width: 8.5rem; }
  /* the whole sheet in a window of its own that scrolls both ways (owner,
     2026-10-12), its head and item column held by the sheet's own sticky
     rules */
  .jd-about .jd-sheet-card .jdc-tablewrap { max-height: 62svh; overflow: auto; }
  .jd-about .jd-ph-card .jdc-turns { position: relative; }
  .jd-about .jd-ph-hint {
    margin: 0 0 6px; text-align: right;
    font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.04em;
    color: var(--ink-soft, #555);
  }
  .jd-about .jd-ph-fade {
    position: absolute; right: 0; top: 24px; bottom: 0; width: 28px;
    pointer-events: none;
    background: linear-gradient(to right, rgba(255, 255, 255, 0), var(--ph-paper));
  }
  .jd-about .jdc-turns.is-end .jd-ph-fade { display: none; }
  .jd-about .jdc-sheet .jdc-hint::after { font-size: 12px; }

  /* the sheet's heads at a readable contrast on its paper (4.5:1 and up;
     the desk's 0.64 ink measured 3.9:1) */
  .jd-about .jd-sheet-card .jdc-sheet th { color: rgba(51, 36, 15, 0.86); }

  /* the small print a reader is meant to read, at 11px and up on a phone
     (PLAN-MOBILE-ABOUT phase 7): the plates' labels and column heads, the
     intake card's labels, the heat map's figures */
  .jd-about--phone .jdf-plates-head,
  .jd-about--phone .jdf-plates-guide,
  .jd-about.jd-about--phone .jdf-pipe-fk { font-size: 11px; }
  .jd-about--phone .jdf-plates-rh { font-size: 11.5px; }
  .jd-about.jd-about--phone .jdc-bt-n,
  .jd-about.jd-about--phone .jdc-bt-w,
  .jd-about.jd-about--phone .jdc-bt-gloss { font-size: 11.5px; }

  /* the issue-rate panel beside its claim (panelExcerpt): one panel, lit */
  .jd-about .jd-ph-excerpt { grid-template-columns: minmax(0, 1fr); }


  /* the item names wrap to two lines rather than cut at fourteen letters;
     and the frozen column's sticky ground covered some row rules, so its
     own hairline is drawn on it */
  .jd-about .jd-ph-card .jdc-sheet td.jdc-c-prompt {
    white-space: normal; text-overflow: clip;
    line-height: 1.25; padding-top: 5px; padding-bottom: 5px;
    box-shadow: inset 0 -1px 0 var(--jdc-hair);
  }
  /* the charts' small print, at or over 11px; the value column wide enough
     for "3.1 n 104" on one line (audit P2-5) */
  .jd-about .jd-charts { --jdc-val: 4.6rem; padding: 12px 10px; }
  .jd-about .jdc-n { font-size: 0.7rem; white-space: nowrap; }
  .jd-about .jdc-val { white-space: nowrap; }
  .jd-about .jdc-hrow-lab { font-size: 0.72rem; }
  .jd-about .jdc-hrow-n { font-size: 11.5px; }
  .jd-about .jdc-hrow-t { font-size: 0.8rem; }

  /* ---- scene 4: the spread, alone, its leaders picked out ------------------ */
  .jd-about [data-ph="distribution"] .jdc-sec-avg { display: none; }
  .jd-about [data-ph="distribution"] .jdc-sec + .jdc-sec { margin-top: 0; padding-top: 0; border-top: 0; }
  /* main's "spread-lead" (owner, 2026-09-29): the top three grades of the
     three leading models at full strength; GPT-5.1's head and every other
     bar recede */
  .jd-about [data-ph="distribution"] .jdc-hrow-t[data-model="gpt-5-1"],
  .jd-about [data-ph="distribution"] .jdc-hrow-cell { opacity: 0.22; }
  .jd-about [data-ph="distribution"] .jdc-hrow-cell:is([data-model="claude-opus-5"], [data-model="gemini-3-1-pro"], [data-model="kimi-k3"]):is([data-grade="5"], [data-grade="4"], [data-grade="3"]) { opacity: 1; }

  /* ---- the instrument's honest fallback (only if the card cannot stand) - */
  .jd-about .jd-ph-fallback { font-size: 15px; font-style: italic; color: var(--ink-soft, #555); }

  /* ---- progress: a 2px hairline under the banner, set by the scroll ------ */
  .jd-about .jd-ph-progress {
    position: fixed; left: 0; right: 0; top: var(--banner-h);
    height: 2px; z-index: 50;
    background: var(--ink, #111);
    transform: scaleX(0); transform-origin: 0 50%;
    pointer-events: none;
  }
}

/* PORTRAIT PHONES, THE HELD DRAWER: no brass pull under it (32px of band a
   reader has no use for); the poster keeps its size, so the band ends 32px
   higher on every scene-1 step. Also before the script runs, so the first
   screen is the same either side of it. (Tall phones only until the drawer
   went wide, 2026-10-12: now every portrait phone holds it.) */
@media (max-width: 768px) and (min-height: 501px) {
  .jd-about .jd-ph-sec[data-ph="drawer"] .jd-pull,
  .jd-about--live:not(.jd-about--phone) .jd-about-pane .jd-pull { display: none; }
  .jd-about--live .jd-ph-sec[data-ph="drawer"] .jd-stage,
  .jd-about--live:not(.jd-about--phone) .jd-about-pane .jd-stage { margin-bottom: 0; }
}
/* LANDSCAPE PHONES. The drawer stands in the flow at full width. (Short
   portrait phones, an SE or iPhone Safari with its toolbars, did too while
   the drawer was 4:5 — a poster held in 38svh was narrower than its own
   tag; the wide drawer is held there, 2026-10-12.) */
@media (max-height: 500px) {
  .jd-about { --ph-pin: 86svh; }
  .jd-about .jd-ph-sec[data-ph="drawer"] > .jd-ph-pin { position: static; }
  .jd-about .jd-ph-sec[data-ph="drawer"] > .jd-ph-pin::after { content: none; }
}
/* SHORT PORTRAIT SCREENS: Gemini's and Kimi's DRAWINGS are still held — the
   words point at them — but without the card's masthead (the name is in the
   words), at a card width of 46svh - 70px: a ~211px drawing and its 44px
   replay under it, the band ending near y=348 of 659, eleven lines of text
   below. (Round 2, P1-1; no crop — every crop cut Gemini's stand.) */
@media (max-width: 768px) and (max-height: 700px) and (min-height: 501px) {
  .jd-about .jd-ph-pin:has(.jd-ph-card--pin) { padding: 6px var(--ph-gut); }
  .jd-about .jd-ph-sec .jd-ph-card.jd-ph-card--pin { width: min(100%, calc(46svh - 70px)); }
}
/* LANDSCAPE PHONES: nothing is held — the article, plain (Option A). The
   wall follows the STAGE here, not the viewport's width (junk-drawer.css
   sizes it by vw: 45px on an 852px-wide phone, leaving a 131px well), and
   the whole drawer fits one screen. */
@media (max-height: 500px) {
  .jd-about .jd-ph-pin { position: static; }
  .jd-about .jd-ph-pin::after { content: none; }
  .jd-about--live .jd-stage {
    --wall: clamp(12px, calc((100svh - var(--banner-h) - 24px) * 0.035), 20px);
    width: min(100%, calc((100svh - var(--banner-h) - 24px - var(--jd-pull-drop, 0px)) * 4 / 3));
  }
}

/* ===================== THE FIGURE SCENES (about rework, 2026-10-05) ========
   the card the engine wraps each about-fig-*.js view in: 640px natural on the
   desk (fitCard scales it to the pane), the column's width on a phone. Each
   module styles its own figure under its own prefix. */
.jd-about .jd-inline-card.jd-fig-card { width: 640px; box-sizing: border-box; }
.jd-about--phone .jd-fig-card { width: 100%; box-sizing: border-box; }
/* a bracketed line still waiting on the owner (drafts only; none ships) */
.jd-about .jd-draft-note { color: #9b3a2a; font-style: italic; }

/* THE LAST PLATE STANDS ON THE PANE'S FOOT (owner, 2026-10-06: the
   fadograph). fitCard sizes it to the band the page's foot leaves and sets
   .is-end on the pane while it is the current card, so it never moves
   within the pane (about-scenes.js, THE LAST PLATE FITS THE PAGE'S FOOT). */
.jd-about--live:not(.jd-about--phone) .jd-about-pane.is-end {
  justify-content: flex-end;
  padding-bottom: var(--jd-end-lift, 0px);
}
