/* truemanity studio — components (visual-bible.md §4, §4a, §4b)
   Depends on tokens.css and paper.css. Radii are 0 everywhere. Pictures always sit in a 1px aperture and play clean. */

/* ——— Base & type ——— */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--type-body-size); font-weight: var(--type-body-weight);
  letter-spacing: var(--type-body-tracking); line-height: var(--type-body-leading);
  color: var(--ink-primary);
  -webkit-font-smoothing: antialiased;
  background: var(--wall-ambient);
}
img { display: block; max-width: 100%; }
.t-display { font-family: var(--font-sans); font-size: var(--type-display-size); font-weight: var(--type-display-weight); letter-spacing: var(--type-display-tracking); line-height: var(--type-display-leading); margin: 0; }   /* the hero statement only */
.t-title { font-family: var(--font-sans); font-size: var(--type-title-size); font-weight: var(--type-title-weight); letter-spacing: var(--type-title-tracking); line-height: var(--type-title-leading); margin: 0; }
.t-card-serif { font-family: var(--font-serif); font-style: italic; font-size: var(--type-card-serif-size); font-weight: var(--type-card-serif-weight); letter-spacing: var(--type-card-serif-tracking); line-height: var(--type-card-serif-leading); margin: 0; }
.t-body { font-size: var(--type-body-size); font-weight: var(--type-body-weight); letter-spacing: var(--type-body-tracking); line-height: var(--type-body-leading); margin: 0; }
.t-card-body { font-size: var(--type-card-body-size); font-weight: var(--type-card-body-weight); letter-spacing: var(--type-card-body-tracking); line-height: var(--type-card-body-leading); margin: 0; }
.t-label { font-family: var(--font-label, var(--font-sans)); font-size: var(--type-label-size); font-weight: var(--type-label-weight); letter-spacing: var(--type-label-tracking); line-height: var(--type-label-leading); text-transform: uppercase; margin: 0; }
.t-mono { font-family: var(--font-mono); font-size: var(--type-mono-size); font-weight: var(--type-mono-weight); letter-spacing: var(--type-mono-tracking); line-height: var(--type-mono-leading); margin: 0; }
.ink-2 { color: var(--ink-secondary); }
.paper-board-dark .ink-2, .paper-card-dark .ink-2 { color: #8E949D; }

/* [COPY: …] slot — director-approved text goes here; never fill with slogans */
.copy-slot { font-family: var(--font-mono); font-size: var(--type-mono-size); letter-spacing: var(--type-mono-tracking); line-height: 1.5; color: var(--ink-secondary); }
.paper-board-dark .copy-slot { color: #8E949D; }
.paper-card-dark .copy-slot { color: var(--ink-red-dark); }

/* ——— The room ——— */
.room { display: flex; flex-direction: column; align-items: center; gap: var(--board-gap); padding: var(--board-gap) var(--wall-margin-x) calc(var(--board-gap) * 1.5); }

/* ——— 2. GalleryBoard ——— */
/* a <picture> (responsive.py) takes no box of its own: every layout sees the <img> it holds */
picture { display: contents; }
picture > source { display: none; }   /* else a grid counts the sources as its items */
.board { width: 100%; max-width: var(--board-max); padding: var(--board-pad-y) var(--board-pad-x); }
.board__head { display: flex; justify-content: space-between; align-items: baseline; column-gap: var(--space-4); margin-bottom: var(--space-12); color: var(--ink-secondary); }
/* the board's note: what the board shows, under its head (2026-10-24) */
.board__note { max-width: 76ch; margin: calc(var(--space-6) * -1) 0 var(--space-8); color: var(--ink-secondary); }
.paper-board-dark .board__note { color: #8E949D; }
.paper-board-dark .board__head { color: #8E949D; }
.grid-12 { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--gutter); }
.span-2 { grid-column: span 2; } .span-3 { grid-column: span 3; } .span-4 { grid-column: span 4; } .span-5 { grid-column: span 5; }
.span-6 { grid-column: span 6; } .span-7 { grid-column: span 7; } .span-8 { grid-column: span 8; } .span-9 { grid-column: span 9; } .span-12 { grid-column: span 12; }
.stack > * + * { margin-top: var(--space-4); }
.section-label { display: flex; gap: var(--space-3); align-items: baseline; margin-bottom: var(--space-6); }
.section-label .t-mono { color: var(--ink-secondary); }
/* Section break — no rule. Two registration crosses at the content edges, air around (drafting, not a form). */
.hr {
  --m: var(--mark);
  height: 9px; border: 0; margin: var(--space-24) 0 var(--space-16);
  background:
    linear-gradient(var(--m), var(--m)) 0 4px / 9px 1px no-repeat,
    linear-gradient(var(--m), var(--m)) 4px 0 / 1px 9px no-repeat,
    linear-gradient(var(--m), var(--m)) 100% 4px / 9px 1px no-repeat,
    linear-gradient(var(--m), var(--m)) calc(100% - 4px) 0 / 1px 9px no-repeat;
}
@media (max-width: 720px) {
  .grid-12 { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
  .grid-12 > [class*="span-"] { grid-column: 1 / -1; }
  /* through the variable, so the flush heads (TopBar, FlushHead) pull up by the same 32px and still start at the edge */
  .board { --board-pad-y: 32px; }
}

/* ——— 1. TopBar ——— */
/* The TopBar is a flush head (component 15) with the nav: the strip starts at the board's top edge and hangs in the air — no rule, no marks */
.topbar { height: 56px; display: flex; align-items: center; justify-content: space-between; margin: calc(var(--board-pad-y) * -1) 0 var(--space-12); }
.topbar__brand { display: flex; align-items: center; gap: 10px; color: var(--ink-primary); text-decoration: none; }
.topbar__mark { width: 6px; height: 16px; background: var(--datum-red); flex: none; }
.topbar__nav { display: flex; gap: var(--space-8); list-style: none; margin: 0; padding: 0; }
.topbar__nav a { color: var(--ink-primary); text-decoration: none; padding: 6px 0; border-bottom: 1px solid transparent; transition: border-color var(--dur-hover) var(--ease), color var(--dur-hover) var(--ease); }
.topbar__nav a:hover, .topbar__nav a[aria-current="page"] { border-bottom-color: var(--datum-red); }
/* the TopBar's index (2026-10-25): a long page's own sections, on a line of their own under the bar */
.topbar--index { height: auto; min-height: 0; justify-content: flex-start; margin: calc(var(--space-8) * -1) 0 var(--space-12); }
.topbar--index .topbar__nav { flex-wrap: wrap; gap: 4px var(--space-6); }
.topbar--index .topbar__nav a { color: var(--ink-secondary); }
/* On a phone the nav drops under the wordmark instead of breaking words; the strip still starts at the edge */
@media (max-width: 720px) {
  .topbar { height: auto; min-height: 56px; flex-wrap: wrap; align-content: center; gap: 6px var(--space-4); padding: 14px 0; }
  .topbar__nav { gap: var(--space-4); }
  .topbar__brand, .topbar__nav a { white-space: nowrap; }
}

/* ——— 3. PaperVideoPlayer ——— */
.pvp { width: 100%; }
.pvp__bar {
  height: 28px; display: flex; align-items: center; gap: 12px; padding: 0 10px;
  border-top: 1px solid var(--hairline-dark);
  background-color: var(--ink-primary); background-image: var(--grain-paper); background-size: var(--grain-size); background-blend-mode: overlay;
  color: var(--ink-on-dark);
}
.pvp__btn { appearance: none; background: none; border: 0; padding: 0; margin: 0; color: inherit; cursor: pointer; display: grid; place-items: center; width: 16px; height: 16px; }
.pvp__btn:focus-visible { outline: 1px solid var(--datum-red); outline-offset: 2px; }
.pvp__scrub { position: relative; flex: 1; height: 1px; background: #383C42; cursor: pointer; }
.pvp__progress { position: absolute; left: 0; top: -0.5px; height: 2px; background: var(--datum-red); }
.pvp__node { position: absolute; top: 50%; width: 6px; height: 6px; background: var(--datum-red); transform: translate(-50%, -50%); }
.pvp__time { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.04em; color: var(--ink-on-dark); white-space: nowrap; }
.pvp__txt { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.08em; width: auto; height: auto; color: #8E949D; }
.pvp__txt[aria-pressed="true"] { color: var(--ink-on-dark); }
.pvp__sep { width: 1px; height: 12px; background: #2C3036; flex: none; }
.pvp__captions { min-height: 46px; margin: 0; padding: 14px 8% 0; text-align: center; font-family: var(--font-sans); font-size: 15px; line-height: 1.4; letter-spacing: -0.005em; color: var(--ink-primary); }
.pvp__captions[hidden] { display: block; visibility: hidden; }
.act[hidden], .hero-band__key[hidden] { display: none; }   /* their own display would keep them on screen */
/* touch targets: an invisible 44px hit area round the small links and the player's controls — nothing is drawn */
.topbar__brand, .topbar__nav a, .brief__foot a, .pvp__btn { position: relative; }
.topbar__brand::after, .brief__foot a::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 44px; transform: translateY(-50%); }
.topbar__nav a::after { content: ""; position: absolute; left: 50%; top: 50%; width: max(100%, 44px); height: 44px; transform: translate(-50%, -50%); }
.pvp__btn::after { content: ""; position: absolute; left: 50%; top: 50%; width: 44px; height: 44px; transform: translate(-50%, -50%); }
.pvp__scrub::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 44px; transform: translateY(-50%); }
.pvp__btn { z-index: 1; }   /* the buttons' areas stay above the scrub's where the two meet */
.film-aperture > video { cursor: pointer; }
.pvp--mini .pvp__bar { height: 22px; gap: 8px; padding: 0 8px; }

/* ——— 4. StoryCard ——— */
.story-card { aspect-ratio: 3 / 4; padding: 24px; display: flex; flex-direction: column; position: relative; }
.story-card::after { content: ""; position: absolute; right: 12px; bottom: 12px; width: 4px; height: 4px; background: var(--datum-red); }
.story-card__meta { display: flex; justify-content: space-between; color: var(--ink-secondary); margin-bottom: var(--space-4); }
.story-card__title { margin-bottom: var(--space-6); }
.story-card__body { margin-top: auto; }   /* two auto margins float the body in the card's middle, as in REF-12 */
.story-card__foot { margin-top: auto; color: var(--ink-secondary); }
.story-card.paper-card-dark .story-card__title { color: var(--ink-on-dark); }
.story-card.paper-card-dark .story-card__body { color: var(--ink-red-dark); }
.story-card.paper-card-dark .story-card__meta, .story-card.paper-card-dark .story-card__foot { color: var(--ink-red-dark); }
.story-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-6); }
@media (max-width: 720px) { .story-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; } }

/* ——— 10. SpecTable ——— */
.spec { display: grid; grid-template-columns: 140px 1fr; gap: 9px var(--space-4); margin: 0; font-family: var(--font-mono); font-size: var(--type-mono-size); letter-spacing: var(--type-mono-tracking); line-height: 1.4; }
.spec dt, .spec dd { margin: 0; }
.spec dt { color: var(--ink-secondary); text-transform: uppercase; }
.spec dd { color: var(--ink-primary); }
.paper-board-dark .spec dt { color: #8E949D; } .paper-board-dark .spec dd { color: var(--ink-on-dark); }
.spec .copy-slot { color: var(--ink-secondary); } .paper-board-dark .spec .copy-slot { color: #8E949D; }   /* a slot stays a slot inside a value */
/* a link in a spec, or in a page's foot: the ink of its row, a hairline under it, the datum red when pointed at */
.spec a, .brief__foot a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--mark); transition: border-color var(--dur-hover) var(--ease); }
.spec a:hover, .spec a:focus-visible, .brief__foot a:hover, .brief__foot a:focus-visible { border-bottom-color: var(--datum-red); outline: 0; }

/* ——— 11. IndexCard (Mechanism Appendix) ——— */
.index-card { padding: 24px; display: flex; flex-direction: column; gap: var(--space-4); }
.index-card__head { display: flex; justify-content: space-between; color: var(--ink-secondary); }
.index-card__pics { display: flex; flex-direction: column; gap: 8px; }
.plate { outline: 1px solid var(--hairline-light); background: #0B0A0A; }
.plate img { width: 100%; height: auto; }
.index-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-6); }
@media (max-width: 720px) { .index-row { grid-template-columns: 1fr; } }

/* ——— 12. CaseRow ——— */
.case-row { align-items: start; }
.case-row__cta { display: inline-flex; align-items: center; gap: 10px; margin-top: var(--space-6); color: var(--ink-primary); text-decoration: none; font-family: var(--font-mono); font-size: var(--type-mono-size); letter-spacing: var(--type-mono-tracking); text-transform: uppercase; }
.case-row__cta::before { content: ""; width: 24px; height: 1px; background: var(--ink-primary); transition: width var(--dur-hover) var(--ease), background var(--dur-hover) var(--ease); }
.case-row__cta:hover::before { width: 40px; background: var(--datum-red); }
.case-row__strip { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--gutter-strip); margin-top: var(--gutter-strip); }
.case-row--reserved { min-height: 120px; display: grid; place-items: center; color: var(--ink-secondary); }

/* ——— Leader lines, brackets, ticks (shared instruments) ——— */
.leader { display: flex; align-items: center; gap: 8px; color: var(--ink-secondary); }
.leader::before { content: ""; flex: 1; height: 0; border-top: 1px dotted var(--ink-secondary); }
.leader--right::before { order: 2; }
.tick { width: 4px; height: 4px; background: var(--ink-primary); }
.node-red { width: 5px; height: 5px; background: var(--datum-red); }
.datum-v { width: 2px; background: var(--datum-red); align-self: stretch; }
.datum-h { height: 2px; background: var(--datum-red); width: 100%; }

/* ——— 5. CharacterMapBoard ——— */
.charmap__pair { display: flex; align-items: stretch; gap: 12px; }
.charmap__pair .crop { position: relative; overflow: hidden; outline: 1px solid var(--hairline-light); }
.charmap__pair .crop img { position: absolute; top: 0; height: 100%; max-width: none; }
/* PAIR-09 is two pictures on one sheet: office 0–1190px (2.39:1), dark archer 1202–1600px (4:5) of 1600×499 */
.crop--pair09-office { flex: 1190 1190 0; aspect-ratio: 1190 / 499; }
.crop--pair09-office img { left: 0; width: 134.454%; }
.crop--pair09-dark { flex: 398 398 0; aspect-ratio: 398 / 499; }
.crop--pair09-dark img { left: -302.010%; width: 402.010%; }
.charmap__flow { display: grid; grid-template-columns: 2fr 5fr 5fr; gap: var(--space-6); align-items: end; }
.charmap__keys { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-6); }
.charmap__link { position: relative; height: 40px; }
.charmap__link svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.fig { display: flex; flex-direction: column; gap: 8px; }
.fig__cap { display: flex; justify-content: space-between; gap: 8px; color: var(--ink-secondary); }
.fig__cap b { font-weight: 500; color: var(--ink-primary); }
.paper-board-dark .fig__cap { color: #8E949D; } .paper-board-dark .fig__cap b { color: var(--ink-on-dark); }
@media (max-width: 720px) { .charmap__flow { grid-template-columns: 1fr; } .charmap__keys { grid-template-columns: 1fr; } }

/* ——— 6. HarmonisingBoard ——— */
.harm { background-color: var(--paper-tint); background-image: var(--grain-paper), var(--shaft-paper); background-size: var(--grain-size), auto; background-blend-mode: overlay, normal; background-attachment: scroll, fixed; padding: var(--space-8); }
.palette-bar__heads { display: flex; justify-content: space-between; margin-bottom: 8px; color: var(--ink-secondary); }
.palette-bar { display: flex; gap: 0; height: 44px; }
.palette-bar__seg { height: 100%; }
.palette-bar__gap { width: 10px; flex: none; }
.palette-bar__labels { display: flex; margin-top: 8px; }
.palette-bar__labels > div { min-width: 0; padding-right: 6px; }
.palette-bar__labels .t-mono { white-space: nowrap; overflow: hidden; text-overflow: clip; }
/* a phone: the labels too narrow to stand under their shares become a list of three columns (2026-10-25) */
@media (max-width: 720px) { .palette-bar__labels { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px 10px; padding-bottom: var(--space-3); } .palette-bar__labels > div { flex: none !important; width: auto !important; padding-right: 0; } .palette-bar__labels > div:empty { display: none; } }
.harm__split { display: grid; grid-template-columns: 1fr 2px 1fr; gap: var(--space-8); margin-top: var(--space-8); }
.harm__col-head { display: flex; justify-content: space-between; margin-bottom: var(--space-4); }
.contact-2x2 { display: grid; grid-template-columns: 1fr 1fr; gap: 20px 12px; }
.contact-2x2 figure { margin: 0; display: flex; flex-direction: column; gap: 6px; }
.contact-2x2 .ix { color: var(--ink-secondary); }
.contact-2x2 .cell { outline: 1px solid var(--hairline-light); overflow: hidden; background: #0B0A0A; }
.contact-2x2 .cell img { width: 100%; height: 100%; object-fit: cover; }
.cell--portrait { aspect-ratio: 2 / 3; width: 100%; }
.contact-2x2 figure.fig-portrait { width: 38%; margin: 0 auto; }
.cell--wide { aspect-ratio: 3 / 1; }
.cell--harm02 { aspect-ratio: 1680 / 704; }
.callout { position: relative; display: flex; align-items: center; gap: 8px; margin: 2px 0 0; padding-top: 14px; color: var(--ink-primary); }
.callout::before { content: ""; position: absolute; left: 2px; top: -6px; height: 18px; border-left: 1px dotted var(--ink-primary); }
.callout .node-red { flex: none; }

/* ——— 7. ProcessStrip ——— */
.process { position: relative; }
.process__bracket { position: relative; height: 18px; margin-bottom: 10px; }
.process__bracket i:first-child::after { left: 0; } .process__bracket i:last-child::after { left: auto; right: 0; }
.process__bracket::before { content: ""; position: absolute; left: 0; right: 0; top: 8px; border-top: 1px solid var(--ink-primary); }
.process__bracket i { position: absolute; top: 6px; width: 5px; height: 5px; background: var(--ink-primary); transform: translateX(-50%); }
/* REF-07 gantry: from every node a 1px hanger drops to the row, suspending the apertures */
.process__bracket i::after { content: ""; position: absolute; left: 2px; top: 5px; width: 1px; height: 17px; background: var(--ink-primary); }
.process__bracket i:first-child { left: 0; transform: none; } .process__bracket i:last-child { right: 0; left: auto; transform: none; }
.process__row { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--gutter-strip); }
.process__timeline { position: relative; height: 22px; margin-top: 16px; }
.process__timeline::before { content: ""; position: absolute; left: 0; right: 0; top: 10px; border-top: 1px solid var(--timeline-red); }
.process__timeline i { position: absolute; top: 8px; width: 5px; height: 5px; background: var(--datum-red); transform: translateX(-50%); }
.process__steps { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--gutter-strip); margin-top: 6px; }
.process__steps > div { display: flex; flex-direction: column; gap: 6px; padding-right: 8px; }
@media (max-width: 720px) { .process__row, .process__steps { grid-template-columns: repeat(5, minmax(120px, 1fr)); } .process { overflow-x: auto; } }

/* ——— 8. BeforeAfterBoard ——— */
.before-after { position: relative; }
.before-after__gap { position: relative; height: 40px; }
.before-after__gap .datum-h { position: absolute; top: 19px; left: 0; }
.before-after__gap .datum-run { position: absolute; top: 19.5px; left: 100%; width: calc(33.4% + 16px); height: 1px; background: var(--timeline-red); }
.before-after__gap .proj-node { position: absolute; bottom: -2px; width: 4px; height: 4px; background: var(--datum-red); transform: translateX(-50%); }
.before-after__gap .proj-node--datum { bottom: auto; top: 18px; width: 5px; height: 5px; background: var(--ink-primary); }
.before-after__gap .proj-label { position: absolute; top: 2px; transform: translateX(6px); color: var(--ink-secondary); font-size: 9px; }
/* BeforeAfter on the dark board (moved here from the case page, 2026-10-25): its measured lines and labels in the dark board's inks */
.paper-board-dark .before-after__proj polyline, .paper-board-dark .before-after__proj line[stroke="#161717"] { stroke: var(--ink-on-dark); stroke-opacity: .5; }
.paper-board-dark .before-after__gap .proj-node--datum { background: var(--ink-on-dark); }
.paper-board-dark .before-after__gap .proj-label { color: #8E949D; }
.before-after__proj { position: absolute; left: 0; right: 0; pointer-events: none; overflow: visible; }
/* Below 1100px the spec column moves under the frames, and the datum runs only a short way into the margin */
@media (max-width: 1100px) { .before-after-layout > .span-9, .before-after-layout > .span-3 { grid-column: 1 / -1; } .before-after-layout .before-after__gap .datum-run { width: 24px; } .before-after-layout > .span-3 { margin-top: var(--space-6); } .before-after-layout .spec { max-width: 520px; } }



/* ——— 9. ContactStrip ——— */
.contact-strip { display: grid; gap: 6px var(--gutter-strip); }
.contact-strip--6 { grid-template-columns: 64px repeat(6, minmax(0, 1fr)); grid-auto-flow: row; }
.contact-strip .row-label { color: var(--ink-secondary); align-self: center; line-height: 1.5; }
.contact-strip .ix { color: var(--ink-secondary); margin-top: 2px; }
.contact-strip .film-aperture { outline-width: 1px; }
.contact-band + .contact-band { margin-top: var(--space-8); }
/* Variant B — the 10-frame flicker on the dark monolith (REF-09) */
.flicker { position: relative; }
.flicker__bracket { position: relative; height: 22px; margin-bottom: 8px; }
.flicker__bracket span { position: absolute; top: 0; height: 12px; border: 1px solid var(--laser-red-dark); border-bottom: 0; }
.flicker__bracket b { position: absolute; top: -16px; font-weight: 400; color: var(--ink-on-dark); white-space: nowrap; }
.flicker__row { position: relative; display: grid; grid-template-columns: repeat(var(--n, 15), minmax(0, 1fr)); gap: 0; border-top: 1px solid var(--hairline-dark); border-bottom: 1px solid var(--hairline-dark); }
.flicker__row .film-aperture { outline: 0; border-right: 1px solid var(--hairline-dark); }
.flicker__row .film-aperture:first-child { border-left: 1px solid var(--hairline-dark); }
.flicker__laser { position: absolute; left: calc(var(--board-pad-x) * -1); right: calc(var(--board-pad-x) * -1); top: 50%; height: 1px; background: var(--laser-red-dark); pointer-events: none; }
.flicker__nums { display: grid; grid-template-columns: repeat(var(--n, 15), minmax(0, 1fr)); gap: 0; margin-top: 8px; color: #8E949D; }
.flicker__nums > span { padding-left: 4px; }
.flicker__beats { display: grid; grid-template-columns: repeat(var(--n, 15), minmax(0, 1fr)); gap: 0; margin-top: 14px; }
.flicker__beats > div { margin-right: 4px; }
.flicker__beats > div { border-top: 1px dotted #4A4E55; padding-top: 6px; color: #8E949D; }
.flicker__beats > div.is-beat { border-top: 1px solid var(--laser-red-dark); color: var(--ink-on-dark); }
@media (max-width: 720px) { .contact-strip--6 { grid-template-columns: 48px repeat(6, minmax(72px, 1fr)); overflow-x: auto; } .flicker { overflow-x: auto; } .flicker__row, .flicker__nums, .flicker__beats { min-width: 900px; } }

/* ——— Horizon cut (REF-11) ——— */
.horizon { width: 100%; height: 4px; background: var(--horizon-red); }

/* ——— Token specimens (this page only) ——— */
.swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--space-6) var(--space-4); }
.swatch__chip { height: 64px; outline: 1px solid rgba(22, 23, 23, 0.08); }
.swatch__name { margin-top: 8px; }
.swatch__hex { color: var(--ink-secondary); }

.type-spec { display: grid; grid-template-columns: 160px 1fr 280px; gap: 12px var(--space-6); align-items: baseline; }
.type-spec > .t-mono:first-child, .type-spec .meta { color: var(--ink-secondary); }
@media (max-width: 720px) { .type-spec { grid-template-columns: minmax(0, 1fr); gap: 4px; } .type-spec .meta { margin-bottom: var(--space-4); } }   /* a phone: name, sample, measures, one under the other */
.space-spec { display: flex; align-items: flex-end; gap: var(--space-6); flex-wrap: wrap; }
.space-spec > div { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.space-spec i { display: block; background: var(--ink-primary); height: 8px; }
.code { font-family: var(--font-mono); font-size: 11px; line-height: 1.55; color: var(--ink-primary); white-space: pre; overflow-x: auto; margin: 0; padding: 20px 24px; }

@media (prefers-reduced-motion: no-preference) {
  .enter { opacity: 0; transform: translateY(2px); animation: settle var(--dur-enter) var(--ease) forwards; }
  @keyframes settle { to { opacity: 1; transform: none; } }
}

/* ——— Drafting marks (the system's line language: CAD drawing / photography museum, never a form) ———
   Rules of use: no full-width rules between rows or paragraphs. Separate with air first; where a mark is needed use
   registration crosses (.hr), crop marks (.board corners), corner brackets (.brackets), dimension lines (.dim),
   ticks (.tick-label) and dotted leaders (.leader). All marks are 1px in --mark. */
:root { --mark-strong: var(--ink-primary); }   /* --mark lives in tokens */
.paper-board-dark, .paper-card-dark { --mark: rgba(236, 239, 244, 0.30); }

/* Corner brackets — four 12px L-corners instead of a closed box */
.brackets {
  --b: 12px; --m: var(--mark);
  background:
    linear-gradient(var(--m), var(--m)) 0 0 / var(--b) 1px no-repeat,
    linear-gradient(var(--m), var(--m)) 0 0 / 1px var(--b) no-repeat,
    linear-gradient(var(--m), var(--m)) 100% 0 / var(--b) 1px no-repeat,
    linear-gradient(var(--m), var(--m)) 100% 0 / 1px var(--b) no-repeat,
    linear-gradient(var(--m), var(--m)) 0 100% / var(--b) 1px no-repeat,
    linear-gradient(var(--m), var(--m)) 0 100% / 1px var(--b) no-repeat,
    linear-gradient(var(--m), var(--m)) 100% 100% / var(--b) 1px no-repeat,
    linear-gradient(var(--m), var(--m)) 100% 100% / 1px var(--b) no-repeat;
}

/* Dimension line — a measured span with end ticks and a small centred label */
.dim { display: flex; align-items: center; gap: 10px; color: var(--ink-secondary); font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; line-height: 1; white-space: nowrap; }
.dim::before, .dim::after { content: ""; flex: 1; height: 7px; }
.dim::before { background: linear-gradient(var(--mark), var(--mark)) 0 3px / 100% 1px no-repeat, linear-gradient(var(--mark), var(--mark)) 0 0 / 1px 7px no-repeat; }
.dim::after  { background: linear-gradient(var(--mark), var(--mark)) 0 3px / 100% 1px no-repeat, linear-gradient(var(--mark), var(--mark)) 100% 0 / 1px 7px no-repeat; }
.dim--above { margin-bottom: 10px; } .dim--below { margin-top: 10px; }
.paper-board-dark .dim { color: #8E949D; }

/* Tick label — a short 24px tick over a mono label (replaces ruled caption rows) */
.tick-label { position: relative; padding-top: 10px; }
.tick-label::before { content: ""; position: absolute; top: 0; left: 0; width: 24px; height: 5px; background: linear-gradient(var(--mark-strong), var(--mark-strong)) 0 0 / 24px 1px no-repeat, linear-gradient(var(--mark-strong), var(--mark-strong)) 0 0 / 1px 5px no-repeat; }

/* Board registration marks — small crop marks just inside the four corners of a mounted board */
.board { --reg: 10px; --reg-inset: 22px; }
.board::after {
  content: ""; position: absolute; inset: var(--reg-inset); pointer-events: none; --m: var(--mark);
  background:
    linear-gradient(var(--m), var(--m)) 0 0 / var(--reg) 1px no-repeat,
    linear-gradient(var(--m), var(--m)) 0 0 / 1px var(--reg) no-repeat,
    linear-gradient(var(--m), var(--m)) 100% 0 / var(--reg) 1px no-repeat,
    linear-gradient(var(--m), var(--m)) 100% 0 / 1px var(--reg) no-repeat,
    linear-gradient(var(--m), var(--m)) 0 100% / var(--reg) 1px no-repeat,
    linear-gradient(var(--m), var(--m)) 0 100% / 1px var(--reg) no-repeat,
    linear-gradient(var(--m), var(--m)) 100% 100% / var(--reg) 1px no-repeat,
    linear-gradient(var(--m), var(--m)) 100% 100% / 1px var(--reg) no-repeat;
  opacity: .7;
}
@media (max-width: 720px) { .board { --reg-inset: 10px; --reg: 8px; } }

/* ——— 13. GalleryFrame — one picture (or the film) hung alone, a print on the gallery wall, with its museum label ———
   A narrow board with a wide passe-partout and large wall margins all round; a small museum label on the wall
   beside its lower edge. It focuses attention where the wide GalleryBoard explains. */
.gallery-frame { width: 100%; max-width: var(--board-max); display: grid; grid-template-columns: 1fr minmax(0, 880px) 1fr; column-gap: var(--space-8); align-items: end; padding: clamp(64px, 12vh, 160px) 0; }
.gallery-frame__print { grid-column: 2; margin: 0; padding: clamp(32px, 7%, 72px) clamp(32px, 8%, 80px) clamp(40px, 9%, 88px); }
.gallery-frame__print .dim { margin-top: 14px; }
.gallery-frame__label { grid-column: 3; align-self: end; justify-self: start; width: 188px; padding: 14px 16px 16px; margin-bottom: 6px; }
.gallery-frame__label p { margin: 0; }
.gallery-frame__label .t-mono + .t-mono { margin-top: 4px; }
.gallery-frame__label .copy-slot { margin-top: 10px; }

@media (max-width: 1100px) { .gallery-frame { grid-template-columns: 1fr minmax(0, 720px) 1fr; } .gallery-frame__label { grid-column: 2; justify-self: end; margin-top: 16px; } }
@media (max-width: 720px) { .gallery-frame { grid-template-columns: 1fr; padding: 48px 0; } .gallery-frame__print, .gallery-frame__label { grid-column: 1; } }

/* ——— 14. SwatchGrid — a world sheet: the palette, the material, the sequence (REF-10) ———
   Three columns on a --paper-tint panel, centred on one another: colour chips with hex and role, a tall material
   study, a short strip of 2.39 frames with two text columns under it. Chips are content swatches (case01-*), never UI. */
.swatch-grid { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr) minmax(0, 6fr); column-gap: clamp(32px, 5%, 80px); align-items: center; padding: clamp(24px, 3%, 48px) 0; }
/* The world sheet is one sheet: the board itself takes --paper-tint (bible §2), the three zones sit straight on it */
.board--tint { --paper-board: var(--paper-tint); }
.swatch-grid__head { margin: 0 0 var(--space-4); color: var(--ink-secondary); }
.swatch-grid__chips { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.swatch-grid__chips i { display: block; aspect-ratio: 1; box-shadow: inset 0 0 0 1px rgba(22, 23, 23, 0.08); }
.swatch-grid__legend { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px 6px; margin-top: var(--space-4); }
.swatch-grid__legend p { margin: 0; white-space: nowrap; }
.swatch-grid__sum { margin: var(--space-4) 0 0; color: var(--ink-secondary); }
.swatch-grid__material { margin: 0; }
.swatch-grid__material .cell { aspect-ratio: var(--material-aspect, 1000 / 2200); outline: 1px solid var(--hairline-light); overflow: hidden; background: #0B0A0A; }
.swatch-grid__material .cell img { display: block; width: 100%; height: 100%; object-fit: cover; }
.swatch-grid__material figcaption { margin-top: 14px; }
.swatch-grid__strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--gutter-strip); }
.swatch-grid__strip figure { margin: 0; min-width: 0; }
.swatch-grid__strip figcaption { margin-top: 6px; color: var(--ink-secondary); white-space: nowrap; overflow: hidden; }
.swatch-grid__notes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6); margin-top: var(--space-8); max-width: 520px; }
.swatch-grid__notes p { margin: 0; }
.swatch-grid__notes .t-label { margin-bottom: 8px; }
@media (max-width: 1000px) { .swatch-grid { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); row-gap: var(--space-12); } .swatch-grid__seq { grid-column: 1 / -1; } }
@media (max-width: 720px) { .swatch-grid { grid-template-columns: 1fr; } .swatch-grid__material { width: 56%; } .swatch-grid__strip { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: var(--space-4); } .swatch-grid__notes { grid-template-columns: 1fr; } }

/* ——— 15. Heads — flush and deep ———
   Flush head: the paper names itself at its own top edge. A strip that starts at the edge (56px on boards, 40px on cards),
   the datum-red mark and a type-label in caps centred in it, no rule under it — the label hangs close to the edge, not
   pushed down by a web-style margin. For identity: the studio (TopBar), a case, a world.
   Deep head: the board's own margin — .board__head in mono at the full board padding, then a long breath of paper.
   For boards that explain: process, measurement, contact sheets. One paper, one head. */
.flush-head { display: flex; align-items: center; gap: 10px; height: 56px; margin: calc(var(--board-pad-y) * -1) 0 var(--space-12); }
.flush-head__mark { width: 6px; height: 16px; background: var(--datum-red); flex: none; }
.flush-head__meta { margin-left: auto; color: var(--ink-secondary); }
.flush-head--card { height: 40px; gap: 8px; margin: calc(var(--card-pad, 24px) * -1) 0 var(--space-4); }
.flush-head--card .flush-head__mark { width: 4px; height: 12px; }
.paper-board-dark .flush-head, .paper-card-dark .flush-head { color: var(--ink-on-dark); }
.paper-board-dark .flush-head__meta, .paper-card-dark .flush-head__meta { color: #8E949D; }
.heads-cards { display: grid; gap: var(--space-6); }
.heads-card { padding: 24px; --card-pad: 24px; }

/* ——— The constructor board: how the system grows (three layers, the nine primitives, the open component list) ——— */
.layers { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 6fr) minmax(0, 2.4fr); column-gap: clamp(32px, 4%, 64px); align-items: start; }
.layer__head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; }
.layer__head > .t-mono:first-child { color: var(--ink-secondary); }
.layer__note { margin: 0 0 var(--space-6); }
.layer-list, .comp-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.layer-list li { display: grid; gap: 2px; }
.layer-list__src { opacity: .75; }
.comp-list { gap: 7px; }
.comp-list__next { margin-top: var(--space-4); padding: 10px 12px; }
.prims__group { display: flex; align-items: center; margin: 0 0 var(--space-4); }
.prims__group--marks { margin-top: var(--space-8); color: var(--ink-secondary); }
.prims__flag { display: inline-block; width: 4px; height: 12px; background: var(--datum-red); margin-right: 8px; flex: none; vertical-align: -2px; }
.prims { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-6) var(--space-4); }
.prims--5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.prim { min-width: 0; }
.prim p { margin: 0; }
.prim p + p { margin-top: 3px; }
.prim__cls { font-size: 10px; letter-spacing: 0.02em; line-height: 1.45; }
.prim__spec { height: 76px; display: flex; align-items: center; margin-bottom: 12px; }
.prim-chip { width: 100%; height: 56px; }
.prim-chip--card { width: 82%; height: 44px; }
.gallery-frame__print.prim-print { grid-column: auto; width: 100%; padding: 9px 11px 13px; }
.prim-ap { width: 100%; }
.prim-brackets { width: 100%; height: 52px; }
.prim-dim { width: 100%; }
.prim-spec { grid-template-columns: 48px 1fr; gap: 6px 10px; }
.rules { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-8) clamp(32px, 4%, 64px); }
.rule p { margin: 0; }
.rule p.mt-4 { margin-top: var(--space-4); }
.rule__hard { display: flex; align-items: baseline; }
.rule__hard .prims__flag { margin-top: 3px; align-self: flex-start; }
.rule__steps { margin: var(--space-4) 0 0; padding-left: 22px; display: grid; gap: 6px; }
@media (max-width: 1100px) { .layers { grid-template-columns: 1fr; row-gap: var(--space-12); } .layer-list { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--space-8); } .comp-list { grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: var(--space-6); } .comp-list__next { max-width: 320px; } }
@media (max-width: 720px) { .prims, .prims--5 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .rules { grid-template-columns: 1fr; } .layer-list, .comp-list { grid-template-columns: 1fr; } }

/* ——— Review controls (the director's switches; not part of any page) ——— */
.review { display: flex; flex-wrap: wrap; gap: 8px 28px; align-items: baseline; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.08em; color: var(--ink-secondary); }
.review button { appearance: none; background: none; border: 0; padding: 2px 0; margin: 0 0 0 10px; font: inherit; letter-spacing: inherit; color: var(--ink-secondary); cursor: pointer; border-bottom: 1px solid transparent; }
.review button[aria-pressed="true"] { color: var(--ink-primary); border-bottom-color: var(--datum-red); }
.review button:focus-visible { outline: 1px solid var(--datum-red); outline-offset: 2px; }

/* ——— Scroll-snap rooms (opt-in): each board is one viewport, the page moves board to board ——— */
html.snap-rooms { scroll-snap-type: y proximity; }
html.snap-rooms .room > .board, html.snap-rooms .gallery-frame { scroll-snap-align: center; scroll-snap-stop: normal; }
html.snap-rooms .room > .board { min-height: calc(100vh - 2 * var(--board-gap)); display: flex; flex-direction: column; justify-content: center; }
html.snap-rooms .room > .board > .topbar { margin-top: 0; }
html.snap-rooms .gallery-frame { min-height: 100vh; align-content: center; }

/* Dimension line carrying the studio's datum: red end ticks (hero apertures only) */
.dim--datum::before { background: linear-gradient(var(--mark), var(--mark)) 0 3px / 100% 1px no-repeat, linear-gradient(var(--datum-red), var(--datum-red)) 0 0 / 1px 7px no-repeat; }
.dim--datum::after  { background: linear-gradient(var(--mark), var(--mark)) 0 3px / 100% 1px no-repeat, linear-gradient(var(--datum-red), var(--datum-red)) 100% 0 / 1px 7px no-repeat; }

/* Registration mark — the 4px datum-red square in a card's bottom-right corner (StoryCard, museum label) */
.reg-mark::after { content: ""; position: absolute; right: 10px; bottom: 10px; width: 4px; height: 4px; background: var(--datum-red); }

/* The print sits recessed in its passe-partout: a 1px mat-cut catchlight below/right, a hair of depth above/left */
.gallery-frame__print .film-aperture { box-shadow: 1px 1px 0 rgba(255, 255, 255, 0.9), -1px -1px 0 rgba(22, 23, 23, 0.10); }

/* ——— 16. SplitAperture — two pictures of one comparison in one 2.39 aperture, split by the 2px datum ———
   One P4 aperture, two pictures side by side and the datum-red 2px divider between them (the bible's divider between
   worlds or before/after). Each half is a crop of its own picture, nothing is drawn over either. The halves are crops,
   never a wipe: no line claims a landmark across the cut. The key under it names each half in mono, under its half. */
.split-aperture { display: grid; grid-template-columns: minmax(0, 1fr) 2px minmax(0, 1fr); }
.split-aperture > img, .split-aperture > picture > img, .split-aperture > video { min-width: 0; }
.split-aperture__key { display: grid; grid-template-columns: minmax(0, 1fr) 2px minmax(0, 1fr); margin: 6px 0 0; color: var(--ink-secondary); }
.split-aperture__key > span { min-width: 0; white-space: nowrap; overflow: hidden; }
.split-aperture__key > span:last-child { grid-column: 3; padding-left: 8px; }
.paper-board-dark .split-aperture__key { color: #8E949D; }

/* ——— Spacing helpers — last, so they win over component margins ——— */
.mt-4 { margin-top: var(--space-4); } .mt-6 { margin-top: var(--space-6); } .mt-8 { margin-top: var(--space-8); } .mt-12 { margin-top: var(--space-12); }

/* ════════ The home's components, 17–27 — tried in pages/components-book.html, registered 2026-10-23 (NOTES 11) ════════
   Built only from the system: tokens, the paper (P1–P4), the marks (P5–P9). The one new style is type-display (the hero
   statement only, the director's decision). Their behaviour is sections.js. */

/* Action link — a 24px line or the play triangle before a caps label (the CaseRow CTA, used on its own) */
.act { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; color: var(--ink-primary); text-decoration: none; font-family: var(--font-label); font-size: var(--type-label-size); font-weight: var(--type-label-weight); letter-spacing: var(--type-label-tracking); text-transform: uppercase; }
.act::before { content: ""; width: 24px; height: 1px; background: currentColor; transition: width var(--dur-hover) var(--ease), background var(--dur-hover) var(--ease); }
.act:hover::before, .act:focus-visible::before { width: 40px; background: var(--datum-red); }
.act--red::before { background: var(--datum-red); }
.act--play::before { width: 8px; height: 10px; clip-path: polygon(0 0, 100% 50%, 0 100%); }
.act--play:hover::before, .act--play:focus-visible::before { width: 8px; }
.act:focus-visible { outline: 1px solid var(--datum-red); outline-offset: 4px; }
.paper-board-dark .act, .gallery-wall-dark .act { color: var(--ink-on-dark); }
button.act { appearance: none; background: none; border: 0; padding: 0; cursor: pointer; }

/* ——— 17. HeroBand — one photograph, a paper band cut across it (REF-01, integrated) ———
   The photograph is one picture behind the whole section; the band is P2 paper laid flush across it — cut, not
   mounted, so it has no shadow. The photograph shows above (the sky) and below (the floor); nothing is drawn on it. */
.hero-band { position: relative; display: grid; grid-template-rows: auto auto auto; }
/* two photographs of the one world — above the band and below it — each its own composition */
/* the pictures a page hands the HeroBand and the BriefSheet: registered as <url>, so a relative path resolves against the
   page that names it, not against this stylesheet — a page at any depth can set them (v-audience, fault 1) */
@property --hero-top { syntax: '<url> | none'; inherits: true; initial-value: none; }
@property --hero-bottom { syntax: '<url> | none'; inherits: true; initial-value: none; }
@property --brief-photo { syntax: '<url> | none'; inherits: true; initial-value: none; }
.hero-band__sky { min-height: clamp(280px, 36vh, 420px); background: #E6E9EE var(--hero-top, none) var(--hero-top-pos, 50% 30%) / cover no-repeat; }
.hero-band__floor { min-height: clamp(200px, 29vh, 340px); background: #E9ECF0 var(--hero-bottom, none) var(--hero-bottom-pos, 50% 50%) / cover no-repeat; }
.hero-band__top { display: flex; align-items: center; justify-content: space-between; gap: 6px var(--space-6); flex-wrap: wrap; min-height: 56px; padding: 0 var(--wall-margin-x); }
.hero-band__top .topbar__brand, .hero-band__top .topbar__nav a { white-space: nowrap; }
.hero-band__band {
  background-color: var(--paper-card);
  background-image: var(--grain-paper), var(--shaft-paper);
  background-size: var(--grain-size), auto; background-blend-mode: overlay, normal; background-attachment: scroll, fixed;
  padding: 28px var(--wall-margin-x) 24px;
}
.hero-band__grid { max-width: var(--board-max); margin: 0 auto; display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--space-8) clamp(32px, 5%, 80px); align-items: end; }
.hero-band__film { justify-self: end; width: 100%; max-width: 780px; }
.hero-band__film .pvp__bar[hidden], .pvp__bar[hidden] { display: none; }
.hero-band__say { display: flex; flex-direction: column; gap: var(--space-4); }
.hero-band__say .t-display.copy-slot { font-family: var(--font-sans); font-size: var(--type-display-size); letter-spacing: var(--type-display-tracking); line-height: var(--type-display-leading); }
.hero-band__acts { display: flex; flex-wrap: wrap; gap: 0 var(--space-8); margin-top: var(--space-2); }
.hero-band__film .film-aperture video { pointer-events: none; }
.hero-band__key { display: flex; justify-content: space-between; gap: var(--space-4); margin-top: 8px; color: var(--ink-secondary); }
.hero-band__spec { max-width: var(--board-max); margin: var(--space-6) auto 0; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-4) var(--space-6); }
.hero-band__spec dt { color: var(--ink-secondary); text-transform: uppercase; }
.hero-band__spec dd { margin: 2px 0 0; }
.hero-band__spec a { color: var(--ink-primary); }
.hero-band__spec a:hover { color: var(--datum-red); }
.hero-band__spec .jump { justify-self: end; text-align: right; }
@media (max-width: 900px) { .hero-band__grid { grid-template-columns: 1fr; } .hero-band__spec { grid-template-columns: repeat(2, minmax(0, 1fr)); } .hero-band__spec .jump { justify-self: start; text-align: left; } }
@media (max-width: 720px) { /* the pictures a page hands the HeroBand and the BriefSheet: registered as <url>, so a relative path resolves against the
   page that names it, not against this stylesheet — a page at any depth can set them (v-audience, fault 1) */
@property --hero-top { syntax: '<url> | none'; inherits: true; initial-value: none; }
@property --hero-bottom { syntax: '<url> | none'; inherits: true; initial-value: none; }
@property --brief-photo { syntax: '<url> | none'; inherits: true; initial-value: none; }
.hero-band__sky { min-height: 200px; } .hero-band__floor { min-height: 140px; } .hero-band__top .topbar__nav { gap: var(--space-4); } }

/* ——— 18. OfferWall — the kinds of work, straight on the wall in the window shaft (REF-12) ———
   No board around it: a label and a line on the wall, one GalleryBoard offset right, StoryCards under it, light to dark. */
.offer-wall { width: 100%; max-width: var(--board-max); display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--space-12) var(--gutter); padding: var(--space-12) 0 var(--space-8); }
.offer-wall__say { grid-column: 1 / span 4; display: flex; flex-direction: column; gap: var(--space-4); padding-top: var(--space-6); max-width: 340px; }
.offer-wall__board { grid-column: 5 / -1; padding: clamp(24px, 3vw, 44px); display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 6fr) minmax(0, 2fr); gap: var(--space-6); align-items: stretch; }
.offer-wall__col { display: flex; flex-direction: column; justify-content: space-between; gap: var(--space-4); }
.offer-wall__col p { margin: 0; }
.offer-wall__cards { grid-column: 4 / -1; justify-self: end; width: 100%; max-width: 840px; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.offer-wall__cards .story-card.paper-card-dark .t-card-body { color: var(--ink-red-dark); }
@media (max-width: 1000px) { .offer-wall__say, .offer-wall__board, .offer-wall__cards { grid-column: 1 / -1; } .offer-wall__say { max-width: 520px; } }
@media (max-width: 720px) { .offer-wall { gap: var(--space-8) 0; } .offer-wall__board { grid-template-columns: 1fr; } .offer-wall__cards { grid-template-columns: 1fr; } .offer-wall__cards .story-card { aspect-ratio: auto; min-height: 240px; } }

/* ——— 19. PracticeBoard — where we are strong: the BeforeAfterBoard read as one practice (REF-04) ———
   The systems layer (the CAD plate) above, the direction layer (the finished frame) below, the datum between them; the
   layers named in the margin; the five strengths in a row under it, each a tick, a label and one line. */
.practice { display: grid; grid-template-columns: minmax(150px, 2fr) minmax(0, 10fr); gap: var(--space-8) clamp(24px, 3vw, 48px); }
.practice__margin { display: grid; grid-template-rows: 1fr 40px 1fr; }
.practice > .before-after, .practice__strengths { max-width: 820px; }
.practice__margin { grid-row: 1; }
.practice__margin > div { display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-end; text-align: right; gap: 6px; padding-bottom: 4px; }
.practice__margin p { margin: 0; }
.practice__margin .is-datum { justify-content: center; color: var(--datum-red); }
.practice__strengths { grid-column: 2; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-6); margin-top: var(--space-6); }
.practice__strengths p { margin: 0; }
.practice__strengths > div { display: flex; flex-direction: column; gap: 8px; }
.practice__strengths .t-label { display: flex; align-items: center; gap: 8px; }
.practice__strengths .t-label::before { content: ""; width: 4px; height: 4px; background: var(--ink-primary); flex: none; }
.practice__strengths .is-system .t-label::before { background: var(--datum-red); }
.practice > * { min-width: 0; }
.practice .before-after__gap .datum-run { width: 48px; }   /* a short run into the margin: here no spec column sits to the right */
@media (max-width: 1000px) { .practice { grid-template-columns: 1fr; } .practice__margin { grid-template-rows: none; grid-template-columns: none; display: flex; flex-wrap: wrap; gap: var(--space-4) var(--space-6); } .practice .before-after__gap .datum-run { width: 24px; } .practice .dim { white-space: normal; text-align: center; line-height: 1.4; } .practice__strengths { grid-column: 1; grid-template-columns: repeat(2, minmax(0, 1fr)); } .practice__margin > div { align-items: flex-start; text-align: left; } }

/* ——— 20. Swimlane + 21. StepCard — how we work, compact: what the agents check, what the studio does, where you decide ———
   Three lanes under the REF-07 gantry of the three acts; the studio lane holds the nine StepCards (a picture and a name),
   the REF-06 thread runs under them, and the client's lane marks each decision with the 2px datum. */
.steps__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-4) var(--space-12); }
.steps__head .t-body { max-width: 60ch; margin: 0; }
.swimlane-wrap { overflow-x: auto; margin-top: var(--space-12); padding-bottom: 6px; }
.swimlane { min-width: 980px; display: grid; grid-template-columns: 84px repeat(9, minmax(0, 1fr)); column-gap: var(--gutter-strip); row-gap: var(--space-4); }
.swimlane__lane { grid-column: 1; align-self: center; color: var(--ink-secondary); }
.swimlane__lane--agents { color: var(--datum-red); }
.swimlane__act { position: relative; padding-bottom: 26px; }
.swimlane__act .process__bracket { position: absolute; left: 0; right: 0; bottom: 0; margin: 0; }
.swimlane__act .t-mono { color: var(--ink-primary); }
.swimlane__agent { color: var(--ink-secondary); font-size: 10px; line-height: 1.35; min-height: 28px; }
/* where the agents check, the gantry's own node and hanger turn datum-red — the rail is the multi-agent layer */
.swimlane__act .process__bracket i.is-check { background: var(--datum-red); }
.swimlane__act .process__bracket i.is-check::after { background: var(--datum-red); }
.step-card { display: flex; flex-direction: column; gap: 8px; padding: 0; margin: 0; border: 0; background: none; text-align: left; color: var(--ink-primary); cursor: pointer; font: inherit; min-width: 0; }
.step-card__pic { aspect-ratio: 4 / 3; outline: 1px solid var(--hairline-light); overflow: hidden; background: #0B0A0A; transition: outline-color var(--dur-hover) var(--ease); }
.step-card__pic img, .step-card__pic video { width: 100%; height: 100%; object-fit: cover; }
/* small composite pictures that say the step: the sheet's chips, a moodboard, a cast and set, a strip of the cut */
.step-card__pic--chips { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; padding: 0; background: var(--paper-card); }
.step-card__pic--grid { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; gap: 2px; background: var(--paper-card); }
.step-card__pic--grid img, .step-card__pic--strip img { min-width: 0; min-height: 0; }
.step-card__pic--strip { display: grid; grid-template-rows: repeat(4, 1fr); gap: 2px; background: var(--paper-card); }
.step-card__n { color: var(--ink-secondary); }
.step-card__name { font-family: var(--font-label); font-size: 10px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; line-height: 1.3; }
.step-card:hover .step-card__pic, .step-card:focus-visible .step-card__pic { outline-color: var(--datum-red); }
.step-card:focus-visible { outline: 1px solid var(--datum-red); outline-offset: 4px; }
.swimlane__thread { grid-column: 2 / -1; position: relative; height: 12px; }
.swimlane__thread::before { content: ""; position: absolute; left: 0; right: 0; top: 5px; border-top: 1px solid var(--timeline-red); }
.swimlane__thread i { position: absolute; top: 3px; width: 5px; height: 5px; background: var(--datum-red); }
.swimlane__you { position: relative; padding-top: 10px; color: var(--ink-primary); font-size: 10px; line-height: 1.35; }
.swimlane__you::before { content: ""; position: absolute; left: 0; top: 0; width: 16px; height: 2px; background: var(--datum-red); }
.swimlane__you--none::before { display: none; }
.steps__more { display: flex; justify-content: space-between; align-items: center; gap: var(--space-6); flex-wrap: wrap; margin-top: var(--space-8); }

/* ——— 22. StepCarousel — "More detail": the nine steps as one panorama in slides (Instagram-carousel style) ———
   One continuous strip of paper, cut into slides only by small boundary marks; the next slide's edge always shows.
   Every picture, line and diagram is placed on the panorama, not in a slide, so each one can run across a boundary.
   Geometry: --slide-w is one slide; --pz the height of the picture zone. Figures take --x/--w in slides, --y/--h in --pz. */
.steps[data-mode="compact"] .step-carousel, .steps[data-mode="detail"] .steps__compact { display: none; }
.steps[data-mode="detail"] .step-carousel { animation: settle-in var(--dur-enter) var(--ease); }
@keyframes settle-in { from { opacity: 0; transform: translateY(2px); } to { opacity: 1; transform: none; } }
.step-carousel { container-type: inline-size; margin-top: var(--space-8); }
.step-carousel__viewport { overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; scrollbar-width: none; overscroll-behavior-x: contain; outline: 0; }
.step-carousel__viewport::-webkit-scrollbar { display: none; }
.step-carousel__viewport:focus-visible { outline: 1px solid var(--datum-red); outline-offset: 4px; }
.step-carousel__track { --slide-w: min(80cqw, 1080px); --pz: calc(var(--slide-w) * 0.33); --head: 64px;
  position: relative; display: grid; grid-auto-flow: column; grid-auto-columns: var(--slide-w); width: max-content; padding-right: calc(100cqw - var(--slide-w)); }
.step-slide { position: relative; scroll-snap-align: start; display: grid; grid-template-rows: var(--head) var(--pz) auto; padding: 0 calc(var(--slide-w) * 0.06); }
/* the boundary: two short ticks, top and bottom — a cut mark, not a frame */
.step-slide::before, .step-slide::after { content: ""; position: absolute; left: 0; width: 1px; height: 14px; background: var(--mark); }
.step-slide::before { top: 0; } .step-slide::after { bottom: 0; }
.step-slide:first-child::before, .step-slide:first-child::after { display: none; }
.step-slide__head { display: flex; align-items: flex-end; gap: var(--space-4); padding-bottom: 16px; }
.step-slide__head .t-label { font-size: 13px; }
.step-slide__head .t-mono:last-child { margin-left: auto; color: var(--ink-secondary); }
.step-slide__text { padding: 44px 0 var(--space-8); display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-4) var(--space-8); }
.step-slide__text > div { display: flex; flex-direction: column; gap: 8px; }
.step-slide__text p { margin: 0; }
/* the slide in view holds the text; a neighbour's text waits, quieted, so the edge never reads as an overflow */
.step-slide__text { transition: opacity var(--dur-enter) var(--ease); }
.step-slide[aria-hidden="true"] .step-slide__text { opacity: .28; }
.datum-leader { position: relative; height: 0; border-top: 1px solid var(--datum-red); }
.datum-leader::before, .datum-leader::after { content: ""; position: absolute; top: -2px; width: 4px; height: 4px; background: var(--datum-red); }
.datum-leader::before { left: 0; } .datum-leader::after { right: 0; }
.step-slide__text .t-label { color: var(--ink-secondary); font-size: 10px; }
.step-slide__marks { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-8); margin-top: var(--space-2); }
.step-slide__marks .is-agents { display: flex; align-items: center; gap: 8px; color: var(--ink-secondary); }
.step-slide__marks .is-you { padding-left: 10px; border-left: 2px solid var(--datum-red); }
/* the panorama: pictures, lines and diagrams in track coordinates */
.pano { position: absolute; left: 0; top: var(--head); height: var(--pz); width: calc(var(--slide-w) * 9); pointer-events: none; }
.pano__fig { position: absolute; margin: 0; left: calc(var(--slide-w) * var(--x)); top: calc(var(--pz) * var(--y, 0)); width: calc(var(--slide-w) * var(--w)); height: calc(var(--pz) * var(--h, 1)); }
.pano__fig.is-ar { height: auto; aspect-ratio: var(--ar); }
.pano__pic { outline: 1px solid var(--hairline-light); overflow: hidden; background: #0B0A0A; }
.pano__pic > img, .pano__pic > picture > img, .pano__pic > video { display: block; width: 100%; height: 100%; object-fit: cover; }
.pano__cap { position: absolute; left: 0; top: calc(100% + 6px); white-space: nowrap; color: var(--ink-secondary); font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.04em; }

.pano__note { height: auto; white-space: normal; color: var(--ink-secondary); font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.04em; line-height: 1.3; }
.pano__line { position: absolute; height: 0; border-top: 1px solid var(--mark-strong); }

/* the two lines that run the whole strip: the gantry (the multi-agent layer) and the thread (the nine steps) */
.pano-rail { position: absolute; left: calc(var(--slide-w) * 0.06); width: calc(var(--slide-w) * 8.94); top: 20px; height: 0; border-top: 1px solid var(--ink-primary); }
.pano-rail i { position: absolute; top: -3px; width: 5px; height: 5px; background: var(--ink-primary); }
.pano-rail i::after { content: ""; position: absolute; left: 2px; top: 5px; width: 1px; height: 8px; background: inherit; }
.pano-rail b { position: absolute; left: 0; top: -18px; font-weight: 400; white-space: nowrap; color: var(--ink-secondary); }
.pano-thread { position: absolute; left: 0; width: calc(var(--slide-w) * 9); top: calc(var(--head) + var(--pz) + 22px); height: 0; border-top: 1px solid var(--timeline-red); }
.pano-thread i { position: absolute; top: -3px; width: 5px; height: 5px; background: var(--datum-red); }
.step-carousel__bar { display: flex; align-items: center; gap: var(--space-6); margin-top: var(--space-4); }
.step-carousel__bar .t-mono { color: var(--ink-secondary); }
.step-carousel__bar .count { color: var(--ink-primary); min-width: 64px; }
.step-carousel__bar button { appearance: none; background: none; border: 0; padding: 0 2px; min-height: 44px; font-family: var(--font-mono); font-size: var(--type-mono-size); letter-spacing: 0.08em; color: var(--ink-primary); cursor: pointer; }
.step-carousel__bar button:disabled { color: var(--ink-secondary); opacity: .5; cursor: default; }
.step-carousel__bar button:focus-visible { outline: 1px solid var(--datum-red); outline-offset: 2px; }
.step-carousel__bar .act { margin-left: auto; }
@media (max-width: 720px) {
  .step-carousel__track { --slide-w: 86cqw; --pz: calc(var(--slide-w) * 0.78); --head: 76px; }
  .step-slide__text { grid-template-columns: 1fr; padding-top: 40px; }
  /* a phone has no room beside the count: the act steps back, the title may take two lines under the rail */
  .step-slide__head { flex-wrap: wrap; align-items: baseline; align-content: flex-end; gap: 2px var(--space-3); }
  .step-slide__head .t-mono:first-child { white-space: nowrap; }
  .step-slide__head .t-mono:last-child { display: none; }
  /* nor for the panorama's museum labels at 10px: the pictures, the bar and the lines carry it, the slide's text explains */
  .pano .pano__note, .pano .pano__cap, .pano .palette-bar__labels { display: none; }
}

/* ——— 27. FoldCorner — the sheet's corner turned up, the next sheet showing under it: there is more ———
   Built from the paper: the flap is the same P2 paper seen from its back, with the paper's own falloff and the card's
   shadow; under it a second sheet (paper-tint) shows a glimpse of what lies beneath — an aperture's edge and the thread.
   The control is the corner and its label together. --f sizes the fold; .is-unfolding and the cancelable
   'truemanity:unfold' event (sections.js) are the hooks for the unfolding animation to come. */
.fold { position: absolute; right: 0; bottom: 0; z-index: 2; --f: 112px; display: flex; align-items: flex-end; gap: var(--space-4); margin: 0; padding: 0; border: 0; background: none; font: inherit; color: var(--ink-primary); text-align: right; cursor: pointer; }
.fold:hover, .fold:focus-visible { --f: 126px; }
.fold:focus-visible { outline: 1px solid var(--datum-red); outline-offset: -6px; }
.fold__label { display: flex; flex-direction: column; align-items: flex-end; gap: 0; padding-bottom: 18px; }
.fold__label .act { min-height: 32px; }
.fold:hover .act::before, .fold:focus-visible .act::before { width: 40px; background: var(--datum-red); }
.fold__corner { position: relative; width: var(--f); height: var(--f); flex: none; transition: width var(--dur-hover) var(--ease), height var(--dur-hover) var(--ease); }
.fold__under { position: absolute; inset: 0; overflow: hidden; clip-path: polygon(100% 0, 100% 100%, 0 100%); background-color: var(--paper-tint); background-image: var(--grain-paper); background-size: var(--grain-size); background-blend-mode: overlay; }
/* the flap's shadow on the sheet beneath — darkest along the fold, gone toward the corner (the card shadow's colours) */
/* the flap's shadow on the sheet beneath: an ellipse laid along the crease — nothing where the paper still touches (the
   two ends), widest where the flap stands highest (the middle); the card shadow's colours */
.fold__under::after { content: ""; position: absolute; left: 50%; top: 50%; width: 142%; height: 44%; transform: translate(-50%, 0) rotate(-45deg); transform-origin: 50% 0; background: radial-gradient(ellipse 50% 100% at 50% 0%, rgba(22, 25, 29, 0.24) 0%, rgba(40, 46, 56, 0.10) 38%, rgba(40, 46, 56, 0) 72%); }
.fold__glimpse { position: absolute; right: -14%; bottom: 20%; width: 64%; aspect-ratio: 2.39 / 1; background: #0B0A0A; outline: 1px solid var(--hairline-light); }
.fold__glimpse img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 30% 50%; }
.fold__thread { position: absolute; left: 0; right: 0; bottom: 11%; border-top: 1px solid var(--timeline-red); }
.fold__flap { position: absolute; inset: 0; filter: drop-shadow(2px 4px 4px rgba(22, 25, 29, 0.18)) drop-shadow(6px 12px 14px rgba(40, 46, 56, 0.11)); }
/* the back of the paper: its grain, its falloff, and the bend along the crease catching the window — a thin light, not a line */
.fold__back { position: absolute; inset: 0; clip-path: polygon(0 0, 100% 0, 0 100%); background-color: var(--paper-card); background-image: var(--grain-paper), linear-gradient(135deg, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 30%, rgba(30, 45, 80, 0.05) 46%, rgba(255, 255, 255, 0.9) 49.4%, rgba(255, 255, 255, 0) 50%); background-size: var(--grain-size), auto; background-blend-mode: overlay, normal; box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.95); }
.steps .steps__compact { padding-bottom: 48px; }
@media (max-width: 720px) { .fold { --f: 84px; } .fold:hover, .fold:focus-visible { --f: 92px; } .fold__label { padding-bottom: 18px; } }

/* ——— 23. PartsTray — no glass ceiling: the parts round a lens ring, each project's line a figure of its own (REF-02, REF-04) ———
   Every part is drawn once, round the ring: each kind an arc with its name inside, an empty slot at the top for the next
   part, the names level beside the ring on dotted leaders, as callouts on a drawing. A project's line is a figure across
   the ring in the datum red, drawn at a plotter's pace, its step numbers set as it lands; the one pipeline for every
   project is the only line that never leaves the rim. Beside the ring, every project's figure small, as the picker.
   The data is the markup (.parts__data); behaviour in sections.js. Second form, 2026-10-24 (the first was the tray of
   chips and the lines under it). */
.parts { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-8); }
.parts__data { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-6); font-family: var(--font-mono); font-size: var(--type-mono-size); color: var(--ink-secondary); }
.parts__data ul, .parts__data ol { margin: 6px 0 0; padding: 0 0 0 18px; }
.parts__data p { margin: 0; font-family: var(--font-label); font-weight: 600; letter-spacing: var(--type-label-tracking); text-transform: uppercase; color: var(--ink-primary); }
.parts.is-drawn .parts__data { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.parts__wrap { display: grid; grid-template-columns: minmax(0, 1fr) minmax(250px, 300px); gap: var(--space-12); align-items: center; }
.parts__ring { width: 100%; min-width: 0; }
.parts-svg { display: block; overflow: visible; }
.parts-svg text { font-family: var(--font-mono); }
.parts-head { font-family: var(--font-label) !important; font-size: var(--type-label-size); font-weight: 600; letter-spacing: var(--type-label-tracking); fill: var(--ink-primary); }
.parts-count { font-size: 10px; letter-spacing: 0.04em; fill: var(--ink-secondary); }
.parts-name { font-size: 11px; letter-spacing: 0.02em; fill: currentColor; transition: fill 220ms var(--ease); }
.parts-row.is-on .parts-name { font-weight: 500; }
.parts-step { font-size: 10px; font-weight: 500; letter-spacing: 0.02em; fill: var(--datum-red); }
.parts-halo { paint-order: stroke; stroke: var(--paper-board); stroke-width: 5px; stroke-linejoin: round; }
.parts-row { color: var(--ink-secondary); }
.parts-row.is-on { color: var(--ink-primary); }
.parts-row.is-reserve.is-on { color: var(--datum-red); }
.parts-glyph { fill: currentColor; transition: fill 220ms var(--ease); }
.parts-glyph.is-ring, .parts-glyph.is-new { fill: none; stroke: currentColor; stroke-width: 1.2; }
.parts-glyph.is-new { stroke-width: 1; stroke-dasharray: 1.8 1.8; fill: var(--paper-board); }
.parts-rim { fill: none; stroke: var(--ink-secondary); stroke-opacity: 0.6; stroke-width: 1; }
.parts-rim.is-reserve { stroke-dasharray: 2 3; }
.parts-inner { fill: none; stroke: var(--mark); stroke-width: 1; stroke-dasharray: 1 4; }
.parts-callouts path { fill: none; stroke: var(--mark); stroke-width: 1; stroke-dasharray: 1 2.5; }
.parts-route { transition: opacity 200ms linear; }
.parts-route.is-leaving { opacity: 0; }
.parts-line { fill: none; stroke: var(--datum-red); stroke-width: 1.25; }
.parts-line.is-open { stroke-dasharray: 3 4; }
.parts-line.is-ghost { stroke: var(--ink-secondary); stroke-width: 1; }
.parts-node { fill: var(--datum-red); }
.parts-node.is-ghost { fill: var(--ink-secondary); transform-box: fill-box; transform-origin: center; transform: scale(0.6); }
.parts-node.is-new { fill: var(--paper-card); stroke: var(--datum-red); stroke-width: 1; stroke-dasharray: 2 1.5; }
/* the picker: every project's figure, small */
.parts__sigs { display: grid; gap: var(--space-2); }
.parts__sig { appearance: none; border: 0; background: none; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-4); align-items: center; padding: 6px 0; text-align: left; cursor: pointer; color: var(--ink-secondary); transition: color var(--dur-hover) var(--ease); }
.parts__sig svg { display: block; overflow: visible; }
.parts__sig .parts-rim { stroke: var(--mark); stroke-opacity: 1; }
.parts-chord { fill: none; stroke: currentColor; stroke-width: 1; stroke-opacity: 0.75; }
.parts-chord.is-ghost { stroke-opacity: 0.5; }
.parts__sig-cap { display: grid; gap: 5px; }
.parts__sig-cap .t-mono { color: var(--ink-secondary); }
.parts__sig-cap .t-label { position: relative; }
.parts__sig[aria-pressed="true"] .parts__sig-cap .t-label::before { content: ""; position: absolute; left: -12px; top: 1px; width: 3px; height: 11px; background: var(--datum-red); }
.parts__sig:hover, .parts__sig[aria-pressed="true"] { color: var(--ink-primary); }
.parts__sig[aria-pressed="true"] .parts-chord { stroke: var(--datum-red); stroke-opacity: 1; stroke-width: 1.25; }
.parts__sig.is-ghost[aria-pressed="true"] .parts-chord { stroke: var(--ink-secondary); stroke-width: 1; }   /* the one pipeline stays grey, as it is on the ring */
.parts__sig:focus-visible { outline: 1px solid var(--datum-red); outline-offset: 4px; }
.parts__order { display: none; }
/* the key: what kind of thing each part is */
.parts__legend { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-6); color: var(--ink-secondary); }
.parts__legend span { display: inline-flex; align-items: center; gap: 8px; }
.parts__k { display: inline-block; flex: none; width: 6px; height: 6px; background: currentColor; }
.parts__k--agent { border-radius: 50%; }
.parts__k--model { background: none; border: 1.2px solid currentColor; border-radius: 50%; }
.parts__k--person { transform: rotate(45deg) scale(0.86); }
.parts__k--new { background: none; border: 1px dashed currentColor; }
/* on a phone: the figures in a row above the ring, no names round it, the line read under it in order */
@media (max-width: 720px) {
  .parts__wrap { grid-template-columns: minmax(0, 1fr); gap: var(--space-4); }
  .parts__sigs { order: -1; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 4px; }
  .parts__sig { grid-template-columns: minmax(0, 1fr); justify-items: center; gap: 6px; padding: 0; min-height: 44px; }
  .parts__sig-cap { text-align: center; }
  .parts__sig-cap .t-label { font-size: 9px; letter-spacing: 0.05em; }
  .parts__sig[aria-pressed="true"] .parts__sig-cap .t-label::before { display: none; }
  .parts__order { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px var(--space-4); margin: var(--space-2) 0 0; padding: 0; list-style: none; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.02em; color: var(--ink-primary); }
  .parts__order span { color: var(--datum-red); margin-right: 6px; }
  .parts__order-head { grid-column: 1 / -1; margin-bottom: 4px; color: var(--ink-primary); }
}

/* ——— 24. ProjectApertures — the work: three apertures on the monolith's equator, pierced by the laser (REF-09) ———
   Case 01, the reserved Case 02 and the visitor's own project — an aperture of corner brackets only. Above them the
   board is a void; a portrait may come out of it with no frame, its black the board's black (integrated). */
.monolith { position: relative; overflow: hidden; min-height: 720px; display: flex; flex-direction: column; }
/* lighten: where the portrait is black the board itself shows, grain and falloff, so there is no edge to find */
.monolith__figure { position: absolute; right: 0; top: 0; width: 50%; height: 70%; margin: 0; pointer-events: none; mix-blend-mode: lighten;
  -webkit-mask-image: linear-gradient(to bottom, #000 58%, transparent 96%); mask-image: linear-gradient(to bottom, #000 58%, transparent 96%); }
.monolith__figure img { width: 100%; height: 100%; object-fit: cover; object-position: 60% 30%; }
.monolith__say { position: relative; max-width: 440px; display: flex; flex-direction: column; gap: var(--space-4); margin-top: var(--space-8); }
.monolith__say .t-body { color: #8E949D; margin: 0; }
.monolith__equator { position: relative; margin-top: auto; padding-top: var(--space-24); }
/* the finished work leads the row; the reserved case and the visitor's own follow */
.monolith__row { position: relative; display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr); gap: var(--gutter-strip); align-items: center; }   /* one equator through the three centres */
.monolith__index { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr); gap: var(--gutter-strip); margin-bottom: 8px; color: #8E949D; }
/* inside the row of apertures: it crosses them and runs out to both edges of the board */
.monolith__laser { position: absolute; left: calc(var(--board-pad-x) * -1 - 1px); right: calc(var(--board-pad-x) * -1 - 1px); height: 1px; background: var(--laser-red-dark); top: 50%; pointer-events: none; z-index: 1; }
.monolith__ap.is-yours { outline: 0; background: none; --m: rgba(236, 239, 244, 0.42); }
.monolith__ap.is-yours .brackets { position: absolute; inset: 0; }
.monolith__ap.is-yours a { position: absolute; left: 50%; top: 58%; transform: translate(-50%, -50%); z-index: 2; display: inline-flex; align-items: center; gap: 8px; padding: 6px 12px; background: var(--paper-dark); color: var(--ink-on-dark); text-decoration: none; white-space: nowrap; }
.monolith__ap.is-yours a:hover, .monolith__ap.is-yours a:focus-visible { color: #fff; }
/* reserved: no picture until a real one exists — an empty aperture with its line */
.monolith__ap.is-reserved { display: grid; place-items: end start; padding: 10px 12px; background: var(--paper-dark); }   /* its label off the equator, so the laser never strikes it */
.monolith__ap.is-reserved .t-mono { color: #8E949D; }
.monolith__notes { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr); gap: var(--gutter-strip); margin-top: var(--space-6); }
.monolith__notes > div { display: flex; flex-direction: column; gap: 6px; }
.monolith__notes .t-mono { color: #8E949D; }
.monolith__notes .t-label { color: var(--ink-on-dark); }
.monolith__notes .copy-slot { color: #8E949D; }
@media (max-width: 900px) { .monolith__figure { position: relative; order: -1; width: calc(100% + 2 * var(--board-pad-x)); height: 300px; margin: 0 calc(var(--board-pad-x) * -1) calc(var(--space-6) * -1); } .monolith__row, .monolith__notes { grid-template-columns: 1fr; } .monolith__laser { display: none; } .monolith { min-height: 0; } }

/* ——— 25. CornerIndex — who I am: two pictures meet at one corner, the index card locks into it (REF-05, integrated) ———
   The pictures run off the page on their outer sides and keep the wall's own light, so the edge is lost there; only at
   the vertex are they cut, and the card (P2) sits flush in that corner with no gap. */
/* its own wall: the even #E3E6ED with grain and no moving shaft, so the pictures can dissolve into it */
.corner-index { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); overflow-x: clip; background-color: var(--wall-ambient); background-image: var(--grain-wall); background-size: var(--grain-size); background-blend-mode: overlay; }
.corner-index__wall { grid-column: 1; grid-row: 1; align-self: end; display: flex; flex-direction: column; gap: var(--space-4); padding: var(--space-12) var(--wall-margin-x) var(--space-8); max-width: 520px; }
/* each picture is crisp only at the vertex and fades into the wall away from it */
.corner-index__a { grid-column: 2; grid-row: 1; margin: 0; aspect-ratio: 4 / 3; overflow: hidden; -webkit-mask-image: radial-gradient(ellipse 125% 130% at 0% 100%, #000 60%, transparent 99%); mask-image: radial-gradient(ellipse 125% 130% at 0% 100%, #000 60%, transparent 99%); }
.corner-index__b { grid-column: 1; grid-row: 2; margin: 0; aspect-ratio: 4 / 3.2; overflow: hidden; -webkit-mask-image: radial-gradient(ellipse 125% 130% at 100% 0%, #000 60%, transparent 99%); mask-image: radial-gradient(ellipse 125% 130% at 100% 0%, #000 60%, transparent 99%); }
.corner-index__a img, .corner-index__b img { width: 100%; height: 100%; object-fit: cover; }
.corner-index__card { grid-column: 2; grid-row: 2; align-self: start; justify-self: start; width: min(400px, 92%); padding: 28px 28px 24px; display: flex; flex-direction: column; gap: var(--space-4); }
.corner-index__spec { grid-template-columns: 124px 1fr; gap: 12px var(--space-4); margin: var(--space-2) 0; }





@media (max-width: 720px) { .corner-index { grid-template-columns: 1fr; } .corner-index__wall, .corner-index__a, .corner-index__b, .corner-index__card { grid-column: 1; grid-row: auto; } .corner-index__card { width: auto; margin: 0 var(--wall-margin-x); } }

/* ——— 26. BriefSheet — the call to action: one paper sheet floating in the lower third of a high-key picture (REF-08) ———
   The picture is full bleed and white on white with the sheet; the sheet's left spine holds the three ways in and what
   happens next, its right half stays open paper. */
.brief { position: relative; min-height: max(1040px, 118svh); display: flex; flex-direction: column; justify-content: flex-end; align-items: center; padding: 0 var(--wall-margin-x) clamp(32px, 5vh, 64px); background: #EEF1F6 var(--brief-photo, none) var(--brief-pos, 50% 18%) / cover no-repeat; }
/* an upright index leaf; the system's static card shadow (data-light-static), so it rests on the picture instead of lifting off it */
.brief__sheet { width: min(440px, 100%); min-height: 440px; display: flex; flex-direction: column; gap: 20px; padding: 28px 32px 26px; }
.brief__sheet h2 { margin: 0; font-weight: 400; }
/* paper resting on a photograph keeps its grain and falloff but not the room's shaft: the photograph has its own light */
.paper-card--on-photo { background-image: var(--grain-paper), linear-gradient(var(--ga, 135deg), rgba(255, 255, 255, var(--lit, 0.7)) 0%, rgba(255, 255, 255, 0) 60%, rgba(30, 45, 80, 0.035) 100%); background-size: var(--grain-size), auto; background-blend-mode: overlay, normal; background-attachment: scroll, scroll; }
.brief__ways { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.brief__ways li { position: relative; padding-left: 16px; }
.brief__ways li::before { content: ""; position: absolute; left: 0; top: 4px; width: 4px; height: 4px; background: var(--ink-primary); }
.brief__ways p { margin: 0; }
.brief__ways .copy-slot { margin-top: 3px; }
.brief__next { position: relative; display: flex; flex-direction: column; gap: 8px; padding-left: 16px; margin: 0; }
.brief__next::before { content: ""; position: absolute; left: 2px; top: 6px; bottom: 6px; border-left: 1px solid var(--timeline-red); }
.brief__next p { position: relative; margin: 0; }
.brief__next p::before { content: ""; position: absolute; left: -16px; top: 6px; width: 5px; height: 5px; background: var(--datum-red); }
.brief__sheet .act { margin-top: auto; align-self: flex-start; }
.brief__foot { margin-top: var(--space-4); display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px var(--space-6); width: min(720px, 100%); color: var(--ink-secondary); }
@media (max-width: 720px) { .brief { min-height: 0; padding-top: 420px; } .brief__sheet { min-height: 0; } }

/* ════════ The case page's components, 28–30 (registered 2026-10-24) ════════
   Built by the constructor rule from what is registered: the player, P2 StoryCard, P4 aperture, P6 datum, ContactStrip
   B. Their behaviour is in sections.js; with reduced motion, or no script, each one stands as a plain, readable board. */

/* ——— 28. FilmBeats — the film and its monologue as one instrument: the PaperVideoPlayer over four StoryCards, one per
   beat. While the film plays, the card of the beat being spoken stands up a little from the board, and a datum line
   runs along its top edge as far as the beat has been spoken; a card pressed plays the film from its beat. The words
   on the cards are the film's own (its captions), not copy. ——— */
.film-beats__row { margin-top: var(--space-8); }
.film-beats__card { position: relative; }
.film-beats__card::before { content: ""; position: absolute; left: 0; top: 0; height: 2px; width: 0; background: var(--datum-red); z-index: 1; }
.film-beats__card.is-now::before { width: var(--beat-p, 100%); }
.film-beats__card.is-said::before { width: 100%; opacity: 0.35; }
.film-beats__go { position: absolute; inset: 0; z-index: 2; appearance: none; border: 0; background: none; padding: 0; margin: 0; cursor: pointer; }
.film-beats__go:focus-visible { outline: 1px solid var(--datum-red); outline-offset: -5px; }
.film-beats__card .story-card__title { quotes: none; }
.film-beats__card .story-card__foot { display: flex; justify-content: space-between; gap: var(--space-3); }
.film-beats__card .story-card__foot .is-play { color: var(--datum-red); opacity: 0; }
.film-beats__card:hover .story-card__foot .is-play, .film-beats__go:focus-visible ~ .story-card__foot .is-play { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .film-beats__card { transition: transform var(--dur-enter) var(--ease); }
  .film-beats__card.is-now { transform: translateY(-3px); }
  .film-beats__card .story-card__foot .is-play { transition: opacity var(--dur-hover) var(--ease); }
}

/* ——— 29. DatumWipe — two layers of one picture in one aperture (previs and final, raw and graded), and the datum red
   line between them: drag it, or press the arrow keys on it. With [data-sweep="50"] the line crosses once by itself
   as the picture comes into view and stops where it says — the grade passing over the stills, the film arriving over
   its plan. Left of the line is the second layer (b), right of it the first (a). ——— */
.datum-wipe { margin: 0; --wipe: 50%; }
.datum-wipe__tags { display: flex; justify-content: space-between; gap: var(--space-4); margin-bottom: 8px; color: var(--ink-secondary); }
.datum-wipe__tags b { font-weight: 400; color: var(--ink-primary); }
.datum-wipe__frame { position: relative; cursor: ew-resize; touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.datum-wipe__frame img { display: block; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.datum-wipe__a { position: absolute; inset: 0; }
.datum-wipe__b { position: absolute; inset: 0; clip-path: inset(0 calc(100% - var(--wipe)) 0 0); }
.datum-wipe__frame.is-collage { aspect-ratio: auto; background: transparent; outline: 0; }
.datum-wipe__frame.is-collage .datum-wipe__a { position: relative; }
.datum-wipe__collage { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 4px; }
.datum-wipe__collage > div { aspect-ratio: 2 / 3; overflow: hidden; background: #0B0A0A; outline: 1px solid var(--hairline-light); }


.datum-wipe__line { position: absolute; top: 0; bottom: 0; left: var(--wipe); width: 2px; margin-left: -1px; background: var(--datum-red); z-index: 1; outline: 0; }   /* the datum's own 2px */
.datum-wipe__line::before, .datum-wipe__line::after { content: ""; position: absolute; left: -1.5px; width: 5px; height: 5px; background: var(--datum-red); }
.datum-wipe__line::before { top: 0; } .datum-wipe__line::after { bottom: 0; }
.datum-wipe__line:focus-visible { box-shadow: 0 0 0 3px rgba(196, 22, 34, 0.22); }
.datum-wipe .fig__cap { margin-top: 8px; }

/* ——— 30. FlickerScrub — the 10-frame flicker, frame by frame (any run of frames: --n, set by the script, is their
   count; ContactStrip B reads it too, 15 when unset). On the dark board the frame stands large over the
   ContactStrip B row; as the page scrolls past, the board holds (a short pinned moment, about two screens) and the
   frames follow the scroll, F00 to F14 — the current one marked in the row, named over the picture with its beat.
   With reduced motion, or no script, it is the registered ContactStrip B with F00 large over it, and nothing holds. ——— */
.flicker-scrub__frame { position: relative; }
.flicker-scrub__frame img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; }
.flicker-scrub__frame img.is-on { opacity: 1; }
.flicker-scrub__head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-4); margin-bottom: 10px; color: #8E949D; }
.flicker-scrub__head b { font-weight: 400; color: var(--ink-on-dark); }
.flicker-scrub__head [data-scrub-beat] { color: var(--ink-on-dark); }
.flicker-scrub .flicker { margin-top: var(--space-6); }
.flicker-scrub .flicker__row .film-aperture.is-on { outline: 1px solid var(--laser-red-dark); outline-offset: -1px; z-index: 1; }
.flicker-scrub .flicker__nums > span.is-on { color: var(--ink-on-dark); }
/* the projection: a laser tick from the current frame in the row up to the picture over it (REF-09) */
.flicker-scrub .flicker::before { content: ""; position: absolute; left: calc((var(--k, 0) + 0.5) / var(--n, 15) * 100%); top: calc(-1 * var(--space-6)); height: calc(var(--space-6) + 30px); width: 1px; background: var(--laser-red-dark); }
.flicker-scrub .flicker::after { content: ""; position: absolute; left: calc((var(--k, 0) + 0.5) / var(--n, 15) * 100% - 2px); top: calc(-1 * var(--space-6)); width: 5px; height: 5px; background: var(--laser-red-dark); }
.flicker-scrub .flicker__row .film-aperture { cursor: pointer; }
html.motion .flicker-scrub { height: 260vh; }
html.motion .flicker-scrub__hold { position: sticky; top: 0; min-height: 100vh; display: flex; flex-direction: column; justify-content: center; padding: var(--space-8) 0; }
html.motion .flicker-scrub__frame { width: min(100%, calc(52vh * 2.39)); margin: 0 auto; }   /* the frame and the row both in one screen */
html.motion .flicker-scrub__head { width: min(100%, calc(52vh * 2.39)); margin-left: auto; margin-right: auto; }
@media (max-width: 720px) {
  html.motion .flicker-scrub { height: 220vh; }
  /* on a phone the whole row stays in view, a ruler of fifteen slivers: only the current frame's number shows under it,
     and the beat is named over the picture */
  .flicker-scrub .flicker { overflow: visible; }
  .flicker-scrub .flicker__row, .flicker-scrub .flicker__nums, .flicker-scrub .flicker__beats { min-width: 0; }
  .flicker-scrub .flicker__nums > span { visibility: hidden; padding-left: 0; }
  .flicker-scrub .flicker__nums > span.is-on { visibility: visible; }
  .flicker-scrub .flicker__beats > div { font-size: 0; }
}

/* ════════ The home's steps, threaded: components 31–33 (registered 2026-10-24) ════════
   "More detail" opens the steps in two forms, one shown at a time: ThreadedStrip on a wide screen, StepDeck on a phone,
   each with its StepScale under it. Both are pulled, not scrolled (sections.js, [data-pull-fx] on the section): the
   strip holds a moment, gathers speed, blurs along its motion, lands a little soft and focuses as an eye does — the
   words first, the pictures after. Never under reduced motion. The panorama on the strip is StepCarousel's (22). */
.steps[data-mode="compact"] .steps__detail { display: none; }
.steps[data-mode="detail"] .steps__detail { animation: settle-in var(--dur-enter) var(--ease); }
.steps__phone { display: none; }
.steps__less { display: flex; justify-content: flex-end; margin-top: var(--space-2); }

/* ——— 31. ThreadedStrip — two thin cuts in the board at the carousel's two edges, and a strip of card paper threaded
   through them: up through the left cut, lying on the board, down again through the right. The board is not cut away
   anywhere. The strip runs from just above the rail to just under the red thread; the step's words stay printed on the
   board under it and change as it settles (REF-06, REF-12) ——— */
.threaded__band { position: relative; }
.threaded .threaded__strip { z-index: 1; background-attachment: local, fixed, scroll;   /* its grain travels with it */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95), inset 0 -1px 0 rgba(22, 23, 23, 0.07); }   /* the top edge catches the window */
.threaded .step-carousel__viewport { cursor: grab; }
.threaded .step-carousel__viewport:focus-visible { outline-offset: -3px; }
.step-carousel__viewport.is-pulling { cursor: grabbing; }
.step-carousel__viewport.is-pulling * { pointer-events: none; }
.threaded .step-carousel__track { margin-top: 14px; }
.threaded .step-slide__text { display: none; }
.threaded .step-slide { grid-template-rows: var(--head) var(--pz) 40px; }
/* its cast shadow (light.js's, as for any card) is laid under it and stops short of the cuts, where it touches the board */
.threaded .threaded__lift { position: absolute; top: 0; bottom: 0; left: 40px; right: 72px; z-index: 0; pointer-events: none; }   /* more room on the right: the shadow falls that way */
/* a cut: a hairline gap in the board, a little longer than the strip is wide, its far lip catching the window */
.threaded__cut { position: absolute; top: -4px; bottom: -4px; width: 1px; z-index: 3; pointer-events: none; background: rgba(22, 25, 29, 0.24); }
.threaded__cut::after { content: ""; position: absolute; top: 0; bottom: 0; width: 1px; background: rgba(255, 255, 255, 0.9); }
.threaded__cut--l { left: 0; } .threaded__cut--l::after { left: -1px; }
.threaded__cut--r { right: 0; } .threaded__cut--r::after { right: -1px; }
/* tight, at the cuts only: on the left the board's lip lies over the strip coming up from under it (a contact shadow);
   on the right the strip bends down into the cut and turns from the light */
.threaded__band::before, .threaded__band::after { content: ""; position: absolute; top: 0; bottom: 0; width: 8px; z-index: 2; pointer-events: none; }
.threaded__band::before { left: 0; background: linear-gradient(90deg, rgba(22, 25, 29, 0.18), rgba(22, 25, 29, 0.05) 3px, rgba(22, 25, 29, 0) 7px); }
.threaded__band::after { right: 0; background: linear-gradient(270deg, rgba(22, 25, 29, 0.14), rgba(22, 25, 29, 0.04) 3px, rgba(22, 25, 29, 0) 8px); }
/* the words, printed on the board under the strip at the slide's own margin; they focus in as the strip settles */
.threaded__words { --slide-w: min(80cqw, 1080px); display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-content: start; gap: var(--space-4) var(--space-8); min-height: 150px; padding: 30px calc(var(--slide-w) * 0.06) 0; }
.threaded__words > div { display: flex; flex-direction: column; gap: 8px; }
.threaded__words p { margin: 0; }
.threaded__words .t-label { color: var(--ink-secondary); font-size: 10px; }
@media (prefers-reduced-motion: no-preference) {
  .threaded__words.is-new { animation: words-focus 220ms var(--ease) both; }
  @keyframes words-focus { 0% { opacity: 0.3; filter: blur(1.4px); } 55% { opacity: 1; filter: blur(0.35px); } 100% { opacity: 1; filter: none; } }
}

/* ——— 32. StepScale — a drafting scale under the steps: a tick per step, the current one in the datum red, a drafting
   arrowhead at each end for the previous and the next. Ticks and ends are buttons; it replaces PREV / count / NEXT ——— */
.step-scale { position: relative; display: grid; grid-template-columns: 44px repeat(9, minmax(0, 1fr)) 44px; align-items: start; margin: var(--space-6) 24px 0; }
.step-scale::before { content: ""; position: absolute; left: 44px; right: 44px; top: 8px; border-top: 1px solid var(--mark); }
.step-scale__tick { appearance: none; border: 0; background: none; padding: 0; margin: 0; cursor: pointer; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; min-height: 44px; color: var(--ink-secondary); }
.step-scale__tick::before { content: ""; width: 1px; height: 17px; background: var(--mark); transition: background var(--dur-hover) var(--ease), width var(--dur-hover) var(--ease); }
.step-scale__tick.is-current { color: var(--ink-primary); }
.step-scale__tick.is-current::before { width: 2px; background: var(--datum-red); }
.step-scale__tick:hover::before { background: var(--ink-primary); }
.step-scale__tick:focus-visible { outline: 1px solid var(--datum-red); outline-offset: 2px; }
.step-scale__end { appearance: none; border: 0; background: none; padding: 0; cursor: pointer; width: 44px; height: 44px; display: grid; place-items: start center; color: var(--ink-primary); }
.step-scale__end svg { width: 22px; height: 18px; overflow: visible; }
.step-scale__end:disabled { opacity: .25; cursor: default; }
.step-scale__end:focus-visible { outline: 1px solid var(--datum-red); outline-offset: -8px; }

/* ——— 33. StepDeck — the steps on a phone: one step on one card, the cards lying stacked, the current on top; pulled
   away to the left it shows the next under it, while the steps to come stay in a pile at the right, each edge a few px
   past the one above, so the pile thins as you go. Native scroll and snap do the pulling: the sheets are sticky to the
   right, so a sheet waits under the one above until it is uncovered; the snap points are marks of their own ——— */
.step-sheet { flex: none; display: flex; flex-direction: column; gap: 12px; padding: 16px 16px 18px; }
.step-sheet__head { display: flex; align-items: baseline; gap: var(--space-3); }
.step-sheet__head .t-label { margin: 0; font-size: 13px; }
.step-sheet__head .t-mono { white-space: nowrap; }
.step-sheet__pic { aspect-ratio: 2 / 1; display: grid; gap: 4px; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
.step-sheet__pic > img, .step-sheet__pic > picture > img, .step-sheet__pic > video, .step-sheet__pic > .cell { display: block; width: 100%; height: 100%; min-height: 0; object-fit: cover; outline: 1px solid var(--hairline-light); background: #0B0A0A; }
.step-sheet__pic > .swatch-grid__chips { height: 100%; }
.step-sheet__pic--grid { grid-auto-flow: row; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-rows: repeat(2, minmax(0, 1fr)); }
.step-sheet__pic--harm { grid-template-columns: 1fr 1fr 2px 1fr 1fr; grid-template-rows: repeat(2, minmax(0, 1fr)); grid-auto-flow: column; }
.step-sheet__pic--harm > i { grid-row: 1 / -1; background: var(--datum-red); }
.step-sheet__pic--wide { grid-template-columns: 1fr 2px 1fr; }
.step-sheet__pic--wide > i { background: var(--datum-red); }
.step-sheet__cap { margin: -6px 0 0; color: var(--ink-secondary); font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.04em; line-height: 1.3; }
.step-sheet__text { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 16px; }
.step-sheet__text > div { display: flex; flex-direction: column; gap: 6px; }
.step-sheet__text > div:first-child { grid-column: 1 / -1; }
.step-sheet__text p { margin: 0; }
.step-sheet__text .t-label { color: var(--ink-secondary); font-size: 10px; }
.deck { container-type: inline-size; margin-top: var(--space-6); }
/* the deck is cut at the board's margin on the left, so a sheet pulled away is gone, not peeking; on the right it runs
   into the margin, where the pile lies */
.deck .step-carousel__viewport { margin: 0 calc(var(--board-pad-x) * -1) 0 0; padding: 6px 0 30px; }
.deck__track { --sheet-w: 82cqw; position: relative; display: flex; align-items: flex-start; width: max-content; padding-right: calc(100cqw - var(--sheet-w) + var(--board-pad-x)); }
.deck__mark { position: absolute; top: 0; left: calc(var(--sheet-w) * var(--k)); width: 1px; height: 1px; scroll-snap-align: start; }
.deck .step-sheet { width: var(--sheet-w); position: sticky; right: calc(var(--board-pad-x) + (8 - var(--k)) * 3px); z-index: calc(20 - var(--k)); }

@media (max-width: 720px) {
  .steps__wide { display: none; } .steps__phone { display: block; }
  .steps__phone .step-scale { margin: var(--space-2) 0 0; grid-template-columns: 36px repeat(9, minmax(0, 1fr)) 36px; }
  .steps__phone .step-scale::before { left: 36px; right: 36px; }
  .steps__phone .step-scale__end { width: 36px; }
}

/* ════════ The contact page: component 34 (registered 2026-10-24) ════════ */
/* ——— 34. InquiryForm — the brief, written down: hairline fields on matte paper, labels in the label face, what you are
   sending chosen as ticks, and the datum red bar to send it (REF-03). No radius, no fill colour of its own ——— */
.inquiry { display: grid; gap: var(--space-6); margin: 0; }
.inquiry__row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6); }
.inquiry__field { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.inquiry__field .t-mono { color: var(--ink-secondary); }
.inquiry input[type="text"], .inquiry input[type="email"], .inquiry input[type="url"], .inquiry textarea {
  appearance: none; width: 100%; border: 1px solid var(--hairline-light); border-radius: 0; background: var(--paper-card); padding: 11px 12px;
  font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.02em; line-height: 1.4; color: var(--ink-primary); outline: 0;
  transition: border-color var(--dur-hover) var(--ease), box-shadow var(--dur-hover) var(--ease); }
.inquiry textarea { min-height: 168px; resize: none; line-height: 1.55; }
.inquiry ::placeholder { color: var(--ink-secondary); opacity: 0.75; }
.inquiry input:focus-visible, .inquiry textarea:focus-visible { border-color: var(--ink-primary); box-shadow: inset 0 -2px 0 var(--datum-red); }
.inquiry__kinds { border: 0; margin: 0; padding: 0; min-width: 0; }
.inquiry__kinds legend { padding: 0; margin-bottom: 10px; }
.inquiry__kinds > div { display: flex; flex-wrap: wrap; gap: 8px; }
.inquiry__kind { position: relative; display: inline-flex; }
.inquiry__kind input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.inquiry__kind span { display: inline-flex; align-items: center; gap: 9px; min-height: 40px; padding: 0 14px; border: 1px solid var(--hairline-light); background: var(--paper-card);
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em; color: var(--ink-secondary); transition: color var(--dur-hover) var(--ease), border-color var(--dur-hover) var(--ease); }
.inquiry__kind span::before { content: ""; width: 5px; height: 5px; box-shadow: inset 0 0 0 1px currentColor; }
.inquiry__kind input:checked + span { color: var(--ink-primary); border-color: var(--ink-primary); }
.inquiry__kind input:checked + span::before { background: var(--datum-red); box-shadow: none; }
.inquiry__kind input:focus-visible + span { outline: 1px solid var(--datum-red); outline-offset: 2px; }
/* the bar that sends it: a card on the board, the datum red along its top edge */
.inquiry__send { appearance: none; border: 0; border-radius: 0; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  width: 100%; min-height: 52px; padding: 0 18px; background: var(--paper-card); box-shadow: inset 0 2px 0 var(--datum-red), var(--shadow-card);
  font-family: var(--font-label); font-size: var(--type-label-size); font-weight: var(--type-label-weight); letter-spacing: var(--type-label-tracking); text-transform: uppercase; color: var(--ink-primary); }
.inquiry__send .t-mono { color: var(--ink-secondary); font-weight: 400; text-transform: none; letter-spacing: var(--type-mono-tracking); }
.inquiry__send:hover { box-shadow: inset 0 3px 0 var(--datum-red), var(--shadow-card); }
.inquiry__send:focus-visible { outline: 1px solid var(--datum-red); outline-offset: 3px; }
.inquiry__done { margin: 0; padding: 14px 16px; border-left: 2px solid var(--datum-red); background: var(--paper-card); }
@media (max-width: 720px) { .inquiry__row { grid-template-columns: 1fr; } }

/* ════════ The real process: component 35 (registered 2026-10-24, note 14) ════════ */
/* ——— 35. TryChain — one still from its raw state to the one we keep, every try between them, each marked as it ended:
   rejected (a red cross), kept but flagged (a red ring), accepted (the datum's square, and the datum along its edge).
   The marks sit on the paper under the pictures, never on them; a thread runs under the tries, turning red into the one
   kept. The record shows only the last verdict of each run, so a try before a retry is marked rejected and no reason is
   given for it. Laid into another component (a panorama, a card, a page of a PDF) the stills are .try-cells and their
   marks a .try-cells__marks row under them. ——— */
.try-chain { display: grid; grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); gap: var(--space-3); margin: 0; }
.try-chain__step { margin: 0; display: grid; gap: 8px; align-content: start; min-width: 0; }
/* the thread: one line under the tries, across the gaps, a tick at each try; red under the one kept */
.try-chain__step figcaption { position: relative; padding-top: 11px; }
.try-chain__step figcaption::before { content: ""; position: absolute; left: 0; right: calc(-1 * var(--space-3)); top: 0; height: 1px; background: var(--hairline-light); }
.try-chain__step:last-child figcaption::before { right: 0; }
.try-chain__step figcaption::after { content: ""; position: absolute; left: 0; top: 0; width: 1px; height: 5px; background: var(--hairline-light); }
.try-chain__step.is-accepted figcaption::before, .try-chain__step.is-flagged figcaption::before { background: var(--timeline-red); }
.try-chain__step.is-accepted figcaption::after, .try-chain__step.is-flagged figcaption::after { background: var(--datum-red); }
.try-chain__mark { display: inline-flex; align-items: center; gap: 8px; color: var(--ink-primary); font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; }
.try-chain__mark::before { content: ""; flex: none; width: 7px; height: 7px; }
.try-chain__step.is-input .try-chain__mark::before, .try-chain__mark.is-input::before { box-shadow: inset 0 0 0 1px var(--ink-secondary); }
.try-chain__step.is-rejected .try-chain__mark::before, .try-chain__mark.is-rejected::before { background: linear-gradient(45deg, transparent 44%, var(--datum-red) 44%, var(--datum-red) 58%, transparent 58%), linear-gradient(-45deg, transparent 44%, var(--datum-red) 44%, var(--datum-red) 58%, transparent 58%); }
.try-chain__step.is-flagged .try-chain__mark::before, .try-chain__mark.is-flagged::before { border-radius: 50%; box-shadow: inset 0 0 0 1.4px var(--datum-red); }
.try-chain__step.is-accepted .try-chain__mark::before, .try-chain__mark.is-accepted::before { background: var(--datum-red); }
.try-chain__step.is-accepted .film-aperture, .try-cell.is-accepted { outline: 1px solid var(--datum-red); outline-offset: -1px; }
.try-chain__step.is-flagged .film-aperture, .try-cell.is-flagged { box-shadow: 0 1px 0 var(--timeline-red); }
.try-chain__why { margin: 0; color: var(--ink-secondary); font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.02em; line-height: 1.4; }
.try-chain__head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-4); margin-bottom: var(--space-3); }
.try-chain-wrap + .try-chain-wrap { margin-top: var(--space-8); }
.paper-board-dark .try-chain__mark { color: var(--ink-on-dark); }
.paper-board-dark .try-chain__why { color: #8E949D; }
/* laid into another component: the stills in cells, the marks in a row of their own under them */
.try-cells { display: grid; grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); gap: 4px; }
.try-cell { position: relative; display: block; overflow: hidden; outline: 1px solid var(--hairline-light); background: #0B0A0A; }
.try-cell img { display: block; width: 100%; height: 100%; object-fit: cover; }
.try-cells__marks { display: grid; grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); gap: 4px; margin-top: 6px;
  background: linear-gradient(to right, var(--hairline-light) calc((100% + 4px) * (var(--n, 3) - 1) / var(--n, 3) - 4px), var(--timeline-red) 0) 0 0 / 100% 1px no-repeat; }
.try-cells__marks > * { padding-top: 9px; background: linear-gradient(var(--hairline-light), var(--hairline-light)) 0 0 / 1px 5px no-repeat; }
.try-cells__marks > :last-child { background-image: linear-gradient(var(--datum-red), var(--datum-red)); }
.try-cells__marks .try-chain__mark { font-size: 9px; gap: 6px; letter-spacing: 0.05em; }
.try-cells__marks .try-chain__mark::before { width: 6px; height: 6px; }
@media (max-width: 720px) { .try-chain { grid-template-columns: minmax(0, 1fr); } }

/* TryChain's detail (35, extended 2026-10-24, NOTES 17–18): a crop of a try, enlarged, under its words — what the check
   caught, readable at any size. It hangs under the thread, so the thread stays one line across the tries. */
.try-chain__detail { position: relative; display: grid; gap: 6px; padding-top: 12px; min-width: 0; }
.try-chain__detail::before { content: ""; position: absolute; left: 0; top: 0; width: 1px; height: 12px; background: var(--hairline-light); }   /* tethered to its try's words */
.try-chain__detail .film-aperture { outline: 1px solid var(--mark); outline-offset: -1px; }
.try-chain__detail p { margin: 0; font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-secondary); }
.paper-board-dark .try-chain__detail p { color: #8E949D; }
.try-catches { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-12) var(--space-8); align-items: start; }
.try-catches > .try-chain-wrap + .try-chain-wrap { margin-top: 0; }
.try-catches__key { display: grid; gap: var(--space-4); align-content: start; padding-top: 2px; }
.try-catches__marks { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; }
.try-catches__marks li { display: grid; grid-template-columns: 150px 1fr; gap: var(--space-3); align-items: baseline; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.02em; color: var(--ink-secondary); }
@media (max-width: 900px) { .try-catches { grid-template-columns: minmax(0, 1fr); } }

/* ════════ The process, drawn from the record: components 36–40 (registered 2026-10-24, NOTES 14–18) ════════
   One hand for all of them, from the system's tokens and line language only: the four roles' glyphs — ● analyse
   (Gemini), ○ generate (GPT Image, Midjourney), ■ plan (Blender, Direction), ◆ decide (a person) — dashed where the step
   is outside the logged model calls; the datum red line for the path that was kept; --mark for the drafting marks; the
   label and mono faces. The material is NEW-14-process as checked by eye (verified/): no verdict of a checker is drawn
   as a fact. Behaviour: process.js; with reduced motion every drawing stands, drawn. */
.pc { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-6); }
.pc-holder { width: 100%; min-width: 0; }
.pc-svg { display: block; overflow: visible; }
.pc-svg text { font-family: var(--font-mono); }
.pc-cap { font-size: 10px; letter-spacing: 0.06em; fill: var(--ink-secondary); }
.pc-lbl { font-size: 9.5px; letter-spacing: 0.02em; fill: var(--ink-primary); }
.pc-lbl.is-2, .pc-num { fill: var(--ink-secondary); }
.pc-num { font-size: 9.5px; letter-spacing: 0.04em; }
.pc-head { font-family: var(--font-label) !important; font-size: var(--type-label-size); font-weight: 600; letter-spacing: var(--type-label-tracking); fill: var(--ink-primary); }
.pc-big { font-family: var(--font-sans) !important; font-size: var(--type-title-size); font-weight: 500; letter-spacing: -0.02em; fill: var(--ink-primary); }
.pc-red { fill: var(--datum-red); }


/* the four roles */
.pc-glyph--analyse { fill: var(--ink-primary); }
.pc-glyph--generate { fill: var(--paper-card); stroke: var(--datum-red); stroke-width: 1.4; }
.pc-glyph--plan { fill: var(--ink-secondary); }
.pc-glyph--decide { fill: var(--datum-red); }
.pc-glyph.is-out { stroke-dasharray: 2 1.6; }   /* made outside the logged calls: Midjourney, Blender, a person */
.pc-glyph--plan.is-out, .pc-glyph--decide.is-out { stroke: none; }

/* lines and marks */
.pc-line { fill: none; stroke: var(--datum-red); stroke-width: 1.25; stroke-linejoin: round; stroke-linecap: round; }
.pc-line.is-off { stroke: var(--ink-secondary); stroke-opacity: 0.45; stroke-width: 1; }
.pc-line.is-thin { stroke-width: 1; }
.pc-mark { fill: none; stroke: var(--mark); stroke-width: 1; }
.pc-mark.is-dot { stroke-dasharray: 1 3; }
.pc-rule { stroke: var(--hairline-light); stroke-width: 1; }
.pc-tick { fill: var(--ink-primary); }
.paper-board-dark .pc-rule { stroke: var(--hairline-dark); }
.paper-board-dark .pc-tick { fill: #8E949D; }
.pc-frame { fill: none; stroke: var(--hairline-light); stroke-width: 1; }
.pc-frame.is-on { stroke: var(--datum-red); stroke-width: 1.5; }
.pc-x { stroke: var(--datum-red); stroke-width: 1.4; }

.pc-off { opacity: 0.78; }
.pc-off image { filter: grayscale(0.35); }
.pc-bar--g { fill: var(--datum-red); }
.pc-bar--a { fill: var(--ink-primary); fill-opacity: 0.72; }
.pc-tick--g { stroke: var(--datum-red); stroke-width: 1; }
.pc-tick--a { stroke: var(--ink-primary); stroke-width: 1; stroke-opacity: 0.7; }
.pc-fade { transition: opacity 360ms var(--ease); }


/* on the dark board */
.paper-board-dark .pc-lbl, .paper-board-dark .pc-head, .paper-board-dark .pc-big { fill: var(--ink-on-dark); }
.paper-board-dark .pc-cap, .paper-board-dark .pc-num, .paper-board-dark .pc-lbl.is-2 { fill: #8E949D; }
.paper-board-dark .pc-tick--g { stroke: var(--laser-red-dark); }
.paper-board-dark .pc-tick--a { stroke: var(--ink-on-dark); stroke-opacity: 0.55; }
.paper-board-dark .pc-mark { stroke: rgba(236, 239, 244, 0.30); }
.paper-board-dark .pc-red { fill: var(--laser-red-dark); }

.paper-board-dark .pc-glyph--analyse { fill: var(--ink-on-dark); }
.paper-board-dark .pc-glyph--generate { fill: var(--paper-dark); stroke: var(--laser-red-dark); }
.paper-board-dark .pc-k--generate { box-shadow: inset 0 0 0 1.4px var(--laser-red-dark); }

/* the key, and the controls */
.pc-legend { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-6); color: var(--ink-secondary); }
.pc-legend span { display: inline-flex; align-items: center; gap: 8px; }
.pc-k { display: inline-block; flex: none; width: 7px; height: 7px; }
.pc-k--analyse { background: var(--ink-primary); border-radius: 50%; }
.pc-k--generate { box-shadow: inset 0 0 0 1.4px var(--datum-red); border-radius: 50%; }
.pc-k--plan { background: var(--ink-secondary); }
.pc-k--decide { background: var(--datum-red); transform: rotate(45deg) scale(0.86); }
.paper-board-dark .pc-legend { color: #8E949D; }
.paper-board-dark .pc-k--analyse { background: var(--ink-on-dark); }
.pc-honest { max-width: 72ch; margin: 0; color: var(--ink-secondary); font-family: var(--font-sans); font-size: var(--type-card-body-size); line-height: var(--type-card-body-leading); letter-spacing: 0; }
.pc-legend svg { display: block; flex: none; overflow: visible; }
.pc-honest b { color: var(--ink-primary); font-weight: 400; }
.paper-board-dark .pc-honest b { color: var(--ink-on-dark); }
.pc-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-4); }

/* ——— 36. ProcessTree — the tree of one frame: the real images behind shot 1.11, in columns by stage; the line to the
   frame in the film red, the tries that went nowhere grey (a cross only where a check rejected one), the director's pick
   the ◆. With [data-fold] it opens on the belief — A, one call, B — and unfolds into the tree. ——— */
.pc-tree__foot { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-3) var(--space-8); }

/* ——— 37. ProcessScore — the same steps as a score: a staff per role, the line moving between them; a try and its check
   sound together as a chord; the images hang under the steps that made them. ——— */

/* ——— 38. CallRing — every logged model call of the four days the pipeline was developed in, round a ring of its days:
   generate outward in the red, analyse inward in ink. The research behind the method — never the cost of a film, and
   never set beside a film's running time. On the dark board. ——— */

/* ——— 39. HexTrace — a world's palette at work, in five columns: the palette; its hexes in the Midjourney prompt; what
   came back, as the colour agent read it; the colours pulled to the palette; the still accepted. ——— */
.hex-trace { display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.25fr) minmax(0, 1.45fr) minmax(0, 0.9fr) minmax(0, 1.45fr); gap: var(--space-6) var(--space-4); align-items: start; }
.hex-trace__col { display: grid; gap: 10px; align-content: start; min-width: 0; }
.hex-trace__head { display: grid; gap: 2px; min-height: 52px; align-content: start; padding-top: 8px; border-top: 1px solid var(--hairline-light); }
.hex-trace__head .t-mono { color: var(--ink-secondary); }
.hex-trace__clause { margin: 0; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.01em; line-height: 1.55; color: var(--ink-primary); }
.hex-trace__hex { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.hex-trace__hex i { display: inline-block; flex: none; width: 10px; height: 10px; box-shadow: inset 0 0 0 1px rgba(22, 23, 23, 0.12); }
.hex-trace__table { display: grid; gap: 8px; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.02em; color: var(--ink-primary); }
.hex-trace__read { display: grid; gap: 2px; }
.hex-trace__read > span:last-child { color: var(--ink-secondary); }
.hex-trace__pull { display: grid; grid-template-columns: auto 18px auto; gap: 6px; align-items: center; font-family: var(--font-mono); font-size: 10px; white-space: nowrap; }
.hex-trace__arrow { width: 18px; height: 1px; background: var(--datum-red); position: relative; }
.hex-trace__arrow::after { content: ""; position: absolute; right: -1px; top: -1px; width: 3px; height: 3px; background: var(--datum-red); }
.hex-trace__off { margin: 0; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; color: var(--datum-red); }
.hex-trace__labels { display: grid; grid-template-columns: auto 1fr auto; gap: 4px 8px; margin-top: 6px; font-size: 10px; color: var(--ink-secondary); white-space: nowrap; }
.hex-trace__labels b { font-weight: 400; color: var(--ink-primary); }
.hex-trace + .pc-honest { margin-top: var(--space-8); }
@media (max-width: 900px) { .hex-trace { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
@media (max-width: 720px) { .hex-trace { grid-template-columns: minmax(0, 1fr); } }

/* ——— 40. ClaimCheck — the checker checked: a frame a checking agent described wrongly, its words quoted once and
   marked false, the details that show what is there, and the person who decided. The agents are models too. ——— */
.claim-check { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--space-6) var(--space-12); align-items: start; margin: 0; }
.claim-check__pics { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-3); }
.claim-check__pics > .film-aperture { grid-column: 1 / -1; }
.claim-check__detail { display: grid; gap: 6px; min-width: 0; }
.claim-check__detail .film-aperture { outline: 1px solid var(--mark); outline-offset: -1px; }
.claim-check__detail p { margin: 0; font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-secondary); }
.claim-check__say { display: flex; flex-direction: column; gap: var(--space-4); }
.claim-check__claim { display: grid; grid-template-columns: 7px 1fr; gap: 12px; align-items: baseline; margin: 0; font-family: var(--font-serif); font-style: italic; font-size: var(--type-card-serif-size); line-height: 1.35; color: var(--ink-secondary); }
.claim-check__claim q { quotes: "“" "”"; }
.claim-check__claim { padding-bottom: var(--space-4); border-bottom: 1px solid var(--hairline-light); }
.claim-check__claim .try-chain__mark { transform: translateY(-2px); }
.claim-check__loci { position: relative; grid-column: 1 / -1; height: 20px; margin-top: calc(var(--space-3) * -1); }
.claim-check__loci span { position: absolute; top: 0; transform: translateX(-50%); padding-top: 8px; font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.06em; color: var(--datum-red); }
.claim-check__loci span::before { content: ""; position: absolute; left: 50%; top: 0; width: 1px; height: 6px; background: var(--datum-red); }
.claim-check__spec { grid-template-columns: 24px 1fr; }
.claim-check__spec dt:last-of-type { color: var(--datum-red); }
@media (max-width: 900px) { .claim-check { grid-template-columns: minmax(0, 1fr); } }

/* ——— CornerIndex, the record under the card (25, extended 2026-10-24 — note 14's 4B): the card carries a FoldCorner,
   "The edge"; turned, the card lifts aside and the record under it shows — the years before the studio. ——— */
.corner-index__stack { grid-column: 2; grid-row: 2; align-self: start; justify-self: start; position: relative; width: min(400px, 92%); }
.corner-index__stack > .corner-index__card { width: 100%; position: relative; z-index: 2; transition: transform 700ms var(--ease), box-shadow 700ms var(--ease); }
.corner-index__record { position: absolute; inset: 0; z-index: 1; padding: 28px 28px 24px 44px; display: flex; flex-direction: column; gap: var(--space-4); opacity: 0; transition: opacity 420ms var(--ease) 200ms; }
.corner-index__stack.is-open .corner-index__record { opacity: 1; }
/* lifted, it still overlaps the record it came off, and casts the deeper shadow of a sheet held up */
.corner-index__stack.is-open > .corner-index__card { transform: translate(calc(-100% + 28px), -12px) rotate(-1.8deg); box-shadow: var(--shadow-board-light); }
.corner-index__stack.is-open .fold { --f: 48px; }
.corner-index__card.has-fold { padding-bottom: 104px; }
.corner-index__card .fold { --f: 84px; right: 0; bottom: 0; }
.corner-index__card .fold:hover, .corner-index__card .fold:focus-visible { --f: 92px; }
@media (max-width: 720px) {
  .corner-index__stack { grid-column: 1; grid-row: auto; width: auto; margin: 0 var(--wall-margin-x); display: flex; flex-direction: column; }
  .corner-index__record { position: relative; inset: auto; display: none; margin-top: var(--space-4); order: 2; }
  .corner-index__stack.is-open .corner-index__record { display: flex; }
  .corner-index__stack.is-open > .corner-index__card { transform: none; }
}
@media (prefers-reduced-motion: reduce) { .corner-index__stack > .corner-index__card, .corner-index__record { transition: none; } }

/* ——— 41. SystemRebuild — note 14's 4A, as the director asked it (NOTES 18): the shape of a bank's multi-agent system,
   agents in clusters round their hubs, a person who approves and a record, turns in depth as the page scrolls and builds
   itself again into the studio's creative system — the same kind of structure, now directing a film. True perspective,
   drawn in SVG by rebuild.js, so the lines stay hairlines and the datum red. The section is the scroll's runway; the
   pin holds the stage. Without motion the two diagrams stand side by side. ——— */
.rebuild { position: relative; }
.rebuild__pin { display: grid; gap: var(--space-6); }
.rebuild__heads, .rebuild__says { display: grid; }
.rebuild__heads > *, .rebuild__says > * { grid-area: 1 / 1; margin: 0; }
.rebuild__heads > * { color: var(--ink-secondary); }
.rebuild__stage { display: block; width: 100%; overflow: visible; }
.rebuild__grid { stroke: var(--mark); stroke-width: 0.6; stroke-dasharray: 1 4; }
.rebuild__per { stroke: var(--mark); stroke-width: 0.8; }
.rebuild__halo { fill: var(--paper-board); }
.rebuild__back { stroke-dasharray: 3 3; }
.rebuild__plumb { stroke: var(--hairline-light); stroke-width: 0.75; stroke-dasharray: 2 2; }
.rebuild__foot-tick { fill: var(--ink-secondary); }
.rebuild__flow { stroke-width: 1.5; }

.rebuild__label { letter-spacing: 0.06em; }
.rebuild__label.is-red { fill: var(--datum-red); }
.rebuild__foot { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--space-6) var(--space-12); align-items: end; }
.rebuild__scale { position: relative; display: flex; justify-content: space-between; padding-top: 14px; color: var(--ink-secondary);
  background: linear-gradient(var(--timeline-red), var(--timeline-red)) 0 4px / calc(var(--p, 0) * 100%) 1px no-repeat,
              linear-gradient(var(--ink-secondary), var(--ink-secondary)) 0 4px / 100% 1px no-repeat; }
.rebuild__scale::before, .rebuild__scale::after { content: ""; position: absolute; top: 2px; width: 1px; height: 5px; background: var(--ink-primary); }
.rebuild__scale::before { left: 0; } .rebuild__scale::after { right: 0; }
.rebuild__tick { position: absolute; top: 0; left: calc(var(--p, 0) * (100% - 9px)); width: 9px; height: 9px; background: var(--datum-red); transform: rotate(45deg) scale(0.78); }
.rebuild__stills { display: none; }
.rebuild.is-still .rebuild__stage, .rebuild.is-still .rebuild__heads, .rebuild.is-still .rebuild__foot { display: none; }
.rebuild.is-still .rebuild__stills { display: grid; grid-template-columns: minmax(0, 1fr) 2px minmax(0, 1fr); gap: var(--space-8); align-items: start; }
.rebuild__stills figure { margin: 0; display: grid; gap: var(--space-4); }
.rebuild__stills .rebuild__datum { align-self: stretch; background: var(--datum-red); }
.rebuild__still { display: block; width: 100%; overflow: visible; }
html.motion .rebuild:not(.is-still):not(.is-manual) { height: 240vh; }
html.motion .rebuild:not(.is-still):not(.is-manual) .rebuild__pin { position: sticky; top: max(16px, calc(50vh - 380px)); }
.rebuild__range { width: 100%; margin: 0; accent-color: var(--datum-red); }   /* .is-manual: a range in place of the scroll */
@media (max-width: 900px) {
  .rebuild__foot { grid-template-columns: minmax(0, 1fr); }
  .rebuild.is-still .rebuild__stills { grid-template-columns: minmax(0, 1fr); }
  .rebuild__stills .rebuild__datum { height: 2px; }
  html.motion .rebuild:not(.is-still):not(.is-manual) { height: 200vh; }
}

/* ——— 42. AgentMark — every agent's own mark (NOTES 21–22): the role sets the shape (● analyse · Gemini, ○ generate ·
   GPT Image, ■ plan, ◆ decide), the stage sets the sign in it or round it; outside the logged calls, the ring dashed.
   On the disc and the square the sign is cut in the paper; on the ring it is drawn in the red. Names only, never what
   an agent looks for. Drawn by agents.js. ——— */
.ag-holder { position: relative; }
.ag-mark--analyse .ag-base { fill: var(--ink-primary); }
.ag-mark--analyse .ag-sign, .ag-mark--plan .ag-sign { fill: none; stroke: var(--paper-board); stroke-width: 1.5; }   /* a cut in ink closes up: wider than the red line */
.ag-mark--analyse .ag-dot, .ag-mark--plan .ag-dot { fill: var(--paper-board); }
.ag-mark--analyse .ag-tick { stroke: var(--ink-primary); stroke-width: 1; }
.ag-mark--generate .ag-base { fill: var(--paper-card); stroke: var(--datum-red); stroke-width: 1.4; }
.ag-mark--generate .ag-sign { fill: none; stroke: var(--datum-red); stroke-width: 1.2; }
.ag-mark--generate .ag-dot { fill: var(--datum-red); }
.ag-mark--generate .ag-tick { stroke: var(--datum-red); stroke-width: 1; }
.ag-mark--generate.is-out .ag-base { stroke-dasharray: 2 1.6; }
.ag-mark--plan .ag-base { fill: var(--ink-secondary); }
.ag-mark--decide .ag-base { fill: var(--datum-red); }
.ag-cut { fill: var(--paper-board); }
.ag-film { fill: var(--datum-red); }
.ag-entry, .ag-beat { transition: opacity 240ms var(--ease); }
.ag-entry .ag-mark { transform-box: fill-box; transform-origin: center; transition: transform 200ms var(--ease); }
.ag-entry.is-now .ag-mark { transform: scale(1.35); }   /* the agent at work, for a beat */
.ag-entry.is-dim, .ag-beat.is-dim { opacity: 0.26; }
.ag-beat:focus { outline: none; }
.ag-beat:focus-visible .ag-base { stroke: var(--ink-primary); stroke-width: 1.6; }
.paper-board-dark .ag-mark--analyse .ag-base { fill: var(--ink-on-dark); }
.paper-board-dark .ag-mark--analyse .ag-sign, .paper-board-dark .ag-mark--plan .ag-sign { stroke: var(--paper-dark); }
.paper-board-dark .ag-mark--analyse .ag-dot, .paper-board-dark .ag-mark--plan .ag-dot, .paper-board-dark .ag-cut { fill: var(--paper-dark); }
.paper-board-dark .ag-mark--analyse .ag-tick { stroke: var(--ink-on-dark); }
.paper-board-dark .ag-mark--generate .ag-base { fill: var(--paper-dark); stroke: var(--laser-red-dark); }
.paper-board-dark .ag-mark--generate .ag-sign, .paper-board-dark .ag-mark--generate .ag-tick { stroke: var(--laser-red-dark); }
.paper-board-dark .ag-mark--generate .ag-dot, .paper-board-dark .ag-mark--decide .ag-base, .paper-board-dark .ag-film { fill: var(--laser-red-dark); }

/* ——— 43. AgentThread — one real sequence on one thread: shot 1.11's keyframe, call by call, to the director's pick.
   An agent is named where it first works and known by its mark after; two at once stand as a chord across the thread.
   On a phone the thread runs down the page. [data-compact]: the thread and one line of names, for the home. ——— */
.ag-bracket { fill: none; }   /* a step of the frame, bracketed under the thread as a drawing brackets a span */
.ag + .pc-honest, .ag .pc-honest { margin-top: var(--space-6); }
.ag .pc-legend { margin-top: var(--space-6); }

/* ——— 44. AgentIcons — who is at work, by eye (registered 2026-11-01; the director chose the instruments): the next form
   of AgentMark's family, the system's second glyph family. Three families, from the roster (TMSimple.family): our
   agents are instruments in ink — the lens analyses, the nib lays its red line (it generates), the set square plans,
   each with its stage's sign engraved in it; a tool outside our system is a mounted plate, one dashed rim (the sign
   for outside the log) and mono initials, in the drafting grey; the person is the one red scale figure. Lines are
   drafting marks: 1px, the instrument's rim 1.15–1.4px. No glow, no shadow, radius 0. AgentMark 42's dots stay
   registered for dense, compact threads (43, the home's thread). Drawn by agent-icons.js; .is-in draws an icon in,
   .is-live is one beat of its work; nothing moves under reduced motion. Names only. ——— */
.ii-host { overflow: visible; }

/* the strokes */
.ii .ii-rim { fill: none; stroke: var(--ink-primary); stroke-width: 1.15; stroke-linejoin: miter; }
.ii.is-big .ii-rim { stroke-width: 1.4; }
.ii .ii-line { fill: none; stroke: var(--ink-primary); stroke-width: 1; stroke-linecap: butt; }
.ii.is-big .ii-line { stroke-width: 1.2; }
.ii .ii-hair, .ii .ii-cut { fill: none; stroke: var(--ink-primary); stroke-width: 1; }
.ii .ii-cut { stroke-width: 0.9; }
.ii .ii-faint { stroke: var(--ink-secondary); }
.ii .ii-cross { fill: none; stroke: var(--ink-primary); stroke-width: 1; }
.ii .ii-hand { fill: none; stroke: var(--ink-primary); stroke-width: 1; stroke-linecap: butt; }
.ii.is-big .ii-hand { stroke-width: 1.4; }
.ii .ii-slit { fill: none; stroke: var(--ink-primary); stroke-width: 0.9; }
.ii .ii-ink { fill: var(--ink-primary); }
.ii .ii-glass, .ii .ii-blank { fill: var(--paper-card); }

/* generate: the line it lays, in the thread's red */
.ii .ii-trail { fill: none; stroke: var(--timeline-red); stroke-width: 1.4; stroke-linecap: butt; }
.ii:not(.is-big) .ii-trail { stroke: var(--datum-red); stroke-width: 1.5; }   /* at the sheet's size the made line must carry */
.ii .ii-point { fill: var(--datum-red); }

/* plan: the set square's cut, dashed — outside the logged calls */
.ii .ii-cutout { fill: var(--paper-board); stroke: var(--ink-primary); stroke-width: 1; stroke-dasharray: 2 1.6; }
.ii.is-small .ii-cutout { stroke-dasharray: 1.6 1.2; }

/* two analysts at once: the facing sight marks give way to the bridge between them */
.ii.is-pair-l .ii-s90, .ii.is-pair-r .ii-s270 { display: none; }

/* the analyst's reading sweep: seen only at work */
.ii .ii-scan { fill: none; stroke: var(--timeline-red); stroke-width: 1.4; stroke-dasharray: 0.16 0.84; stroke-dashoffset: 0; opacity: 0; }

/* tools: the mounted plate, in the drafting grey — its one rim dashed, outside our system */
.ii .ii-plate { fill: var(--paper-card); }
.ii .ii-plate-rim { fill: none; stroke: var(--ink-secondary); stroke-width: 1; stroke-dasharray: 2.4 1.6; }
.ii.is-big .ii-plate-rim { stroke-dasharray: 3 2; }
.ii .ii-mark { fill: none; stroke: var(--ink-secondary); stroke-width: 1; opacity: 0.75; }
.ii .ii-init { fill: var(--ink-secondary); font-family: var(--font-mono); font-weight: 600; letter-spacing: -0.02em; }
.ii.is-big .ii-init { font-weight: 500; letter-spacing: 0.08em; }
.ii:not(.is-big) .ii-init { fill: var(--ink-primary); }   /* at the sheet's size the initials are stamped in ink; the plate stays grey */

/* the person */
.ii .ii-red { fill: var(--datum-red); }
.ii .ii-ground { stroke: var(--ink-primary); }
.ii .ii-pick { fill: none; stroke: var(--datum-red); stroke-width: 1.5; opacity: 0; }

/* ——— motion: slow and physical, never under reduced motion ——— */
@media (prefers-reduced-motion: no-preference) {
  /* drawn in: the lines laid one after another, the fills set after them */
  .ii.is-in .ii-d { stroke-dasharray: 1 1; animation: ii-lay 820ms var(--ease) both; animation-delay: calc(var(--ii-i, 0) * 60ms); }
  .ii.is-in .ii-f, .ii.is-in .ii-glass, .ii.is-in .ii-blank, .ii.is-in .ii-plate, .ii.is-in .ii-cutout, .ii.is-in .ii-fd {
    animation: ii-set 520ms var(--ease) both; animation-delay: calc(var(--ii-i, 0) * 60ms + 240ms); }
  .ii.is-in .ii-trail { stroke-dasharray: 1 1; animation: ii-lay 820ms var(--ease) both; animation-delay: calc(var(--ii-i, 0) * 60ms + 200ms); }

  /* at work, for a beat */
  .ii--analyse.is-live .ii-scan { animation: ii-sweep 1500ms var(--ease) both; }
  .ii--analyse.is-live .ii-sight { transform-box: view-box; transform-origin: 0 0; animation: ii-turn 1500ms var(--ease) both; }
  .ii--analyse.is-live .ii-core { transform-box: view-box; transform-origin: 0 0; animation: ii-focus 1500ms var(--ease) both; }
  .ii--generate.is-live .ii-trail { stroke-dasharray: 1 1; animation: ii-lay 1400ms var(--ease) both; }
  .ii--generate.is-live .ii-pen { animation: ii-run 1400ms var(--ease) both; }
  .ii--plan.is-live .ii-sq { transform-box: view-box; animation: ii-swing 1500ms var(--ease) both; }
  .ii--tool.is-live .ii-corner { animation: ii-register 1300ms var(--ease) both; }
  .ii--tool.is-live .ii-plate-rim { animation: ii-march 1300ms var(--ease) both; }   /* the dashes run once round: mounted, registered */
  .ii--person.is-live .ii-pick { stroke-dasharray: 1 1; animation: ii-pick 1300ms var(--ease) both; }
}
/* reduced motion: at work is still told, standing — the sweep and the pick drawn, nothing moving */
@media (prefers-reduced-motion: reduce) {
  .ii.is-live .ii-scan { opacity: 1; }
  .ii.is-live .ii-pick { opacity: 1; }
}

@keyframes ii-lay { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes ii-march { from { stroke-dashoffset: 0; } to { stroke-dashoffset: -12; } }
@keyframes ii-set { from { opacity: 0; } to { opacity: 1; } }
@keyframes ii-sweep { 0% { opacity: 0; stroke-dashoffset: 0; } 12% { opacity: 1; } 85% { opacity: 1; } 100% { opacity: 0; stroke-dashoffset: -1; } }
@keyframes ii-turn { 0% { transform: rotate(0deg); } 55% { transform: rotate(45deg); } 100% { transform: rotate(90deg); } }
@keyframes ii-focus { 0% { transform: scale(1); } 45% { transform: scale(0.78); } 100% { transform: scale(1); } }
@keyframes ii-run { from { transform: translateX(var(--ii-run, -8px)); } to { transform: none; } }
@keyframes ii-swing { 0% { transform: rotate(-14deg); } 100% { transform: none; } }
@keyframes ii-register { 0% { transform: none; } 45% { transform: translate(var(--ii-cx, 0), var(--ii-cy, 0)); } 100% { transform: none; } }
@keyframes ii-pick { 0% { opacity: 1; stroke-dashoffset: 1; } 60% { opacity: 1; stroke-dashoffset: 0; } 100% { opacity: 1; stroke-dashoffset: 0; } }

/* the specimen, [data-agent-icons="key"]: the three families at the engraving's size, then the roster by stage —
   each stage under a tick label, each agent its icon and its name, as AgentMark's key gives it (names only) */
.ii-key__svg { display: block; overflow: visible; flex: none; }
.ii-fams { display: grid; grid-template-columns: minmax(0, 2.6fr) minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-8) clamp(24px, 4%, 64px); align-items: start; }   /* every icon box is the same size: their tops line up, a longer key line only runs down */
.ii-fam { min-width: 0; }
.ii-fam__icons { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-4) var(--space-6); }   /* the three instruments on one line beside the plate and the figure */
.ii-fam__cell { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.ii-fam__cap { color: var(--ink-secondary); text-transform: uppercase; white-space: nowrap; }
/* the family's lane across its column, 45's line types: continuous ink for our agents, dashed grey for a tool, datum red
   for the person */
.ii-fam__lane { position: relative; display: block; height: 0; margin-top: var(--space-4); color: var(--ink-primary); border-top: 1px solid currentColor; }
.ii-fam__lane::before, .ii-fam__lane::after { content: ""; position: absolute; top: -3px; width: 1px; height: 5px; background: currentColor; }   /* it ends on ticks, as a dimension does (REF-07) */
.ii-fam__lane::before { left: 0; } .ii-fam__lane::after { right: 0; }
.ii-fam--tool .ii-fam__lane { color: var(--ink-secondary); border-top-style: dashed; }
.ii-fam--person .ii-fam__lane { color: var(--datum-red); border-top-width: 1.5px; }
.ii-fam--person .ii-fam__lane::before, .ii-fam--person .ii-fam__lane::after { top: -3.25px; }
.ii-fam__t { margin: var(--space-4) 0 4px; }
.ii-fam__k { color: var(--ink-secondary); text-transform: uppercase; }
.ii-roster { display: grid; gap: var(--space-8); margin-top: var(--space-16); }
.ii-stage { display: grid; grid-template-columns: 168px minmax(0, 1fr); gap: var(--space-4) var(--space-6); align-items: start; }
.ii-stage__t { margin: 0; color: var(--ink-primary); text-transform: uppercase; }
.ii-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(176px, 1fr)); gap: var(--space-4); }
.ii-ag { display: flex; align-items: center; gap: 8px; min-width: 0; }
.ii-ag__n { color: var(--ink-primary); line-height: 1.3; }
.ii-ag--tool .ii-ag__n { color: var(--ink-secondary); }
@media (max-width: 760px) {
  .ii-fams { grid-template-columns: minmax(0, 1fr); }
  .ii-fam__icons { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); }   /* the three instruments side by side, as 45's key on a phone */
  .ii-fam__cap { white-space: normal; line-height: 1.4; }
  .ii-stage { grid-template-columns: minmax(0, 1fr); }
  .ii-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ——— 45. DraftingSheet — THE MAIN WAY to show "you think it's simple": one finished frame as the main view of a CAD
   sheet, the steps drawn out of it one by one along five acts — a timeline-red thread from the frame's lower edge,
   each step a node hung from its act's dimension line (the gantry, REF-07) — and the thread closing back into the
   frame, whose aperture turns red. Who is at work heads every step (44), with the step's lane in its family's line
   type: continuous ink, dashed grey, datum red. The title block is the spec grid in brackets. ≥1200px with motion the
   sheet holds (.sb-is-pin) while the scroll draws it; under 1200px one vertical thread, drawn as each step enters
   (.sb-is-enter); reduced motion: the whole sheet stands drawn. Behaviour: sheet.js, on section[data-drafting-sheet].
   Every class is the sheet's own layout (sb-, and sp- for a step's row of icons); colours, lines and type are tokens
   and registered classes (film-aperture, dim, spec, brackets, palette-bar, hex-trace, try-chain__mark, copy-slot). ——— */
.sp-marks { display: block; overflow: visible; flex: none; }   /* a step's agents as icons, side by side (TMSimple.marks) */

.sb-run { position: relative; }
.sb-sheet { position: relative; }
.sb-lines { position: absolute; left: 0; top: 0; overflow: visible; pointer-events: none; }
.sb-thread { fill: none; stroke: var(--timeline-red); stroke-width: 1; }
.sb-hang { fill: none; stroke: var(--mark); stroke-width: 1; }
.sb-dot { fill: none; stroke: var(--ink-secondary); stroke-width: 1; stroke-dasharray: 1 2; }
.sb-node { fill: var(--datum-red); }
.sb-tick { fill: var(--ink-primary); }
.sb-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ——— the belief: the naive line, one call drawn into the frame ——— */
.sb-naive__in { position: relative; }
.sb-naive__line { margin: 0; }
.sb-naive__line .copy-slot { display: block; font-family: var(--font-sans); font-size: var(--type-title-size); letter-spacing: var(--type-title-tracking); line-height: var(--type-title-leading); color: var(--ink-secondary); }
.sb-one { position: relative; height: 22px; margin-top: var(--space-6); }
.sb-one__mark { display: block; overflow: visible; position: relative; z-index: 1; }
.sb-one__lead { display: none; }
.sb-one__cap { margin: 6px 0 0; }
.sb-count { display: flex; align-items: baseline; gap: 8px; margin: var(--space-6) 0 0; }
.sb-count__n { color: var(--ink-primary); font-size: var(--type-mono-size); }

/* ——— the main view ——— */
.sb-main { margin: 0; }
.sb-main__dim { margin-bottom: 10px; }
.sb-main__ap { transition: outline-color 600ms var(--ease); }
.sb-main__ap.is-closed { outline-color: var(--datum-red); }

/* ——— the acts and their steps ——— */
.sb-acts { list-style: none; margin: 0; padding: 0; }
.sb-steps { list-style: none; margin: 0; padding: 0; }
.sb-step { position: relative; min-width: 0; }
.sb-zone { min-width: 0; }
.sb-zone__in { display: grid; gap: 4px; min-width: 0; }
.sb-ap { width: 100%; }
.sb-ap.is-on { outline: 1px solid var(--datum-red); outline-offset: -1px; }
.sb-ap.is-off { opacity: 0.78; }
.sb-ap > video { pointer-events: none; }
.sb-pics { display: grid; grid-template-columns: repeat(var(--k, 1), minmax(0, 1fr)); gap: 4px; }
.sb-txt { min-width: 0; }
/* the head: who is at work — the icons, then the number on the step's lane. The lane takes the family's line type, as
   a drawing's legend gives its lines: continuous ink for our agents, dashed grey for a tool outside our system (the
   system's own sign for outside the log), datum red for the person. The number takes the family's value. */
.sb-id { display: flex; align-items: center; gap: 8px; margin: 0 0 4px; }
.sb-id .sp-marks { flex: none; }
.sb-num { color: var(--ink-primary); line-height: 1; }
.sb-fam--tool .sb-num { color: var(--ink-secondary); }
.sb-fam--person .sb-num { color: var(--datum-red); }
.sb-rule { position: relative; display: block; flex: 1 1 auto; min-width: 12px; height: 0; color: var(--ink-primary); border-top: 1px solid currentColor; }
.sb-rule::after { content: ""; position: absolute; right: 0; top: -3px; width: 1px; height: 5px; background: currentColor; }   /* the lane ends on a tick, as a dimension does (REF-07) */
.sb-fam--tool .sb-rule { color: var(--ink-secondary); border-top-style: dashed; }
.sb-fam--person .sb-rule { color: var(--datum-red); border-top-width: 1.5px; }
.sb-fam--person .sb-rule::after { top: -3.25px; }
.sb-fam { flex: none; color: var(--ink-primary); font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; white-space: nowrap; line-height: 1; }
.sb-fam--tool .sb-fam { color: var(--ink-secondary); }
.sb-fam--person .sb-fam { color: var(--datum-red); }
@media (prefers-reduced-motion: no-preference) {
  /* the lane is ruled after the icon is drawn, left to right, as the pen reaches the step */
  .sb-is-pin .sb-step .sb-rule, .sb-is-enter .sb-step .sb-rule { transform: scaleX(0); transform-origin: 0 50%; transition: transform 900ms var(--ease) 360ms; }
  .sb-is-enter .sb-step .sb-rule { transition-duration: 640ms; transition-delay: 140ms; }   /* down one thread: ruled as the step enters, before its icon works */
  .sb-is-pin .sb-step.is-woke .sb-rule, .sb-is-enter .sb-step.is-woke .sb-rule { transform: none; }
}

/* the key of the three families: on the sheet beside the title block, and in the intro */
.sb-sheet > .sb-key { border-top: 1px solid var(--hairline-light); padding-top: 10px; }
.sb-key__t { margin: 0 0 8px; color: var(--ink-secondary); font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; }
.sb-key__fam { display: grid; grid-template-columns: 86px 22px minmax(0, 1fr); align-items: center; column-gap: 8px; min-height: 28px; }
.sb-key__icons { display: flex; align-items: center; gap: 6px; }
.sb-key__cell { display: flex; flex-direction: column; align-items: flex-start; }
.sb-key__svg { display: block; overflow: visible; margin: -2px -2px; }
.sb-key__name { margin: 0; color: var(--ink-primary); font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase; line-height: 1.35; }
.sb-key .sb-rule { flex: none; width: 100%; min-width: 0; }
.sb-key--intro { display: grid; grid-template-columns: minmax(0, 2.3fr) minmax(0, 1fr) minmax(0, 1fr); margin-top: var(--space-8); border-top: 1px solid var(--hairline-light); border-bottom: 1px solid var(--hairline-light); }
.sb-key--intro > p { margin: 0; padding: 14px 0; }
.sb-key--intro .sb-key__fam { display: flex; flex-direction: column; align-items: stretch; gap: 0; padding: 18px 20px 18px 0; min-width: 0; }
.sb-key--intro .sb-key__fam + .sb-key__fam { border-left: 1px solid var(--hairline-light); padding-left: 20px; }
.sb-key--intro .sb-key__icons { gap: 26px; align-items: flex-end; flex-wrap: wrap; }
.sb-key--intro .sb-key__svg { margin: 0 0 0 -4px; }
.sb-key--intro .sb-key__cap { margin-top: 6px; color: var(--ink-secondary); font-size: 9.5px; letter-spacing: 0.08em; text-transform: uppercase; white-space: nowrap; }
.sb-key--intro .sb-rule { margin: 14px 0 12px; }
.sb-key--intro .sb-key__name { font-size: 10.5px; letter-spacing: 0.1em; }
.sb-key__note { margin: 4px 0 0; color: var(--ink-secondary); font-family: var(--font-mono); font-size: 10.5px; line-height: 1.5; max-width: 46ch; }
@media (max-width: 860px) {
  .sb-key--intro { grid-template-columns: 1fr; }
  .sb-key--intro .sb-key__fam { padding: 16px 0; }
  .sb-key--intro .sb-key__fam + .sb-key__fam { border-left: 0; border-top: 1px solid var(--hairline-light); padding-left: 0; }
  .sb-key--intro .sb-key__icons { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; align-items: end; }
  .sb-key--intro .sb-key__cap { white-space: normal; line-height: 1.4; }
}

/* the belief's one call: on the sheet a nib laying its line into the frame; down one thread the system's ring */
.sb-one__nib { display: none; }
@media (min-width: 1200px) {
  .sb-has-nib .sb-one__nib { display: inline; }
  .sb-has-nib .sb-one__ring { display: none; }
}
.sb-lbl { margin: 0; color: var(--ink-primary); font-size: 10px; letter-spacing: 0.02em; line-height: 1.38; }
.sb-who { margin: 3px 0 0; color: var(--ink-secondary); font-size: 10px; letter-spacing: 0.02em; line-height: 1.38; }
.sb-who--fresh { display: none; }
.sb-note { margin: 3px 0 0; color: var(--ink-secondary); font-size: 9px; letter-spacing: 0.04em; line-height: 1.4; text-transform: uppercase; }
.sb-only-narrow { display: block; }

/* native drawings: the palette, the hexes in the prompt */
.sb-pal .palette-bar { height: 12px; }
.sb-pal .palette-bar__gap { width: 3px; }
.sb-pal .palette-bar__seg { outline: 1px solid var(--hairline-light); outline-offset: -1px; }
.sb-pal__hex { display: grid; gap: 1px; margin-top: 6px; font-size: 9px; color: var(--ink-primary); }
.sb-pal__hex span { white-space: nowrap; }
.sb-pal__hex i { font-style: normal; color: var(--ink-secondary); }
.sb-hex { font-size: 9px; line-height: 1.45; }
.sb-hex .hex-trace__hex i { width: 8px; height: 8px; }
.sb-status { padding-bottom: 2px; }

/* case 02: bracketed under act I */
.sb-case { margin-top: var(--space-4); }
.sb-case .dim { white-space: normal; }
.sb-case__note { display: none; }

/* case 05 and the title block */
.sb-foot { display: grid; gap: var(--space-6); }
.sb-c05 { display: grid; grid-template-columns: repeat(2, minmax(0, 120px)) minmax(0, 1fr); gap: 6px 12px; align-items: start; }
.sb-c05 figure { margin: 0; display: grid; gap: 5px; min-width: 0; }
.sb-c05 figcaption { color: var(--ink-secondary); }
.sb-c05 .try-chain__mark { font-size: 9px; }
.sb-c05__say { display: grid; gap: 3px; align-content: start; }
.sb-c05__say p { margin: 0; }
.sb-tb { padding: 14px 18px; }

/* ——— the phone, and every width under the sheet: one vertical thread ——— */
@media (max-width: 1199.98px) {
  .sb-sheet { display: flex; flex-direction: column; }
  .sb-main { order: -1; }
  .sb-naive__in, .sb-acts, .sb-foot { padding-left: 26px; }
  .sb-main { margin-bottom: var(--space-8); }
  .sb-one { margin-left: -26px; margin-top: var(--space-6); }
  .sb-one__mark { margin-left: -4px; }
  .sb-one__cap { margin-top: 2px; }
  .sb-acts { margin-top: var(--space-12); }
  .sb-act + .sb-act { margin-top: var(--space-12); }
  .sb-act > .dim, .sb-case .dim { margin-bottom: var(--space-6); font-size: 9px; letter-spacing: 0.02em; }
  .sb-case .dim { margin-bottom: 8px; }
  .sb-case__more { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .sb-case__note { display: block; margin: 0; color: var(--ink-secondary); text-transform: uppercase; font-size: 9px; letter-spacing: 0.04em; }
  .sb-case { margin-top: var(--space-8); }
  .sb-steps { display: grid; gap: 40px; }
  .sb-step { display: flex; flex-direction: column; gap: 10px; }
  .sb-zone { order: 2; max-width: 360px; }
  .sb-zone:empty { display: none; }
  .sb-zone__in:empty { display: none; }
  .sb-sheet > .sb-key { padding-left: 26px; margin-top: var(--space-8); max-width: 420px; }
  .sb-key__fam { min-height: 30px; }
  .sb-id { gap: 10px; margin-bottom: 0; }
  .sb-id .ii .ii-rim { stroke-width: 1; }   /* drawn at full size down one thread: the rim at the hairline */
  .sb-lbl { font-family: var(--font-sans); font-size: var(--type-card-body-size); letter-spacing: var(--type-card-body-tracking); line-height: var(--type-card-body-leading); }
  .sb-who { font-size: var(--type-mono-size); }
  .sb-pics--many { --k: 4 !important; }
  .sb-foot { margin-top: var(--space-12); }
  .sb-c05 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sb-c05__say { grid-column: 1 / -1; order: -1; margin-bottom: 6px; }
  .sb-tb { grid-template-columns: 96px 1fr; }
}
@media (max-width: 720px) {
  .sb-zone { max-width: 100%; }
  .sb-pics--many { --k: 2 !important; gap: 6px; }
}

/* ——— the sheet (1200px and wider): one drawing, a 24-column grid ——— */
@media (min-width: 1200px) {
  .sb-sheet { display: grid; grid-template-columns: repeat(24, minmax(0, 1fr)); column-gap: 18px; row-gap: 20px; align-items: start; }
  .sb-sheet > .sb-key { grid-column: 1 / 7; grid-row: 5; align-self: end; position: relative; z-index: 1; }
  .sb-acts { display: contents; }
  .sb-naive { grid-column: 1 / 8; grid-row: 1; align-self: stretch; }
  .sb-naive__in { height: 100%; padding-top: 22px; }
  .sb-main { grid-column: 8 / 17; grid-row: 1; }
  .sb-act--motion { grid-column: 17 / 25; grid-row: 1; }
  .sb-act--world { grid-column: 1 / -1; grid-row: 2; }
  .sb-act--moodboard { grid-column: 1 / 12; grid-row: 3; }
  .sb-act--plan { grid-column: 12 / 15; grid-row: 3; }
  .sb-act--keyframe { grid-column: 1 / -1; grid-row: 4; }
  .sb-foot { grid-column: 1 / -1; grid-row: 5; grid-template-columns: repeat(24, minmax(0, 1fr)); column-gap: 18px; align-items: end; }
  .sb-c05 { grid-column: 7 / 16; }
  .sb-tb { grid-column: 16 / 25; justify-self: end; grid-template-columns: repeat(5, auto); grid-template-rows: auto auto; grid-auto-flow: column; gap: 4px 26px; }

  /* the belief beside the main view: the one call runs into the frame's left edge */
  .sb-one { position: absolute; left: 0; right: 0; top: 64%; margin: 0; }
  .sb-one__lead { display: block; position: absolute; left: 17px; right: -12px; top: 10.5px; height: 1px; background: var(--timeline-red); }   /* its node stops 4px short of the frame's edge */
  .sb-one__lead::after { content: ""; position: absolute; right: -2px; top: -2px; width: 5px; height: 5px; background: var(--datum-red); }
  .sb-one__cap { position: absolute; left: 0; top: calc(64% + 28px); margin: 0; }
  .sb-count { position: absolute; left: 0; bottom: 0; margin: 0; }

  .sb-act > .dim { margin-bottom: 6px; }
  .sb-steps { display: grid; grid-template-columns: var(--cols); column-gap: 14px; }
  .sb-case { display: grid; grid-template-columns: var(--cols); column-gap: 14px; margin-top: 8px; }
  .sb-step { display: grid; grid-template-rows: var(--zone, auto) auto; row-gap: 16px; padding-right: 6px; }
  /* the head on the sheet: the icons on their own line under the step's node, the number on the lane beneath them */
  .sb-id { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 7px; row-gap: 5px; align-items: center; margin-bottom: 5px; }
  .sb-id .sp-marks { grid-column: 1 / -1; grid-row: 1; margin-left: -1px; }
  .sb-id .sb-num { grid-column: 1; grid-row: 2; }
  .sb-id .sb-rule { grid-column: 2; grid-row: 2; }
  .sb-id .sb-fam { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .sb-zone { display: flex; align-items: flex-end; height: var(--zone, auto); }
  .sb-zone__in { width: 100%; }
  .sb-only-narrow { display: none; }
  .sb-who--fresh { display: block; }
  .sb-who.is-repeat { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; margin: 0; }
  /* act V reads toward the frame: 24 at the right, 25 beside the frame */
  .sb-act--motion .sb-step[data-n="24"] { grid-column: 2; grid-row: 1; }
  .sb-act--motion .sb-step[data-n="25"] { grid-column: 1; grid-row: 1; }
}

/* ——— pinned: the sheet holds while the steps are drawn (simple-b.js sets .sb-is-pin, only with motion) ——— */
.board.sb-is-pin { padding-bottom: 0; }   /* the hold ends where the board does: the sheet never slides off its last state */
.sb-is-pin .sb-stage { position: sticky; top: 0; height: 100vh; display: flow-root; }
.sb-is-pin .sb-sheet { transform-origin: 50% 0; }
.sb-is-pin .sb-main__ap, .sb-is-pin .sb-naive__in { transform-origin: 0 50%; }
.sb-is-pin .sb-step, .sb-is-pin .sb-act > .dim, .sb-is-pin .sb-case, .sb-is-pin .sb-c05, .sb-is-pin .sb-tb, .sb-is-pin .sb-count, .sb-is-pin .sb-main__dim, .sb-is-pin .sb-key { opacity: 0; }

/* drawn as they enter (the phone, and a sheet too short to hold): only with motion */
.sb-is-enter .sb-step, .sb-is-enter .sb-act > .dim, .sb-is-enter .sb-case, .sb-is-enter .sb-c05, .sb-is-enter .sb-key { opacity: 0; transition: opacity var(--dur-enter) var(--ease) 260ms; }
.sb-is-enter .sb-in, .sb-is-enter .sb-act > .dim.sb-in, .sb-is-enter .sb-key.sb-in { opacity: 1; }

/* ——— 46. FrameInDepth — AN EXAMPLE, registered for the cases where it is right (2026-11-01): the frame turns to
   three-quarters and the chain's pictures settle behind it in depth, earliest at the back, on a red thread; every
   plane drops a leader to its node (REF-06), the acts hang the planes from a gantry (REF-07), the steps without a
   picture sit on the thread as their icons (44, small); under the stage the chain as text and cases 02 and 05. Right
   for a short chain of mostly pictures, one beat of revelation, a single still (a deck slide, a PDF cover, an Open
   Graph card, a vertical reel frame) or an audience that will not read; to explain the process use 45, and never A
   beside B for the same chain. Sizes and positions only: every colour, line, shadow and face is a token or a
   registered class (film-aperture, paper-card, try-chain, t-*, copy-slot, hr); the step rows use 45's .sp-marks.
   Behaviour: depth.js, on section.sa[data-frame-in-depth]; reduced motion: the exploded stack as a still. ——— */
.sa { --sa-k: 1; --sa-w: 800px; }
.sa-sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* the naive line: the director's words, set in the type it will have — still a slot until he approves it */
.sa-naive { margin: var(--space-6) 0 0; max-width: 32ch; }
.sa-naive .copy-slot { font-family: var(--font-sans); font-size: var(--type-title-size); letter-spacing: var(--type-title-tracking); line-height: var(--type-title-leading); }

/* without the script: the frame and the line, in the flow */
.sa-stage { position: relative; }
.sa-layer { margin: 0; }
.sa:not(.is-on) .sa-layer { max-width: 980px; }
.sa:not(.is-on) .sa-draw, .sa:not(.is-on) .sa-read, .sa:not(.is-on) .sa-count { display: none; }

/* with it: one stage as tall as the screen; the planes are placed in 3D by simple-a.js */
.sa.is-on .sa-stage { height: 100vh; height: 100svh; min-height: 600px; overflow: hidden; }
.sa.is-live .sa-run { height: 720vh; }
.sa.is-live .sa-stage { position: sticky; top: 0; }
.sa.is-on .sa-scene { position: absolute; inset: 0; }
.sa.is-on .sa-stack { position: absolute; inset: 0; transform-style: preserve-3d; }
.sa.is-on .sa-layer { position: absolute; left: 0; top: 0; transform-origin: 50% 50%; backface-visibility: hidden; visibility: hidden; }
.sa.is-on .sa-layer.is-up { visibility: visible; }
/* the planes are drawn large and set down small: their edges are kept at one hairline on screen */
.sa.is-on .sa-layer .film-aperture, .sa.is-on .sa-sheet { outline-width: calc(1px * var(--sa-k)); }
.sa.is-on .sa-naive { position: absolute; margin: 0; max-width: none; }
.sa-draw { position: absolute; left: 0; top: 0; overflow: visible; pointer-events: none; }

/* a plane that holds more than one picture, or none: a sheet of paper, edged like an aperture, unlit */
.sa-sheet { width: 100%; height: 100%; display: grid; align-content: center; padding: calc(var(--sa-w) * 0.04); outline: 1px solid var(--hairline-light); box-shadow: none; }
.sa-sheet__row { display: grid; grid-template-columns: repeat(var(--n, 2), minmax(0, 1fr)); gap: calc(var(--sa-w) * 0.022); align-items: center; }
.sa-sheet__grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: calc(var(--sa-w) * 0.014); }
.sa-layer.is-kept > .film-aperture, .sa-sheet .film-aperture.is-kept { outline-color: var(--datum-red); }
.sa-pal { gap: calc(var(--sa-w) * 0.03); align-content: center; }
.sa-pal__bar { display: flex; height: calc(var(--sa-w) * 0.13); outline: calc(1px * var(--sa-k)) solid var(--hairline-light); }
.sa-pal__bar i { display: block; height: 100%; flex-basis: 0; }
.sa-pal__keys, .sa-hex { font-family: var(--font-mono); letter-spacing: var(--type-mono-tracking); color: var(--ink-primary); }
.sa-pal__keys { display: flex; justify-content: space-between; gap: calc(var(--sa-w) * 0.02); font-size: calc(var(--sa-w) * 0.024); text-transform: uppercase; }
.sa-hex { margin: 0; padding: 0; list-style: none; display: grid; gap: calc(var(--sa-w) * 0.016); font-size: calc(var(--sa-w) * 0.031); line-height: 1.25; }
.sa-hex i, .sa-chips i { display: inline-block; width: 0.8em; height: 0.8em; margin-right: 0.6em; vertical-align: -0.06em; outline: 1px solid var(--hairline-light); outline-offset: -1px; }

/* the drawing on the paper: thread, leaders, gantry — all 1px marks */
.sa-guide { stroke: var(--hairline-light); stroke-width: 1; }
.sa-thread { stroke: var(--timeline-red); stroke-width: 1; }
.sa-lead, .sa-post, .sa-dim { stroke: var(--mark); stroke-width: 1; fill: none; }
.sa-beam, .sa-arrow { stroke: var(--ink-primary); stroke-width: 1; fill: none; }
.sa-node { fill: var(--ink-primary); }   /* a hanger's node on the beam: the ProcessStrip gantry's 5px square */
.sa-ring { fill: var(--paper-card); stroke: var(--datum-red); stroke-width: 1.4; }
.sa-x { stroke: var(--datum-red); stroke-width: 1.2; }
.sa-ok { fill: var(--datum-red); }
.sa-num, .sa-cap { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; fill: var(--ink-secondary); }
.sa-cap { text-transform: uppercase; }
.sa-num.is-now { fill: var(--ink-primary); }
.sa-act { font-family: var(--font-label); font-size: var(--type-label-size); font-weight: var(--type-label-weight); letter-spacing: var(--type-label-tracking); text-transform: uppercase; fill: var(--ink-primary); }

/* the step being laid down, under the drawing; the counter in the corner */
.sa-read { position: absolute; left: 0; margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--space-3); transition: opacity var(--dur-enter) var(--ease); }
.sa-read .sp-marks { display: block; }
.sa-read__what { flex-basis: 100%; }
.sa-count { position: absolute; right: 0; margin: 0; color: var(--ink-secondary); white-space: nowrap; }
.sa-aside { position: absolute; right: 0; width: 248px; padding: 12px 14px 14px; display: grid; gap: 8px; opacity: 0; transition: opacity 700ms var(--ease); pointer-events: none; }
.sa-aside.is-on { opacity: 1; }
.sa-aside p { margin: 0; }

/* the parts list: the chain as text, with the two verified cases beside it */
.sa-parts { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); gap: var(--space-12) clamp(32px, 5%, 80px); align-items: start; }
.sa-parts__head { color: var(--ink-secondary); margin-bottom: var(--space-8); }
.sa-actbox + .sa-actbox { margin-top: var(--space-8); }
.sa-act__head { display: flex; gap: var(--space-3); align-items: baseline; margin-bottom: var(--space-4); }
.sa-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.sa-step { display: grid; grid-template-columns: 22px 46px minmax(0, 13em) minmax(0, 1fr); gap: 0 var(--space-3); align-items: baseline; }
.sa-step__m { align-self: center; }
.sa-step__what .try-chain__mark { margin-left: var(--space-3); vertical-align: 1px; }
.sa-step__more { grid-column: 4; margin-top: 4px; color: var(--ink-secondary); }
.sa-chips { display: flex; flex-wrap: wrap; gap: 4px var(--space-4); }
.sa-parts__cases { display: grid; gap: var(--space-12); align-content: start; }
.sa-case p { margin: 0; }
.sa-case .t-card-body { margin-bottom: var(--space-4); }
.sa-case__foot { margin-top: var(--space-4); display: grid; gap: 4px; color: var(--ink-secondary); }
.sa-case5 { padding: 18px 18px 20px; }

@media (max-width: 900px) {
  .sa-parts { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 720px) {
  .sa-step { grid-template-columns: 22px 40px minmax(0, 1fr); }
  .sa-step__what, .sa-step__more { grid-column: 3; }
  .sa-step__who { grid-column: 3; }
  .sa-step__m { grid-row: span 2; align-self: start; padding-top: 2px; }
}

/* ════════ The site's new pieces: DatumWipe in passes (29, extended) and components 47–53 (registered 2026-11-01 and
   2026-11-03, carried from design/v-motion-lab, design/v-audience and design/v-work-with-us by the director's decision) ════════ */

/* ——— 29, extended — in passes (DatumWipe, 2026-11-01, motion lab 05): one still as the record keeps it — as it came,
   each try, the one kept — in one aperture, and one datum line crossing it once per pass, a pendulum: left to right the
   next layer comes in from the left, back again the one after from the right. The names of what lies each side travel
   with the line on the paper above the frame, the incoming one in ink; the states on screen are marked where the record
   lists them (on the case page its TryChain), the incoming one in red. The line runs on into the margin in timeline
   red, up between the names and down to its own foot: the handle, on a rail drawn as the frame's dimension line.
   Opt in with [data-wipe-passes]; sections.js drives it. Without script, and with reduced motion, the kept layer
   stands. ——— */
.datum-wipe[data-wipe-passes] { --wipe: 0%; }
.datum-wipe__stage { position: relative; }
/* the frame holds only its layers, in the order the still went; none is dragged, so the picture scrolls like any */
.datum-wipe[data-wipe-passes] .datum-wipe__frame { cursor: auto; touch-action: auto; }
.datum-wipe[data-wipe-passes] .datum-wipe__frame > * { position: absolute; inset: 0; clip-path: none; }
html.motion .datum-wipe[data-wipe-passes] .datum-wipe__frame > * + * { will-change: clip-path; }

/* the names, on the paper above the frame: the one left of the line ends at it, the one right of it starts there,
   each with its arrow pointing at the line. The receding one keeps the tag's own grey, the incoming one is all ink.
   A name is shown only where it fits beside the line; one fading out keeps its place, so the row clips it at the
   frame's width rather than let it push the page sideways. */
.datum-wipe[data-wipe-passes] .datum-wipe__tags { position: relative; display: block; height: calc(var(--type-mono-size) * var(--type-mono-leading)); margin-bottom: 12px; overflow: hidden; overflow: clip; }
.datum-wipe[data-wipe-passes] .datum-wipe__tags > span { position: absolute; top: 0; left: 0; white-space: nowrap; opacity: 0; }
.datum-wipe[data-wipe-passes] .datum-wipe__tags > .is-l { left: auto; right: calc(100% - var(--wipe) + 12px); }
.datum-wipe[data-wipe-passes] .datum-wipe__tags > .is-r { left: calc(var(--wipe) + 12px); }
.datum-wipe[data-wipe-passes] .datum-wipe__tags > .is-shown { opacity: 1; }
.datum-wipe[data-wipe-passes] .datum-wipe__tags > .is-in { color: var(--ink-primary); }
.datum-wipe[data-wipe-passes] .datum-wipe__tags > span::after { content: " \2192"; }
.datum-wipe[data-wipe-passes] .datum-wipe__tags > .is-r::after { content: none; }
.datum-wipe[data-wipe-passes] .datum-wipe__tags > .is-r::before { content: "\2190  "; }
html.motion .datum-wipe[data-wipe-passes] .datum-wipe__tags > span { transition: opacity 200ms var(--ease), color var(--dur-hover) var(--ease); }
/* without script the kept layer stands, named at its left; the line and its handle wait for the script */
.datum-wipe[data-wipe-passes]:not(.is-wired) .datum-wipe__tags > :last-child { opacity: 1; }
.datum-wipe[data-wipe-passes]:not(.is-wired) .datum-wipe__tags > span::after { content: none; }
.datum-wipe[data-wipe-passes]:not(.is-wired) .datum-wipe__run,
.datum-wipe[data-wipe-passes]:not(.is-wired) .datum-wipe__rail { visibility: hidden; }

/* the line: the datum's own 2px across the picture, and its run-on into the margin in the 1px timeline red — up through
   the names' row, so it parts the two names, and down to the handle, the line's own foot. At an edge the picture's
   part goes: there the line is the frame's own edge. */
.datum-wipe__run { --up: calc(12px + var(--type-mono-size) * var(--type-mono-leading)); --down: 20px;
  position: absolute; top: calc(-1 * var(--up)); bottom: calc(-1 * var(--down)); left: var(--wipe); width: 0; z-index: 1; pointer-events: none; }
.datum-wipe__run::before { content: ""; position: absolute; top: var(--up); bottom: var(--down); left: -1px; width: 2px; background: var(--datum-red); }
.datum-wipe__run::after { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 1px;
  background: linear-gradient(var(--timeline-red), var(--timeline-red)) 0 0 / 1px var(--up) no-repeat, linear-gradient(var(--timeline-red), var(--timeline-red)) 0 100% / 1px var(--down) no-repeat; }
.datum-wipe__run.is-parked::before { opacity: 0; }
html.motion .datum-wipe__run::before { transition: opacity 240ms var(--ease); }

/* the handle: the datum's node on a rail under the frame, the line's own foot, with the reading under the rail. The
   rail is drawn as the dimension line (P6) of the frame's width — the span the line measures — with its end ticks,
   so it reads as a measured axis on the drawing, not a player's seek bar. */
.datum-wipe__rail { position: relative; height: 44px; margin: 14px 0 var(--space-4); }
.datum-wipe__rail::before { content: ""; position: absolute; left: 0; right: 0; top: 7px; height: 7px;
  background: linear-gradient(var(--mark), var(--mark)) 0 3px / 100% 1px no-repeat, linear-gradient(var(--mark), var(--mark)) 0 0 / 1px 7px no-repeat, linear-gradient(var(--mark), var(--mark)) 100% 0 / 1px 7px no-repeat; }
.datum-wipe__handle { position: absolute; left: var(--wipe); top: 0; width: 44px; height: 44px; margin-left: -22px; cursor: ew-resize; touch-action: none; }
.datum-wipe__handle::before { content: ""; position: absolute; left: 18px; top: 6px; width: 8px; height: 8px; background: var(--datum-red); }
.datum-wipe__handle:hover::before, .datum-wipe__handle:focus-visible::before, .datum-wipe.is-held .datum-wipe__handle::before { transform: scale(1.35); }
html.motion .datum-wipe__handle::before { transition: transform var(--dur-hover) var(--ease); }
.datum-wipe__handle:focus { outline: 0; }
.datum-wipe__handle:focus-visible { outline: 1px solid var(--datum-red); outline-offset: -8px; }
.datum-wipe__read { position: absolute; left: 0; top: 22px; white-space: nowrap; color: var(--ink-secondary); pointer-events: none; }

/* the states, wherever the record lists them: the ones on screen edged in the drafting mark, the incoming one in the
   datum red, the rest quiet. Only their 1px edges and their names change — never the pictures. The edge is the
   aperture's own, on the paper outside the picture, so it reads against a dark still too, and the mark's grey never
   outweighs the red on a bright one. Laid on a TryChain, its marks and its thread stay; at rest on the kept try its
   red edge is the TryChain's own again. */
[data-wipe-state].is-wipe-state .film-aperture { outline: 1px solid var(--hairline-light); outline-offset: 0; }
[data-wipe-state].is-wipe-state.is-there .film-aperture { outline-color: var(--mark); }
[data-wipe-state].is-wipe-state.is-now .film-aperture { outline-color: var(--datum-red); }
[data-wipe-state].is-wipe-state:not(.is-there) .try-chain__mark { color: var(--ink-secondary); }
html.motion [data-wipe-state].is-wipe-state .film-aperture,
html.motion [data-wipe-state].is-wipe-state .try-chain__mark { transition: outline-color var(--dur-hover) var(--ease), color var(--dur-hover) var(--ease); }
/* on a phone the TryChain that lists a wipe's states stays one row under the frame, as the study's states went to a
   row: the marks must be in sight with the line, and the stills are not shown twice at full width. */
@media (max-width: 720px) {
  .try-chain.datum-wipe__states { grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); gap: var(--space-2); }
  .try-chain.datum-wipe__states .try-chain__step figcaption::before { right: calc(-1 * var(--space-2)); }
  .try-chain.datum-wipe__states .try-chain__step:last-child figcaption::before { right: 0; }
  .try-chain.datum-wipe__states .try-chain__mark { align-items: flex-start; }   /* a name on two lines keeps its mark at the first */
  .try-chain.datum-wipe__states .try-chain__mark::before { margin-top: 3px; }
}

/* ——— 47. AgentCrew — the drawn form of AgentThread (43), registered 2026-11-01 (the motion lab's 04 C, the director's
   choice): the agents of one real run drawn as a cast — a jointed mannequin with its tool each, the director an empty
   chair — and the run on one thread, call by call, each call a small copy of its agent's drawing (a lone call above
   the thread on a stem, two at once across it). Under it the stretches the record keeps, bracketed as a drawing
   brackets a span, each with the picture it made in a P4 aperture as wide as its bracket. The drawings are GPT Image
   plates in the CAD line language with their paper taken out (ink on alpha, media/crew/*.webp): the lab laid them on
   with multiply, but the pinned hold is a stacking context of its own and a blend inside it finds no paper, so the
   paper, grain and light show through the drawings instead. Drawings on the paper, never pictures: no aperture, and
   nothing is laid over a picture. The markup stands drawn; crew.js sets .is-live only where the pen may play — then the
   run holds on the screen while the scroll moves the pen. [data-compact], for the home: smaller, the cast on one line,
   never pinned, inked once as it comes into view, no pictures (the tree above holds them). .is-manual: the pen is a
   slider. Without .is-live — reduced motion, a phone, a run too wide or too tall to hold, no script — all stands. ——— */
.cr { position: relative; }
.cr .board__head { flex-wrap: wrap; gap: var(--space-2) var(--space-6); margin-bottom: var(--space-6); }   /* a head inside a board: the board's own head keeps the long breath */
html.motion .cr.is-live:not([data-compact]):not(.is-manual) { height: calc(var(--bh, 600px) + 160vh); }
html.motion .cr.is-live:not([data-compact]):not(.is-manual) .cr-hold { position: sticky; top: var(--pin-top, 24px); }

/* the cast: who works in this run — the drawing, the name, the model */
.cr-cast { list-style: none; margin: 0 0 var(--space-4); padding: 0; display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); gap: var(--space-3); }
.cr-one { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-width: 0; }
.cr-one img { display: block; width: 100%; height: clamp(72px, 13vh, 118px); object-fit: contain; transition: opacity 240ms var(--ease); }
.cr-label { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
/* the agent at work, underlined right under its name (not its model, not the column), drawn from the left in the red */
.cr-name { position: relative; }
.cr-name::after { content: ""; position: absolute; left: 0; right: 0; bottom: -4px; height: 2px; background: var(--datum-red); transform: scaleX(0); transform-origin: 0 50%; transition: transform 240ms var(--ease); }
.cr-one .t-mono { font-size: 10px; color: var(--ink-secondary); }
.cr-one .cr-name { color: var(--ink-primary); }
.cr.is-live .cr-one img { opacity: 0.62; }   /* the cast waits, quiet; who has worked stays a little stronger */
.cr.is-live .cr-one.has-worked img { opacity: 0.88; }
.cr.is-live .cr-one.is-now img { opacity: 1; }
.cr.is-live .cr-one.is-now .cr-name::after { transform: none; }

/* the run: one grid of calls, shared by the thread and the stretches under it; narrower than this it scrolls sideways */
.cr-scroll { overflow-x: auto; overflow-y: hidden; }
.cr-scroll:focus-visible { outline: 1px solid var(--mark); outline-offset: 4px; }
.cr-run { --ty: 84px; --mini: 56px; --stem: 18px; --across: 10px; position: relative; min-width: 980px; padding: 0 var(--space-4); }   /* inset as the study's thread was, so the pen, resting at either end, never leaves the box */
.cr-thread, .cr-stretches { display: grid; grid-template-columns: repeat(var(--beats, 15), minmax(0, 1fr)); }
.cr-thread { position: relative; height: calc(var(--ty) + var(--across) + var(--mini) + var(--space-4)); }
/* the thread stands inked in the timeline red; while the pen plays it is the guide and the pen inks over it */
.cr-thread::before, .cr-ink { content: ""; position: absolute; left: 0; right: 0; top: var(--ty); height: 1px; background: var(--timeline-red); }
.cr.is-live .cr-thread::before { background: var(--hairline-light); }
.cr-ink { display: none; transform-origin: 0 50%; }
/* the nib: an open square in the datum red, so resting on a call it frames that call's node instead of doubling it */
.cr-nib { display: none; position: absolute; left: 0; top: var(--ty); width: 9px; height: 9px; margin: -4px 0 0 -4.5px; border: 1px solid var(--datum-red); opacity: 0; transition: opacity 160ms linear; }
.cr.is-live .cr-ink, .cr.is-live .cr-nib { display: block; }
/* a call: its node on the thread, its stem, its small copies — a lone call above, two at once across */
.cr-beat { position: relative; }
.cr-beat::before { content: ""; position: absolute; left: 50%; width: 1px; top: calc(var(--ty) - var(--stem)); height: var(--stem); background: var(--ink-primary); }
.cr-beat::after { content: ""; position: absolute; left: 50%; top: var(--ty); width: 5px; height: 5px; margin: -2px 0 0 -2.5px; background: var(--datum-red); }
.cr-beat.is-pair::before { top: calc(var(--ty) - var(--across)); height: calc(2 * var(--across)); }   /* between the two, never through a drawing */
.cr-mini { position: absolute; left: 50%; top: calc(var(--ty) - var(--stem) - var(--mini)); width: var(--mini); height: var(--mini); margin-left: calc(var(--mini) / -2); object-fit: contain; }
.cr-beat.is-pair .cr-mini { top: calc(var(--ty) - var(--across) - var(--mini)); }
.cr-beat.is-pair .cr-mini + .cr-mini { top: calc(var(--ty) + var(--across)); }
/* the runway ahead stands as drafting marks, so the calls read as a measured scale before the pen gets there */
.cr.is-live .cr-beat::after { background: var(--mark); transition: background 200ms var(--ease); }
.cr.is-live .cr-beat.is-on::after { background: var(--datum-red); }
.cr.is-live .cr-beat::before { opacity: 0; transition: opacity 240ms var(--ease); }
.cr.is-live .cr-mini { opacity: 0; transform: translateY(3px); transition: opacity 240ms var(--ease), transform 240ms var(--ease); }
.cr.is-live .cr-beat.is-on::before, .cr.is-live .cr-beat.is-on .cr-mini { opacity: 1; transform: none; }
/* the compact pen glides from call to call in the system's ease; the scrolled pen follows the scroll and needs none */
.cr.is-inking .cr-ink, .cr.is-inking .cr-nib { transition: transform 280ms var(--ease), opacity 160ms linear; }
/* by hand the nib is the slider: always there, a wider grip than its 9px, and a red ring when focused */
.cr.is-manual .cr-run { cursor: ew-resize; touch-action: pan-y; -webkit-user-select: none; user-select: none; }
.cr.is-manual .cr-run img { -webkit-user-drag: none; pointer-events: none; }   /* a drag moves the pen, never lifts a drawing */
.cr.is-manual .cr-nib { opacity: 1; outline: 0; }
.cr.is-manual .cr-nib::before { content: ""; position: absolute; inset: -10px; }   /* inside the run's inset at either end */
.cr.is-manual .cr-nib:focus-visible { outline: 1px solid var(--datum-red); outline-offset: 3px; }

/* the stretches: placed, the tries, the passes — each bracketed under its calls, the picture it made beneath */
.cr-stretches { list-style: none; margin: 0; padding: 0; }
.cr-stretch { grid-column: var(--a) / span var(--n); position: relative; display: flex; flex-direction: column; gap: var(--space-2); margin: 0 6px; padding-top: 9px; min-width: 0; }
.cr-stretch:first-child { margin-left: 0; }   /* the first stretch starts where the thread does: one left edge for line, bracket and picture */
.cr-stretch::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 5px; border: 1px solid var(--ink-secondary); border-top: 0; box-sizing: border-box; transform-origin: 0 0; }
.cr-tag { display: block; font-size: 10px; line-height: 1.3; color: var(--ink-secondary); text-align: center; }
.cr-stretch.is-picked .cr-frame { outline-color: var(--datum-red); }   /* the picked try, the pass in the film */
.cr.is-live .cr-stretch::before { transform: scaleX(0); transition: transform 420ms var(--ease); }
.cr.is-live .cr-stretch.is-on::before { transform: none; }
.cr.is-live .cr-tag { opacity: 0; transition: opacity 240ms var(--ease) 160ms; }
.cr.is-live .cr-stretch.is-on .cr-tag { opacity: 1; }
/* uncovered left to right as the pen leaves the stretch: the picture is shown, never drawn over */
.cr.is-live .cr-frame { clip-path: inset(-2px calc(100% + 2px) -2px -2px); transition: clip-path 560ms var(--ease); }
.cr.is-live .cr-stretch.is-on .cr-frame { clip-path: inset(-2px); }

.cr-foot { display: flex; justify-content: space-between; gap: var(--space-2) var(--space-6); flex-wrap: wrap; margin: var(--space-4) 0 0; color: var(--ink-secondary); }

/* [data-compact], for the home: the cast on one line, a finer run, the brackets without their pictures */
.cr[data-compact] .cr-cast { gap: var(--space-2); margin-bottom: var(--space-2); }
.cr[data-compact] .cr-one img { height: clamp(52px, 8vh, 72px); object-position: 0 50%; }   /* small: each drawing stands over its own name */
.cr[data-compact] .cr-run { --ty: 58px; --mini: 40px; --stem: 12px; --across: 7px; min-width: 760px; }
.cr[data-compact] .cr-thread { height: calc(var(--ty) + var(--across) + var(--mini) + var(--space-3)); }
.cr[data-compact] .cr-foot { margin-top: var(--space-3); }

@media (prefers-reduced-motion: reduce) {
  .cr *, .cr *::before, .cr *::after { transition: none !important; }
}
/* narrower: the cast in two rows of four, so all of it reads (eight on a line stop fitting their longest names, 13
   characters, below about 1000px); the run scrolls sideways in its own box. On a small phone four columns are too
   narrow for those names too, so the cast becomes a list of two columns, each drawing beside its name. */
@media (max-width: 1000px) { .cr-cast { grid-template-columns: repeat(4, minmax(0, 1fr)); row-gap: var(--space-6); } }
@media (max-width: 560px) {
  .cr-cast, .cr[data-compact] .cr-cast { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); }
  .cr-one { flex-direction: row; align-items: center; gap: var(--space-2); }
  .cr .cr-one img, .cr[data-compact] .cr-one img { flex: none; width: 56px; height: 56px; }
}
@media (max-width: 359px) { .cr-cast, .cr[data-compact] .cr-cast { grid-template-columns: minmax(0, 1fr); } }

/* ——— 48. PlateRedraw — note 18's 4A as the director chose it (2026-10-31, the motion lab's 06 A): the shape of a bank's
   multi-agent AI system as one isometric plate, and a datum line that sweeps across it like a plotter head and redraws
   it as the studio's system. Every module keeps its place; the names change exactly where the line passes. The plates
   are drawings in the line language (GPT Image, their paper made white), laid on the board with multiply, so the
   board's own paper and light are theirs and they read as drawn on the sheet, as SystemRebuild's diagram does; only
   drafting marks cross them — the plotter and the dotted callouts, each on a mark measured in both plates. The still
   form is the markup's own and the default (reduced motion, a phone, no script): both plates one above the other, each
   with its head, and the six pairs. plate.js adds .is-live where the line can move; the run (.pl-run) is the scroll's
   runway and the whole board holds while it plays. data-plate="hand" (a card) gives the line to the visitor. ——— */
.pl-run { position: relative; width: 100%; max-width: var(--board-max); }
.pl-ill { display: block; width: 100%; height: auto; mix-blend-mode: multiply; }
.pl-board > .board__head { gap: var(--space-4); }   /* a short name beside a long note must not run into it on a narrow card */

/* the still form: what every visitor gets until the script says the line can move */
.pl-heads, .pl-stage, .pl-names, .pl-says, .pl-scale { display: none; }
.pl-still { display: grid; gap: var(--space-8); }
.pl-still figure { margin: 0; display: grid; gap: var(--space-4); }
.pl-still figcaption { max-width: 72ch; }
.pl-map { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px var(--gutter); }
.pl-map .t-mono { font-size: 10px; }
.pl-map .to { color: var(--ink-primary); }
.pl-map .to::before { content: "→ "; color: var(--datum-red); }
.pl-foot { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--space-3) var(--gutter); align-items: end; margin-top: var(--space-6); }
.pl-legend { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 4px var(--space-6); margin: 0; color: var(--ink-secondary); }
/* the flow's key: the instrument itself, a run of the datum with its square node, beside words in the legend's ink —
   red draws, it does not colour a clause (check_design) */
.pl-legend__flow::before { content: ""; display: inline-block; width: 14px; height: 4px; margin-right: 6px; vertical-align: 0.2em; background: linear-gradient(var(--datum-red), var(--datum-red)) 0 50% / 100% 2px no-repeat, linear-gradient(var(--datum-red), var(--datum-red)) 50% 50% / 4px 4px no-repeat; }

/* live: the still form steps aside for the eye but stays for a screen reader, which hears both plates and the pairs */
.pl-run.is-live .pl-still { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.pl-run.is-live .pl-heads { display: grid; min-height: 28px; }
.pl-heads > p { grid-area: 1 / 1; margin: 0; opacity: 0; }
.pl-heads > p.is-on { opacity: 1; }

/* the stage: sized by plate.js (--pl-fit) so the whole board stays on one screen while it holds */
.pl-run.is-live .pl-stage { display: block; position: relative; width: min(100%, var(--pl-fit, 100%)); margin: 52px auto 0; }
.pl-bank { clip-path: inset(0 0 0 var(--x, 0%)); }
.pl-run.is-plotting .pl-bank { opacity: 0.58; }   /* once the plotter has set off, what it has not reached yet recedes */
.pl-studio { position: absolute; left: 0; top: 0; clip-path: inset(0 calc(100% - var(--x, 0%)) 0 0); }

/* the plotter: the datum line across the plate, running on into the paper above and below, its head a red square.
   The datum's own crisp 2px and nothing round it: the lab's faint wake read as a glow on the instrument (check_design) */
.pl-line { position: absolute; top: -14px; bottom: -14px; left: var(--x, 0%); width: 2px; margin-left: -1px; background: var(--datum-red); outline: 0; }
.pl-line::before { content: ""; position: absolute; left: -3px; top: -2px; width: 8px; height: 8px; background: var(--datum-red); }
.pl-line.is-parked { opacity: 0; }
.pl-plot { position: absolute; left: 10px; top: -4px; font-size: 10px; color: var(--datum-red); white-space: nowrap; }
.pl-run.is-late .pl-plot { left: auto; right: 10px; }

/* callouts: what the marks of the drawing are, on the registered callout's dotted leader — a note, never the plotter.
   --at across, --to down to the mark it names, measured in both plates */
.pl-call { position: absolute; top: -44px; bottom: calc(100% - var(--to, 50%)); left: var(--at, 0%); font-size: 10px; white-space: nowrap; color: var(--ink-primary); }
.pl-call i { position: absolute; left: 0; top: 15px; bottom: 0; width: 0; border-left: 1px dotted var(--ink-primary); }
.pl-call.is-red { color: var(--datum-red); }
.pl-call.is-red i { border-left-color: var(--datum-red); }

/* the names of the modules: the bank's until the line has passed, then the studio's — no crossfade, no overlap */
.pl-run.is-live .pl-names { display: block; position: relative; height: 48px; width: min(100%, var(--pl-fit, 100%)); margin: 8px auto 0; }
.pl-names::before { content: ""; position: absolute; left: 0; right: 0; top: 0; border-top: 1px solid var(--hairline-light); }
.pl-names::after { content: ""; position: absolute; left: 0; width: var(--x, 0%); top: 0; border-top: 1px solid var(--timeline-red); }   /* redrawn so far */
.pl-name { position: absolute; top: 12px; transform: translateX(-50%); white-space: nowrap; font-size: 10px; color: var(--ink-secondary); }
.pl-name.is-b { color: var(--ink-primary); }
.pl-name::before { content: ""; position: absolute; left: 50%; top: -12px; height: 8px; border-left: 1px solid var(--mark); }
.pl-name::after { content: ""; position: absolute; left: 50%; top: -14.5px; width: 5px; height: 5px; margin-left: -2.5px; box-sizing: border-box; border: 1px solid var(--ink-secondary); background: var(--paper-board); }
.pl-name.is-b::after { border-color: var(--datum-red); background: var(--datum-red); }
.pl-name .b, .pl-name.is-b .a { display: none; }
.pl-name.is-b .b { display: inline; }
.pl-name.is-red { color: var(--datum-red); top: 30px; }
.pl-name.is-red::before { top: -30px; height: 26px; }
.pl-name.is-red::after { top: -32.5px; }

/* the foot: the words beside follow the line, and the scale A BANK —◆— A FILM fills red to its node */
.pl-run.is-live .pl-says { display: grid; grid-column: 1 / span 6; }
.pl-says > p { grid-area: 1 / 1; align-self: end; margin: 0; max-width: 56ch; opacity: 0; }
.pl-says > p.is-on { opacity: 1; }
.pl-run.is-live .pl-scale { display: flex; grid-column: 8 / span 5; position: relative; padding-top: 12px; justify-content: space-between; color: var(--ink-secondary); }
.pl-scale::before { content: ""; position: absolute; left: 0; right: 0; top: 3px; border-top: 1px solid var(--mark); }
.pl-scale::after { content: ""; position: absolute; left: 0; width: var(--x, 0%); top: 3px; border-top: 1.5px solid var(--datum-red); }
.pl-scale__node { position: absolute; top: 0; left: var(--x, 0%); width: 7px; height: 7px; margin-left: -3.5px; background: var(--datum-red); transform: rotate(45deg); }

/* by hand (a card): the plate is the handle, as DatumWipe's frame is, and the line is the slider */
.pl-run.is-hand .pl-stage { cursor: ew-resize; touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.pl-run.is-hand .pl-stage .pl-ill { pointer-events: none; }
.pl-run.is-hand .pl-line:focus-visible { box-shadow: 0 0 0 3px color-mix(in srgb, var(--datum-red) 22%, transparent); }

/* the hold: the run is the runway, the board stays on the screen while the line crosses */
html.motion .pl-run.is-live:not(.is-hand) { height: calc(var(--bh, 760px) + 140vh); }
html.motion .pl-run.is-live:not(.is-hand) .pl-board { position: sticky; top: var(--pin-top, 24px); }
html.motion .pl-heads > p, html.motion .pl-says > p { transition: opacity 300ms var(--ease); }
html.motion .pl-bank { transition: opacity var(--dur-enter) var(--ease); }
html.motion .pl-line { transition: opacity 240ms var(--ease); }

@media (max-width: 720px) { .pl-map { grid-template-columns: minmax(0, 1fr); } .pl-still { gap: var(--space-6); } }

/* ——— 49. WorkScale — WS · Ways to work with us (note 16; the audience versions' piece, approved by the director with
   its seventh decision, registered 2026-11-01): the range lives on the studio's own thread, the swimlane's YOU lane
   taken out on its own. The nine steps run from your brief (IN) to the film (OUT), and those two are always yours, so
   they end on ink squares and the red ◆ count is only the decisions taken. Seven decisions can be taken — the first,
   "your vision, shaped", before step 01; the other six the swimlane's own. Each is the ◆ of the decide mark: taken, it
   turns datum red, drops a 1px stem onto the thread, and that step of the thread goes from the 1px timeline red to the
   2px datum (REF-04, on REF-06's thread). Over it a REF-07 bracket from MADE TO ORDER to LED BY THE HAND, one tick per
   decision; its ◆ pointer counts what is taken, and its ends are buttons that clear or take all seven. No tiers and no
   prices: it counts decisions and invents no packages.
   .ws--compact, for the pages: the codes alone on the thread and short stems; live it keeps its labels, because a
   decision you can take has to say what it is; in print (no [data-ws-live]) it drops them. Without .ws__range it is
   the bare thread (a mini). Behaviour: workscale.js (Truemanity.workScale) on .ws[data-ws-live]; without the script,
   with reduced motion or on a phone the scale stands at the point it was written at, and every transition below is
   under html.motion. Under 900px the thread runs down the page: the step, the spine, the stem across to the decision. ——— */
:where(button.ws__end, button.ws__b) { all: unset; box-sizing: border-box; cursor: pointer; }
.ws { display: grid; gap: 14px; }

/* the bracket and its two ends */
.ws__range { display: flex; align-items: flex-start; gap: 18px; }
/* the bracket and the thread a full space-6 apart, so the count and the codes under it never read as one row */
.ws__range + .ws__row { margin-top: calc(var(--space-6) - 14px); }
.ws__end { display: flex; flex-direction: column; gap: 5px; flex: 0 0 auto; min-height: 44px; }
.ws__end--r { align-items: flex-end; text-align: right; }
.ws__end .t-label { display: flex; align-items: center; gap: 8px; }
/* an end's mark only while the scale sits at that end: an empty box read as a missing glyph */
.ws__end .t-label::before { content: ""; display: block; width: 4px; height: 12px; background: transparent; }
.ws__end.is-on .t-label::before { background: var(--datum-red); }
button.ws__end:hover .t-label { color: var(--datum-red); }
.ws__brk { position: relative; flex: 1 1 auto; height: 30px; }
.ws__brk::before { content: ""; position: absolute; left: 0; right: 0; top: 4px; height: 1px; background: var(--ink-primary); }
.ws__brk > i { position: absolute; top: 2px; width: 4px; height: 4px; background: var(--ink-primary); }
/* calibrated one tick per decision, in the drafting line */
.ws__brk > b { position: absolute; top: 5px; width: 1px; height: 5px; background: var(--mark); }
.ws__ptr { position: absolute; top: 1px; left: calc(var(--ws-f, 0) * 100%); width: 0; }
.ws__ptr::before { content: ""; position: absolute; left: -3.5px; top: 0; width: 7px; height: 7px; background: var(--datum-red); transform: rotate(45deg); }
.ws__ptr > span { position: absolute; top: 14px; left: 0; transform: translateX(-50%); white-space: nowrap; font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.04em; }
/* at an end the end itself says the count, so the pointer's own label steps aside (the audience pages' decision,
   accepted with them): it would sit on the end's words, or run off the board */
.ws__ptr.is-min > span, .ws__ptr.is-max > span { opacity: 0; }

/* the thread: a column per step, IN · 00 · 01–09 · OUT */
.ws__row { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); }
.ws__c { display: flex; flex-direction: column; align-items: center; text-align: center; min-width: 0; }
.ws__n { display: flex; flex-direction: column; gap: 1px; min-height: 26px; margin: 0; font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.04em; line-height: 1.25; color: var(--ink-secondary); }
.ws__n b { font-weight: 500; color: var(--ink-primary); }
.ws__seg { position: relative; align-self: stretch; height: 9px; margin-top: 6px; }
.ws__seg::before { content: ""; position: absolute; left: 0; right: 0; top: 4px; height: 1px; background: var(--timeline-red); }
/* .is-wait: taken, but not drawn yet (the sweep, workscale.js) — the state is already the markup's */
.ws__c.is-on:not(.is-wait) .ws__seg::before { top: 3.5px; height: 2px; background: var(--datum-red); }
.ws__c.is-first .ws__seg::before { left: 50%; }
.ws__c.is-last .ws__seg::before { right: 50%; }
.ws__seg > i { position: absolute; left: 50%; top: 2px; width: 5px; height: 5px; margin-left: -2.5px; background: var(--datum-red); }
.ws__c.is-none .ws__seg > i { width: 4px; height: 4px; margin-left: -2px; top: 2.5px; background: var(--ink-primary); }
/* the stem rises from the ◆ to the thread when the decision is taken */
.ws__stem { width: 1px; height: 24px; background: var(--datum-red); transform: scaleY(0); transform-origin: 50% 100%; }
.ws__c.is-on:not(.is-wait) .ws__stem { transform: none; }
.ws__c.is-fixed .ws__stem { background: var(--ink-primary); }
.ws__b { display: flex; flex-direction: column; align-items: center; text-align: center; max-width: 100%; }
button.ws__b { min-height: 44px; padding: 0 2px 4px; }
.ws__dia { width: 7px; height: 7px; box-sizing: border-box; flex: 0 0 auto; transform: rotate(45deg); border: 1px solid var(--ink-secondary); background: transparent; margin-bottom: 8px; }
/* the brief and the film are never taken, so their square stays ink: the red count is only the decisions */
.ws__c.is-on:not(.is-wait, .is-fixed) .ws__dia { background: var(--datum-red); border-color: var(--datum-red); }
.ws__c.is-none .ws__dia { visibility: hidden; }
.ws__c.is-fixed .ws__dia { transform: none; width: 6px; height: 6px; background: var(--ink-primary); border-color: var(--ink-primary); }
button.ws__b:hover .ws__dia { border-color: var(--datum-red); }
.ws__lab { max-width: 84px; font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.04em; line-height: 1.3; color: var(--ink-secondary); }
.ws__c.is-on:not(.is-wait) .ws__lab { color: var(--ink-primary); }
.ws__end:focus-visible, .ws__b:focus-visible { outline: 1px solid var(--datum-red); outline-offset: 3px; }

/* the reading, and the two ends said (editorial slots in their own type) */
.ws__read { margin: 0; font-family: var(--font-mono); font-size: var(--type-mono-size); letter-spacing: var(--type-mono-tracking); line-height: var(--type-mono-leading); }
.ws__say { display: flex; justify-content: space-between; gap: 24px; }
.ws__say > p { flex: 0 1 44%; margin: 0; font-family: var(--font-sans); font-size: var(--type-card-body-size); line-height: var(--type-card-body-leading); color: var(--ink-secondary); }
.ws__say > :last-child { text-align: right; }

/* compact: the codes alone on the thread, short stems; in print, where nothing can be taken, no labels either */
.ws--compact .ws__n span { display: none; }
.ws--compact .ws__n { min-height: 14px; }
.ws--compact .ws__stem { height: 12px; }
.ws--compact:not([data-ws-live]) .ws__lab { display: none; }
/* with no label to end on, a stem is an orphan line: the marks sit just under the thread as a register of states (the
   study's minis), and the stem keeps only its place */
.ws--compact:not([data-ws-live]) .ws__stem, .ws--compact:not([data-ws-live]) .ws__c.is-fixed .ws__stem { height: 6px; background: transparent; }

/* slow and physical, and only when motion is allowed (motion.js sets html.motion): the pointer travels, the step
   thickens, the stem rises */
html.motion .ws__ptr { transition: left var(--dur-enter) var(--ease); }
html.motion .ws__ptr > span { transition: opacity var(--dur-hover) var(--ease); }
html.motion .ws__seg::before { transition: top var(--dur-enter) var(--ease), height var(--dur-enter) var(--ease), background-color var(--dur-enter) var(--ease); }
html.motion .ws__stem { transition: transform var(--dur-enter) var(--ease); }
html.motion .ws__dia, html.motion .ws__lab, html.motion .ws__end .t-label { transition: background-color var(--dur-hover) var(--ease), border-color var(--dur-hover) var(--ease), color var(--dur-hover) var(--ease); }

/* tablet and phone: the thread runs down the page — the step on the left, the spine, the decision on the right */
@media (max-width: 900px) {
  .ws__range { flex-wrap: wrap; }
  .ws__end--r { margin-left: auto; }
  .ws__brk { order: 3; flex: 1 1 100%; }
  .ws__row { grid-template-columns: minmax(0, 1fr); }
  .ws__c { --ws-code: 104px; position: relative; display: grid; grid-template-columns: var(--ws-code) 24px minmax(0, 1fr); align-items: center; min-height: 44px; text-align: left; }
  /* the compact codes are two or three characters: their column stays just wide enough, near the board's edge */
  .ws--compact .ws__c { --ws-code: 32px; }
  .ws__c.is-none { min-height: 22px; }
  .ws--compact:not([data-ws-live]) .ws__c { min-height: 22px; }
  .ws__n { flex-direction: row; justify-content: flex-end; gap: 6px; min-height: 0; padding-right: 10px; }
  .ws--compact .ws__n { min-height: 0; }
  .ws__seg { height: auto; align-self: stretch; margin: 0; }
  /* the spine centred at 11.5px, 1px or the 2px datum, its node centred on it */
  .ws__seg::before { left: 11px; right: auto; top: 0; bottom: 0; width: 1px; height: auto; }
  .ws__c.is-first .ws__seg::before, .ws__c.is-last .ws__seg::before { left: 11px; }
  .ws__c.is-on:not(.is-wait) .ws__seg::before { left: 10.5px; top: 0; width: 2px; height: auto; }
  .ws__c.is-first .ws__seg::before, .ws__c.is-first.is-on:not(.is-wait) .ws__seg::before { top: 50%; }
  .ws__c.is-last .ws__seg::before, .ws__c.is-last.is-on:not(.is-wait) .ws__seg::before { bottom: 50%; }
  .ws__seg > i { left: 9px; top: 50%; margin: -2.5px 0 0; }
  .ws__c.is-none .ws__seg > i { left: 9.5px; top: 50%; margin: -2px 0 0; }
  /* the stem turns with the thread: from the spine across to the decision, drawn when it is taken */
  .ws .ws__stem { position: absolute; left: calc(var(--ws-code) + 13px); top: 50%; width: 9px; height: 1px; transform: scaleX(0); transform-origin: 0 50%; }
  .ws__b { flex-direction: row; gap: 12px; text-align: left; }
  button.ws__b { padding: 0; }
  .ws__dia { margin: 0; }
  .ws__lab { max-width: none; }
  .ws__say { flex-direction: column; gap: 10px; }
  .ws__say > p { flex: 1 1 auto; }
  .ws__say > :last-child { text-align: left; }
}

/* ——— 50. Formats — what arrives from one film, read off the real exports (FM, design/v-audience, approved by the
   director; registered 2026-11-01): a SpecTable (10) of the deliverables beside them — the master in its aperture
   (P4, 2.39) and the reel's covers, each in a 1px cut at its own 9 : 16, as the HARM frames sit at theirs. No 9 : 16
   aperture is added: films stay 2.39, and a vertical aperture waits for vertical footage (the video kit). The rows
   that are offer terms (stills, rounds of changes, the deadline) stay [COPY]. Each group of pictures is its own
   figure with its own caption, so a caption never stands under the other group, at any width. Only tokens and
   registered classes (board, board__note, spec, film-aperture, dim, fig__cap, hr, tick-label, t-title, t-mono, ink-2,
   copy-slot, pc-honest); the prefix fm- is used by no other section. ——— */
.fm { display: grid; grid-template-columns: minmax(320px, 0.9fr) minmax(0, 2fr); gap: var(--space-8); align-items: end; }
/* the title slot and the SpecTable stand on the pictures' baseline, so the facts read as the label of what is shown */
.fm__say { display: grid; gap: var(--space-4); align-content: end; }
/* the master wide, then the covers, twice the strip's gutter apart so the two deliverables read as two groups. Two
   rows shared through subgrid — the pictures, then the captions — keep both pictures on one baseline even when one
   caption runs to two lines; without subgrid each figure simply stands on the row's end */
.fm__show { display: grid; grid-template-columns: minmax(0, 3.2fr) minmax(0, 3fr); grid-template-rows: auto auto; column-gap: calc(var(--gutter-strip) * 2); align-items: end; min-width: 0; }
.fm__master, .fm__covers { display: grid; grid-row: 1 / -1; grid-template-rows: subgrid; align-items: end; margin: 0; min-width: 0; }
.fm__cap { align-self: start; margin-top: var(--space-2); }
/* its P6 dimension line measures the format the master stands for */
.fm__pic { min-width: 0; }
/* the covers on the film strip's own gutter */
.fm__strip { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gutter-strip); }
/* a cover is a still at its own aspect: the P4 edge (1px hairline, outside) without P4's 2.39 */
.fm__v { position: relative; aspect-ratio: 1080 / 1920; overflow: hidden; outline: 1px solid var(--hairline-light); background: var(--paper-dark); }
.fm__v > img, .fm__v > picture > img { display: block; width: 100%; height: 100%; object-fit: cover; }
.paper-board-dark .fm__v { outline-color: var(--hairline-dark); }
/* under 1280px the left column would break the facts inside a size (the SpecTable keeps its 140px labels): the facts
   go above the strip, and the strip takes the whole width */
@media (max-width: 1279px) {
  .fm { grid-template-columns: minmax(0, 1fr); gap: var(--space-6); }
}
/* a phone: the master across the width with its caption, the three covers under it with theirs; the gap between the
   two groups four times the caption's own (8px), so a caption reads as its picture's, never as the next one's */
@media (max-width: 720px) {
  .fm__show { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; row-gap: var(--space-8); }
  .fm__master, .fm__covers { grid-row: auto; grid-template-rows: none; }
}

/* ——— 51. AgentRhythm — note 22's way C, the key and the rhythm (registered 2026-11-03; the director chose C to show the
   agents wherever AgentThread, 43, showed them, on the same data and marks): the key of every agent (AgentMark, 42,
   names only) and, under it, one real run as a rhythm of marks without a word (43's compact thread, no line of names).
   Pointing at a call lights its agents in the key and every call they make; pointing at a name lights its calls. The
   calls are buttons laid over the drawing, a 44px target each, and a press holds the light; where a call would be
   narrower than that, on a phone, the run stands as a drawing. Drawn by agents.js ([data-agents="rhythm"]); the marks
   keep 42's classes and colours, light and dark. Without script: the roster as a spec grid and the run as its roles'
   keys (<noscript>). Only motion: the run drawn once as it enters, under html.motion. ——— */
/* the run is its own band of open paper under the key, not a last row of it (check_design, rounds 1 and 2); the key
   ends 14px under its last name, so the caption stands about 64px below it */
.ar-cap { margin: var(--space-12) 0 var(--space-6); }   /* its ink is .ink-2's, on light and dark paper */
.ar .pc-legend { margin-top: var(--space-8); }
.ar-strip { position: relative; }
.ar-hits { position: absolute; inset: 0; }
/* a call's target: the drawing's own mark is the face, so the button is a clear 44px column centred on the thread */
.ar-hit { position: absolute; top: 0; height: 44px; margin: -22px 0 0; padding: 0; border: 0; border-radius: 0; background: none; color: inherit; font: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.ar-hit:focus { outline: none; }
.ar-hit:focus-visible { outline: 1px solid var(--datum-red); outline-offset: -2px; }
/* a held call: a datum node under its marks, as the system marks an active node */
.ar-hit::after { content: ""; position: absolute; left: 50%; bottom: 2px; width: 12px; height: 2px; margin-left: -6px; background: var(--datum-red); opacity: 0; }
.ar-hit[aria-pressed="true"]::after { opacity: 1; }
/* on dark paper the thread and the node are the laser's red; the focus ring is ink, which holds 3:1 there */
.paper-board-dark .ar .pc-line { stroke: var(--laser-red-dark); }
.paper-board-dark .ar-hit::after { background: var(--laser-red-dark); }
.paper-board-dark .ar-hit:focus-visible { outline-color: var(--ink-on-dark); }
.paper-board-dark .ar .pc-honest { color: #8E949D; }   /* ink-secondary is 3.7:1 on dark paper; its metadata ink is 6.4:1 */
/* the light goes quiet at once without motion; with it, 42's own 240ms */
.ar .ag-entry, .ar .ag-beat, .ar .ag-entry .ag-mark { transition: none; }
html.motion .ar .ag-entry, html.motion .ar .ag-beat { transition: opacity 240ms var(--ease); }

/* without script: the key as a spec grid (stage, names), the run as its roles' keys, a chord stacked as in the drawing */
.ar-still { grid-template-columns: 140px minmax(0, 1fr); }
.ar-run { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); min-height: 44px; }
.ar-run > span { display: inline-flex; flex-direction: column; gap: 5px; }
@media (max-width: 720px) { .ar-still { grid-template-columns: 96px minmax(0, 1fr); } }

/* ——— 52. WorkDial — 1A · the dial (note 16; the director's choice of 2026-11-03 among the ways to work with us, with
   its model as it stands: eight decisions, four settings, the two middle names [COPY], no prices; registered
   2026-11-03 from design/v-work-with-us/parts/1a-dial.*). The scale from made to order to led by the hand as a drafting
   instrument: a protractor in the 1px drafting line (--mark) with a detent for each setting (01–04), the index an ink
   arm ending in the 2px datum and the 5px red node (REF-04). The client's eight decision points ◆ lie on the scale
   where each passes from the studio to the client — hollow in the drafting line while the studio decides it, datum red
   once the index has passed it — so turning toward the maximum hands them over one by one in project order, and
   turning back takes them back. Beside it the readout of the setting (the rule-less spec grid, P9); under it the lane of
   the eight ◆ under the REF-07 bracket (ProcessStrip's .process__bracket). The key, every setting against every ◆
   (REF-10's chip grid, rule-less), is in the markup: it stands with reduced motion and without script, and steps aside
   only when the dial can turn under motion. Behaviour: workdial.js (Truemanity.workDial) on .wd[data-workdial], with
   the model in the page's JSON (#workdial-data); data-wd-demo turns it by itself, at most three detents, until the
   visitor points at it or types in a form. .wd--key is the key alone, for print. Every transition below is under
   html.motion. ——— */
.wd { display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); grid-template-areas: "dial read" "key read" "lane lane"; column-gap: clamp(40px, 6%, 104px); align-items: start; }

/* the instrument */
.wd__dial { grid-area: dial; min-width: 0; max-width: 640px; }
.wd__plate { position: relative; }
.wd__face { display: block; cursor: grab; touch-action: pan-y pinch-zoom; -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; outline: 0; }
.wd.is-turning .wd__face { cursor: grabbing; }
.wd__face:focus-visible { outline: 1px solid var(--datum-red); outline-offset: 6px; }
.wd__svg { display: block; width: 100%; height: auto; overflow: visible; }
.wd__tick, .wd__arc, .wd__base { fill: none; stroke: var(--mark); stroke-width: 1; }
.wd__tick--det { stroke: var(--ink-primary); }
.wd__leader { fill: none; stroke: var(--mark); stroke-width: 1; stroke-dasharray: 1 3; }
.wd__arm { stroke: var(--mark-strong); stroke-width: 1; }
.wd__needle { stroke: var(--datum-red); stroke-width: 2; }
.wd__node { fill: var(--datum-red); }
.wd__mk { fill: none; stroke: var(--mark); stroke-width: 1; }
.wd__mk.is-held { fill: var(--datum-red); stroke: none; }

/* type inside the instrument: the system's styles in the dial's own units (the drawing scales, so a 26-unit count
   reads about 24px on a desk and the phone's 20px title on a phone) */
.wd__num { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em; fill: var(--ink-secondary); }
.wd__num.is-on { fill: var(--ink-primary); }
.wd__cap { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em; fill: var(--ink-secondary); }
.wd__count { font-family: var(--font-sans); font-size: 26px; font-weight: 500; letter-spacing: -0.02em; fill: var(--ink-primary); }
.wd__of { fill: var(--ink-secondary); }

/* the settings' names, set beside their detents */
.wd__dets { position: absolute; inset: 0; pointer-events: none; }
.wd__det {
  position: absolute; pointer-events: auto; appearance: none; -webkit-appearance: none;
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  width: max-content; max-width: 200px; margin: 0; padding: 4px 0; border: 0; background: none;
  font: inherit; text-align: left; color: var(--ink-secondary); cursor: pointer;
  -webkit-tap-highlight-color: transparent;   /* a tap flashes no grey box over the paper (check_design, phone round 2) */
}
/* a name is one line of label type: its touch target is drawn by nothing, an invisible 44px band round it */
.wd__det::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: max(100%, 44px); transform: translateY(-50%); }
.wd__det-n { display: none; color: var(--ink-secondary); }
.wd__det .t-label { color: inherit; }
.wd__det[aria-pressed="true"] { color: var(--ink-primary); }
.wd__det[aria-pressed="true"] .copy-slot { color: var(--ink-primary); }
.wd__det:hover { color: var(--ink-primary); }
.wd__det:focus-visible { outline: 1px solid var(--datum-red); outline-offset: 4px; }
.wd__det.is-br { transform: translateX(-100%); align-items: flex-end; text-align: right; max-width: 132px; }
.wd__det.is-tl { transform: translate(-100%, -100%); align-items: flex-end; text-align: right; max-width: 150px; }
.wd__det.is-tr { transform: translate(0, -100%); max-width: 150px; }
.wd__det.is-t { transform: translate(-50%, -100%); align-items: center; text-align: center; }

.wd__hint { margin-top: var(--space-6); color: var(--ink-secondary); }

/* the readout, level with the names over the scale */
.wd__read { grid-area: read; min-width: 0; padding-top: 12px; }
/* the four settings' texts lie on one another; the cell keeps the tallest, so turning never moves the board */
.wd__stack { display: grid; }
.wd__stack > * { grid-area: 1 / 1; min-width: 0; }
.wd__stack > [aria-hidden="true"] { visibility: hidden; }
.wd__name { margin-top: var(--space-3); }
.wd__name .copy-slot { display: inline-block; padding: 6px 0 2px; }
.wd__line { margin-top: var(--space-3); max-width: 54ch; }
.wd__spec { margin-top: var(--space-8); grid-template-columns: 112px 1fr; }
.wd__copy { margin: var(--space-6) 0 0; max-width: 62ch; }

/* the lane: the client's eight ◆ in project order, under the REF-07 bracket, across the board (as the swimlane's YOU
   lane). The bracket is ProcessStrip's; its drops stand over the eight columns instead of its own ends, so the
   overrides carry .wd to outrank its :first-child and :last-child */
.wd__lanebox { grid-area: lane; min-width: 0; margin-top: var(--space-12); }
.wd__lane-cap { margin-bottom: var(--space-3); }
.wd .wd__lane-bracket i { left: calc((100% + var(--gutter-strip)) * var(--c) / 8); right: auto; transform: none; }
.wd .wd__lane-bracket i::after { left: 2px; right: auto; background: var(--mark); }
.wd .wd__lane-bracket i.is-held::after { background: var(--ink-primary); }
.wd .wd__lane-bracket::before { right: calc((100% + var(--gutter-strip)) / 8 - var(--gutter-strip) - 5px); }
.wd__lane-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); column-gap: var(--gutter-strip); }
.wd__lane-d { position: relative; min-width: 0; padding-top: 16px; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.04em; line-height: 1.35; color: var(--ink-secondary); }
.wd__lane-name { display: block; }
.wd__lane-who { display: block; margin-top: 4px; font-size: 10px; text-transform: uppercase; color: var(--ink-secondary); }
.wd__lane-who.t-label { font-size: var(--type-label-size); line-height: 1.35; }
.wd__lane-d.is-held { color: var(--ink-primary); }
.wd__lane-d.is-held .wd__lane-who { color: var(--ink-primary); }

/* the ◆: decide. Solid datum red when the client holds it, hollow in the drafting line when the studio does */
.wd__lg { position: absolute; top: 0; left: -1px; width: 7px; height: 7px; box-sizing: border-box; transform: rotate(45deg); border: 1px solid var(--mark); }
.is-held > .wd__lg { background: var(--datum-red); border-color: var(--datum-red); }

/* the key: every setting against every ◆, rule-less. It stands with reduced motion and without script; when the dial
   can be turned, the dial is the reading and the key steps aside */
.wd__key { grid-area: key; min-width: 0; max-width: 560px; margin-top: var(--space-12); }
html.motion .wd.is-built .wd__key { display: none; }
.wd__key-t { width: 100%; border-collapse: collapse; }
.wd__key-cap { caption-side: top; text-align: left; padding-bottom: var(--space-4); color: var(--ink-secondary); }
.wd__key-t th, .wd__key-t td { height: 22px; padding: 0; font-weight: 400; vertical-align: middle; }
.wd__key-t tbody th, .wd__key-t tfoot th { text-align: left; color: var(--ink-primary); padding-right: var(--space-4); }
.wd__key-t tbody th .ink-2 { display: inline-block; width: 3ch; }
.wd__key-t thead th { width: 48px; text-align: center; color: var(--ink-secondary); padding-bottom: 6px; }
.wd__key-t thead th.is-on { color: var(--ink-primary); }
.wd__key-t tbody td { position: relative; }
.wd__key-t tbody td .wd__lg { top: calc(50% - 3.5px); left: calc(50% - 3.5px); }
.wd__key-t tfoot th { color: var(--ink-secondary); padding-top: 6px; }
.wd__key-t tfoot td { text-align: center; padding-top: 6px; }
.wd__sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* the key alone, as print and the specimen show it: nothing to turn, so no grid around it */
.wd--key { display: block; }
.wd--key .wd__key { margin-top: 0; }

/* motion: only the handing over — a ◆ fills, its label inks, as the index passes it */
html.motion .wd .wd__lane-bracket i::after { transition: background-color var(--dur-hover) var(--ease); }
html.motion .wd__lg { transition: background-color var(--dur-hover) var(--ease), border-color var(--dur-hover) var(--ease); }
html.motion .wd__lane-d, html.motion .wd__lane-who, html.motion .wd__det { transition: color var(--dur-hover) var(--ease); }

/* a phone: the dial above, its settings in two columns under it, the readout, the lane in two columns */
@media (max-width: 720px) {
  .wd { grid-template-columns: minmax(0, 1fr); grid-template-areas: "dial" "read" "lane" "key"; }
  .wd__dial { max-width: none; }
  .wd__num, .wd__cap { font-size: 13px; }
  .wd__dets { position: static; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2) var(--space-4); margin-top: var(--space-4); pointer-events: auto; }
  .wd__det, .wd__det.is-br, .wd__det.is-tl, .wd__det.is-tr, .wd__det.is-t {
    position: relative; transform: none; width: auto; max-width: none; align-items: flex-start; text-align: left; flex-direction: row; gap: 8px;
    left: auto !important; top: auto !important; min-height: 44px;   /* the script places them on the scale inline */
  }
  .wd__det-n { display: inline; flex: none; }
  .wd__det[aria-pressed="true"] .wd__det-n { color: var(--ink-primary); }
  .wd__hint { margin-top: var(--space-4); }
  .wd__read { margin-top: var(--space-12); padding-top: 0; }
  .wd__spec { grid-template-columns: 88px 1fr; }
  .wd__lane-bracket { display: none; }
  .wd__lane-list { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: repeat(4, auto); grid-auto-flow: column; gap: var(--space-4) var(--space-4); }
  .wd__lane-d { padding: 0 0 0 16px; }
  .wd__lane-d .wd__lg { top: 3px; left: 1px; }
  .wd__lane-who { margin-top: 2px; }
  .wd__key { max-width: none; }
  .wd__key-t thead th { width: 34px; }
  .wd__key-t tbody th, .wd__key-t tfoot th { padding-right: var(--space-2); }
  /* the study's own rule for its board: the head stacks on a phone instead of breaking its code ("1A · THE DIAL")
     across two lines beside the long right line */
  .board:has(> .wd) > .board__head { flex-direction: column; row-gap: var(--space-1); }
}

/* ——— 53. RegisteredSheets — 2A · two sheets, registered (why me, notes 14 · 16; design/v-work-with-us, revision 2,
   the director's choice of 2026-11-03, registered the same day): two drafting sheets on one grid, sheet A the bank and
   sheet B the studio, drawing the same four patterns — 01 automation, 02 scale, 03 pipelines, 04 control — one detail
   each, on one line, at the same place on both sheets. As the page scrolls (a pinned moment, 165vh, the home's) B slides
   over A until their registration crosses meet: every pattern falls on its counterpart, the film (FILM-10) lands in the
   bank's PRODUCTION slot, the crosses turn datum red, the 2px datum crosses both and the title block reads
   SHEET A + B · ONE SHEET with its [COPY]. Flat paper and registration, unlike SystemRebuild (41), which rebuilds in
   depth, and PlateRedraw (48), which rewrites one drawing in place.
   Built only from the system: two P2 cards on a P1 board, one P4 aperture, the drafting line (corner brackets,
   registration crosses, tick labels; solid and dotted), the try mark ×, the role glyphs and SVG captions of 36–40
   (.pc-*), the 2px datum, copy slots. The stage is 1184 × 410 units: two 580-wide sheets 24 apart, each moving half the
   distance (302), so they meet in the middle. The drawings are static SVG written by kits/RegisteredSheets/draw.mjs, so
   the section stands fully drawn without script.
   --e (0 → 1) is the registration, --dat the datum, --mrg the merged title block. All three are 1 by default, so with
   reduced motion, without script and under data-sheets="still" the sheets stand registered, A's paper a step under B's.
   Under html.motion on a wide screen the pin's --p (motion.js) drives them; data-sheets="hand" (a card of fixed height)
   gives sheet B to the visitor's hand instead (sheets.js, Truemanity.sheets). Under 1180px nothing is pinned: the
   registered sheet is drawn down the page. The prefix rs- and the attribute data-sheets are used by no other section. ——— */
.rs-pin { --e: 1; --dat: 1; --mrg: 1; }

/* the stage (wide screens): the two cards, one SVG with both drawings (each clipped to its own card, so where the cards
   overlap both drawings show, as two sheets of drafting film would), the title blocks and the film above them */
.rs-stage { position: relative; width: 100%; aspect-ratio: 1184 / 410; }
.rs-stage .rs-card, .rs-layer { position: absolute; top: 0; width: 48.986%; height: 100%; }
.rs-stage .rs-card--a, .rs-layer--a { left: 0; transform: translateX(calc(var(--e) * var(--travel))); }
.rs-stage .rs-card--b, .rs-layer--b { left: 51.014%; transform: translateX(calc(var(--e) * var(--travel) * -1)); }
.rs-stage .rs-card--a { z-index: 1; }
.rs-stage .rs-card--b { z-index: 2; }
.rs-stage .rs-svg { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 3; pointer-events: none; }
.rs-layer--a { z-index: 4; pointer-events: none; }
.rs-layer--b { z-index: 5; pointer-events: none; }   /* the film rides above every line: nothing is drawn over a picture */
.rs-g--a { transform: translateX(calc(var(--e) * var(--travel-u))); }
.rs-g--b { transform: translateX(calc(var(--e) * var(--travel-u) * -1)); }
/* while B is on its way, A's ink recedes under it (to 0.4 for most of the way, back to full in the last few per cent),
   as PlateRedraw's undrawn part does, so the two drawings never tangle at full weight; apart and registered (and so in
   every still form) it is full ink. No new colour: the same ink, less of it, only while the sheet moves (check_design,
   round 1) */
.rs-g--a, .rs-layer--a { opacity: calc(1 - 0.6 * clamp(0, calc(6 * var(--e) * (1 - var(--e))), 1)); }

/* each sheet's outline: corner brackets just outside its corners, so at registration they coincide */
.rs-card::before {
  content: ""; position: absolute; inset: -10px; pointer-events: none; --b: 10px; --m: var(--mark);
  background:
    linear-gradient(var(--m), var(--m)) 0 0 / var(--b) 1px no-repeat,
    linear-gradient(var(--m), var(--m)) 0 0 / 1px var(--b) no-repeat,
    linear-gradient(var(--m), var(--m)) 100% 0 / var(--b) 1px no-repeat,
    linear-gradient(var(--m), var(--m)) 100% 0 / 1px var(--b) no-repeat,
    linear-gradient(var(--m), var(--m)) 0 100% / var(--b) 1px no-repeat,
    linear-gradient(var(--m), var(--m)) 0 100% / 1px var(--b) no-repeat,
    linear-gradient(var(--m), var(--m)) 100% 100% / var(--b) 1px no-repeat,
    linear-gradient(var(--m), var(--m)) 100% 100% / 1px var(--b) no-repeat;
}

/* the drawing: the flow in ink, everything else the 1px drafting line; the labels are the system's SVG captions */
.rs-flow { fill: none; stroke: var(--ink-primary); stroke-width: 1; }
.rs-svg .pc-cap.is-ink { fill: var(--ink-primary); }
.rs-item { fill: none; stroke: var(--ink-primary); stroke-width: 1; }   /* one item of work, a short ink tick */
.rs-stage .rs-axis { opacity: calc(1 - var(--dat)); }                  /* the ink axis gives way to the datum drawn under it */
.rs-x { fill: none; stroke: var(--datum-red); stroke-width: 1; }
.rs-xred { opacity: var(--mrg); }                                       /* the crosses meet: they turn datum red */
.rs-ap { fill: none; stroke: var(--hairline-light); stroke-width: 1; }  /* the bank's slot: an aperture's own 1px edge, empty */
.rs-datum-line { fill: none; stroke: var(--datum-red); stroke-width: 2; }
.rs-datum-node { fill: var(--datum-red); }

/* the title blocks, the film, the datum, the merged block */
.rs-tb p, .rs-merged p { margin: 0; }
.rs-tb .t-label { margin: 3px 0 6px; }
.rs-stage .rs-tb, .rs-stage .rs-film, .rs-merged { position: absolute; }
.rs-datum { position: absolute; height: 2px; margin-top: -1px; background: var(--datum-red); z-index: 2; transform: scaleX(var(--dat)); transform-origin: 0 50%; }
.rs-datum--r { transform: scaleX(clamp(0, calc(var(--dat) * 3 - 2), 1)); }   /* the run past the film draws last */
.rs-datum--l::after { content: ""; position: absolute; right: -2px; top: -1px; width: 4px; height: 4px; background: var(--datum-red); }
.rs-merged { z-index: 6; padding-top: 12px; opacity: var(--mrg); transform: translateY(calc((1 - var(--mrg)) * 2px)); }   /* hangs from the datum's run past the sheet */
.rs-merged .t-mono, .rs-tb--merged .t-mono { color: var(--ink-primary); margin-bottom: 4px; }

.rs-foot { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-3) var(--space-8); margin-top: var(--space-8); }
.rs-read { font-variant-numeric: tabular-nums; }
.rs-source { margin-top: var(--space-3); max-width: 96ch; }

/* the still form (reduced motion, no script, data-sheets="still"): registered, and sheet A's paper shows a step up-left
   under B — two sheets, one drawing. The live and hand forms take the step away: there A must end exactly under B. */
.rs-stage .rs-card--a { translate: -12px -12px; }

/* the pinned moment (wide screens, motion allowed): 0 → .10 the two sheets side by side · .10 → .68 B slides over A,
   eased · .68 → .80 the datum draws across both · .76 → .86 the crosses turn red and the merged block settles · a hold */
@media (min-width: 1180px) {
  html.motion .rs-pin[data-pin] {
    height: 165vh;   /* the home's pinned moment's length (.pin): longer left most of the board blank */
    --k: clamp(0, calc((var(--p, 0) - 0.10) / 0.58), 1);
    --e: calc(var(--k) * var(--k) * (3 - 2 * var(--k)));
    --dat: clamp(0, calc((var(--p, 0) - 0.68) / 0.12), 1);
    --mrg: clamp(0, calc((var(--p, 0) - 0.76) / 0.10), 1);
  }
  html.motion .rs-pin[data-pin] .rs-hold { position: sticky; top: max(16px, calc(50vh - 250px)); }
  html.motion .rs-pin[data-pin] .rs-stage .rs-card--a { translate: none; }
}

/* by hand (a card): sheet B is the handle, a role="slider" (sheets.js adds .is-hand only where the wide stage shows).
   B follows the hand exactly, with no easing of its own; when it meets A the datum, the red crosses and the merged block
   follow — drawn under html.motion, at once without it. */
.rs.is-hand .rs-pin { --e: var(--h, 0); --dat: 0; --mrg: 0; }
.rs.is-hand.is-registered .rs-pin { --dat: 1; --mrg: 1; }
.rs.is-hand .rs-stage .rs-card--a { translate: none; }
.rs.is-hand .rs-stage { cursor: grab; touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.rs.is-hand.is-dragging .rs-stage { cursor: grabbing; }
.rs.is-hand .rs-card--b { outline: 0; }
.rs.is-hand .rs-card--b:focus-visible { outline: 1px solid var(--datum-red); outline-offset: 2px; }
html.motion .rs.is-hand .rs-datum { transition: transform var(--dur-enter) var(--ease); }
html.motion .rs.is-hand .rs-merged, html.motion .rs.is-hand .rs-xred, html.motion .rs.is-hand .rs-axis { transition: opacity var(--dur-enter) var(--ease), transform var(--dur-enter) var(--ease); }
html.motion .rs.is-hand.is-registered .rs-datum--l { transition-duration: calc(var(--dur-enter) * 3); }   /* a line draws at three times the enter, as data-draw does */
html.motion .rs.is-hand.is-registered .rs-datum--r { transition-delay: calc(var(--dur-enter) * 2.5); }
html.motion .rs.is-hand.is-registered .rs-xred { transition-delay: calc(var(--dur-enter) * 1.5); }
html.motion .rs.is-hand.is-registered .rs-merged { transition-delay: calc(var(--dur-enter) * 2.25); }

/* narrow screens and the phone: no pin; the registered sheet drawn down the page, sheet A's paper showing under B's */
.rs-narrow { display: none; }
@media (max-width: 1179px) {
  .rs-pin { display: none; }
  .rs-narrow { display: grid; grid-template-columns: minmax(0, 400px) minmax(0, 1fr); gap: var(--space-12); align-items: end; }
}
.rs-tall { position: relative; padding: 10px 0 0 10px; }
.rs-tall .rs-card--a { position: absolute; top: 0; left: 0; right: 10px; bottom: 10px; }
.rs-tall .rs-card--b { padding-bottom: var(--space-6); }
.rs-tallart { position: relative; }
.rs-tallart .rs-svg { display: block; width: 100%; height: auto; }
.rs-tallart .rs-film { position: absolute; }
.rs-tbs { display: grid; gap: var(--space-6); padding: var(--space-2) var(--space-4) 0; }
.rs-narrow__side { display: grid; gap: var(--space-8); padding-bottom: var(--space-6); }
@media (max-width: 720px) {
  .rs-narrow { grid-template-columns: minmax(0, 1fr); gap: var(--space-8); }
  .rs-narrow__side { padding-bottom: 0; }
}

/* ════════ Motion — motion.js (NOTES 11): depth, reveals, drawn lines, pinned moments, only where they carry meaning ════════
   Every rule sits under html.motion, which motion.js sets only when the visitor allows motion; without it the page
   stands, fully readable. Slow and physical: the system's ease, the 400ms enter, lines drawn at three times that. */
html.motion [data-reveal] { opacity: 0; transform: translateY(2px); transition: opacity var(--dur-enter) var(--ease), transform var(--dur-enter) var(--ease); transition-delay: calc(var(--i, 0) * 110ms); }
html.motion [data-reveal].is-in { opacity: 1; transform: none; }
html.motion [data-draw] { transform: scaleX(0); transform-origin: 0 50%; transition: transform calc(var(--dur-enter) * 3) var(--ease); transition-delay: calc(var(--i, 0) * 110ms); }
html.motion [data-draw="down"] { transform: none; clip-path: inset(0 0 100% 0); transition: clip-path calc(var(--dur-enter) * 3) var(--ease); transition-delay: calc(var(--i, 0) * 110ms); }
html.motion [data-draw].is-in { transform: none; clip-path: inset(0); }

/* HeroBand: the band is the paper in front; the two photographs behind it move slower, each at its own depth */
html.motion .hero-band__sky, html.motion .hero-band__floor { position: relative; overflow: hidden; background-image: none; }
html.motion .hero-band__sky::before, html.motion .hero-band__floor::before { content: ""; position: absolute; left: 0; right: 0; top: -72px; bottom: -72px; transform: translate3d(0, var(--py, 0px), 0); will-change: transform; }
html.motion .hero-band__sky::before { background: var(--hero-top, none) var(--hero-top-pos, 50% 30%) / cover no-repeat; }
html.motion .hero-band__floor::before { background: var(--hero-bottom, none) var(--hero-bottom-pos, 50% 50%) / cover no-repeat; }
html.motion .hero-band__top { position: relative; z-index: 1; }

/* BriefSheet: the picture behind moves slower than the sheet resting on it */
html.motion .brief { overflow: hidden; background-image: none; }
html.motion .brief::before { content: ""; position: absolute; left: 0; right: 0; top: -9%; bottom: -9%; background: var(--brief-photo, none) var(--brief-pos, 50% 18%) / cover no-repeat; transform: translate3d(0, var(--py, 0px), 0); will-change: transform; }
html.motion .brief > * { position: relative; z-index: 1; }

/* CornerIndex: the two pictures come in toward their shared corner and lock there as the section reaches the middle */
html.motion .corner-index__a { transform: translate3d(max(0px, calc(var(--py, 0px) * -1)), min(0px, var(--py, 0px)), 0); }
html.motion .corner-index__b { transform: translate3d(min(0px, var(--py, 0px)), max(0px, calc(var(--py, 0px) * -1)), 0); }

/* The pinned moment: entering the dark room, the monolith holds while the portrait comes out of the black and the
   laser crosses the work. --p runs 0 → 1 through the pin's length (motion.js). */
html.motion .pin { height: 165vh; }
html.motion .pin__hold { position: sticky; top: max(16px, calc(50vh - 390px)); }
html.motion .pin .monolith__figure { opacity: clamp(0.08, calc(var(--p, 0) * 1.6), 1); transform: translate3d(0, calc((1 - clamp(0, calc(var(--p, 0) * 1.6), 1)) * 40px), 0); }
html.motion .pin .monolith__laser { transform: scaleX(clamp(0, calc(var(--p, 0) * 1.8 - 0.35), 1)); transform-origin: 0 50%; }
@media (max-width: 900px) { html.motion .pin { height: auto; } html.motion .pin__hold { position: static; } html.motion .pin .monolith__figure { opacity: 1; transform: none; } html.motion .pin .monolith__laser { transform: none; } }
