/* ==== build: css/tokens.css ==== */
/* tokens.css: design tokens (SPEC §B). Foundation-owned. Section CSS uses the semantic
   variables (--bg, --fg, --ai, --conflict ...) and never hard-codes a hex value. */

/* Windows' hand face, scaled toward Architects Daughter's metrics, which G0.1's redline positions are tuned to */
@font-face { font-family: "DTC Hand Fallback"; src: local("Segoe Print"), local("SegoePrint"); size-adjust: 85%; }

:root {
  /* B1 desk + shell */
  --desk: #0B0E12;
  --tb-bg: #0F1318;
  --tb-rule: #263140;

  /* B1 PAPER (plotted set) */
  --paper: #F4F1EA;
  --paper-2: #EAE5DA;
  --paper-rule: #D6D0C3;
  --ink: #1A1D21;
  --pencil: #5B6169;
  --redline-ink: #B42318;
  --vision-ink: #3F5F00;
  --verify-ink: #8A5300;
  --mismatch-ink: #7A2E8C;
  --notshown-ink: #1F5E7A;
  --highlighter: #FFE14D;

  /* B1 MODEL (CAD model space) */
  --model: #10151B;
  --model-2: #18202A;
  --model-rule: #2A3542;
  --line: #E6ECF2;
  --line-dim: #93A1B0;
  --vision: #C6F432;
  --redline: #FF6B5E;
  --verify: #FFB547;
  --mismatch: #D9A6FF;
  --notshown: #7CC4F0;

  /* B1 CAD layer colors (model-space drawings only) */
  --lyr-wall: #E6ECF2; --lyr-door: #F2D46B; --lyr-glaz: #7CC4F0; --lyr-fixt: #B7C2CE;
  --lyr-furn: #5E6B78; --lyr-dims: #8FC9A8; --lyr-grid: #93A1B0;

  /* B1 occupancy tints for the AI layer (fills only) */
  --occ-a: rgba(255,181,71,.16);
  --occ-m: rgba(124,196,240,.14);
  --occ-r: rgba(217,166,255,.14);
  --occ-acc: rgba(198,244,50,.10);
  --occ-exit: rgba(230,236,242,.08);

  /* derived fills (not text) */
  --vision-fill: rgba(198,244,50,.22);   /* fixed delta fill on model, highlighter on dark */
  --scrim: rgba(5,7,10,.62);             /* behind drawers */

  /* B2 typography */
  --font-sans: "Archivo", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, "PingFang SC", "Microsoft YaHei", monospace;
  --font-hand: "Architects Daughter", "DTC Hand Fallback", "Bradley Hand", cursive;

  --fs-hero:    clamp(2.5rem, 1.2rem + 3.6vw, 6rem);
  --fs-h2:      clamp(2rem, 1.1rem + 2.6vw, 4.25rem);
  --fs-h3:      clamp(1.25rem, 1.05rem + 0.7vw, 1.75rem);
  --fs-lead:    clamp(1.0625rem, 0.98rem + 0.35vw, 1.3125rem);
  --fs-body:    clamp(1rem, 0.96rem + 0.2vw, 1.125rem);
  --fs-small:   0.875rem;
  --fs-mono:    0.8125rem;
  --fs-micro:   0.75rem;
  --fs-sheetno: clamp(2.25rem, 1.6rem + 1.8vw, 3.75rem);

  --lh-display: 0.98; --lh-head: 1.06; --lh-body: 1.55; --lh-mono: 1.45;
  --lh-zh-display: 1.18; --lh-zh-head: 1.25; --lh-zh-body: 1.75;
  --tr-display: -0.025em; --tr-head: -0.015em; --tr-caps: 0.08em;
  --measure: 62ch; --measure-zh: 36em;

  /* B3 space, grid */
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 24px; --s-6: 32px; --s-7: 48px; --s-8: 64px; --s-9: 96px; --s-10: 128px;
  --gutter: clamp(16px, 2vw, 32px);
  --sheet-pad: clamp(16px, 3.2vw, 56px);
  --sheet-gap: clamp(12px, 1.6vw, 24px);
  --content-max: 1680px;
  --tb-w: 264px;

  /* sheet frame geometry (B7.1): outer border at --frame-inset, inner border 6px inside it.
     --sheet-inner is the distance from the sheet edge to the inner border's inside face. */
  --frame-inset: var(--s-3);
  --frame-gap: 6px;
  --sheet-inner: calc(var(--frame-inset) + var(--frame-gap) + 1px);

  /* shell metrics */
  --bbar-h: 56px;
  --chip-h: 44px;
  --progress: 0;   /* 0..1 reading progress, written on <html> by core.js */

  /* B4 radii, borders, shadows, glows */
  --r-0: 0; --r-1: 2px; --r-2: 4px; --r-3: 8px; --r-round: 999px;
  --bw-hair: 1px; --bw-rule: 1.5px; --bw-heavy: 2.5px;
  --sh-sheet: 0 2px 0 rgba(0,0,0,.55), 0 28px 56px -28px rgba(0,0,0,.75);
  --sh-card: 0 1px 0 rgba(0,0,0,.06), 0 10px 24px -14px rgba(0,0,0,.35);
  --sh-loupe: 0 0 0 1.5px var(--vision), 0 18px 40px -12px rgba(0,0,0,.65);
  --glow-ai: 0 0 0 1px rgba(198,244,50,.55), 0 0 18px rgba(198,244,50,.32);
  --glow-red: 0 0 14px rgba(255,107,94,.45);
  --sh-pop: 0 14px 32px -14px rgba(0,0,0,.55);

  /* B5 z-index layers */
  --z-base: 0; --z-sheet: 1; --z-drawing-overlay: 10; --z-loupe: 20; --z-card: 30; --z-sticky: 40;
  --z-titleblock: 50; --z-drawer: 60; --z-popover: 70; --z-toast: 80; --z-skip: 90;

  /* B6 motion */
  --ease-out: cubic-bezier(.2,0,0,1);
  --ease-in-out: cubic-bezier(.65,0,.35,1);
  --ease-snap: cubic-bezier(.2,1.25,.35,1);
  --ease-stamp: cubic-bezier(.3,1.5,.5,1);
  --dur-1: 80ms; --dur-2: 120ms; --dur-3: 150ms; --dur-4: 240ms; --dur-5: 420ms; --dur-6: 600ms; --dur-7: 900ms;
}

@media (min-width: 1920px) {
  :root { --tb-w: 296px; }
}

/* ---- Semantic theme variables ------------------------------------------------------
   Desk (default on :root): the page between sheets, the title block, chip, bottom bar.
   .sheet--paper / .theme-paper and .sheet--model / .theme-model redefine every one.
   Extra semantic names beyond B1: --hl (highlighter fill behind text), --primary and
   --on-primary (primary button), --card-sh (card shadow), --grid-c (grid/dim linework),
   --scale-k (fine ink for ticks and hairlines that are not text). */
:root, .theme-desk {
  --bg: var(--desk); --bg-2: var(--tb-bg); --fg: var(--line); --fg-2: var(--line-dim); --rule: var(--tb-rule);
  --ai: var(--vision); --conflict: var(--redline); --verify-c: var(--verify);
  --mismatch-c: var(--mismatch); --notshown-c: var(--notshown); --pass-c: var(--line-dim);
  --link: var(--vision); --focus: var(--vision);
  --hl: var(--vision-fill); --primary: var(--vision); --on-primary: var(--model);
  --card-sh: var(--sh-card); --grid-c: var(--lyr-grid); --scale-k: var(--line-dim);
}
.sheet--paper, .theme-paper {
  --bg: var(--paper); --bg-2: var(--paper-2); --fg: var(--ink); --fg-2: var(--pencil); --rule: var(--paper-rule);
  --ai: var(--vision-ink); --conflict: var(--redline-ink); --verify-c: var(--verify-ink);
  --mismatch-c: var(--mismatch-ink); --notshown-c: var(--notshown-ink); --pass-c: var(--pencil);
  --link: var(--notshown-ink); --focus: var(--ink);
  --hl: var(--highlighter); --primary: var(--ink); --on-primary: var(--paper);
  --card-sh: none; --grid-c: var(--pencil); --scale-k: var(--pencil);
}
.sheet--model, .theme-model {
  --bg: var(--model); --bg-2: var(--model-2); --fg: var(--line); --fg-2: var(--line-dim); --rule: var(--model-rule);
  --ai: var(--vision); --conflict: var(--redline); --verify-c: var(--verify);
  --mismatch-c: var(--mismatch); --notshown-c: var(--notshown); --pass-c: var(--line-dim);
  --link: var(--vision); --focus: var(--vision);
  --hl: var(--vision-fill); --primary: var(--vision); --on-primary: var(--model);
  --card-sh: var(--sh-card); --grid-c: var(--lyr-grid); --scale-k: var(--line-dim);
}

/* ==== build: css/base.css ==== */
/* base.css: reset, type, sheet frame and zones, shared components (SPEC §B7, §B8),
   the language rule (§G1) and the reduced-motion guard (§B6). Foundation-owned.
   Element-level defaults use :where() so any single section class overrides them. */

/* ---- Reset -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
  color-scheme: dark;
  background: var(--desk);
  scroll-behavior: smooth;
  scroll-padding-top: var(--s-4);
}
html[data-motion="off"] { scroll-behavior: auto; }
body {
  margin: 0;
  min-height: 100vh;
  background: var(--desk);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 400;
  font-stretch: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip; /* last resort only (B3); every element must fit at 360px on its own */
}
body:lang(zh-Hans) { line-height: var(--lh-zh-body); }
:where(h1, h2, h3, h4, h5, h6, p, ol, ul, dl, dd, figure, blockquote, fieldset) { margin: 0; }
:where(ol, ul)[class] { padding: 0; list-style: none; }
:where(fieldset) { padding: 0; border: 0; min-width: 0; }
:where(img, canvas, video) { display: block; max-width: 100%; height: auto; }
:where(svg) { max-width: 100%; }
:where(button, input, select, textarea) { font: inherit; color: inherit; }
:where(button) { cursor: pointer; }
:where(a) { color: var(--link); text-underline-offset: 3px; text-decoration-thickness: 1px; }
:where(a:hover) { text-decoration-thickness: 2px; }
:where(strong, b) { font-weight: 700; }
:where(table) { border-collapse: collapse; }
[hidden] { display: none !important; }
::selection { background: var(--hl); color: var(--fg); }

/* ---- §G1 language rule ----------------------------------------------------------------- */
html[data-lang="en"] [lang="zh-Hans"], html[data-lang="zh"] [lang="en"] { display: none !important; }

/* ---- §B6.7 reduced motion (core.js sets data-motion="off"; the media query covers no-JS) - */
/* Delays go to 0 too, or staggered entrances would still arrive late, one by one. */
html[data-motion="off"] *, html[data-motion="off"] *::before, html[data-motion="off"] *::after {
  animation-duration: 1ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important;
  transition-duration: 1ms !important; transition-delay: 0s !important; scroll-behavior: auto !important; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  html *, html *::before, html *::after {
    animation-duration: 1ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important;
    transition-duration: 1ms !important; transition-delay: 0s !important; scroll-behavior: auto !important; }
}

/* ---- No-JS fallbacks ------------------------------------------------------------------- */
html:not(.js) .seg, html:not(.js) .js-only { display: none !important; }
html.js .nojs-only { display: none !important; }

/* ---- Focus (B8) -------------------------------------------------------------------------- */
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
:focus:not(:focus-visible) { outline: none; }
[tabindex="-1"]:focus { outline: none; }
.halo:focus-visible { box-shadow: 0 0 0 4px var(--bg); }   /* add on controls that sit over linework */

/* ---- Visually hidden + skip link --------------------------------------------------------- */
.vh {
  position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important;
  overflow: hidden !important; clip: rect(0 0 0 0) !important; clip-path: inset(50%) !important; white-space: nowrap !important; border: 0 !important;
}
.skip {
  position: fixed; left: var(--s-4); top: var(--s-4); z-index: var(--z-skip);
  padding: 12px 18px; border-radius: var(--r-1);
  background: var(--vision); color: var(--model);
  font: 600 15px/1.1 var(--font-sans); font-stretch: 108%; text-decoration: none;
  transform: translateY(calc(-100% - 40px));
}
.skip:focus { transform: none; }
.skip:focus-visible { outline-color: var(--line); }

/* ---- Type helpers ------------------------------------------------------------------------ */
.mono { font-family: var(--font-mono); font-size: var(--fs-mono); line-height: var(--lh-mono); font-variant-numeric: tabular-nums; }
.caps { font-stretch: 125%; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; }
.caps:lang(zh-Hans) { font-stretch: 100%; letter-spacing: .02em; }
.micro { font: 600 var(--fs-micro)/1.35 var(--font-mono); letter-spacing: var(--tr-caps); text-transform: uppercase; color: var(--fg-2); }
.micro:lang(zh-Hans) { letter-spacing: .02em; }
.small { font-size: var(--fs-small); }
.hand { font-family: var(--font-hand); color: var(--conflict); }
:where(.sheet, .ft) :where(p) { max-width: var(--measure); }
:where(.sheet, .ft) :where(p):lang(zh-Hans) { max-width: var(--measure-zh); }
:where(.sheet) :where(h3) { font-size: var(--fs-h3); font-weight: 700; font-stretch: 108%; line-height: 1.15; letter-spacing: -.005em; }
:where(.sheet) :where(h3):lang(zh-Hans) { line-height: var(--lh-zh-head); letter-spacing: .01em; }

/* ---- Sheets (§D skeleton, B3 layout) ------------------------------------------------------ */
.sheet {
  position: relative;
  min-width: 0;
  background-color: var(--bg);
  color: var(--fg);
  box-shadow: var(--sh-sheet);
}
.sheet + .sheet { margin-top: var(--sheet-gap); }

/* No content-visibility on the sheets: Chrome leaves a skipped box out of the accessibility tree, or (for screen
   readers) exposes it unstyled, both languages at once (SPEC §B3). */

/* B7.11 paper grain */
.sheet--paper {
  background-color: var(--paper);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .10  0 0 0 0 .09  0 0 0 0 .07  0 0 0 .05 0'/></filter><rect width='100%' height='100%' filter='url(%23g)'/></svg>");
}
/* B7.12 model-space dot grid */
.sheet--model {
  background-color: var(--model);
  background-image: radial-gradient(circle at 1px 1px, rgba(147,161,176,.14) 1px, transparent 1.4px), linear-gradient(rgba(147,161,176,.05) 1px, transparent 1px), linear-gradient(90deg, rgba(147,161,176,.05) 1px, transparent 1px);
  background-size: 24px 24px, 120px 120px, 120px 120px;
}
@media (pointer: fine) { .sheet--model .illus :is(svg, canvas) { cursor: crosshair; } }

/* B7.1 frame: the outer border is drawn as eight corner-anchored strokes so it can plot in
   from the corners; the inner border is ::after, crop marks are ::before. */
.sheet__frame {
  --fw: var(--bw-rule);
  position: absolute; inset: var(--frame-inset); z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(var(--fg), var(--fg)), linear-gradient(var(--fg), var(--fg)),
    linear-gradient(var(--fg), var(--fg)), linear-gradient(var(--fg), var(--fg)),
    linear-gradient(var(--fg), var(--fg)), linear-gradient(var(--fg), var(--fg)),
    linear-gradient(var(--fg), var(--fg)), linear-gradient(var(--fg), var(--fg));
  background-repeat: no-repeat;
  background-position: left top, right top, left bottom, right bottom, left top, left bottom, right top, right bottom;
  background-size: 50% var(--fw), 50% var(--fw), 50% var(--fw), 50% var(--fw), var(--fw) 50%, var(--fw) 50%, var(--fw) 50%, var(--fw) 50%;
  transition: background-size var(--dur-7) var(--ease-in-out);
}
.sheet__frame::after {
  content: ""; position: absolute; inset: var(--frame-gap);
  border: 1px solid var(--fg); opacity: .6;
}
.sheet__frame::before {
  content: ""; position: absolute; inset: -7px; opacity: .7;
  background-image:
    linear-gradient(var(--fg), var(--fg)), linear-gradient(var(--fg), var(--fg)),
    linear-gradient(var(--fg), var(--fg)), linear-gradient(var(--fg), var(--fg)),
    linear-gradient(var(--fg), var(--fg)), linear-gradient(var(--fg), var(--fg)),
    linear-gradient(var(--fg), var(--fg)), linear-gradient(var(--fg), var(--fg));
  background-repeat: no-repeat;
  background-position: left top, left top, right top, right top, left bottom, left bottom, right bottom, right bottom;
  background-size: 14px 1px, 1px 14px, 14px 1px, 1px 14px, 14px 1px, 1px 14px, 14px 1px, 1px 14px;
}
.sheet__frame::after, .sheet__frame::before, .sheet__frame > * { transition: opacity var(--dur-5) var(--ease-out) var(--dur-5); }

/* zone strips: ticks span the 6px band between the borders; labels sit just inside */
.sheet__zones-x, .sheet__zones-y {
  position: absolute; display: flex; counter-reset: dtcz;
  font: 500 10px/1 var(--font-mono); color: var(--fg-2); font-variant-numeric: tabular-nums;
}
.sheet__zones-x { left: 0; right: 0; top: 0; height: var(--frame-gap); }
.sheet__zones-x--b { top: auto; bottom: 0; }
.sheet__zones-y { top: 0; bottom: 0; left: 0; width: var(--frame-gap); flex-direction: column; }
.sheet__zones-y--r { left: auto; right: 0; }
.sheet__zones-x > b, .sheet__zones-y > b { flex: 1 1 0; position: relative; font-weight: inherit; counter-increment: dtcz; }
.sheet__zones-x > b + b { border-left: 1px solid var(--fg); }
.sheet__zones-y > b + b { border-top: 1px solid var(--fg); }
.sheet__zones-x > b::after { content: counter(dtcz); position: absolute; left: 50%; top: calc(var(--frame-gap) + 5px); transform: translateX(-50%); }
.sheet__zones-x--b > b::after { top: auto; bottom: calc(var(--frame-gap) + 5px); }
.sheet__zones-y > b::after { content: counter(dtcz, upper-alpha); position: absolute; top: 50%; left: calc(var(--frame-gap) + 5px); transform: translateY(-50%); }
.sheet__zones-y--r > b::after { left: auto; right: calc(var(--frame-gap) + 5px); }
@media (max-width: 767.98px) {
  .sheet__zones-x, .sheet__zones-y, .sheet__frame::before { display: none; }
}

/* plot-in: core.js adds html.frames once it observes sheets, and .is-in on each sheet when
   it first crosses 15% visibility. Without core.js the frames are simply drawn. */
html.frames[data-motion="on"] .sheet:not(.is-in) .sheet__frame {
  background-size: 0 var(--fw), 0 var(--fw), 0 var(--fw), 0 var(--fw), var(--fw) 0, var(--fw) 0, var(--fw) 0, var(--fw) 0;
}
html.frames[data-motion="on"] .sheet:not(.is-in) .sheet__frame::after,
html.frames[data-motion="on"] .sheet:not(.is-in) .sheet__frame::before,
html.frames[data-motion="on"] .sheet:not(.is-in) .sheet__frame > :is(.sheet__zones-x, .sheet__zones-y) { opacity: 0; }

/* body: 1 column (xs/sm), 8 (md), 12 (lg+). Children default to full width; place them
   on columns only inside min-width media queries. */
.sheet__body {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: minmax(0, 1fr); column-gap: var(--gutter);
  max-width: var(--content-max); margin-inline: auto;
  padding: calc(var(--sheet-inner) + var(--sheet-pad));
}
.sheet__body > * { grid-column: 1 / -1; min-width: 0; }
@media (min-width: 768px) { .sheet__body { grid-template-columns: repeat(8, minmax(0, 1fr)); } }
@media (min-width: 1280px) { .sheet__body { grid-template-columns: repeat(12, minmax(0, 1fr)); } }

.sheet__head { margin-bottom: var(--s-7); }
.sheet__eyebrow {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-3);
  margin: 0 0 var(--s-5); max-width: none;
  font: 700 0.8125rem/1.2 var(--font-sans); font-stretch: 125%; letter-spacing: .06em; text-transform: uppercase;
  color: var(--fg-2);
}
.sheet__eyebrow:lang(zh-Hans) { font-stretch: 100%; letter-spacing: .04em; }
.sheet__no {
  display: inline-block; padding: 4px 7px 3px;
  border: var(--bw-rule) solid var(--fg); border-radius: var(--r-1);
  font: 600 0.8125rem/1 var(--font-mono); letter-spacing: .02em; font-stretch: 100%;
  font-variant-numeric: tabular-nums; color: var(--fg);
}
.sheet__h {
  font-size: var(--fs-h2); font-weight: 760; font-stretch: 108%;
  letter-spacing: var(--tr-head); line-height: 1.02; text-wrap: balance;
}
h1.sheet__h, .sheet__h--hero {
  font-size: var(--fs-hero); font-weight: 780; letter-spacing: var(--tr-display); line-height: var(--lh-display);
}
.sheet__h:lang(zh-Hans) { font-weight: 700; letter-spacing: .01em; line-height: var(--lh-zh-head); }
h1.sheet__h:lang(zh-Hans), .sheet__h--hero:lang(zh-Hans) { line-height: var(--lh-zh-display); }
.sheet__lead { font-size: var(--fs-lead); line-height: 1.5; max-width: var(--measure); }
.sheet__lead:lang(zh-Hans) { line-height: var(--lh-zh-body); max-width: var(--measure-zh); }

/* ---- B8 buttons ---------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: 44px; min-width: 44px; padding: 12px 20px;
  border: var(--bw-rule) solid transparent; border-radius: var(--r-1);
  font: 600 15px/1.15 var(--font-sans); font-stretch: 108%; text-align: center; text-decoration: none;
  background: transparent; color: var(--fg); cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out);
}
.btn--primary { background: var(--primary); color: var(--on-primary); border-color: var(--primary); }
.btn--secondary { border-color: var(--fg); }
.btn--ghost { min-width: 0; padding-inline: 2px; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.btn--sm { min-height: 36px; padding: 8px 14px; font-size: 14px; }
@media (pointer: coarse) { .btn--sm { min-height: 44px; } }   /* B8: 44px targets on touch */
@media (hover: hover) {
  .btn:not(.btn--ghost):hover { transform: translate(0, -1px); box-shadow: 2px 2px 0 var(--fg); }
  .btn--ghost:hover { text-decoration-thickness: 2px; }
}
.btn:not(.btn--ghost):active { transform: none; box-shadow: none; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; transform: none; box-shadow: none; }

/* ---- B8 citation chip + popover --------------------------------------------------------- */
.cite {
  display: inline-flex; align-items: center; min-height: 24px;
  padding: 2px 6px; border: 1px solid var(--fg-2); border-radius: var(--r-1);
  font: 500 var(--fs-mono)/1.3 var(--font-mono); font-variant-numeric: tabular-nums;
  white-space: nowrap; color: var(--fg); background: transparent; text-decoration: none;
  vertical-align: baseline;
}
button.cite { cursor: pointer; }
button.cite:hover { border-color: var(--fg); }
button.cite[aria-expanded="true"] { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.pop {
  position: absolute; z-index: var(--z-popover);
  width: max-content; max-width: min(36ch, calc(100vw - 32px));
  padding: 10px 12px;
  background: var(--bg-2); color: var(--fg);
  border: 1px solid var(--fg-2); border-radius: var(--r-1); box-shadow: var(--sh-pop);
  font-size: var(--fs-small); line-height: 1.45;
}
.pop:lang(zh-Hans) { line-height: 1.65; }

/* ---- B8 segmented toggle ------------------------------------------------------------------- */
.seg { display: inline-flex; align-items: stretch; flex: none; }
.seg > button {
  appearance: none; margin: 0; min-height: 32px; min-width: 40px; padding: 0 10px;
  border: 1px solid var(--fg); background: transparent; color: var(--fg);
  font: 600 12px/1 var(--font-mono); letter-spacing: .04em; white-space: nowrap;
}
.seg > button + button { border-left-width: 0; }
.seg > button:first-of-type { border-radius: var(--r-1) 0 0 var(--r-1); }
.seg > button:last-of-type { border-radius: 0 var(--r-1) var(--r-1) 0; }
.seg > button[aria-pressed="true"] { background: var(--fg); color: var(--bg); }
.seg > button:disabled { opacity: .45; cursor: not-allowed; }
@media (hover: hover) { .seg > button[aria-pressed="false"]:not(:disabled):hover { background: var(--hl); } }
@media (pointer: coarse) { .seg > button { min-height: 44px; min-width: 44px; } }

/* ---- B8 schedule table ------------------------------------------------------------------- */
.sched { width: 100%; border: var(--bw-heavy) solid var(--fg); font-size: var(--fs-small); }
.sched th {
  padding: 8px 10px; text-align: left; vertical-align: bottom;
  border-bottom: var(--bw-rule) solid var(--fg);
  font: 600 var(--fs-micro)/1.3 var(--font-mono); letter-spacing: .06em; text-transform: uppercase;
}
.sched td { padding: 8px 10px; vertical-align: top; border-top: 1px solid var(--rule); }
.sched tbody tr:nth-child(even) { background: color-mix(in srgb, var(--bg-2) 50%, transparent); }
.sched .num, .sched td[data-num] { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
@media (max-width: 767.98px) {
  .sched, .sched tbody, .sched tr, .sched td { display: block; }
  .sched { border-width: var(--bw-heavy) 0 0; }
  .sched thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .sched tr { padding: var(--s-3) 0; border-bottom: 1px solid var(--fg); }
  .sched td { border: 0; padding: 3px 0; text-align: left; }
  .sched td:is([data-label], [data-label-en]) { display: grid; grid-template-columns: minmax(6.5rem, 34%) minmax(0, 1fr); gap: var(--s-3); }
  .sched td:is([data-label], [data-label-en])::before {
    content: attr(data-label);
    font: 600 var(--fs-micro)/1.5 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--fg-2);
  }
  html[data-lang="en"] .sched td[data-label-en]::before { content: attr(data-label-en); }
  html[data-lang="zh"] .sched td[data-label-zh]::before { content: attr(data-label-zh); }
}

/* ---- B8 card, bottom sheet ------------------------------------------------------------- */
.card { background: var(--bg-2); color: var(--fg); border: 1px solid var(--rule); border-radius: var(--r-1); box-shadow: var(--card-sh); }
.bsheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-drawer);
  max-height: 60vh; overflow-y: auto; overscroll-behavior: contain;
  padding: var(--s-3) var(--s-4) calc(var(--s-4) + env(safe-area-inset-bottom));
  background: var(--bg); color: var(--fg);
  border-radius: var(--r-3) var(--r-3) 0 0;
  box-shadow: 0 -16px 40px -16px rgba(0,0,0,.6);
  transform: translateY(105%); visibility: hidden;
  transition: transform var(--dur-5) var(--ease-out), visibility 0s linear var(--dur-5);
}
.bsheet.is-open { transform: none; visibility: visible; transition: transform var(--dur-5) var(--ease-out), visibility 0s; }
.bsheet__handle { display: block; width: 40px; height: 4px; margin: 0 auto var(--s-3); border-radius: 2px; background: var(--fg-2); opacity: .7; }

/* ---- B7.13 status chip --------------------------------------------------------------------- */
.st {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 6px; border: 1px solid currentColor; border-radius: var(--r-1);
  font: 600 var(--fs-micro)/1.25 var(--font-mono); letter-spacing: .04em; text-transform: uppercase; white-space: nowrap;
}
.st__i { width: 12px; height: 12px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.st--conflict { color: var(--conflict); }
.st--mismatch { color: var(--mismatch-c); }
.st--notshown { color: var(--notshown-c); }
.st--verify { color: var(--verify-c); }
.st--pass { color: var(--pass-c); }

/* ---- B7.14 illustrative label (never hidden, covered or faded) --------------------------- */
.illus { position: relative; margin: 0; min-width: 0; }
.illus__tag {
  position: absolute; left: 0; top: 0; z-index: var(--z-card);
  margin: 0; padding: 2px 8px; max-width: none;
  border: 1px dashed var(--fg-2); background: var(--bg); color: var(--fg);
  font: 600 var(--fs-micro)/1.35 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; white-space: nowrap;
  opacity: 1 !important; visibility: visible !important; pointer-events: none;
}
.illus figcaption { margin-top: var(--s-3); font: 400 var(--fs-mono)/var(--lh-mono) var(--font-mono); color: var(--fg-2); max-width: var(--measure); }
.illus figcaption:lang(zh-Hans) { font-family: var(--font-sans); font-size: var(--fs-small); line-height: 1.7; }

/* ---- B7.2 drawing title bar ----------------------------------------------------------------- */
.dtitle { display: flex; flex-wrap: wrap; align-items: flex-end; row-gap: var(--s-3); margin-top: var(--s-4); padding-bottom: 6px; }
.dtitle__bubble {
  flex: none; position: relative; display: grid; grid-template-rows: 1fr 1fr; justify-items: center;
  width: 40px; height: 40px; margin-right: var(--s-3);
  border: var(--bw-rule) solid var(--fg); border-radius: 50%;
}
.dtitle__bubble::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; border-top: 1px solid var(--fg); }
.dtitle__bubble b { align-self: end; padding-bottom: 2px; font: 600 13px/1 var(--font-mono); }
.dtitle__bubble i { align-self: start; padding-top: 3px; font: 500 10px/1 var(--font-mono); font-style: normal; }
.dtitle__name, .dtitle__scale { position: relative; padding-bottom: 4px; border-bottom: var(--bw-heavy) solid var(--fg); }
.dtitle__name::after, .dtitle__scale::after { content: ""; position: absolute; left: 0; right: 0; bottom: -6.5px; height: 1px; background: var(--fg); }
.dtitle__name {
  flex: 1 1 auto; padding-right: var(--s-4);
  font: 700 15px/1.2 var(--font-sans); font-stretch: 125%; letter-spacing: .06em; text-transform: uppercase;
}
.dtitle__name:lang(zh-Hans) { font-stretch: 100%; letter-spacing: .02em; }
.dtitle__scale { flex: 0 0 auto; font: 400 12px/1.2 var(--font-mono); color: var(--fg-2); white-space: nowrap; }

/* ---- B7.12 model-space furniture: command line + UCS icon ------------------------------ */
.cmdline {
  display: flex; flex-direction: column; justify-content: flex-end;
  height: calc(2 * 1.45em + 14px); padding: 6px 10px; overflow: hidden;
  background: var(--model-2); color: var(--line); border-top: 1px solid var(--model-rule);
  font: 400 13px/1.45 var(--font-mono); white-space: pre-wrap;
}
.cmdline__p { color: var(--line-dim); }
.cmdline__caret { display: inline-block; width: 1ch; height: 1.1em; vertical-align: text-bottom; background: var(--line); animation: dtc-blink 1s step-end infinite; }
html[data-motion="off"] .cmdline__caret { animation: none; }
@keyframes dtc-blink { 50% { opacity: 0; } }
/* model sheets reserve a 64px band at the bottom of .sheet__body for the UCS icon (lower-left) */
.sheet--model > .sheet__body { padding-bottom: calc(var(--sheet-inner) + var(--sheet-pad) + 64px); }
.ucs { position: absolute; z-index: 1; left: calc(var(--sheet-inner) + var(--s-5)); bottom: calc(var(--sheet-inner) + 20px); width: 56px; height: 56px; color: var(--line-dim); fill: none; stroke: currentColor; stroke-width: 1.25; pointer-events: none; }
.ucs text { fill: currentColor; stroke: none; font: 500 10px var(--font-mono); }

/* ---- highlighter swipe (220ms) ---------------------------------------------------------------- */
.hl {
  background-image: linear-gradient(var(--hl), var(--hl)); background-repeat: no-repeat; background-size: 0 100%;
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
  transition: background-size 220ms var(--ease-out);
}
.hl.is-hl { background-size: 100% 100%; }

/* ==== build: css/shell.css ==== */
/* shell.css: title block (.tb-), md chip (.tb-chip), xs/sm bottom bar (.bbar), footer (.ft-).
   SPEC §D0. Breakpoints: xs/sm < 768 | md 768-1279 | lg >= 1280 (docked) | xl >= 1920. */

main { display: block; padding: var(--sheet-gap); }
@media (min-width: 1280px) {
  main { margin-right: var(--tb-w); }
}
@media (min-width: 768px) and (max-width: 1279.98px) {
  html { scroll-padding-top: calc(var(--chip-h) + 28px); }
}
@media (max-width: 767.98px) {
  html { scroll-padding-bottom: 72px; }
  body { padding-bottom: calc(var(--bbar-h) + env(safe-area-inset-bottom)); }
}

/* ---- Title block ------------------------------------------------------------------------ */
.tb {
  --bg: var(--tb-bg); --bg-2: var(--model-2); --fg: var(--line); --fg-2: var(--line-dim); --rule: var(--tb-rule);
  --hl: var(--vision-fill); --focus: var(--vision); --link: var(--vision);
  position: fixed; z-index: var(--z-titleblock);
  display: flex; flex-direction: column; padding-right: env(safe-area-inset-right);
  background: var(--tb-bg); color: var(--line);
  font-size: 14px; line-height: 1.35;
}
.tb :where(p) { margin: 0; }
.tb-row { flex: none; padding: 12px 16px; border-top: 1px solid var(--tb-rule); }
.tb-k {
  margin: 0 0 4px; color: var(--line-dim);
  font: 600 var(--fs-micro)/1.3 var(--font-mono); letter-spacing: .06em; text-transform: uppercase;
}
.tb-v { font-size: 13px; line-height: 1.35; }
.tb-mono { font-family: var(--font-mono); font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* 1 firm */
.tb-firm { border-top: 0; padding-top: 16px; }
.tb-mark { font: 800 20px/1.1 var(--font-sans); font-stretch: 112%; letter-spacing: -.01em; color: var(--line); }
.tb-sub { margin-top: 3px; color: var(--line-dim); font: 500 12px/1.3 var(--font-mono); letter-spacing: .04em; }
.tb-cta { margin-top: 12px; width: 100%; }
.tb .btn--primary:hover { box-shadow: 2px 2px 0 var(--line); }

/* 2 project + status */
.tb-proj { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.tb-status { color: var(--line); }

/* 3 revisions: the flexible row. core.js shows as many whole entries as it has room for; it never shrinks below the
   label and the entries shown (the docked block scrolls first), so no entry is ever cut. */
.tb-rev { display: flex; flex-direction: column; flex: 1 1 auto; min-height: min-content; overflow: hidden; }
.tb-rev__list { display: grid; gap: 6px; align-content: start; }
.tb-rev__i { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; column-gap: 8px; align-items: start; font-size: 13px; line-height: 1.3; }
.tb-rev__i--init { grid-template-columns: minmax(0, 1fr); color: var(--line-dim); }
.tb-rev__d { width: 22px; height: 19px; margin-top: -1px; overflow: visible; }
.tb-rev__d path { fill: var(--tb-bg); stroke: var(--vision); stroke-width: 1.5; stroke-linejoin: round; }
.tb-rev__d text { fill: var(--line); font: 600 11px var(--font-mono); text-anchor: middle; dominant-baseline: central; }
.tb-rev__i--note .tb-rev__d path { stroke: var(--line-dim); }
.tb-rev__t { min-width: 0; padding: 0 2px; overflow-wrap: anywhere; }
.tb-rev__time { font: 500 12px/1.3 var(--font-mono); color: var(--line-dim); font-variant-numeric: tabular-nums; }
.tb-rev__more { margin-top: 6px; font: 600 12px/1 var(--font-mono); color: var(--line-dim); }
.tb-rev__i.is-new { animation: tb-rev-in var(--dur-4) var(--ease-out) both; }
@keyframes tb-rev-in { from { opacity: 0; transform: translateY(-4px); } }

/* 4 sheet title */
.tb-title {
  min-height: 2.6em;
  font: 700 14px/1.3 var(--font-sans); font-stretch: 125%; letter-spacing: .06em; text-transform: uppercase;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
}
.tb-title:lang(zh-Hans) { font-stretch: 100%; letter-spacing: .04em; font-size: 15px; }

/* 5 sheet number (plotter glyphs) + scale + date */
.tb-num { display: flex; align-items: flex-end; justify-content: space-between; gap: 10px; }
.tb-num__main { min-width: 0; }
.tb-num__svg { display: block; height: 56px; width: auto; overflow: visible; color: var(--line); }
.tb-num__svg path { fill: none; stroke: currentColor; stroke-width: 6; stroke-linecap: round; stroke-linejoin: round; }
.tb-num__svg .gl-x { stroke-linecap: butt; }
.tb-num__side { flex: none; padding-bottom: 1px; }
.tb-num__side .tb-k:not(:first-child) { margin-top: 8px; }

/* 6 drawn / pre-checked / sealed */
.tb-trio { font: 500 11px/1.5 var(--font-mono); letter-spacing: .03em; }
.tb-trio__k { color: var(--line-dim); }

/* 7 seal */
.tb-seal { display: flex; align-items: center; gap: 12px; }
.tb-seal__ring { flex: none; width: 72px; height: 72px; border: 1.5px dashed var(--line-dim); border-radius: 50%; }
.tb-seal__t { font: 600 var(--fs-micro)/1.35 var(--font-mono); letter-spacing: .05em; text-transform: uppercase; color: var(--line-dim); }

/* 8 controls */
.tb-ctl { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 14px; }
.tb-ctl__g { display: flex; flex-direction: column; }
.tb-idxbtn {
  flex: 1 1 100%; display: flex; align-items: center; gap: 8px;
  min-height: 36px; padding: 0 12px;
  border: 1px solid var(--tb-rule); border-radius: var(--r-1); background: transparent; color: var(--line);
  font: 600 12px/1 var(--font-mono); letter-spacing: .06em; text-transform: uppercase;
}
.tb-idxbtn svg, .tb-close svg, .tb-chip__i, .bbar__idx svg { flex: none; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; }
.tb-idxbtn[aria-expanded="true"] { background: var(--line); color: var(--tb-bg); border-color: var(--line); }
@media (hover: hover) { .tb-idxbtn:hover { border-color: var(--line-dim); } }

/* 9 graphic scale (reading progress) + north arrow */
.tb-foot { display: flex; align-items: flex-end; gap: 14px; }
.tb-scale { flex: 1 1 auto; min-width: 0; }
.tb-scale__k { margin-bottom: 5px; font: 600 var(--fs-micro)/1.2 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--line-dim); }
.tb-scale__bar {
  position: relative; height: 8px; border: 1px solid var(--line-dim);
  background:
    linear-gradient(var(--line-dim), var(--line-dim)) 0 0 / 25% 50% no-repeat,
    linear-gradient(var(--line-dim), var(--line-dim)) 33.333% 100% / 25% 50% no-repeat,
    linear-gradient(var(--line-dim), var(--line-dim)) 100% 0 / 50% 50% no-repeat;
}
.tb-scale__bar::before, .tb-scale__bar::after { content: ""; position: absolute; top: -1px; bottom: -1px; width: 1px; background: var(--line-dim); }
.tb-scale__bar::before { left: 25%; }
.tb-scale__bar::after { left: 50%; }
.tb-scale__fill { position: absolute; inset: 0; background: var(--vision); transform-origin: 0 50%; transform: scaleX(var(--progress)); }
.tb-scale__n { position: relative; height: 15px; }
.tb-scale__n b { position: absolute; top: 3px; font: 500 10px/1 var(--font-mono); color: var(--line-dim); transform: translateX(-50%); }
.tb-scale__n b:nth-child(1) { left: 0; transform: none; }
.tb-scale__n b:nth-child(2) { left: 25%; }
.tb-scale__n b:nth-child(3) { left: 50%; }
.tb-scale__n b:nth-child(4) { left: auto; right: 0; transform: none; }
.tb-north {
  flex: none; display: grid; place-items: center; width: 44px; height: 44px; padding: 0;
  border: 0; background: transparent; color: currentColor; border-radius: var(--r-1);
}
.tb-north svg { width: 40px; height: 40px; overflow: visible; }
.tb-north circle { fill: none; stroke: currentColor; stroke-width: 1.25; opacity: .7; }
.tb-north__a { fill: currentColor; stroke: currentColor; stroke-width: 1; stroke-linejoin: round; }
.tb-north text { fill: currentColor; font: 600 9px var(--font-mono); text-anchor: middle; }
.tb-north svg { transition: transform var(--dur-4) var(--ease-snap); }
@media (hover: hover) { .tb-north:hover svg { transform: translateY(-2px); } }

/* sheet index: drawer list (md/xs) or popover (lg) */
.tb-idx { padding: 12px 16px 14px; }
.tb-idx__list { display: grid; }
.tb-idx__list li + li { border-top: 1px solid var(--tb-rule); }
.tb-idx__list a {
  display: grid; grid-template-columns: 3.4em minmax(0, 1fr); align-items: center; gap: 8px;
  min-height: 40px; padding: 4px 8px; margin: 0 -8px; border-radius: var(--r-1);
  color: var(--line); text-decoration: none; font-size: 14px; line-height: 1.25;
}
.tb-idx__no { font: 600 12px/1 var(--font-mono); color: var(--line-dim); font-variant-numeric: tabular-nums; }
.tb-idx__list a[aria-current="true"] { background: var(--vision-fill); }
.tb-idx__list a[aria-current="true"] .tb-idx__no { color: var(--vision); }
@media (hover: hover) { .tb-idx__list a:hover { background: rgba(230,236,242,.07); } }

/* drawer header (md/xs only) */
.tb-dhead { display: none; }
.tb-dhead__grip { display: none; }
.tb-close {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 12px; margin-left: auto;
  border: 1px solid var(--tb-rule); border-radius: var(--r-1); background: transparent; color: var(--line); text-decoration: none;
  font: 600 12px/1 var(--font-mono); letter-spacing: .06em; text-transform: uppercase;
}

/* lg+: docked */
@media (min-width: 1280px) {
  .tb { top: 0; right: 0; bottom: 0; width: var(--tb-w); border-left: 1px solid var(--tb-rule); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
  .tb-idx {
    display: none; position: fixed; z-index: var(--z-popover);
    right: calc(var(--tb-w) + 8px); bottom: 16px; width: 300px; max-height: calc(100vh - 32px); overflow-y: auto;
    background: var(--tb-bg); border: 1px solid var(--tb-rule); border-radius: var(--r-1); box-shadow: var(--sh-pop);
  }
  .tb.idx-open .tb-idx { display: block; animation: tb-pop var(--dur-4) var(--ease-out) both; }
  @keyframes tb-pop { from { opacity: 0; transform: translateX(8px); } }
  /* no JS: the index sits where the revision log would be */
  html:not(.js) .tb-rev { display: none; }
  html:not(.js) .tb-idx { display: block; position: static; order: 1; flex: 1 1 auto; min-height: 0; width: auto; max-height: none; border: 0; border-top: 1px solid var(--tb-rule); border-radius: 0; box-shadow: none; }
  html:not(.js) .tb-idx ~ .tb-row:not(.tb-firm):not(.tb-proj) { order: 2; }
}
/* lg, short viewports: seal goes first (< 880px), then rows 2 and 3 compact and every row tightens (< 780px), then the
   trio, the tagline and the date go and the title and number take less room (< 700px: 1280x600, 1440x560), so the
   progress row stays on screen with the revision label and one whole entry, even a 3-line one with '+N' */
@media (min-width: 1280px) and (max-height: 879.98px) {
  .tb-seal { display: none; }
}
@media (min-width: 1280px) and (max-height: 779.98px) {
  .tb-row { padding-block: 8px; }
  .tb-proj { grid-template-columns: 1fr; gap: 2px; }
  .tb-proj .tb-cell { display: flex; gap: 8px; align-items: baseline; min-width: 0; }
  .tb-proj .tb-k { margin: 0; flex: none; }
  .tb-proj .tb-v { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .tb-firm { padding-top: 12px; }
  .tb-cta { margin-top: 8px; }
}
@media (min-width: 1280px) and (max-height: 699.98px) {
  .tb-trio, .tb-sub, .tb-num__side > :nth-child(n+3) { display: none; }
  .tb-firm { padding-top: 8px; }
  .tb-title { min-height: 1.3em; }
  .tb-num__svg { height: 44px; }
}

/* md + xs/sm: the same aside becomes a drawer */
@media (max-width: 1279.98px) {
  .tb {
    z-index: var(--z-drawer);
    top: 0; right: 0; bottom: 0; width: min(360px, 90vw);
    overflow-y: auto; overscroll-behavior: contain;
    border-left: 1px solid var(--tb-rule); box-shadow: -24px 0 48px -24px rgba(0,0,0,.75);
    transform: translateX(105%); visibility: hidden;
    transition: transform var(--dur-5) var(--ease-out), visibility 0s linear var(--dur-5);
  }
  .tb.is-open, html:not(.js) .tb:target { transform: none; visibility: visible; transition: transform var(--dur-5) var(--ease-out), visibility 0s; }
  .tb-dhead { display: flex; align-items: center; padding: 12px 16px 4px; position: sticky; top: 0; z-index: 1; background: var(--tb-bg); }
  .tb-idx { display: block; }
  .tb-idxbtn { display: none; }
  .tb-rev { flex: none; }
  .tb-firm { border-top: 1px solid var(--tb-rule); }
}
@media (max-width: 767.98px) {
  .tb {
    top: auto; left: 0; width: auto; height: 85vh; height: 85dvh;
    border-left: 0; border-top: 1px solid var(--tb-rule); border-radius: var(--r-3) var(--r-3) 0 0;
    padding: 0 env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
    box-shadow: 0 -24px 48px -24px rgba(0,0,0,.75);
    transform: translateY(105%);
  }
  .tb-dhead { padding-top: 8px; touch-action: none; }   /* core.js: a downward drag closes the sheet */
  .tb-dhead__grip { display: block; position: absolute; left: 50%; top: 6px; width: 40px; height: 4px; margin-left: -20px; border-radius: 2px; background: var(--line-dim); opacity: .7; }
  .tb-dhead .tb-close { margin-top: 8px; }
}
.tb-scrim {
  position: fixed; inset: 0; z-index: calc(var(--z-drawer) - 1); touch-action: none;   /* no page scroll behind a drawer */
  background: var(--scrim); animation: tb-fade var(--dur-4) var(--ease-out) both;
}
@keyframes tb-fade { from { opacity: 0; } }
@media (min-width: 1280px) { .tb-scrim { display: none !important; } }

/* ---- md chip ------------------------------------------------------------------------------ */
.tb-chip { display: none; }
@media (min-width: 768px) and (max-width: 1279.98px) {
  .tb-chip {
    position: fixed; top: 16px; right: calc(16px + env(safe-area-inset-right)); z-index: var(--z-titleblock);
    display: inline-flex; align-items: center; gap: 8px; height: var(--chip-h); max-width: calc(100vw - 32px); padding: 0 12px 0 14px;
    background: var(--tb-bg); color: var(--line); border: 1px solid var(--tb-rule); border-radius: var(--r-1);
    box-shadow: 0 10px 28px -12px rgba(0,0,0,.7); text-decoration: none; overflow: hidden;
    font: 600 12px/1 var(--font-mono); letter-spacing: .06em;
  }
  .tb-chip__no { font-variant-numeric: tabular-nums; }
  .tb-chip__sep { color: var(--line-dim); }
  .tb-chip__title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--font-sans); font-weight: 700; font-stretch: 125%; }
  .tb-chip__title:lang(zh-Hans) { font-stretch: 100%; }
  .tb-chip__i { margin-left: 4px; color: var(--line-dim); }
  .tb-chip__bar { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--vision); transform-origin: 0 50%; transform: scaleX(var(--progress)); }
  .tb-chip:focus-visible { outline-color: var(--vision); }
}

/* ---- xs/sm bottom bar ---------------------------------------------------------------------- */
.bbar { display: none; }
@media (max-width: 767.98px) {
  .bbar {
    --bg: var(--tb-bg); --fg: var(--line); --focus: var(--vision); --hl: var(--vision-fill);
    position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-titleblock);
    display: flex; align-items: center; gap: 8px;
    height: calc(var(--bbar-h) + env(safe-area-inset-bottom));
    padding: 0 calc(8px + env(safe-area-inset-right)) env(safe-area-inset-bottom) calc(12px + env(safe-area-inset-left));
    background: var(--tb-bg); color: var(--line); border-top: 1px solid var(--tb-rule);
  }
  .bbar__bar { position: absolute; left: 0; right: 0; top: -1px; height: 2px; background: var(--vision); transform-origin: 0 50%; transform: scaleX(var(--progress)); }
  .bbar__no { flex: none; padding: 5px 6px 4px; border: var(--bw-rule) solid var(--line); border-radius: var(--r-1); font: 600 12px/1 var(--font-mono); font-variant-numeric: tabular-nums; }
  .bbar__title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 700 12px/1.2 var(--font-sans); font-stretch: 125%; letter-spacing: .06em; text-transform: uppercase; }
  .bbar__title:lang(zh-Hans) { font-stretch: 100%; letter-spacing: .02em; font-size: 13px; }
  .bbar__idx { flex: none; display: grid; place-items: center; width: 44px; height: 44px; color: var(--line); border: 1px solid var(--tb-rule); border-radius: var(--r-1); }
  .bbar__idx svg { width: 20px; height: 20px; }
  .bbar__lang > button { min-height: 44px; min-width: 44px; }
}

/* ---- toast ----------------------------------------------------------------------------------- */
.tb-toast {
  position: fixed; left: 50%; bottom: 24px; z-index: var(--z-toast);
  max-width: calc(100vw - 32px); padding: 10px 14px;
  background: var(--line); color: var(--model); border-radius: var(--r-1); box-shadow: var(--sh-pop);
  font: 600 13px/1.35 var(--font-mono);
  opacity: 0; transform: translate(-50%, 12px); pointer-events: none;
  transition: opacity var(--dur-4) var(--ease-out), transform var(--dur-4) var(--ease-out);
}
.tb-toast:empty { visibility: hidden; }
.tb-toast.is-on { opacity: 1; transform: translate(-50%, 0); }
@media (min-width: 1280px) { .tb-toast { left: calc(50% - var(--tb-w) / 2); } }
@media (max-width: 767.98px) { .tb-toast { bottom: calc(var(--bbar-h) + 16px + env(safe-area-inset-bottom)); } }

/* ---- Footer: General Notes paper band ------------------------------------------------- */
.ft {
  position: relative;
  margin: 0 var(--sheet-gap) var(--sheet-gap);
  background-color: var(--paper); color: var(--ink); box-shadow: var(--sh-sheet);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .10  0 0 0 0 .09  0 0 0 0 .07  0 0 0 .05 0'/></filter><rect width='100%' height='100%' filter='url(%23g)'/></svg>");
}
@media (min-width: 1280px) { .ft { margin-right: calc(var(--tb-w) + var(--sheet-gap)); } }
.ft::before {
  content: ""; position: absolute; inset: var(--frame-inset); pointer-events: none;
  border: var(--bw-rule) solid var(--ink);
}
.ft-in {
  position: relative; max-width: var(--content-max); margin-inline: auto;
  padding: calc(var(--sheet-inner) + var(--sheet-pad)) calc(var(--sheet-inner) + var(--sheet-pad)) calc(var(--sheet-inner) + var(--s-5));
}
.ft-h {
  display: inline-block; position: relative; margin-bottom: var(--s-6); padding: 0 var(--s-6) 5px 0;
  border-bottom: var(--bw-heavy) solid var(--ink);
  font: 700 15px/1.2 var(--font-sans); font-stretch: 125%; letter-spacing: .08em; text-transform: uppercase;
}
.ft-h::after { content: ""; position: absolute; left: 0; right: 0; bottom: -6.5px; height: 1px; background: var(--ink); }
.ft-h:lang(zh-Hans) { font-stretch: 100%; letter-spacing: .06em; font-size: 16px; }
.ft-notes { counter-reset: ftn; font-size: var(--fs-small); line-height: 1.55; }
.ft-notes:lang(zh-Hans) { line-height: 1.75; }
.ft-notes > li { counter-increment: ftn; display: grid; grid-template-columns: 2em minmax(0, 1fr); margin-bottom: var(--s-3); break-inside: avoid; max-width: 72ch; }
.ft-notes > li::before { content: counter(ftn) "."; font: 600 13px/1.65 var(--font-mono); color: var(--pencil); }
@media (min-width: 1024px) { .ft-notes { columns: 2; column-gap: var(--s-8); } }

.ft-code { margin-top: var(--s-6); padding-top: var(--s-5); border-top: 1px solid var(--ink); }
.ft-h3 { margin-bottom: var(--s-4); font: 700 13px/1.25 var(--font-sans); font-stretch: 125%; letter-spacing: .06em; text-transform: uppercase; }
.ft-h3:lang(zh-Hans) { font-stretch: 100%; font-size: 14px; }
/* generated/code-index.html: chapters (.ft-index__ch) holding <ul class="ft-index__list"> of <li>
   each with one .cite chip + its paraphrase pair. Element fallbacks keep other markup tidy. */
.ft-code > :where(.ft-index, ul, ol, dl) { columns: 4 15rem; column-gap: var(--s-6); }
.ft-code .ft-index__ch { margin-bottom: var(--s-5); }
.ft-code :where(h4, .ft-index__h) {
  margin: 0 0 var(--s-3); padding-bottom: 5px; border-bottom: var(--bw-rule) solid var(--ink);
  font: 700 var(--fs-micro)/1.35 var(--font-sans); font-stretch: 125%; letter-spacing: .06em; text-transform: uppercase; color: var(--ink);
  break-after: avoid; break-inside: avoid;
}
.ft-code :where(h4, .ft-index__h):lang(zh-Hans) { font-stretch: 100%; letter-spacing: .04em; }
.ft-code :where(li, dl > div) {
  display: grid; justify-items: start; gap: 3px;
  break-inside: avoid; margin-bottom: var(--s-3);
  font-size: 13px; line-height: 1.45; color: var(--ink);
}
.ft-code :where(li, dl > div):lang(zh-Hans) { line-height: 1.6; }
.ft-code :where(li, dl > div) .cite { font-size: 12px; min-height: 0; padding: 1px 6px; background: var(--paper); }
.ft-code :where(dd) { margin: 0; }

.ft-bot {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3) var(--s-5);
  margin-top: var(--s-7); padding-top: var(--s-4); border-top: var(--bw-heavy) solid var(--ink);
  font: 400 13px/1.45 var(--font-mono); color: var(--pencil);
}
.ft-bot :where(p) { max-width: none; }
.ft-mark { font: 800 20px/1 var(--font-sans); font-stretch: 112%; letter-spacing: -.01em; color: var(--ink); }
.ft-colo { flex: 1 1 26rem; font-family: var(--font-sans); font-size: var(--fs-small); }
.ft-contact a { color: var(--notshown-ink); overflow-wrap: anywhere; }
.ft-copy { white-space: nowrap; }
.ft-tools { display: flex; align-items: center; gap: var(--s-3); margin-left: auto; color: var(--ink); }
@media (max-width: 599.98px) {
  .ft-copy { white-space: normal; }
  .ft-tools { margin-left: 0; }
}

/* ==== build: css/sections/cover.css ==== */
/* cover.css: G0.0 cover sheet (SPEC §D1). Prefix cv-. */

.cv-body { row-gap: var(--s-6); align-items: start; }
.cv-head .sheet__eyebrow { margin: 0 0 var(--s-5); }
.cv-h1 { max-width: 16ch; font-size: clamp(2.5rem, 1.2rem + 3.3vw, 5.5rem); }
.cv-h1:lang(zh-Hans) { max-width: 13em; }
.cv-copy { display: grid; gap: var(--s-5); align-content: start; }
.cv-sub { margin: 0; }
.cv-ctas { display: flex; flex-wrap: wrap; gap: var(--s-3); }
.cv-disc { margin: 0; font-size: var(--fs-micro); color: var(--fg-2); max-width: 52ch; }
.cv-disc:lang(zh-Hans) { font-family: var(--font-sans); }

/* Headline across the top; the drawing is the hero, the finding card is its callout. */
@media (min-width: 1280px) {
  .cv-head { grid-column: 1 / span 7; grid-row: 1; align-self: end; }
  .cv-copy { grid-column: 8 / -1; grid-row: 1; align-self: end; }
  .cv-sub { font-size: var(--fs-body); }
  .cv-fig { grid-column: 1 / span 8; grid-row: 2; }
  .cv-cards { grid-column: 9 / -1; grid-row: 2; padding-top: 28px; }
}

/* ---- the drawing ------------------------------------------------------------------------ */
.cv-fig { padding-top: 28px; }
.cv-stage {
  position: relative; aspect-ratio: 1204 / 960; width: 100%;
  border: var(--bw-hair) solid var(--rule); background: var(--bg);
  touch-action: pan-y; user-select: none; -webkit-user-select: none;
}
.cv-stage > .cv-plan { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.cv-cap { margin-top: var(--s-3); }

/* plotted in drafting order, then scanned (SPEC §B6: plotted, not faded) */
@keyframes cv-wipe { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes cv-draw { to { stroke-dashoffset: 0; } }
@keyframes cv-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes cv-scan { from { transform: translate3d(-100%, 0, 0); } to { transform: translate3d(100%, 0, 0); } }

html.js[data-motion="on"] .cv-plan .cv-l-grid  { animation: cv-wipe 700ms var(--ease-out) 60ms both; }
html.js[data-motion="on"] .cv-plan .cv-l-walls { animation: cv-wipe 650ms steps(12, end) 220ms both; }
html.js[data-motion="on"] .cv-plan .cv-l-open  { animation: cv-wipe 520ms var(--ease-out) 520ms both; }
html.js[data-motion="on"] .cv-plan .cv-l-fixt  { animation: cv-wipe 520ms var(--ease-out) 640ms both; }
html.js[data-motion="on"] .cv-plan .cv-l-furn  { animation: cv-wipe 520ms var(--ease-out) 760ms both; }
html.js[data-motion="on"] .cv-plan .cv-l-dims  { animation: cv-wipe 560ms var(--ease-out) 860ms both; }
html.js[data-motion="on"] .cv-plan .cv-l-text  { animation: cv-wipe 560ms steps(8, end) 960ms both; }
html.js[data-motion="on"] .cv-plan .cv-plot { stroke-dasharray: 1; stroke-dashoffset: 1; animation: cv-draw 760ms var(--ease-out) var(--d, 1600ms) forwards; }
html.js[data-motion="on"] .cv-plan .cv-delta { animation: cv-in 260ms var(--ease-out) calc(var(--d, 1600ms) + 420ms) both; }

.cv-scan { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 2; }
.cv-scan::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent 0 70%, rgba(198,244,50,.10) 82%, rgba(198,244,50,.42) 98.6%, var(--vision-ink) 99.6%, transparent 100%);
  transform: translate3d(-100%, 0, 0);
}
html.js[data-motion="on"] .cv-scan::before { animation: cv-scan 3400ms linear 1150ms both; }
html:not(.js) .cv-scan, html[data-motion="off"] .cv-scan { display: none; }

/* ---- machine-view loupe: composited, counter-translated (SPEC §D1) ----------------------- */
.cv-loupe {
  --r: 112px;
  position: absolute; left: 0; top: 0; z-index: 3;
  width: calc(var(--r) * 2); height: calc(var(--r) * 2); border-radius: 50%;
  overflow: hidden; pointer-events: none; background: var(--model);
  box-shadow: 0 0 0 1.5px var(--vision), 0 0 0 7px rgba(198,244,50,.16), 0 22px 44px -14px rgba(0,0,0,.6);
  opacity: 0; transition: opacity var(--dur-5) var(--ease-out);
  will-change: transform; contain: layout paint;
}
.cv-loupe.is-on { opacity: 1; }
.cv-loupe__in { position: absolute; left: 0; top: 0; will-change: transform; }
.cv-loupe__in > .cv-ai { display: block; width: 100%; height: 100%; }
.cv-loupe.is-glide, .cv-loupe.is-glide .cv-loupe__in { transition: transform var(--dur-6) var(--ease-in-out), opacity var(--dur-5) var(--ease-out); }
.cv-loupe__tab {
  position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%);
  padding: 2px 7px; border-radius: var(--r-1); white-space: nowrap;
  font: 600 10px/1.3 var(--font-mono); letter-spacing: .08em; color: var(--model); background: var(--vision);
}
html:not(.js) .cv-loupe { display: none; }
@media (max-width: 767px) { .cv-loupe { --r: 76px; } .cv-loupe__tab { bottom: 8px; font-size: 9px; } }

/* keyboard / tap targets on the delta tags: 44px where they fit, never under 24px, never overlapping. cover.static.js
   gives each the gap to its nearest tag and that tag's own gap (--k, --kn, % of the stage width) and, to a pair too
   close for two 24px buttons, the way to part (--nx / --ny); fit() there mirrors these three lines. */
.cv-hits { position: absolute; inset: 0; z-index: 4; pointer-events: none; container-type: inline-size; }
.cv-hit {
  --bn: clamp(24px, var(--kn, 100) * 1cqw, 44px);
  --b: clamp(24px, 2 * var(--k, 100) * 1cqw - var(--bn), 44px);
  --p: max(0px, ((var(--b) + var(--bn)) / 2 - var(--k, 100) * 1cqw) / 2);
  position: absolute; width: var(--b); height: var(--b); margin: calc(var(--b) / -2) 0 0 calc(var(--b) / -2); padding: 0;
  translate: calc(var(--nx, 0) * var(--p)) calc(var(--ny, 0) * var(--p));
  border: 0; border-radius: 50%; background: transparent; cursor: pointer; pointer-events: auto;
}
@supports not (width: 1cqw) { .cv-hit { --b: 44px; --p: 0px; } }   /* no container units: the old centred 44px */
/* a focused hit sits over paper or over the dark loupe that glides to it: a lime ring on a model band reads on both */
.cv-hit:focus-visible { outline: 2px solid var(--vision); outline-offset: 2px; box-shadow: 0 0 0 6px var(--model); }
html:not(.js) .cv-hits { display: none; }

/* ---- finding cards ------------------------------------------------------------------------ */
.cv-cards { display: grid; gap: var(--s-3); }
.cv-hint { margin: 0; font-size: var(--fs-micro); color: var(--fg-2); }
.cv-hint:lang(zh-Hans) { font-family: var(--font-sans); }
.cv-hint__touch { display: none; }
@media (pointer: coarse) { .cv-hint__pointer { display: none; } .cv-hint__touch { display: inline; } }
/* The five cards share one cell, so the area keeps the tallest card's height: a swap (or the touch tour) never moves
   the page or the buttons under it. .is-on is the card on show; without JS only the static Δ4 card is laid out. */
.cv-deck { display: grid; container-type: inline-size; }
.cv-deck > .cv-card { grid-area: 1 / 1; }
/* rows: tag, status, h3, message, then the dl takes any height the tallest card adds, so the sheet line sits at the foot */
.cv-card {
  position: relative; display: grid; gap: var(--s-3); grid-template-rows: auto auto auto auto 1fr;
  padding: 0 var(--s-5) var(--s-5); border: var(--bw-rule) solid var(--fg); background: var(--bg);
  box-shadow: 4px 4px 0 var(--rule);
}
.cv-card:not(.is-on) { visibility: hidden; }
.cv-card:not(.is-on) > .cv-card__tag { visibility: hidden !important; }   /* .illus__tag forces visible; its card is off */
html:not(.js) .cv-card:not(.is-on) { display: none; }
html.js[data-motion="on"] .cv-card.is-in { animation: cv-card 360ms var(--ease-out) both; }
@keyframes cv-card { from { opacity: 0; transform: translate3d(0, 8px, 0); } to { opacity: 1; transform: none; } }
/* the tag rides the top border in the card's own flow, so on a narrow phone it wraps inside the card (its right edge
   stays within the outer edge whether the 1.5px rule renders at 1px or 1.5px) */
.cv-card__tag { position: relative; justify-self: start; white-space: normal; margin: -1.5px calc(-1px - var(--s-5)) 7px calc(-1.5px - var(--s-5)); }
.cv-card__top { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.cv-card__count { font-size: var(--fs-micro); color: var(--fg-2); }
.cv-card__h { margin: 0; font: 700 var(--fs-h3)/1.15 var(--font-sans); font-stretch: 108%; }
.cv-card__msg { margin: 0; font-size: var(--fs-body); }
.cv-card__dl { margin: 0; display: grid; gap: var(--s-3); align-content: start; border-top: var(--bw-hair) solid var(--rule); padding-top: var(--s-3); }
.cv-card__dl > div { display: grid; grid-template-columns: 7.5em 1fr; gap: var(--s-3); }
.cv-card__dl dt { font: 600 var(--fs-micro)/1.6 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--fg-2); }
.cv-card__dl dd { margin: 0; font-size: var(--fs-small); line-height: 1.5; }
.cv-card__dl dd:lang(zh-Hans), .cv-card__dl dd :lang(zh-Hans) { line-height: 1.7; }
.cv-card__cites { display: inline-flex; flex-wrap: wrap; gap: 4px; margin-left: 4px; }
.cv-card__loc { margin: 0; font-size: var(--fs-micro); color: var(--fg-2); }
.cv-cardnav { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); }
/* Pause/Play for the touch tour (the A5.0 pattern): laid out only where a tour can run, hidden in place once it ends */
.cv-play { display: none; }
@media (pointer: coarse) { html.js[data-motion="on"] .cv-play { display: inline-flex; } }
.cv-play.is-off { visibility: hidden; }
.cv-play > button { display: inline-flex; align-items: center; gap: 6px; }
.cv-play svg { width: 10px; height: 10px; fill: currentColor; }
.cv-play :lang(zh-Hans) { font-family: var(--font-sans); }
@media (max-width: 479px) { .cv-card__dl > div { grid-template-columns: 1fr; gap: 2px; } }
/* any narrow card (phones, and the lg column beside the plan) puts each label over its value, so the CBC chips fit */
@container (max-width: 399.98px) { .cv-card__dl > div { grid-template-columns: 1fr; gap: 2px; } }

/* ==== build: css/sections/story.css ==== */
/* story.css: G0.1 Correction history (lp-) and G0.2 Code references (cw-). SPEC §D2-D3. Semantic tokens only.
   G0.1 lg: a 240vh scrub track with the copy and the stage pinned; md and xs/sm: no pinning.
   G0.2 lg: the square stage rides along (sticky) beside the copy, chips and cards; md and xs/sm: stacked. */

.lp :is(p, li, figcaption) { text-wrap: pretty; }

/* =========================================================================================
   G0.1 layout
   ========================================================================================= */
.lp-body { row-gap: var(--s-7); align-items: start; }
.lp-head { margin-bottom: var(--s-5); }
.lp-h :lang(zh-Hans) { word-break: keep-all; }   /* break after the comma: 漏一条，/ 就再来一轮。 */
.lp-lead { margin: 0; }
.lp-fig { min-width: 0; }
.lp-pin { position: relative; display: flex; flex-direction: column; }
.lp-tag { position: relative; align-self: flex-start; margin-bottom: var(--s-3); }
.lp-after { padding-top: var(--s-6); }

@media (min-width: 768px) {
  .lp-copy { grid-column: 1 / span 7; }
  .lp-why { grid-column: 1 / span 6; }
}
@media (min-width: 1280px) {
  .lp-body { grid-template-rows: auto auto auto; row-gap: 0; }
  .lp-copy { grid-column: 1 / span 4; grid-row: 1; align-self: stretch; }
  .lp-fig { grid-column: 5 / -1; grid-row: 1 / span 3; display: grid; grid-template-rows: subgrid; }
  .lp-why { grid-column: 1 / span 4; grid-row: 2 / span 2; align-self: start; padding-top: var(--s-7); }
  .lp-after { padding-top: var(--s-7); }
  .lp-h { font-size: clamp(2.25rem, -0.625rem + 3.75vw, 4rem); }
  .lp-copy__pin { padding-right: var(--s-2); }
}
/* the scrub: copy and stage stay pinned while the 240vh track scrolls by (motion on, tall enough to pin) */
@media (min-width: 1280px) and (min-height: 700px) {
  html.js[data-motion="on"] .lp-track { height: 240vh; }
  html.js[data-motion="on"] :is(.lp-pin, .lp-copy__pin) {
    position: sticky; top: 0; height: 100vh; justify-content: center; padding-block: var(--s-6);
  }
  html.js[data-motion="on"] .lp-copy__pin { display: flex; flex-direction: column; }
}

/* =========================================================================================
   The stage: the returned set (left 58%) and the thread (right 42%), 16:10 from md up
   ========================================================================================= */
.lp-stage { position: relative; border: var(--bw-hair) solid var(--rule); background: var(--bg); overflow: clip; }   /* a slamming stamp (1.9×) never widens the page */
.lp[data-module-state="loading"] .lp-stage { visibility: hidden; }
.lp-set { position: relative; display: flex; flex-direction: column; justify-content: center; min-width: 0; padding: var(--s-3); }
.lp-sheet { position: relative; width: 100%; aspect-ratio: 1204 / 1040; container-type: inline-size; }
.lp-plan { position: absolute; inset: 0; display: block; width: 100%; height: 100%; overflow: visible; }
.lp-over { position: absolute; inset: 0; }
.lp-dtitle { margin-top: var(--s-2); }
.lp-dtitle .dtitle__name { font-size: 13px; }
@media (max-width: 479.98px) { .lp-dtitle .dtitle__scale { display: none; } }
@media (min-width: 768px) {
  .lp-stage { display: grid; grid-template-columns: 58% 42%; aspect-ratio: 16 / 10; }
  .lp-set { border-right: var(--bw-hair) solid var(--rule); }
}

/* plan: room names at 60% ink; the plan checker's clouds bloom with their round */
.lp-rooms text { font: 500 22px var(--font-mono); letter-spacing: .08em; fill: var(--ink); text-anchor: middle; }
.lp-cloud { fill: none; stroke: var(--conflict); stroke-width: 6; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1 1; }

/* RESUBMITTAL REQUIRED (B7.10): one impression per round, piling up on the corner */
.lp-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.lp-stamp {
  position: absolute; z-index: 1; color: var(--conflict); mix-blend-mode: multiply; pointer-events: none;
  transform: rotate(var(--rot)); will-change: transform, opacity;
}
.lp-stamp svg { display: block; width: 100%; height: auto; overflow: visible; }
.lp-stamp:not(:last-of-type) { opacity: .55; }   /* the static Round-3 pile: older impressions have dried */
.lp-stamp__t { font: 800 30px/1 var(--font-sans); font-stretch: 125%; stroke: currentColor; stroke-width: .9px; paint-order: stroke; }

/* the hand-lettered redlines: text over the drawing, written left to right, struck when the next round lands */
.lp-red {
  position: absolute; top: var(--t); z-index: 2; display: block; white-space: nowrap; text-decoration: none; color: var(--conflict);
  font: 400 14px/1.09 var(--font-hand); font-size: min(18px, 3.65cqw);
  transform: rotate(var(--rot)); transform-origin: 0 0;
  transition: opacity var(--dur-4) var(--ease-out), visibility 0s;
}
.lp-red--r { text-align: right; transform-origin: 100% 0; }
.lp-red__t { display: block; }
.lp-red__l { position: relative; display: block; width: fit-content; clip-path: inset(-.45em calc((1 - var(--w, 1)) * 100%) -.45em -.3em); }
.lp-red--r .lp-red__l { margin-left: auto; }
.lp-red__l::after {
  content: ""; position: absolute; left: -.12em; right: -.12em; top: 50%; height: 1.5px; margin-top: -1px;
  background: currentColor; transform: scaleX(var(--k, 0)); transform-origin: 0 50%;
}
.lp-red[data-round="1"] .lp-red__l, .lp-red[data-round="2"] .lp-red__l { --k: 1; }   /* the static Round-3 state */
/* before its round a note is faded, not hidden: Tab still reaches it, and focus in the figure shows the final state */
.lp.is-live .lp-red[data-on="0"] { opacity: 0; pointer-events: none; }
.lp[data-lp-caught="1"] .lp-red { visibility: hidden; opacity: 0; transition: opacity var(--dur-4) var(--ease-out), visibility 0s var(--dur-4); }
.lp-red:focus-visible { z-index: 3; outline: 2px solid var(--focus); outline-offset: 3px; box-shadow: 0 0 0 4px var(--bg); }
/* no min-height on phones: grown boxes overlap their neighbours; the list links below (same #f rows) are the targets.
   R6 and R7 sit lower there (--ts), clear of R8 and of each other */
@media (max-width: 767.98px) { .lp-red { top: var(--ts, var(--t)); } }
/* lp.badge: the machine's note on the human's comment */
.lp-badge {
  position: absolute; top: 100%; left: 0; margin-top: 6px; padding: 3px 8px; border-radius: var(--r-1);
  background: var(--model-2); color: var(--vision); box-shadow: 0 0 0 1px var(--model), var(--sh-pop);
  font: 600 var(--fs-micro)/1.3 var(--font-mono); letter-spacing: .04em; white-space: nowrap; text-align: left;
  transform: rotate(calc(var(--rot) * -1)); display: none; pointer-events: none;
}
.lp-badge :lang(zh-Hans) { font-family: var(--font-sans); letter-spacing: .02em; }
.lp-red--e .lp-badge { left: auto; right: 0; }
.lp-red:focus-visible:not(.is-quiet) .lp-badge { display: block; }   /* Esc sets .is-quiet (story/loop.js) */
@media (hover: hover) {
  .lp-red:hover { z-index: 3; }
  .lp-red:hover:not(.is-quiet) .lp-badge { display: block; }
}
@media (max-width: 479.98px) { .lp-badge { width: 11rem; white-space: normal; } }   /* two lines, inside a 240 px sheet */

/* =========================================================================================
   The thread panel
   ========================================================================================= */
.lp-thr { position: relative; min-width: 0; }
.lp-box { position: relative; }
.lp-svg { position: absolute; inset: 0; display: block; width: 100%; height: 100%; overflow: visible; }
html:not(.js) .lp-svg { display: none; }
.lp-svg path { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.lp-svg__ahead { stroke: var(--fg-2); stroke-width: 1; stroke-dasharray: 2 4; opacity: .6; }
.lp-svg__ticks { stroke: var(--fg); stroke-width: 1.25; }
.lp-svg__q { stroke: var(--fg-2); stroke-width: 1; }
.lp-svg__a { stroke: color-mix(in srgb, var(--fg) calc(clamp(0, (var(--lp-t, 0) - .6) * 250, 100) * 1%), var(--conflict)); stroke-width: 2.25; }
.lp-svg__b { stroke: var(--conflict); stroke-width: 2.25; }
.lp-svg__lead { stroke: var(--fg); stroke-width: 2.25; }
.lp-svg__track { stroke: var(--fg-2); stroke-width: 1.25; stroke-dasharray: 3 4; opacity: 0; transition: opacity var(--dur-5) var(--ease-out); }
.lp-svg__set { transition: opacity var(--dur-3) linear; }
.lp-svg .lp-svg__set-t { fill: var(--bg); stroke: var(--fg); stroke-width: 1.2; }
.lp-svg .lp-svg__set-e { stroke: var(--fg); stroke-width: 1; }
.lp-svg .lp-svg__set-x { stroke: var(--fg-2); stroke-width: .9; }
.lp[data-lp-ready="1"]:not([data-lp-done="1"]) .lp-svg__track { opacity: 1; }

/* ROUND n: a numbering stamp */
.lp-round {
  margin: 0; max-width: none; font: 600 32px/1 var(--font-mono); letter-spacing: .04em; color: var(--conflict);
  filter: url(#lp-ink); white-space: nowrap;
}
.lp-round b { display: inline-block; min-width: .7em; font-weight: 600; animation: none 220ms var(--ease-snap) both; }
@keyframes lp-flip { from { opacity: 0; transform: translateY(-55%); } }
@keyframes lp-flop { from { opacity: 0; transform: translateY(-55%); } }

/* station legend */
.lp-st { display: grid; gap: 3px; margin: 0; font: 500 var(--fs-micro)/1.35 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--fg-2); }
.lp-st :lang(zh-Hans) { font-family: var(--font-sans); letter-spacing: .02em; }
.lp-st li { position: relative; padding-left: 14px; }
.lp-st li::before { content: ""; position: absolute; left: 0; top: .62em; width: 8px; height: 1.25px; background: currentColor; }
.lp-st li[data-on] { color: var(--fg); font-weight: 600; }   /* "you are here": ink, since red means conflict only (B1) */
.lp-st li[data-on]::before { width: 10px; height: 2px; }
.lp.is-live .lp-st { opacity: calc(1 - var(--lp-t, 0) * 2.5); }

/* pull: the cue, the grip (lg/md) or the range (xs/sm), the Submit tick, the caught chips, the result. Until READY the
   controls are faded, not hidden, so Tab reaches them (focus in the figure then shows the final state); a click on the
   cue (a button), on the grip or on the thread pulls it */
.lp-cue {
  width: fit-content; min-height: 24px; margin: 0; padding: 3px 0; border: 0; background: none; text-align: left;
  font: 600 15px/1.2 var(--font-sans); font-stretch: 108%; color: var(--fg); opacity: 0; pointer-events: none;
}
.lp-cue :lang(zh-Hans) { font-stretch: 100%; }
.lp[data-lp-ready="1"] .lp-cue { opacity: 1; pointer-events: auto; animation: lp-in var(--dur-5) var(--ease-out) backwards; }   /* no clip left on the focus ring */
.lp[data-lp-ready="1"][data-lp-caught="1"] .lp-cue { visibility: hidden; }
@media (hover: hover) { .lp-cue:hover { text-decoration: underline; text-underline-offset: 3px; } }
@keyframes lp-in { from { opacity: 0; clip-path: inset(0 100% 0 0); } to { opacity: 1; clip-path: inset(0 0 0 0); } }

.lp-grip {
  position: absolute; left: 0; top: 0; z-index: 4; width: 44px; height: 44px; margin: -22px 0 0 -22px; border-radius: 50%;
  background: var(--model); box-shadow: 0 0 0 1.5px var(--vision), 0 0 0 6px var(--vision-fill), var(--sh-pop);
  cursor: grab; touch-action: none; opacity: 0; pointer-events: none; -webkit-tap-highlight-color: transparent;
}
.lp-grip:active { cursor: grabbing; }
.lp-grip__k { position: absolute; inset: 14px 15px; border-inline: 1.5px solid var(--vision); }
.lp-grip__k::after { content: ""; position: absolute; left: 50%; top: 0; bottom: 0; border-left: 1.5px solid var(--vision); }
.lp-grip__t {
  position: absolute; left: 46px; top: 25px; white-space: nowrap; translate: calc(var(--lp-t, 0) * (-100% - 54px)) calc(var(--lp-t, 0) * -42px);
  font: 600 var(--fs-micro)/1.2 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--ai);
}
.lp-grip__t :lang(zh-Hans) { font-family: var(--font-sans); letter-spacing: .02em; }
.lp-grip:focus-visible { outline: 2px solid var(--focus); outline-offset: 5px; }
.lp[data-lp-ready="1"] .lp-grip { opacity: 1; pointer-events: auto; animation: lp-pop var(--dur-5) var(--ease-snap) both; }
@keyframes lp-pop { from { opacity: 0; scale: .6; } to { opacity: 1; scale: 1; } }

.lp-rangebox { display: grid; gap: 4px; opacity: 0; pointer-events: none; }
.lp[data-lp-ready="1"] .lp-rangebox { opacity: 1; pointer-events: auto; }
.lp-rangebox__t { font: 600 var(--fs-micro)/1.2 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--ai); }
.lp-rangebox__t :lang(zh-Hans) { font-family: var(--font-sans); }
.lp-range { -webkit-appearance: none; appearance: none; width: 100%; height: 44px; margin: 0; background: transparent; cursor: pointer; touch-action: pan-y; }
.lp-range::-webkit-slider-runnable-track { height: 2px; background: repeating-linear-gradient(90deg, var(--fg-2) 0 4px, transparent 4px 8px); }
.lp-range::-moz-range-track { height: 2px; background: repeating-linear-gradient(90deg, var(--fg-2) 0 4px, transparent 4px 8px); }
.lp-range::-webkit-slider-thumb {
  -webkit-appearance: none; width: 44px; height: 44px; margin-top: -21px; border: 0; border-radius: 50%;
  background: radial-gradient(circle, var(--model) 0 59%, var(--vision) 60% 64%, var(--vision-fill) 65% 100%);
}
.lp-range::-moz-range-thumb { width: 44px; height: 44px; border: 0; border-radius: 50%; background: radial-gradient(circle, var(--model) 0 59%, var(--vision) 60% 64%, var(--vision-fill) 65% 100%); }
.lp-range:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

.lp-submit {
  position: absolute; left: var(--sx); top: var(--sy); z-index: 2; translate: 0 -50%;
  font: 600 var(--fs-micro)/1 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--fg);
  opacity: 0; transition: opacity var(--dur-4) var(--ease-out); pointer-events: none;
}
.lp-submit :lang(zh-Hans) { font-family: var(--font-sans); }
.lp[data-lp-caught="1"] .lp-submit { opacity: 1; }

.lp-caught { display: none; }
.lp[data-lp-caught="1"] .lp-caught { display: block; }
.lp-caught__h { margin: 0 0 4px; font: 600 var(--fs-micro)/1.3 var(--font-mono); letter-spacing: 0; text-transform: uppercase; color: var(--ai); }
.lp-caught__h :lang(zh-Hans) { font-family: var(--font-sans); letter-spacing: .02em; }
.lp-chips { display: grid; gap: 0; }
/* the chips are the sheet's links to A3.0 once the redlines are gone: each row is as tall as the room above Submit
   allows, up to a 24 px target (lg/md, from the thread's own variables), 32 px on phones where the list is in flow */
.lp-chip {
  display: block; width: fit-content; padding: 0 4px; margin-left: -4px; border-radius: var(--r-1);
  font: 500 var(--fs-micro)/1.3 var(--font-mono); line-height: var(--lp-chip-h, 1.3); color: var(--fg); text-decoration: none; white-space: nowrap;
}
.lp-chip b { font-weight: 600; color: var(--ai); }
.lp-chip [lang="zh-Hans"] { font-family: var(--font-sans); }   /* the pair member only: Δn and the tags stay mono */
@media (hover: hover) { .lp-chip:hover { text-decoration: underline; } }
.lp-chip:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }

.lp-done { margin: 0; font: 700 clamp(1.125rem, 0.95rem + 0.5vw, 1.5rem)/1.12 var(--font-sans); font-stretch: 108%; color: var(--fg); }
.lp-done :lang(zh-Hans), .lp-done:lang(zh-Hans) { font-stretch: 100%; }

/* the result shows with the pull; before it, it is faded (still read, and shown once Tab reaches the A1.0 link) */
.lp-under { display: grid; gap: var(--s-2); justify-items: start; padding-top: var(--s-4); }
.lp-note { margin: 0; font: 400 var(--fs-small)/1.5 var(--font-sans); color: var(--fg); max-width: 46ch; }
.lp-note:lang(zh-Hans), .lp-note :lang(zh-Hans) { line-height: 1.7; }
.lp-next { font: 600 15px/1.3 var(--font-sans); font-stretch: 108%; }
.lp.is-live:not([data-lp-done="1"]) .lp-under:not(:focus-within) { opacity: 0; pointer-events: none; }
.lp.is-live[data-lp-done="1"] .lp-under { animation: lp-in var(--dur-5) var(--ease-out) backwards; }

/* lg/md: everything on the thread panel sits in the thread's own coordinates (story/loop.js sets the variables) */
@media (min-width: 768px) {
  .lp-thr { padding: 0; }
  .lp-box { position: absolute; inset: 0; }
  .lp-round { position: absolute; bottom: 6px; right: 8px; }
  .lp-st { position: absolute; left: calc(var(--ox, 40px) + 1.9 * var(--R, 16px) + 20px); top: 50%; right: 8px; translate: 0 -50%; }
  .lp-cue { position: absolute; left: 14px; top: 6px; right: 8px; }
  .lp-rangebox { display: none; }
  .lp-caught {
    position: absolute; left: calc(var(--ox, 40px) + (1.9 - 1.65 * var(--lp-t, 1)) * var(--R, 16px) + 14px); top: calc(var(--oy, 56px) + 26px); right: 4px;
    --lp-chip-h: clamp(1.3em, (var(--sy, 0px) - var(--oy, 56px) - 62px) / 8, 24px);   /* heading 21 + 8 rows + 14 clear of Submit */
  }
  .lp-submit { left: calc(var(--sx) + 10px); }
  .lp-under { margin-left: 58%; padding-left: var(--s-4); min-height: 150px; align-content: start; }
}
/* xs/sm: plan, then the thread band (3:1) with a native range, then the legend and the result, in flow */
@media (max-width: 767.98px) {
  .lp-thr { display: flex; flex-direction: column; gap: var(--s-3); padding: var(--s-3); border-top: var(--bw-hair) solid var(--rule); }
  .lp-box { aspect-ratio: 3 / 1; }
  .lp-grip { display: none; }
  .lp-st { grid-template-columns: repeat(2, minmax(0, max-content)); column-gap: var(--s-6); }
  .lp-chips { grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr)); gap: 4px var(--s-4); }
  .lp-chip { --lp-chip-h: 32px; }
  .lp-submit { translate: -50% 0; top: calc(var(--sy) + 1.9 * var(--R)); }
  .lp.is-live:not([data-lp-done="1"]) .lp-under:not(:focus-within) {   /* no gap in the flow before the pull (the .vh clip) */
    position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
}

/* no JS: the Round-3 state, then three laps → one small loop */
html:not(.js) .lp-thr { display: flex; flex-direction: column; gap: var(--s-3); padding: var(--s-3); }
html:not(.js) :is(.lp-round, .lp-st, .lp-done, .lp-box) { position: static; translate: none; }
html:not(.js) .lp-box { aspect-ratio: auto; }
html:not(.js) .lp-cue { display: none; }
.lp-ba { display: block; width: 100%; max-width: 22rem; height: auto; overflow: visible; }
.lp-ba path { fill: none; stroke-width: 2.25; stroke-linecap: round; stroke-linejoin: round; }
.lp-ba__red { stroke: var(--conflict); }
.lp-ba__ink { stroke: var(--fg); }
.lp-ba .lp-ba__arrow { stroke: var(--fg-2); stroke-width: 1.25; }

/* =========================================================================================
   After the stage: the comment list (inside the figure) and why it matters now
   ========================================================================================= */
.lp-list__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-3) var(--s-5); padding-bottom: var(--s-3); border-bottom: var(--bw-rule) solid var(--fg); }
.lp-list__h { margin: 0; font-size: var(--fs-h3); }
.lp-list__stamp {
  margin: 0; padding: 3px 9px; border: 2px solid currentColor; outline: 1px solid currentColor; outline-offset: 2px;
  font: 800 var(--fs-micro)/1.2 var(--font-sans); font-stretch: 125%; letter-spacing: .08em; text-transform: uppercase;
  color: var(--conflict); transform: rotate(-4deg); filter: url(#lp-ink);
}
.lp-list__stamp:lang(zh-Hans), .lp-list__stamp :lang(zh-Hans) { font-stretch: 100%; letter-spacing: .04em; }
.lp-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); gap: var(--s-4) var(--s-6); margin-top: var(--s-4); }
.lp-li { padding-left: var(--s-3); border-left: var(--bw-rule) solid var(--rule); }
.lp-li[data-round="3"] { border-left-color: var(--conflict); }
/* each comment is a block link to its A3.0 row: the 24 px+ equivalent of the in-stage redlines and chips (2.5.8) */
.lp-li__a { display: grid; gap: 4px; align-content: start; min-height: 24px; color: inherit; text-decoration: none; }
@media (hover: hover) { .lp-li__a:hover .lp-li__t { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; } }
.lp-li__k { font: 600 var(--fs-micro)/1.3 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--fg-2); }
.lp-li__k b { color: var(--conflict); font-weight: 600; }
.lp-li__k i { font-style: normal; color: var(--ai); }
.lp-li__k [lang="zh-Hans"] { font-family: var(--font-sans); letter-spacing: .02em; }
.lp-li__t { font: 500 var(--fs-mono)/1.45 var(--font-mono); color: var(--fg); }
.lp-li__t :lang(zh-Hans) { font: 400 var(--fs-small)/1.65 var(--font-sans); }
.lp-li__o { display: none; font: 400 var(--fs-micro)/1.4 var(--font-mono); color: var(--fg-2); }
html[data-lang="zh"] .lp-li__o { display: block; }
.lp-cap { margin-top: var(--s-4); }

.lp-why { display: grid; gap: var(--s-5); align-content: start; }
.lp-why__h { margin: 0; padding-top: var(--s-3); border-top: var(--bw-heavy) solid var(--fg); }
.lp-fact { display: grid; gap: var(--s-2); }
.lp-fact__t { margin: 0; font-size: var(--fs-body); line-height: 1.5; }
.lp-fact__t:lang(zh-Hans), .lp-fact__t :lang(zh-Hans) { line-height: 1.75; }
.lp-fact__src { margin: 0; font: 400 var(--fs-micro)/1.5 var(--font-mono); color: var(--fg-2); }
.lp-fact__src :lang(zh-Hans) { font-family: var(--font-sans); line-height: 1.7; }
.lp-fact__src a { color: var(--link); }
.lp-fact__src cite { font-style: normal; }

/* =========================================================================================
   G0.2 Code references (cw-): model space. One square stage: three chapter rings of greeked text (canvases that
   turn while idle), fixed clause nodes, corner vignettes and the AI's lime leaders. Stage units: 1000 across;
   --cw-u = stage units per screen px and --cw-k = ms per stage unit (900 px/s), both set by story/web.js.
   ========================================================================================= */
.cw { --cw-u: 1.45; --cw-k: .76; }
.cw :is(p, dd) { text-wrap: pretty; }
.cw-body { row-gap: var(--s-6); align-items: start; }
/* .cw-main repeats the sheet's columns (1 / 8 / 12) for everything above the command line, so the sticky stage
   stops at the end of the cards instead of riding over the command line */
.cw-main { display: grid; grid-template-columns: minmax(0, 1fr); column-gap: var(--gutter); row-gap: var(--s-6); align-items: start; }
.cw-main > * { grid-column: 1 / -1; min-width: 0; }
.cw-head { margin-bottom: var(--s-5); }
.cw-h :lang(zh-Hans) { word-break: keep-all; }   /* break at the commas, not inside 好几条 */
.cw-lead { margin: 0; }
.cw-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* lg: copy, chips and cards in cols 1-4; the stage rides along in cols 5-12 */
@media (min-width: 1280px) {
  .cw-main { grid-template-columns: repeat(12, minmax(0, 1fr)); grid-template-rows: auto auto 1fr; }
  .cw-copy { grid-column: 1 / span 4; grid-row: 1; }
  .cw-pick { grid-column: 1 / span 4; grid-row: 2; }
  .cw-panel { grid-column: 1 / span 4; grid-row: 3; }
  .cw-fig { grid-column: 5 / -1; grid-row: 1 / span 3; }
  .cw-h { font-size: clamp(2.25rem, -0.625rem + 3.75vw, 4rem); }
  .cw-fig { width: min(100%, calc(100svh - 168px)); justify-self: center; }
}
@media (min-width: 1280px) and (min-height: 700px) { .cw-fig { position: sticky; top: var(--s-6); } }
/* md: the stage full width above the chips (one row) and the cards (two columns; see below the components) */
@media (min-width: 768px) and (max-width: 1279.98px) {
  .cw-main { grid-template-columns: repeat(8, minmax(0, 1fr)); }
  .cw-copy { grid-column: 1 / span 7; grid-row: 1; }
  .cw-fig { grid-column: 1 / -1; grid-row: 2; }
  .cw-pick { grid-row: 3; }
  .cw-panel { grid-row: 4; }
  .cw-fig { width: min(100%, 760px, calc(100svh - 150px)); justify-self: center; }
}
/* xs/sm: chips with thumbnails, the stage, then the cards */
@media (max-width: 767.98px) {
  .cw { --cw-u: 3.1; }
  .cw-copy { order: 1; }
  .cw-pick { order: 2; }
  .cw-fig { order: 3; }
  .cw-panel { order: 4; }
}

/* ---- element chips: a 2×2 radio group (the order of the stage corners), then Play/Pause for the idle cycle (2.2.2) -- */
.cw-pick { display: grid; gap: var(--s-2); }
.cw-chips { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-2); }
html:not(.js) .cw-pick { display: none; }
.cw-play { justify-self: end; }
.cw-play > button { display: inline-flex; align-items: center; gap: 6px; }
.cw-play svg { width: 10px; height: 10px; fill: currentColor; }
.cw-play :lang(zh-Hans) { font-family: var(--font-sans); }
/* the toggle holds its row from the first paint (G0.2 keeps its height through boot) and shows once web.js is ready */
html.js[data-motion="on"] .cw-play { visibility: hidden; }
#web[data-module-state="ready"] .cw-play { visibility: visible; }
html[data-motion="off"] .cw-play, #web[data-module-state="error"] .cw-play { display: none; }
.cw-chip {
  position: relative; display: flex; align-items: center; gap: 10px; min-height: 52px; min-width: 0; padding: 8px 12px;
  border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1); background: var(--bg-2); color: var(--fg);
  font: 600 15px/1.2 var(--font-sans); font-stretch: 104%; text-align: left; -webkit-tap-highlight-color: transparent;
  transition: border-color var(--dur-2) var(--ease-out), background-color var(--dur-2) var(--ease-out);
}
.cw-chip__t { min-width: 0; }
.cw-chip__t :lang(zh-Hans) { font-stretch: 100%; }
.cw-chip__n { margin-left: auto; padding-left: 6px; font: 500 var(--fs-micro)/1 var(--font-mono); color: var(--fg-2); font-variant-numeric: tabular-nums; }
.cw-chip__v { display: none; flex: none; width: 40px; height: 40px; border: var(--bw-hair) solid var(--rule); background: var(--model); overflow: hidden; }
.cw-chip.is-on { border-color: var(--line-dim); }
.cw-chip[aria-checked="true"] { background: var(--fg); border-color: var(--fg); color: var(--bg); }
.cw-chip[aria-checked="true"] .cw-chip__n { color: var(--bg); }
@media (hover: hover) { .cw-chip:not([aria-checked="true"]):hover { background: color-mix(in srgb, var(--fg) 8%, var(--bg-2)); } }
.cw-chip:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
@media (max-width: 767.98px) {
  .cw-chip { gap: 8px; padding: 6px 8px 6px 6px; min-height: 56px; font-size: 14px; }
  .cw-chip__v { display: block; }
  .cw-chip__n { display: none; }
}

/* ---- the clause cards: one group per element; with JS the groups share one cell, so the list keeps its height --- */
.cw-panel { position: relative; display: grid; gap: var(--s-4); align-content: start; }
.cw-count { position: absolute; top: 0; right: 0; display: flex; align-items: flex-end; gap: 10px; pointer-events: none; }
.cw-count__n { display: block; height: 40px; width: auto; overflow: visible; color: var(--fg); }
.cw-count__n path { fill: none; stroke: currentColor; stroke-width: 6; stroke-linecap: round; stroke-linejoin: round; }
.cw-count__n .gl-x { stroke-linecap: butt; }
.cw-count__k { max-width: 7.5em; padding-bottom: 2px; font: 600 var(--fs-micro)/1.25 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--fg-2); }
.cw-count__k :lang(zh-Hans) { font-family: var(--font-sans); letter-spacing: .02em; }
.cw-list { margin: 0; }
.cw-grp { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px 8px; align-content: start; }
.cw-grp > :is(dt, .cw-note) { grid-column: 1 / -1; }
.cw-grp + .cw-grp { margin-top: var(--s-6); }
html.js .cw-list { display: grid; }
html.js .cw-grp { grid-area: 1 / 1; margin: 0; visibility: hidden; }
html.js .cw-grp.is-on { visibility: visible; }
@media (max-width: 767.98px) { html.js .cw-grp:not(.is-on) { display: none; } }   /* phones: no hover previews, no reserved height */
.cw-grp__h { margin: 0 0 6px; font: 700 var(--fs-h3)/1.15 var(--font-sans); font-stretch: 108%; letter-spacing: -.005em; }
.cw-grp__h :lang(zh-Hans) { font-stretch: 100%; letter-spacing: .01em; }
html.js .cw-grp__h { min-height: 40px; padding-right: 9.5rem; }
html.js .cw-grp__n { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.cw-card {
  position: relative; display: grid; gap: 6px; justify-items: start; margin: 0; padding: 10px 12px 11px 14px;
  border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1); background: var(--bg-2);
  transition: border-color var(--dur-2) var(--ease-out);
}
.cw-card::before { content: ""; position: absolute; left: -1px; top: -1px; bottom: -1px; width: 2px; background: var(--rule); }
html.js .cw-grp.is-on .cw-card::before { background: var(--ai); }
.cw-card.is-hi { border-color: var(--ai); }
.cw-card__p { font-size: 15px; line-height: 1.45; }
.cw-card__p :lang(zh-Hans) { line-height: 1.7; }
.cw-note { margin: 6px 0 0; padding-left: var(--s-3); border-left: var(--bw-heavy) solid var(--ai); font-size: var(--fs-small); line-height: 1.5; color: var(--fg); }
.cw-note :lang(zh-Hans) { line-height: 1.75; }
.cw-fig .cw-cap { max-width: 64ch; }
html.js[data-motion="on"] .cw.is-live:not(.is-plotted) .cw-grp.is-on :is(.cw-card, .cw-note) {
  animation: cw-card 260ms var(--ease-out) calc(var(--o) * var(--cw-k) * 1ms) both;
}
@keyframes cw-card { from { opacity: 0; transform: translate3d(-8px, 0, 0); } }
/* md: the four chips in one row under the stage, the cards in two columns */
@media (min-width: 768px) and (max-width: 1279.98px) {
  .cw-chips { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .cw-grp { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---- the stage ------------------------------------------------------------------------------ */
.cw-fig { min-width: 0; }
.cw-tag { position: relative; display: inline-block; margin-bottom: var(--s-3); }
.cw-stage { position: relative; width: 100%; aspect-ratio: 1; margin-inline: auto; border: var(--bw-hair) solid var(--rule); user-select: none; -webkit-user-select: none; }
.cw-rings { position: absolute; inset: 0; overflow: clip; contain: strict; pointer-events: none; }
.cw-ring { position: absolute; left: var(--p); top: var(--p); width: var(--s); height: var(--s); will-change: transform; }
/* idle: Ch. 3 turns at +0.6°/s, Ch. 10 at −0.4°/s, Ch. 11B at +0.25°/s, on the compositor; story/web.js sets .is-spin
   and eases the playback rate to 0 for the 400 ms stop. Paused, a ring keeps its angle */
@keyframes cw-spin { to { transform: rotate(360deg); } }
html.js[data-motion="on"] .cw-ring { animation: cw-spin var(--cw-turn) linear infinite var(--cw-dir, normal) paused; }
html.js[data-motion="on"] .cw.is-spin .cw-ring { animation-play-state: running; }
.cw-ring[data-ring="3"] { --cw-turn: 600s; }
.cw-ring[data-ring="10"] { --cw-turn: 900s; --cw-dir: reverse; }
.cw-ring[data-ring="11B"] { --cw-turn: 1440s; }
html:not(.js) .cw-rings { display: none; }
.cw-svg, .cw-gk { position: absolute; inset: 0; display: block; width: 100%; height: 100%; overflow: visible; }
.cw-gk circle { fill: none; stroke: var(--line-dim); stroke-width: 4.4; opacity: .3; }

/* ring centerlines (B7.3 center linetype) and their chapter names, set along the arcs */
.cw-cl circle { fill: none; stroke: var(--lyr-grid); stroke-width: .75; stroke-dasharray: 24 6 4 6; opacity: .5; vector-effect: non-scaling-stroke; }
.cw-rl__t {
  fill: var(--line-dim); font: 500 calc(var(--cw-u) * 10px) var(--font-mono); letter-spacing: .14em; text-transform: uppercase;
  text-anchor: middle; dominant-baseline: central;
  paint-order: stroke; stroke: var(--model); stroke-width: calc(var(--cw-u) * 5px); stroke-linejoin: round;
}
.cw-rl__t:lang(zh-Hans) { font-family: var(--font-sans); letter-spacing: .24em; }
.cw-k { transform: scale(var(--cw-u)); }   /* symbols drawn in screen px */
.cw-hub { fill: none; stroke: var(--line-dim); stroke-width: 1; }
.cw-hub circle { fill: var(--line-dim); stroke: none; }

/* vignettes: opaque viewports; the drawing keeps hairline weights at any scale */
.cw-vig { cursor: pointer; }
.cw-vig__bg { fill: var(--model); stroke: var(--model-rule); stroke-width: 1; vector-effect: non-scaling-stroke; transition: stroke var(--dur-3) var(--ease-out); }
.cw-vig__br { fill: none; stroke: var(--ai); stroke-width: 1.5; vector-effect: non-scaling-stroke; opacity: 0; }
.cw-vig__tab { fill: var(--model-2); stroke: var(--model-rule); stroke-width: 1; }
.cw-vig__t { fill: var(--line-dim); font: 600 10px var(--font-mono); letter-spacing: .08em; }
html.js .cw-vig.is-on .cw-vig__bg { stroke: var(--line-dim); }
html.js .cw-vig.is-on .cw-vig__br { opacity: 1; }
html.js .cw-vig.is-on .cw-vig__t { fill: var(--line); }
@media (hover: hover) { .cw-vig:hover .cw-vig__bg { stroke: var(--line-dim); } }
.cw-plan :is(path, rect, circle, ellipse) { vector-effect: non-scaling-stroke; }
.cw-sx-cut { fill: url(#cw-m1-hm); stroke: var(--lyr-wall); stroke-width: 1.25; stroke-linejoin: miter; vector-effect: non-scaling-stroke; }
.cw-sx-rail { fill: none; stroke: var(--lyr-fixt); stroke-width: 1.25; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.cw-sx-head { fill: none; stroke: var(--lyr-dims); stroke-width: .75; stroke-dasharray: 5 3; vector-effect: non-scaling-stroke; }
.cw-sx-thin { fill: none; stroke: var(--lyr-grid); stroke-width: .6; opacity: .7; vector-effect: non-scaling-stroke; }
.cw-sx-dim { fill: none; stroke: var(--lyr-dims); stroke-width: .75; stroke-dasharray: 4 2.5; vector-effect: non-scaling-stroke; }
.cw-sx-north { fill: none; stroke: var(--line-dim); stroke-width: 1; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.cw-v-tint { fill: var(--occ-a); stroke: none; opacity: var(--cw-tint, 0); transition: opacity var(--dur-5) var(--ease-out); }
html.js .cw-vig.is-on { --cw-tint: 1; }

/* the AI's leaders: lime cubic Béziers with dot terminators, plotted in order at 900 px/s */
.cw-ld { fill: none; stroke: var(--vision); stroke-width: calc(var(--cw-u) * 1.5px); stroke-linecap: round; opacity: 0; pointer-events: none; }
.cw-ld--k { stroke-width: calc(var(--cw-u) * 1.1px); }
.cw-ld--g { stroke-width: calc(var(--cw-u) * 6px); }
.cw-ld--g.cw-ld--k { stroke-width: calc(var(--cw-u) * 4.5px); }
html:not(.js) .cw-ld { opacity: .3; }
html:not(.js) .cw-ld--g { opacity: 0; }
html.js .cw-ld.is-on { opacity: 1; }
html.js .cw-ld--g.is-on { opacity: .22; }
html.js .cw-ld.is-on.is-hi:not(.cw-ld--g) { stroke-width: calc(var(--cw-u) * 2.5px); }
.cw-dot { fill: var(--vision); r: calc(var(--cw-u) * 2.5px); opacity: 0; pointer-events: none; }
html:not(.js) .cw-dot { opacity: .45; }
html.js .cw-dot.is-on { opacity: 1; }
/* the dash lives only while plotting (fill backwards): a plotted leader is a plain stroke */
html.js[data-motion="on"] .cw.is-live:not(.is-plotted) .cw-ld.is-on { animation: cw-plot calc(var(--l) * var(--cw-k) * 1ms) linear calc(var(--o) * var(--cw-k) * 1ms) backwards; }
html.js[data-motion="on"] .cw.is-live:not(.is-plotted) .cw-dot.is-on { animation: cw-pop 160ms var(--ease-snap) calc(var(--o) * var(--cw-k) * 1ms) both; }
@keyframes cw-plot { from { stroke-dasharray: 1 1; stroke-dashoffset: 1; } to { stroke-dasharray: 1 1; stroke-dashoffset: 0; } }
@keyframes cw-pop { from { opacity: 0; } }

/* clause nodes: pinned, never rotating; they bloom when their leader arrives */
.cw-node { cursor: pointer; }
.cw-node__h { fill: transparent; }
.cw-node__o { fill: var(--model); stroke: var(--vision); stroke-width: 1.5; opacity: 0; transform-box: fill-box; transform-origin: center; }
.cw-node__d { fill: var(--line-dim); }
.cw-node__t {
  fill: var(--line-dim); opacity: .8; font: 500 11px var(--font-mono); letter-spacing: .02em;   /* .8: 4.9:1 on --model */
  paint-order: stroke; stroke: var(--model); stroke-width: 4px; stroke-linejoin: round;
}
html.js .cw-node.is-on .cw-node__o { opacity: 1; }
html.js .cw-node.is-on .cw-node__d { fill: var(--vision); }
html.js .cw-node.is-on .cw-node__t { fill: var(--line); opacity: 1; }
html.js .cw-node.is-hi .cw-node__t, .cw-node:hover .cw-node__t { fill: var(--vision); opacity: 1; }
html.js[data-motion="on"] .cw.is-live:not(.is-plotted) .cw-node.is-on .cw-node__o { animation: cw-bloom 280ms var(--ease-snap) calc(var(--o) * var(--cw-k) * 1ms) both; }
html.js[data-motion="on"] .cw.is-live:not(.is-plotted) .cw-node.is-on :is(.cw-node__t, .cw-node__d) { animation: cw-lit 200ms var(--ease-out) calc(var(--o) * var(--cw-k) * 1ms) both; }
@keyframes cw-bloom { from { opacity: 0; transform: scale(.2); } }
@keyframes cw-lit { from { fill: var(--line-dim); opacity: .8; } }
/* motion on: the default element stays unplotted until its first plot starts (.is-live), so the stage never shows it
   drawn, erases it and plots it again; if the module fails (data-module-state="error") the drawn state stays */
html.js[data-motion="on"] .cw:is([data-module-state="loading"], [data-module-state="ready"]):not(.is-live) :is(.cw-ld, .cw-dot, .cw-node__o),
html.js[data-motion="on"] .cw:is([data-module-state="loading"], [data-module-state="ready"]):not(.is-live) .cw-grp.is-on :is(.cw-card, .cw-note) { opacity: 0; }
html.js[data-motion="on"] .cw:is([data-module-state="loading"], [data-module-state="ready"]):not(.is-live) .cw-node.is-on :is(.cw-node__t, .cw-node__d) { fill: var(--line-dim); }
html.js[data-motion="on"] .cw:is([data-module-state="loading"], [data-module-state="ready"]):not(.is-live) .cw-node.is-on .cw-node__t { opacity: .8; }

/* ring legend: phones only, where the names along the arcs would be too small */
.cw-legend { display: none; }
.cw-legend li { display: flex; align-items: center; gap: 8px; }
.cw-legend svg { flex: none; width: 18px; height: 18px; fill: none; stroke: var(--line-dim); stroke-width: 1; opacity: .7; }
.cw-legend .is-on { stroke: var(--line); stroke-width: 2; }
.cw-legend :lang(zh-Hans) { font-family: var(--font-sans); letter-spacing: .02em; }
.cw-node__t--xs { display: none; }

/* xs/sm: rings only, nodes as dots, labels for the active element; the vignettes move into the chips and the
   chain is told by the cards (cw.chain) */
@media (max-width: 767.98px) {
  .cw-vig, .cw-dots, .cw-rl, .cw-lds, .cw-node__t--lg { display: none; }
  .cw-node:not(.is-on) .cw-node__t, html:not(.js) .cw-node__t { display: none; }
  html.js .cw-node.is-on .cw-node__t--xs { display: inline; }
  .cw-node__t { font-size: 10px; }
  .cw-legend {
    display: flex; flex-wrap: wrap; gap: 6px var(--s-4); margin-top: var(--s-3);
    font: 500 var(--fs-micro)/1.3 var(--font-mono); letter-spacing: .04em; text-transform: uppercase; color: var(--fg-2);
  }
  .cw-legend :lang(zh-Hans) { text-transform: none; }
}

/* command line */
.cw-cmd { margin-top: var(--s-2); }
.cw-cmd > span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ==== build: css/sections/reading.css ==== */
/* reading.css: A1.0 Machine reading (SPEC §D4). Prefix rd-.
   Static by default (no JS, reduced motion, phones, short windows): the exploded stack in its final state, the six
   steps as a list (cards with a detail drawing below 1280px) and the command line fully printed.
   Scrub (md and lg with JS and motion on, in windows at least 560px tall from 1280px wide and 640px tall below: the
   conditions reading.js scrubs under): the sheet runs 260vh from the first paint and the figure is pinned; once
   reading.js sets .is-scrub, the scroll progress drives the planes. Semantic tokens only. */

/* ---- one plan, five readings: #rd-geo / #rd-ann restyled per plane through custom properties ---------------- */
.rd-g-c-wall { color: var(--rd-wall, var(--lyr-wall)); }
.rd-g-c-door { color: var(--rd-door, var(--lyr-door)); }
.rd-g-c-glaz { color: var(--rd-glaz, var(--lyr-glaz)); }
.rd-g-c-fixt { color: var(--rd-fixt, var(--lyr-fixt)); }
.rd-g-c-furn { color: var(--rd-furn, var(--lyr-furn)); }
.rd-g-w { fill: var(--rd-wfill, none); }
.rd-g-w-line { color: var(--rd-wline, var(--lyr-wall)); }
.rd-x-c-grid { color: var(--rd-grid, var(--lyr-grid)); }
.rd-x-c-dims { color: var(--rd-dims, var(--lyr-dims)); }
.rd-x-c-text { color: var(--rd-text, var(--line)); }
.rd-x-c-text2 { color: var(--rd-text2, var(--line-dim)); }
.rd-x-c-bg { color: var(--rd-bg, var(--model)); fill: currentColor; stroke: none; }
.rd-ann { font: 500 10.5px var(--font-mono); font-variant-numeric: tabular-nums; text-anchor: middle; }
.rd-ann text { fill: currentColor; stroke: none; }
.rd-geo path, .rd-ann path, .rd-og { vector-effect: non-scaling-stroke; }
.rd-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
#rd-hatch path { stroke: var(--line-dim); stroke-width: .8; opacity: .55; }

.rd-c--p { --rd-wall: var(--ink); --rd-wfill: currentColor; --rd-wline: transparent; --rd-door: var(--ink); --rd-glaz: var(--ink);
  --rd-fixt: var(--ink); --rd-furn: var(--pencil); --rd-grid: var(--pencil); --rd-dims: var(--pencil); --rd-text: var(--ink);
  --rd-text2: var(--pencil); --rd-bg: var(--paper); }
.rd-c--l { --rd-wfill: none; }
.rd-c--e { --rd-wall: var(--line-dim); --rd-wfill: url(#rd-hatch); --rd-wline: var(--vision); }
.rd-c--t { --rd-bg: var(--model); }

/* planes: the vellum scan, then sheets of acetate */
.rd-plane { fill: color-mix(in srgb, var(--model) 34%, transparent); stroke: color-mix(in srgb, var(--line-dim) 55%, transparent); stroke-width: 1; vector-effect: non-scaling-stroke; }
.rd-plane--p { fill: var(--paper); stroke: var(--pencil); }
.rd-plane--s { fill: none; }
.rd-pborder { fill: none; stroke: var(--pencil); stroke-width: 1; vector-effect: non-scaling-stroke; opacity: .8; }

/* E: machine tags, OSNAP glyphs, ramp arrow */
.rd-tag rect { fill: var(--model-2); stroke: var(--vision); stroke-width: 1; vector-effect: non-scaling-stroke; }
.rd-tag text { fill: var(--vision); font: 500 9px var(--font-mono); letter-spacing: .02em; }
.rd-tag .rd-tag__v { fill: var(--line); font-weight: 400; }
.rd-tag--w rect { stroke: color-mix(in srgb, var(--vision) 55%, transparent); }
.rd-osnap { fill: none; stroke: var(--vision); stroke-width: 1.25; }
.rd-earrow { fill: none; stroke: var(--vision); stroke-width: 1.25; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }

/* T: OCR boxes, the values lifted to the ledger, the A-601 card and its link */
.rd-ocr__b { fill: none; stroke: var(--vision); stroke-width: .75; vector-effect: non-scaling-stroke; }
.rd-ocr__b--d { stroke: color-mix(in srgb, var(--vision) 70%, transparent); }
.rd-ocr__src { fill: color-mix(in srgb, var(--vision) 22%, transparent); stroke: var(--vision); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.rd-card { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.rd-card__bg { fill: var(--model-2); stroke: var(--line-dim); stroke-width: 1; vector-effect: non-scaling-stroke; }
.rd-card__rule { fill: none; stroke: var(--line-dim); stroke-width: 1; vector-effect: non-scaling-stroke; }
.rd-card text { fill: var(--line); }
.rd-card .rd-card__k { fill: var(--line-dim); letter-spacing: .06em; }
.rd-card__h { font-weight: 600; letter-spacing: .04em; }
.rd-card__hl { fill: color-mix(in srgb, var(--mismatch) 16%, transparent); stroke: var(--mismatch); stroke-width: 1; vector-effect: non-scaling-stroke; } /* the hit row */
.rd-card .rd-card__hv { fill: var(--mismatch); font-weight: 600; }
.rd-arc { fill: none; stroke: var(--mismatch); stroke-width: 1.5; stroke-linecap: round; }
.rd-ne circle { fill: var(--model); stroke: var(--mismatch); stroke-width: 1.25; vector-effect: non-scaling-stroke; }
.rd-ne text { fill: var(--mismatch); font: 600 15px var(--font-mono); }
.rd-ne path { fill: none; stroke: var(--mismatch); stroke-width: 1.5; stroke-linecap: round; } /* the card's drawn ≠ */
.rd-card .rd-ne { display: none; } /* the card's own ≠ is for the full tier's texture; here the link's ≠ marks it */

/* S: occupancy tints and boundaries (the in-plane readouts show only in the phone detail drawing) */
.rd-rm { stroke: none; }
.rd-rm--a { fill: var(--occ-a); }
.rd-rm--acc { fill: var(--occ-acc); }
.rd-rm--m { fill: var(--occ-m); }
.rd-rm--r { fill: var(--occ-r); }
.rd-rm--exit { fill: var(--occ-exit); }
.rd-rmo { fill: none; stroke: var(--vision); stroke-width: 1.25; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.rd-c--s2 .rd-rmo { stroke-width: 1; opacity: .5; }
.rd-slbl { visibility: var(--rd-slv, hidden); }
.rd-tag--s rect { stroke: color-mix(in srgb, var(--vision) 60%, transparent); }

/* ---- the figure: an exploded axonometric of the planes ---------------------------------------------- */
/* The stack is --rd-w wide; --rd-zu is the plane spacing (SPEC: 0, 60, 120, 180, 240 px at a 1440 desk). The exploded
   stack stands about .7 W + 3.5 zu tall and 1.28 W wide, plus a margin --rd-m for the labels. --rd-zu is registered so
   it resolves to a length that lite.js reads off the stack. The static figure (its stage height follows its width)
   takes its spacing from the figure's width; the pinned figure (scrub, below) sizes both from the window. */
@property --rd-zu { syntax: "<length>"; inherits: true; initial-value: 60px; }
.rd-fig { position: relative; container-type: inline-size; padding-top: 34px; }
.rd-view { position: relative; }
.rd-stage {
  --rd-zu: clamp(44px, 8.6cqw, 92px); --rd-m: 120px;
  --rd-w: min(calc(100cqw / 1.34), calc((100cqh - var(--rd-zu) * 3.5 - var(--rd-m)) / .7));
  position: relative; height: max(420px, calc(100cqw * .92)); container-type: size;
  border: 1px solid var(--rule); background: var(--bg); overflow: hidden; isolation: isolate;
}
@media (pointer: fine) { .rd-stage { cursor: crosshair; } } /* B7.12: a drawing; the planes take no pointer events */
.rd-stack {
  position: absolute; left: 50%; top: 50%; width: var(--rd-w); height: calc(var(--rd-w) * .7973);
  margin: calc(var(--rd-w) * -.39865) 0 0 calc(var(--rd-w) * -.5);
  transform-style: preserve-3d; transform: translateY(calc(var(--rd-zu) * 1.658)) rotateX(56deg) rotateZ(-38deg);
  pointer-events: none;
}
.rd-layer { --n: 0; position: absolute; inset: 0; transform: translateZ(calc(var(--rd-zu) * var(--n))); will-change: transform; }
.rd-layer--l { --n: 1; }
.rd-layer--e { --n: 2; }
.rd-layer--t { --n: 3; }
.rd-layer--s { --n: 4; }
.rd-layer--s2 { --n: 4.14; }
.rd-layer--f { --n: 4.2; }
.rd-svg { position: absolute; inset: 0; display: block; width: 100%; height: 100%; overflow: visible; }

/* labels projected from the planes (reading.js moves them while scrubbing) */
.rd-lbls { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.rd-lbl {
  position: absolute; white-space: nowrap;
  left: calc(50% + var(--rd-w) * var(--a)); top: calc(50% + var(--rd-w) * var(--b) + var(--rd-zu) * (1.658 - .829 * var(--n)));
  font: 500 11px/1.25 var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: .02em;
}
.rd-lbl--ly { translate: 2px -50%; padding: 1px 6px 1px 0; border-radius: var(--r-1); background: color-mix(in srgb, var(--model) 88%, transparent);
  color: var(--line-dim); font-size: 10.5px; letter-spacing: .08em; }
.rd-lbl--ly::before { content: ""; display: inline-block; width: 10px; height: 1px; margin: 0 6px 3px 0; background: var(--vision); }
.rd-lbl--rm { translate: -50% -50%; display: grid; justify-items: center; padding: .15em .55em .25em; border: 1px solid color-mix(in srgb, var(--vision) 55%, transparent);
  border-radius: var(--r-1); background: color-mix(in srgb, var(--model-2) 92%, transparent); color: var(--line);
  font-size: clamp(9px, calc(var(--rd-w) * .0218), 11px); }
.rd-lbl--rm b { color: var(--vision); font-weight: 600; }
.rd-lbl--rm i { font-style: normal; font-size: .95em; }
@container (max-width: 520px) or (max-height: 420px) { .rd-lbl--minor { display: none; } }
/* hover readout on plane E (reading.js): a machine tag above the element, its leader ending on the anchor */
.rd-hov { position: absolute; left: 0; top: 0; translate: -50% calc(-100% - 12px); padding: 2px 7px 3px; border: 1px solid var(--vision);
  border-radius: var(--r-1); background: color-mix(in srgb, var(--model-2) 94%, transparent); color: var(--vision);
  font: 500 11px/1.35 var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: .02em; white-space: nowrap; pointer-events: none; }
.rd-hov[hidden] { display: none; }
.rd-hov::after { content: ""; position: absolute; left: 50%; top: 100%; width: 1px; height: 12px; background: var(--vision); }
.rd-hov::before { content: ""; position: absolute; left: calc(50% - 2.5px); top: calc(100% + 10px); width: 5px; height: 5px; border-radius: 50%; background: var(--vision); }

/* ledger, cross-sheet link and areas: over the stage from md, under it on phones */
.rd-notes { display: grid; gap: var(--s-2); margin-top: var(--s-3); }
.rd-led, .rd-link, .rd-areas { margin: 0; background: color-mix(in srgb, var(--model-2) 94%, transparent); }
.rd-led { justify-self: start; padding: 7px 10px 8px; border: 1px solid var(--rule); font: 400 12px/1.6 var(--font-mono); font-variant-numeric: tabular-nums; color: var(--line); }
.rd-led__h { margin: 0 0 2px; font-size: 10.5px; font-weight: 600; letter-spacing: .1em; color: var(--line-dim); }
.rd-led ol { margin: 0; padding: 0; list-style: none; }
.rd-led li { display: grid; grid-template-columns: auto auto auto; justify-content: start; gap: 8px; white-space: nowrap; }
.rd-led b { color: var(--vision); font-weight: 600; }
.rd-link { padding: 8px 10px; border: 1px solid var(--mismatch-c); font: 500 var(--fs-mono)/1.5 var(--font-mono); color: var(--fg); }
.rd-link .st { margin: 0 6px 3px 0; vertical-align: middle; }
.rd-ne-t { color: var(--mismatch-c); font-weight: 700; }
.rd-areas { padding: 6px 10px; border-left: 2px solid var(--vision); font: 500 var(--fs-mono)/1.5 var(--font-mono); color: var(--fg); }
.rd-link :lang(zh-Hans), .rd-areas :lang(zh-Hans) { font-family: var(--font-sans); }
@media (min-width: 768px) {
  .rd-notes { display: contents; }
  .rd-led, .rd-link, .rd-areas { position: absolute; z-index: 3; }
  .rd-led { left: 12px; top: 12px; }
  .rd-link { right: 12px; bottom: 12px; max-width: min(44ch, 62%); }
  .rd-areas { left: 12px; bottom: 12px; max-width: min(36ch, 36%); }
}

/* figure foot: replay (scrub only, below), next sheet, caption */
.rd-end { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--s-2) var(--s-4); margin-top: var(--s-3); }
.rd-replay { display: none; }
.rd-end svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.rd-cap { margin-top: var(--s-2); }

/* ---- side column: head, kicker, body, steps, command line ------------------------------------------ */
.rd-body { row-gap: var(--s-6); align-items: start; }
.rd-side { display: grid; gap: var(--s-5); align-content: start; min-width: 0; }
.rd-head { margin: 0; }
.rd-head .sheet__eyebrow { margin-bottom: var(--s-4); }
.rd-h { font-size: clamp(2.25rem, 1.5rem + 1.5vw, 3.25rem); line-height: .98; }
.rd-h:lang(zh-Hans) { font-size: clamp(2rem, 1.35rem + 1.3vw, 2.875rem); }
.rd-h__s { display: inline-block; }
.rd-kicker { margin: 0; font-size: var(--fs-lead); line-height: 1.38; }
.rd-text { margin: 0; font-size: var(--fs-small); line-height: 1.6; color: var(--fg-2); }
.rd-text:lang(zh-Hans), .rd-kicker:lang(zh-Hans) { line-height: var(--lh-zh-body); }
.rd-nav { display: grid; gap: var(--s-4); min-width: 0; }

.rd-steps { display: grid; gap: var(--s-3); }
.rd-step { position: relative; display: grid; grid-template-columns: 2.4em minmax(0, 1fr); align-items: baseline; padding-top: var(--s-3); border-top: 1px solid var(--rule); }
.rd-step__no { grid-row: 1 / span 2; font: 600 var(--fs-mono)/1.6 var(--font-mono); color: var(--ai); font-variant-numeric: tabular-nums; }
.rd-step__t { font: 700 var(--fs-micro)/1.6 var(--font-sans); font-stretch: 125%; letter-spacing: .08em; text-transform: uppercase; color: var(--fg); }
.rd-step__t :lang(zh-Hans) { font-stretch: 100%; letter-spacing: .04em; font-size: var(--fs-small); }
.rd-step__sep { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.rd-step__d { grid-column: 2; font-size: var(--fs-small); line-height: 1.5; color: var(--fg-2); }
.rd-step__d :lang(zh-Hans) { line-height: 1.7; }
.rd-crop { grid-column: 1 / -1; margin-top: var(--s-3); padding-top: 28px; }
.rd-crop__svg { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; border: 1px solid var(--rule); background: var(--bg); }
.rd-crop__ghost { opacity: .3; }
.rd-crop__lbl { --rd-slv: visible; }

.rd-cmd { height: auto; margin: 0; }
.rd-cl { display: block; }
.rd-nb { white-space: nowrap; }
.rd-cl__mm { color: var(--mismatch); font-weight: 600; }

/* static layouts: one column below 1280 (steps as cards), side column + figure from 1280 */
@media (max-width: 1279.98px) {
  .rd:not(.is-scrub) :is(.rd-side, .rd-nav) { display: contents; }
  .rd:not(.is-scrub) :is(.rd-head, .rd-kicker, .rd-text, .rd-steps, .rd-cmd) { grid-column: 1 / -1; min-width: 0; }
  .rd:not(.is-scrub) .rd-head { order: 1; }
  .rd:not(.is-scrub) .rd-kicker { order: 2; }
  .rd:not(.is-scrub) .rd-text { order: 3; }
  .rd:not(.is-scrub) .rd-steps { order: 4; }
  .rd:not(.is-scrub) .rd-fig { order: 5; }
  .rd:not(.is-scrub) .rd-cmd { order: 6; }
  .rd-kicker, .rd-text { max-width: var(--measure); }
}
@media (min-width: 600px) and (max-width: 1279.98px) {
  .rd:not(.is-scrub) .rd-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--gutter); row-gap: var(--s-5); }
}
@media (max-width: 767.98px) {
  .rd-stage { --rd-zu: 40px; --rd-m: 56px; height: calc(100cqw * 1.18); }
  .rd-lbl--rm { display: none; }
}
@media (min-width: 1280px) {
  .rd-side { grid-column: 1 / span 4; }
  .rd-fig { grid-column: 5 / -1; }
  .rd-crop { display: none; }
}
/* the static figure rides along beside the step list (layout only: nothing moves under reduced motion) */
@media (min-width: 1280px) and (min-height: 760px) {
  .rd:not(.is-scrub) .rd-fig { position: sticky; top: var(--s-6); }
}

/* ---- scrub: the sheet runs 260vh, the figure is pinned, the step list rides along ----------------- */
/* CSS lays the scrub out under the conditions reading.js scrubs under (the media query of its mq, JS, motion on), so the
   sheet has its scrub height before the module starts and nothing grows when it does. An init error keeps the static
   layouts above, which these rules override. */
@media (min-width: 1280px) and (min-height: 560px), (min-width: 768px) and (min-height: 640px) {
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) { --rd-pin: var(--s-5); --rd-pin-top: var(--rd-pin); }
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) .rd-body { min-height: 260vh; align-items: stretch; }
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) :is(.rd-side, .rd-nav) { display: grid; }
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) :is(.rd-head, .rd-kicker, .rd-text) { order: 0; }
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) .rd-fig { align-self: start; position: sticky; top: var(--rd-pin-top);
    height: calc(100vh - var(--rd-pin-top) - var(--rd-pin)); height: calc(100svh - var(--rd-pin-top) - var(--rd-pin)); display: flex; flex-direction: column; }
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) .rd-view { flex: 1 1 0; min-height: 0; }
  /* pinned, the window's height is the limit: the spacing is a share --rd-k of the stack's width, so the exploded stack
     keeps its proportions down to short windows instead of collapsing under a fixed reserve. --rd-zu is declared on the
     stage's children here, where the cq units measure the stage. */
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) .rd-stage { height: 100%; --rd-k: .12; --rd-m: clamp(40px, 10cqh, 120px);
    --rd-w: min(calc(100cqw / 1.34), calc((100cqh - var(--rd-m)) / (.7 + 3.5 * var(--rd-k)))); }
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) :is(.rd-stack, .rd-lbls) { --rd-zu: calc(var(--rd-w) * var(--rd-k)); }
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) .rd-nav { position: sticky; top: max(var(--rd-pin), calc(50vh - 230px)); }
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) .rd-steps { grid-template-columns: none; gap: 0; border-top: 1px solid var(--rule); }
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) .rd-crop { display: none; }
  /* Replay holds its place from the first paint, and joins the tab order once reading.js runs it */
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) .rd-replay { display: inline-flex; }
  html.js[data-motion="on"] .rd:not([data-module-state="error"], .is-scrub) .rd-replay { visibility: hidden; }
  /* B7.12 strip, as a CAD command window: the two latest printed lines, whole, above the Command: prompt. It holds five
     rows (two wrapped lines and the prompt in cols 1-4) and grows on narrower columns rather than cut a line. */
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) .rd-cmd { height: auto; min-height: calc(5 * 1.45em + 12px); }
  .rd.is-scrub .rd-cl[hidden],
  .rd.is-scrub .rd-cl:has(~ .rd-cl:not([hidden], .rd-cl--cur) ~ .rd-cl:not([hidden], .rd-cl--cur)) { display: none; }

  /* until reading.js draws its first frame, the figure and the step list wait in the step 01 state, as lite.js poses
     it at p = 0 (the scan alone, flat, scaled to fill the stage, nothing labelled): a fast arrival never sees the
     exploded stack reset when the module starts. A focused Replay or Next always shows (it stays in the tab order). */
  html.js[data-motion="on"] .rd:not([data-module-state="error"], [data-step]) .rd-stack {
    transform: scale(max(1, min(tan(atan2(96cqw, var(--rd-w))), tan(atan2(90cqh, var(--rd-w) * .7973))))); }
  html.js[data-motion="on"] .rd:not([data-module-state="error"], [data-step]) :is(.rd-layer:not(.rd-layer--p), .rd-lbl, .rd-led, .rd-link, .rd-areas) { opacity: 0; }
  html.js[data-motion="on"] .rd:not([data-module-state="error"], [data-step]) .rd-end:not(:has(:focus-visible)) :is(.rd-replay, .rd-next) { opacity: 0; pointer-events: none; }
  html.js[data-motion="on"] .rd:not([data-module-state="error"], [data-step]) .rd-cl:not(.rd-cl--cur):nth-child(n + 3) { display: none; }
  html.js[data-motion="on"] .rd:not([data-module-state="error"], [data-step]) .rd-step {
    grid-template-columns: 10px 2.1em minmax(0, 1fr); column-gap: 8px; min-height: 41px; padding: 9px 8px; border-top: 0; border-bottom: 1px solid var(--rule); }
  html.js[data-motion="on"] .rd:not([data-module-state="error"], [data-step]) .rd-step::before { content: ""; align-self: center; width: 8px; height: 8px; border: 1px solid var(--fg-2); }
  html.js[data-motion="on"] .rd:not([data-module-state="error"], [data-step]) .rd-step__no { grid-row: auto; }
  html.js[data-motion="on"] .rd:not([data-module-state="error"], [data-step]) .rd-step__d { grid-column: 3; max-height: 0; overflow: hidden; opacity: 0; }
  html.js[data-motion="on"] .rd:not([data-module-state="error"], [data-step]) .rd-step:first-child .rd-step__d { max-height: 6em; opacity: 1; margin-top: 2px; }
  html.js[data-motion="on"] .rd:not([data-module-state="error"], [data-step]) .rd-step + .rd-step :is(.rd-step__no, .rd-step__t) { color: var(--fg-2); }
  html.js[data-motion="on"] .rd:not([data-module-state="error"], [data-step]) .rd-step:first-child { background: color-mix(in srgb, var(--vision) 7%, transparent); box-shadow: inset 2px 0 0 var(--vision); }
  html.js[data-motion="on"] .rd:not([data-module-state="error"], [data-step]) .rd-step:first-child::before { background: var(--vision); border-color: var(--vision); }
}
/* md: the side takes three columns and the pinned figure starts under the title-block chip; portrait tablets spread the
   planes over the height */
@media (min-width: 768px) and (max-width: 1279.98px) and (min-height: 640px) {
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) { --rd-pin-top: calc(var(--chip-h) + var(--s-4) + var(--s-3)); }
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) .rd-side { grid-column: 1 / span 3; }
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) .rd-fig { grid-column: 4 / -1; }
}
@media (min-width: 768px) and (max-width: 1279.98px) and (min-height: 640px) and (orientation: portrait) {
  html.js[data-motion="on"] .rd:not([data-module-state="error"]) .rd-stage { --rd-k: .27; }
}

/* the step list as a layer manager: a row per step, the current one open */
.rd-step__b {
  display: grid; grid-template-columns: 10px 2.1em minmax(0, 1fr); column-gap: 8px; align-items: baseline;
  width: 100%; min-height: 40px; margin: 0; padding: 9px 8px 9px 8px; border: 0; border-radius: 0;
  background: none; color: inherit; font: inherit; text-align: left; cursor: pointer;
  transition: background-color var(--dur-3) var(--ease-out);
}
.rd-step__b::before { content: ""; align-self: center; width: 8px; height: 8px; border: 1px solid var(--fg-2); }
.rd-step__b .rd-step__no { grid-row: auto; }
.rd-step__b .rd-step__d { grid-column: 3; display: block; max-height: 0; overflow: hidden; opacity: 0;
  transition: max-height var(--dur-5) var(--ease-out), opacity var(--dur-4) var(--ease-out); }
.rd.is-scrub .rd-step { display: block; padding: 0; border-top: 0; border-bottom: 1px solid var(--rule); }
.rd-step[data-st="past"] .rd-step__b::before { background: var(--fg-2); }
.rd-step[data-st="now"] .rd-step__b { background: color-mix(in srgb, var(--vision) 7%, transparent); box-shadow: inset 2px 0 0 var(--vision); }
.rd-step[data-st="now"] .rd-step__b::before { background: var(--vision); border-color: var(--vision); }
.rd-step[data-st="now"] .rd-step__d { max-height: 6em; opacity: 1; margin-top: 2px; }
.rd-step[data-st="next"] :is(.rd-step__no, .rd-step__t) { color: var(--fg-2); }
@media (hover: hover) { .rd-step__b:hover { background: var(--bg-2); } }
.rd-step__b:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }

/* scrubbed states: reading.js sets the classes from p, CSS draws each change both ways */
.rd.is-scrub .rd-lbl { left: 0; top: 0; transition: opacity var(--dur-4) var(--ease-out); }
.rd.is-scrub .rd-lbl--ly:not(.is-on), .rd.is-scrub.rd-on-lbl .rd-lbl--ly,
.rd.is-scrub:not(.rd-on-lbl) .rd-lbl--rm, .rd.is-scrub.rd-on-f .rd-lbl--rm { opacity: 0; }
.rd.is-scrub :is(.rd-etags, .rd-earrow, .rd-osnap) { transition: opacity var(--dur-4) var(--ease-out); }
.rd.is-scrub:not(.rd-on-e) :is(.rd-etags, .rd-earrow, .rd-osnap) { opacity: 0; }
.rd.is-scrub.rd-on-e .rd-os { animation: rd-osnap var(--dur-2) linear both; } /* .rd-os, not "use": see reading.static.js */
.rd.is-scrub.rd-on-e .rd-os:nth-child(3n + 2) { animation-delay: 90ms; }
.rd.is-scrub.rd-on-e .rd-os:nth-child(3n) { animation-delay: 180ms; }
@keyframes rd-osnap { 0% { opacity: 0; } 35% { opacity: 1; } 65% { opacity: .4; } 100% { opacity: 1; } }
.rd.is-scrub:not(.rd-on-ocr) .rd-ocr { opacity: 0; }
.rd.is-scrub.rd-on-ocr .rd-ocr__b { animation: rd-osnap 160ms linear both; }
.rd.is-scrub.rd-on-ocr .rd-ocr__b--n { animation-delay: 70ms; }
.rd.is-scrub.rd-on-ocr .rd-ocr__b--t { animation-delay: 140ms; }
.rd.is-scrub .rd-card { transition: opacity var(--dur-4) var(--ease-out), transform var(--dur-5) var(--ease-out); }
.rd.is-scrub:not(.rd-on-card) .rd-card { opacity: 0; transform: translateX(80px); }
.rd.is-scrub .rd-arc { stroke: var(--vision); stroke-dasharray: var(--len); stroke-dashoffset: var(--len);
  transition: stroke-dashoffset var(--dur-6) var(--ease-in-out), stroke var(--dur-3) linear; }
.rd.is-scrub.rd-on-arc .rd-arc { stroke-dashoffset: 0; }
.rd.is-scrub.rd-on-mm .rd-arc { stroke: var(--mismatch); }
.rd.is-scrub :is(.rd-ne, .rd-card__hl) { transition: opacity var(--dur-3) var(--ease-out); }
.rd.is-scrub:not(.rd-on-mm) :is(.rd-ne, .rd-card__hl) { opacity: 0; }
.rd.is-scrub:not(.rd-on-mm) .rd-card .rd-card__hv { fill: var(--line); font-weight: 400; }
.rd.is-scrub .rd-plane { transition: opacity var(--dur-5) var(--ease-out); }
.rd.is-scrub.rd-on-f .rd-plane { opacity: 0; } /* folded into one: the acetate frames go, the reading stays */
.rd.is-scrub .rd-layer--f { opacity: 0; transition: opacity var(--dur-3) linear; }
.rd.is-scrub.rd-on-f .rd-layer--f { opacity: 1; }
.rd.is-scrub .rd-f-cloud { stroke-dasharray: var(--len); stroke-dashoffset: var(--len); transition: stroke-dashoffset var(--dur-7) linear; }
.rd.is-scrub.rd-on-f .rd-f-cloud { stroke-dashoffset: 0; }
.rd.is-scrub .rd-f-delta { opacity: 0; transition: opacity var(--dur-4) var(--ease-out); }
.rd.is-scrub.rd-on-f .rd-f-delta { opacity: 1; transition-delay: 500ms; }
.rd.is-scrub :is(.rd-led, .rd-link, .rd-areas, .rd-replay, .rd-next) { transition: opacity var(--dur-4) var(--ease-out); }
.rd.is-scrub .rd-areas { max-width: min(40ch, 72%); } /* the link has given way by then */
.rd.is-scrub .rd-led li { opacity: 0; transition: opacity var(--dur-3) var(--ease-out); }
.rd.is-scrub .rd-led li.is-on { opacity: 1; }
.rd.is-scrub:is(:not(.rd-on-ocr), .rd-off) .rd-led,
.rd.is-scrub:is(:not(.rd-on-mm), .rd-on-areas) .rd-link,
.rd.is-scrub:is(:not(.rd-on-areas), .rd-off) .rd-areas { opacity: 0; }
/* faded, never out of the tab order; named by class, as "> *" would restyle the whole sheet on each toggle */
.rd.is-scrub:not(.rd-on-end) .rd-end:not(:has(:focus-visible)) :is(.rd-replay, .rd-next) { opacity: 0; pointer-events: none; }
.rd.is-scrub:not(.is-vis) :is(.cmdline__caret, .rd-os, .rd-ocr__b) { animation-play-state: paused; }
.rd.rd-jump :is(.rd-lbl, .rd-layer, .rd-plane, .rd-led, .rd-led li, .rd-link, .rd-areas, .rd-replay, .rd-next, .rd-etags, .rd-earrow, .rd-osnap, .rd-os,
  .rd-ocr, .rd-ocr__b, .rd-card, .rd-arc, .rd-ne, .rd-card__hl, .rd-f-cloud, .rd-f-delta, .rd-step__b, .rd-step__d) { transition: none; animation: none; }

/* ---- full tier (reading/scene.js): the WebGL canvas takes the stage once its first frame is drawn --------- */
.rd-gl-cv { position: absolute; inset: 0; z-index: 1; display: block; width: 100%; height: 100%; opacity: 0; transition: opacity var(--dur-5) var(--ease-out); }
.rd.rd-gl .rd-gl-cv { opacity: 1; }
.rd.rd-gl .rd-stack { opacity: 0; visibility: hidden; transition: opacity var(--dur-5) var(--ease-out), visibility 0s linear var(--dur-5); }

/* ==== build: css/sections/logic.css ==== */
/* logic.css: A2.0 Code logic (SPEC §D5). Prefix lg-. A details sheet: bubbles that jump to four stacked detail
   bands; each band is one figure.illus with its drawing (cols 1-7), its ruled trace pad (cols 8-12) and its
   controls under the trace (Detail 4: above it). xs/sm: drawing, controls, trace. Printing, plotting and blooms are CSS; JS adds
   .is-live on the sheet, .is-in on a band (40 % visible), .is-seen on a band (half its drawing in view) and
   .is-print / .is-done on a trace. */

.lg-body { row-gap: var(--s-7); }
.lg-head { margin-bottom: 0; display: grid; gap: var(--s-5); }
.lg-head .sheet__eyebrow { margin: 0; }
.lg-lead { margin: 0; }

/* ---- detail bubbles (jump links) ------------------------------------------------------------- */
.lg-nav__l { display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-6); padding-top: var(--s-4); border-top: var(--bw-heavy) solid var(--fg); }
.lg-bub { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; color: var(--fg); text-decoration: none; }
.lg-bub__c {
  position: relative; display: grid; grid-template-rows: 1fr 1fr; justify-items: center; flex: none;
  width: 36px; height: 36px; border: var(--bw-rule) solid var(--fg); border-radius: 50%; background: var(--bg);
}
.lg-bub__c::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; border-top: 1px solid var(--fg); }
.lg-bub__c b { align-self: end; padding-bottom: 1px; font: 600 12px/1 var(--font-mono); }
.lg-bub__c i { align-self: start; padding-top: 3px; font: 500 9px/1 var(--font-mono); font-style: normal; }
.lg-bub__t { font: 700 13px/1.2 var(--font-sans); font-stretch: 125%; letter-spacing: .08em; text-transform: uppercase; }
.lg-bub__t:lang(zh-Hans), .lg-bub__t :lang(zh-Hans) { font-stretch: 100%; letter-spacing: .04em; }
@media (hover: hover) { .lg-bub:hover .lg-bub__t { text-decoration: underline; text-underline-offset: 4px; } .lg-bub:hover .lg-bub__c { background: var(--hl); } }

/* ---- the band ---------------------------------------------------------------------------- */
.lg-band { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-5); align-content: start; padding-top: 44px; border-top: 1px solid var(--fg); scroll-margin-top: var(--s-4); }
.lg-bh { display: grid; gap: var(--s-2); }
.lg-bt { font: 700 var(--fs-micro)/1.35 var(--font-sans); font-stretch: 125%; letter-spacing: .08em; text-transform: uppercase; color: var(--fg-2); }
.lg-bt:lang(zh-Hans), .lg-bt :lang(zh-Hans) { font-size: var(--fs-small); font-stretch: 100%; letter-spacing: .04em; }
.lg-lede { margin: 0; font-size: var(--fs-h3); font-weight: 700; font-stretch: 108%; line-height: 1.15; letter-spacing: -.005em; text-wrap: balance; }
.lg-lede:lang(zh-Hans), .lg-lede :lang(zh-Hans) { line-height: 1.35; letter-spacing: .01em; }
.lg-dw { min-width: 0; }
.lg-dtb { margin-top: var(--s-3); }
.lg-dtb .dtitle__name { flex: 1 1 0; min-width: 12em; }
.lg-nw { white-space: nowrap; }
.lg-cap { margin-top: 0 !important; }

@media (min-width: 768px) and (max-width: 1279.98px) {
  .lg-band { grid-template-columns: repeat(8, minmax(0, 1fr)); column-gap: var(--gutter);
    grid-template-areas: "h h h h h h h h" "d d d d d t t t" "c c c c c t t t" "f f f f f t t t"; grid-template-rows: auto auto auto 1fr; }
}
@media (min-width: 1280px) {   /* the caption closes the right column, so the riding drawing never covers it */
  .lg-band { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter);
    grid-template-areas: "h h h h h h h t t t t t" "d d d d d d d t t t t t" "d d d d d d d c c c c c" "d d d d d d d f f f f f"; grid-template-rows: auto auto 1fr auto; }
  /* Detail 4's trace takes a whole cascade when the occupancy flips: its control sits above it, by the story, and stays put */
  html.js #lg-d4 { grid-template-areas: "h h h h h h h c c c c c" "d d d d d d d t t t t t" "d d d d d d d f f f f f"; grid-template-rows: auto 1fr auto; }
  .lg-band { min-height: 80vh; }
  #lg-d2 { min-height: 60vh; }
}
/* lg+, at least 600px tall: the drawing rides beside its taller trace and controls (sticky inside its own band, as the
   A5.0 figure does), so it stays in view while the visitor works the controls. Nothing is pinned or scroll-scrubbed. */
@media (min-width: 1280px) and (min-height: 600px) {
  html.js .lg-dw { position: sticky; top: var(--s-4); align-self: start; }
  /* the two tall drawings stay short enough to ride whole on wide, short windows (viewBoxes 62 × 57 and 448 × 632) */
  html.js #lg-d2 .lg-svg { max-width: calc((100vh - 96px) * 62 / 57); }
  html.js #lg-d4 .lg-svg { max-width: calc((100vh - 96px) * 448 / 632); }
}
@media (min-width: 768px) {
  .lg-bh { grid-area: h; } .lg-dw { grid-area: d; } .lg-pad { grid-area: t; align-self: start; } .lg-ctl { grid-area: c; } .lg-cap { grid-area: f; align-self: end; }
}
.lg-story { margin: var(--s-2) 0 0; font-size: var(--fs-body); line-height: var(--lh-body); }
.lg-story:lang(zh-Hans), .lg-story :lang(zh-Hans) { line-height: var(--lh-zh-body); }

/* ---- drawings: SVG in inches; strokes in screen px (non-scaling) unless they plot ---------------- */
.lg-svg { display: block; width: 100%; height: auto; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
@media (max-width: 599.98px) {   /* phones: the drawings bleed into the sheet padding */
  .lg-dw > .lg-svg { width: calc(100% + 2 * var(--sheet-pad)); max-width: none; margin-inline: calc(-1 * var(--sheet-pad)); }
}
.lg-svg text { fill: var(--fg); font-weight: 500; }
.lg-svg .lg-t2 { fill: var(--fg-2); }
.lg-svg .lg-tb { font-weight: 600; }
.lg-svg text.lg-r { fill: var(--conflict); }
.lg-svg text.lg-a { fill: var(--ai); }
.lg-svg .lg-ht, .lg-zd text { paint-order: stroke; stroke: var(--bg); stroke-width: 3px; stroke-linejoin: round; }
.lg-svg :is(.lg-k, .lg-h, .lg-tk, .lg-ds, .lg-rl, .lg-al, .lg-ab, .lg-gd, .lg-gb, .lg-gv, .lg-go, .lg-gl, .lg-tj, .lg-zf, .lg-zr, .lg-og) { vector-effect: non-scaling-stroke; }
.lg-pc { fill: var(--fg); }
.lg-k { fill: none; stroke: var(--fg); stroke-width: 1; }
.lg-h { fill: none; stroke: var(--fg-2); stroke-width: .6; }
.lg-tk { fill: none; stroke: var(--fg-2); stroke-width: 1.25; }
.lg-hp { stroke: var(--fg); stroke-opacity: .42; }
.lg-hr { stroke: var(--conflict); }
.lg-ds { fill: none; stroke: var(--fg); stroke-width: .75; stroke-dasharray: 6 3; }
.lg-tl { fill: none; stroke: var(--fg); stroke-linejoin: miter; }
.lg-og { fill: none; stroke: var(--fg); stroke-width: 1.25; opacity: .25; }
.lg-gw { fill: none; stroke: var(--vision); stroke-opacity: .3; stroke-linejoin: round; }
.lg-gd { fill: none; stroke: var(--ai); stroke-width: 1.5; stroke-dasharray: 5 3; }
.lg-gd.lg-gn { stroke: var(--fg-2); }   /* the fix still fails (tread under 11″): ink, not lime */
.lg-rl { fill: none; stroke: currentColor; color: var(--fg); stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.lg-r { color: var(--conflict); }
.lg-n { color: var(--notshown-c); }
.lg-dm circle { fill: var(--bg); stroke: var(--fg); stroke-width: 1; }
.lg-dm path { fill: var(--fg); }
.lg-hd { fill: none; stroke: var(--fg-2); }
.lg-al { fill: none; stroke: var(--ai); stroke-width: .75; }
.lg-ab { fill: none; stroke: var(--ai); stroke-width: 1.5; }
.lg-cl { fill: none; stroke: var(--conflict); stroke-linejoin: round; }
.lg-dt path:first-child { fill: var(--bg); stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round; }
.lg-dt.is-fx path:first-child { fill: var(--highlighter); }
.lg-dt text { fill: currentColor; font-weight: 600; }
.lg-ck { fill: none; stroke: var(--ai); stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.lg-gb { fill: var(--bg); stroke: var(--fg-2); stroke-width: .75; }
.lg-gv { fill: color-mix(in srgb, var(--ai) 16%, transparent); stroke: var(--ai); stroke-width: 1; }
.lg-go { stroke: var(--conflict); stroke-width: 1; }
.lg-gl { fill: none; stroke: var(--ai); stroke-width: 2; }
.lg-gl.lg-r { stroke: var(--conflict); }
/* guard elevation and the sphere: scene strokes inherit one screen px from the svg (the enlarged <use> passes 1/M) */
.lg-sl { fill: var(--bg-2); stroke: var(--fg); }
.lg-po { fill: var(--bg); stroke: var(--fg); stroke-linejoin: round; }
.lg-ba { fill: var(--fg); }
.lg-fw { fill: none; stroke: var(--vision); stroke-opacity: .32; }
.lg-fb { fill: none; stroke: var(--ai); }
.lg-sp { fill: var(--bg); opacity: .9; }
.lg-sk { fill: none; stroke: var(--bg); stroke-opacity: .6; stroke-width: .28; stroke-linecap: round; }
.lg-rg { fill: none; stroke: var(--vision); stroke-width: .9; stroke-opacity: .5; }
.lg-rk { fill: none; stroke: var(--ai); }
.lg-tj { fill: none; stroke: var(--ai); stroke-width: 1.5; stroke-dasharray: 0 4; stroke-linecap: round; }
.lg-zf { fill: none; stroke: var(--fg); stroke-width: .75; stroke-dasharray: 3 2; }
.lg-zb { fill: var(--bg); }
.lg-zr { fill: none; stroke: var(--fg); stroke-width: 1.5; }

/* plotting (pathLength 1): lines plot when the band enters, and again whenever a redraw replaces them */
@keyframes lg-plot { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes lg-wipe { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
.lg.is-live :is(.lg-plot, .lg-cl) { stroke-dasharray: 1; }
html[data-motion="on"] .lg.is-live .lg-band:not(.is-in) :is(.lg-plot, .lg-cl) { stroke-dashoffset: 1; }
html[data-motion="on"] .lg-band.is-in .lg-plot { animation: lg-plot var(--dur-6) var(--ease-out) both; }
html[data-motion="on"] .lg-band.is-in .lg-cl { animation: lg-plot calc(var(--a, 20) * 30ms) linear both; }
html[data-motion="on"] .lg-band.is-in [data-p="gh"] > *, html[data-motion="on"] .lg-band.is-in [data-p="og"] > * { animation: lg-wipe var(--dur-7) var(--ease-out) both; }
html[data-motion="on"] .lg-band.is-in .lg-svg :is([data-p="st"], [data-p="gd"], [data-p="lt"], [data-p="wl"]) { animation: lg-wipe var(--dur-6) steps(12, end) both; }
html[data-motion="on"] .lg.is-live .lg-band:not(.is-in) .lg-svg :is([data-p="st"], [data-p="gd"], [data-p="lt"], [data-p="wl"]) { clip-path: inset(0 100% 0 0); }

/* ---- the trace pad: --bg-2, ruled in faint non-photo blue ------------------------------------- */
.lg-pad {
  --lh: 22px; position: relative; min-width: 0;
  padding: var(--lh) var(--s-4); border: 1px solid var(--rule); border-radius: var(--r-1);
  background-color: var(--bg-2);
  background-image: linear-gradient(transparent calc(var(--lh) - 1px), color-mix(in srgb, var(--notshown) 12%, transparent) calc(var(--lh) - 1px));
  background-size: 100% var(--lh);
}
.lg-pad { container-type: inline-size; }
.lg-tr { display: grid; font: 400 var(--fs-mono)/var(--lh) var(--font-mono); font-variant-numeric: tabular-nums; }
.lg-l { display: grid; grid-template-columns: 4.6rem minmax(0, 1fr); column-gap: var(--s-3); }
@container (max-width: 300px) { .lg-l { grid-template-columns: minmax(0, 1fr); } }   /* narrow pads: the verb sits over its line */
.lg-l[hidden] { display: none; }
/* a line whose text changes length with the state also carries its other text, invisible, in the same cell (.lg-z), so it
   keeps one height */
.lg-xz { display: grid; }
.lg-xz > * { grid-area: 1 / 1; }
.lg-z { visibility: hidden; }
html:not(.js) .lg-z { display: none; }
.lg-v { font-weight: 600; font-size: var(--fs-micro); letter-spacing: .06em; color: var(--fg-2); }
.lg-v :lang(zh-Hans) { letter-spacing: .02em; }
.lg-x { overflow-wrap: anywhere; }
.lg-l[data-v="RESULT"] .lg-v { color: var(--fg); }
.lg-l[data-v="RESULT"] .lg-x { font-weight: 600; }
.lg-l:is([data-v="TRY"], [data-v="FIX"]) :is(.lg-v, .lg-x) { color: var(--ai); }
.lg-tr .st { padding: 0 5px; vertical-align: 1px; line-height: 18px; }
.lg-tr .cite { min-height: 0; padding: 0 5px; line-height: 18px; }
.lg-dl { font-weight: 600; color: var(--link); }
@keyframes lg-type { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
html[data-motion="on"] .lg.is-live .lg-tr:not(.is-done) > li { clip-path: inset(0 100% 0 0); }
html[data-motion="on"] .lg-tr.is-print:not(.is-done) > li { animation: lg-type var(--d, 1s) steps(var(--n, 40), end) var(--w, 0ms) both; }

/* ---- controls ---------------------------------------------------------------------------- */
.lg-ctl { display: grid; gap: var(--s-4); align-content: start; min-width: 0; }
html:not(.js) .lg-ctl { display: none; }
html.js .lg:not(.is-live) .lg-ctl { visibility: hidden; }
.lg-rng { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "l o" "c c"; gap: 2px var(--s-3); align-items: baseline; }
.lg-rng[hidden] { display: none; }
.lg-rng__l { grid-area: l; font: 600 var(--fs-micro)/1.3 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--fg-2); }
.lg-rng__l :lang(zh-Hans) { letter-spacing: .02em; }
.lg-rng__o { grid-area: o; font: 600 15px/1.2 var(--font-mono); font-variant-numeric: tabular-nums; }
.lg-rng__c { grid-area: c; display: flex; align-items: center; gap: var(--s-2); }
.lg-rng__b {
  flex: none; display: grid; place-items: center; width: 32px; height: 32px; padding: 0;
  border: 1px solid var(--fg); border-radius: var(--r-1); background: var(--bg); color: var(--fg);
  font: 600 16px/1 var(--font-mono); -webkit-tap-highlight-color: transparent;
}
@media (hover: hover) { .lg-rng__b:hover { background: var(--hl); } }
@media (pointer: coarse) { .lg-rng__b { width: 44px; height: 44px; } }
.lg-rng input {
  flex: 1 1 auto; min-width: 0; height: 32px; margin: 0; background: transparent; cursor: pointer;
  -webkit-appearance: none; appearance: none;
  touch-action: pan-y pinch-zoom;   /* sideways is the slider's, up and down the page's (logic.js holds a touch until it knows) */
}
.lg-rng input::-webkit-slider-runnable-track { height: 2px; background: var(--fg); }
.lg-rng input::-webkit-slider-thumb { -webkit-appearance: none; width: 18px; height: 18px; margin-top: -8px; border: var(--bw-rule) solid var(--fg); border-radius: 50%; background: var(--bg); box-shadow: inset 0 0 0 3px var(--bg), inset 0 0 0 8px var(--fg); }
.lg-rng input::-moz-range-track { height: 2px; background: var(--fg); }
.lg-rng input::-moz-range-thumb { width: 15px; height: 15px; border: var(--bw-rule) solid var(--fg); border-radius: 50%; background: var(--bg); box-shadow: inset 0 0 0 3px var(--bg), inset 0 0 0 8px var(--fg); }
.lg-rng input:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.lg-acts { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-3); align-items: center; }
.lg-acts .btn[aria-pressed="true"] { background: var(--fg); color: var(--bg); }
@media (pointer: coarse) { .lg-acts .btn { min-height: 44px; } }
.lg-cad { margin: 0; padding-left: var(--s-3); border-left: var(--bw-heavy) solid var(--fg); font: 400 var(--fs-micro)/1.5 var(--font-mono); color: var(--fg-2); }
.lg-cad :lang(zh-Hans) { font-family: var(--font-sans); line-height: 1.7; }

/* fixed annotations drawn in screen px around a drawing point (logic.static.js U): --k = user units per screen px */
.lg-u { transform: scale(var(--k)); }
@media (max-width: 599.98px) { .lg-u { transform: scale(calc(var(--k) * .82)); } }   /* about 9 px on phones */

/* ---- Detail 2: door 104. The leaf turns on its knuckle at (−1/8″, 2-1/2″); the tape grows from the door face ------- */
.lg-svg :is(.lg-fr, .lg-kn, .lg-lf rect, .lg-gh rect, .lg-br, .lg-ld, .lg-tg, .lg-tm, .lg-hk, .lg-wd) { vector-effect: non-scaling-stroke; }
.lg-fr, .lg-kn, .lg-tg { fill: var(--bg); stroke: var(--fg); stroke-width: 1; }
.lg-lv { transform: rotate(var(--r)); transform-origin: -.125px 2.5px; }
.lg-lf rect { fill: var(--bg); stroke: var(--fg); stroke-width: 1.25; }
.lg-gh rect { fill: none; stroke: var(--fg); stroke-width: 1; stroke-dasharray: 4 3; opacity: .55; }
.lg-sw { fill: none; stroke: var(--fg-2); stroke-dasharray: 1; }
.lg-br { fill: none; stroke: var(--fg); stroke-width: 1; }
.lg-ld { fill: none; stroke: var(--fg-2); stroke-width: .75; }
.lg-tp { transform-origin: -1.875px 6px; }
.lg-tm { fill: none; stroke: var(--ai); stroke-width: 1.25; }
.lg-hk { fill: none; stroke: var(--ai); stroke-width: 1; }
.lg-svg .lg-cu { fill: var(--ai); font-weight: 600; transform: translateY(var(--y)); }
.lg-wd { stroke: var(--conflict); stroke-width: 1; }
.lg-mm { color: var(--mismatch-c); }
@keyframes lg-swing { from { transform: none; } }
@keyframes lg-grow { from { transform: scaleX(0); } }
@keyframes lg-count { from { transform: none; } }
@keyframes lg-show { from { opacity: 0; } }
/* the door and the tiles wait for the drawing itself (.is-seen: half of the drawing, Detail 4: half of its tiles, in view) */
html[data-motion="on"] .lg.is-live .lg-band:not(.is-seen, .is-x) .lg-lf { transform: none; }
html[data-motion="on"] .lg.is-live .lg-band:not(.is-seen, .is-x) .lg-sw { stroke-dashoffset: 1; }
html[data-motion="on"] .lg.is-live .lg-band:not(.is-seen, .is-x) :is(.lg-tp, .lg-cu, .lg-wd, .lg-ti > rect) { opacity: 0; }
/* the cut structure wipes in (600 ms), the door swings 0 → 90° from 450 ms, then the tape runs for 500 ms */
html[data-motion="on"] .lg-band.is-seen:not(.is-x) .lg-lf { animation: lg-swing var(--dur-6) var(--ease-in-out) 450ms both; }
html[data-motion="on"] .lg-band.is-seen:not(.is-x) .lg-sw { animation: lg-plot var(--dur-6) var(--ease-in-out) 450ms both; }
html[data-motion="on"] .lg-band.is-seen:not(.is-x) .lg-tp { animation: lg-grow 500ms linear 1050ms both; }
/* jump-start: a finished steps(…, end) animation can stop one step short in Chrome after a long delay */
html[data-motion="on"] .lg-band.is-seen:not(.is-x) .lg-cu { animation: lg-count 500ms steps(var(--n), jump-start) 1050ms both, lg-show 0s 1050ms both; }
/* a short tape counts in the AI's ink and turns red only where it stops, as the shortfall wedge lands */
@keyframes lg-ink { from { fill: var(--ai); } }
html[data-motion="on"] .lg-band.is-seen:not(.is-x) .lg-cu.lg-r { animation: lg-count 500ms steps(var(--n), jump-start) 1050ms both, lg-show 0s 1050ms both, lg-ink 0s 1550ms both; }
html[data-motion="on"] .lg-band.is-seen:not(.is-x) .lg-wd { animation: lg-show 0s 1550ms both; }

/* ---- Detail 4: the restaurant. Tiles pop in raster order on entry; the wall is the handle; at 50 the G-001 excerpt
   takes the A-2 stamp, the Δ1 cloud blooms and the cascade enters one line every 200 ms (the band's data-c="a2") ------ */
.lg-svg :is(.lg-ti > rect, .lg-fu, .lg-fx, .lg-wn, .lg-dr, .lg-rt, .lg-g0, .lg-gp) { vector-effect: non-scaling-stroke; }
.lg-ti > rect { fill: color-mix(in srgb, var(--ai) 13%, transparent); stroke: var(--ai); stroke-width: .75; transform-box: fill-box; transform-origin: center; }
.lg-fu { fill: none; stroke: var(--fg-2); stroke-width: .6; }
.lg-fx, .lg-dr { fill: none; stroke: var(--fg); stroke-width: 1; }
.lg-dsh { stroke-dasharray: 6 3; stroke-width: .75; }
.lg-wn { fill: none; stroke: var(--fg); stroke-width: .75; }
.lg-rt { fill: var(--bg); stroke: var(--fg); stroke-width: 1; }
.lg-g0 { fill: none; stroke: var(--fg); stroke-width: 1; stroke-dasharray: 6 4; opacity: .5; }
.lg-hit { fill: transparent; }
.lg-gp { fill: var(--ai); stroke: var(--bg); stroke-width: 1.5; paint-order: stroke; pointer-events: none; }
.lg:not(.is-live) .lg-gp { display: none; }
@media (pointer: coarse) { .lg-gp { display: none; } }
@media (pointer: fine) { .lg.is-live .lg-hit { cursor: ns-resize; } }   /* without JS the wall is only drawn */
@media (hover: hover) and (pointer: fine) { .lg.is-live [data-p="wl"]:has(.lg-hit:hover) .lg-pc:first-child { fill: var(--ai); } }
#lg-d4:has([data-s="d"]:focus-visible) [data-p="wl"] .lg-pc:first-child { fill: var(--ai); }   /* the input's wall lights up too */
@keyframes lg-pop { from { transform: scale(.2); opacity: 0; } }
html[data-motion="on"] .lg-band.is-seen:not(.is-x) .lg-ti > rect { animation: lg-pop var(--dur-4) var(--ease-snap) calc(var(--i) * 12ms) both; }

#lg-d4 .lg-dw { display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; column-gap: var(--s-5); }
.lg-side { order: -1; display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--s-4) var(--s-6); margin-bottom: var(--s-4); }
@media (min-width: 1280px) {
  #lg-d4 .lg-dw { grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--s-4); }
  #lg-d4 .lg-side { order: 0; grid-column: 2; grid-row: 1; flex-direction: column; align-items: flex-start; align-self: start; gap: var(--s-5); margin: var(--s-6) 0 0; }
  #lg-d4 .lg-dw > :not(.lg-svg, .lg-side) { grid-column: 1 / -1; }
  #lg-d4 .lg-g1 { width: 208px; margin-left: -16px; }
}
.lg-g1h { margin: 0; font: 600 var(--fs-micro)/1.3 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--fg-2); }
.lg-g1h :lang(zh-Hans) { letter-spacing: .02em; }
.lg-g1 { display: block; width: 232px; height: auto; margin: 2px 0 0 -18px; overflow: visible; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.lg-g1 > text { fill: var(--fg); font-size: 12px; font-weight: 500; }
.lg-g1 > .lg-g1t { font-size: 11px; font-weight: 600; letter-spacing: .06em; }
.lg-g1 > .lg-g1s { fill: var(--fg-2); }
.lg-g1b { fill: var(--bg); stroke: var(--fg); stroke-width: 1.5; }
.lg-g1r { fill: none; stroke: var(--fg); stroke-width: 1; }
.lg-hl { fill: var(--highlighter); }
.lg-vf { color: var(--verify-c); }
.lg-sm { color: var(--verify-c); mix-blend-mode: multiply; transform-box: fill-box; transform-origin: center; transform: rotate(-8deg) scale(1.9); opacity: 0; }
.lg-sm rect { fill: none; stroke: currentColor; stroke-width: 3; }
.lg-sm rect + rect { stroke-width: 1.25; }
.lg-sm text { fill: currentColor; stroke: currentColor; stroke-width: .8px; paint-order: stroke; font: 800 27px/1 var(--font-sans); font-stretch: 125%; letter-spacing: .02em; }
.lg-g1c { fill: none; stroke: var(--verify-c); stroke-width: 1.75; stroke-linejoin: round; stroke-dasharray: 1; stroke-dashoffset: 1; }
.lg-g1d { opacity: 0; }
.lg-band[data-c="a2"] .lg-sm { transform: rotate(-8deg); opacity: 1; }
.lg-band[data-c="a2"] .lg-g1c { stroke-dashoffset: 0; }
.lg-band[data-c="a2"] :is(.lg-g1d, .lg-ctr__n) { opacity: 1; color: var(--verify-c); }
.lg-band.is-in .lg-sm { transition: transform 320ms var(--ease-stamp), opacity 120ms linear; }
.lg-band.is-in .lg-g1c { transition: stroke-dashoffset calc(var(--a) * 30ms) linear 200ms; }
.lg-band.is-in .lg-g1d { transition: opacity var(--dur-3) linear 1.4s; }
.lg-band.is-in:not([data-c="a2"]) :is(.lg-g1c, .lg-g1d) { transition-delay: 0s; }
.lg-ctr { display: grid; gap: 4px; margin: 0; }
.lg-ctr__n { font: 600 clamp(3.25rem, 2.4rem + 2.6vw, 4.75rem)/.86 var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: -.03em; transition: color var(--dur-3) linear; }
.lg-ctr__l { font: 600 var(--fs-micro)/1.3 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--fg-2); }
.lg-ctr__l :lang(zh-Hans) { letter-spacing: .02em; }
.lg-key { display: flex; align-items: center; gap: 8px; margin: 0; font: 400 var(--fs-micro)/1.4 var(--font-mono); color: var(--fg-2); }
.lg-key__t { flex: none; width: 12px; height: 20px; border: 1px solid var(--ai); background: color-mix(in srgb, var(--ai) 13%, transparent); }

/* the cascade: a heading line, then one line per consequence, its status chip where the verb goes */
@container (min-width: 300px) { #lg-d4 .lg-l { grid-template-columns: 7.25rem minmax(0, 1fr); } }
.lg-ch { margin-top: 10px; padding-top: 10px; border-top: var(--bw-rule) solid var(--fg); }
.lg-ch .lg-x { grid-column: 1 / -1; font: 700 var(--fs-micro)/var(--lh) var(--font-sans); font-stretch: 125%; letter-spacing: .08em; text-transform: uppercase; }
.lg-ch .lg-x :lang(zh-Hans) { font-stretch: 100%; letter-spacing: .04em; }
.lg-l[data-v="INFO"] .lg-x { color: var(--fg-2); }
html[data-motion="on"] .lg-tr.is-done > .lg-c { animation: lg-type 160ms steps(12, jump-start) calc(var(--j) * 200ms) both; }
/* the printed trace is the as-drawn 23′-6″ one; logic.js starts at 23′-0″ (Group B). So that the band keeps its height when
   it starts, until then the cascade stays out and the Group B lines keep their space, invisible */
html.js .lg:not(.is-live) #lg-d4 .lg-l[hidden]:not(.lg-c) { display: grid !important; visibility: hidden; order: 1; }   /* over base.css [hidden]; the cascade rows stay out while logic.js boots */
html.js .lg:not(.is-live, [data-module-state="error"]) #lg-d4 .lg-c { display: none; }
.lg-cav { margin: var(--s-3) 0 0; padding-top: var(--s-2); border-top: 1px solid var(--rule); font: 400 var(--fs-micro)/1.6 var(--font-mono); color: var(--fg-2); max-width: none; }
.lg-cav :lang(zh-Hans) { font-family: var(--font-sans); line-height: 1.75; }

/* ---- the no-JS fix drawings ------------------------------------------------------------------------- */
.lg-fix { position: relative; margin-top: var(--s-5); max-width: 26rem; padding: 30px var(--s-3) var(--s-3); border: 1px dashed var(--fg-2); }
.lg-fix__h { position: absolute; left: var(--s-3); top: 8px; margin: 0; font: 600 var(--fs-micro)/1.3 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--ai); }
#lg-d4 .lg-fix { width: max-content; }

html[data-motion="off"] .lg :is(.lg-plot, .lg-cl, .lg-tr > li, [data-p], .lg-lf, .lg-sw, .lg-tp, .lg-cu, .lg-wd, .lg-ti > rect) { animation: none !important; clip-path: none !important; }

/* ==== build: css/sections/report.css ==== */
/* report.css: A3.0 findings report (prefix rp-) and A4.0 building types (prefix ty-). SPEC §D6, §D7.
   Paper sheets: ink linework, status colours from the semantic tokens, --ai (vision-ink) for the machine's marks. */

/* ======================================================================== A3.0 findings report */
.rp-body { row-gap: var(--s-6); align-items: start; }
.rp-head { margin-bottom: 0; }
.rp-h { max-width: 15ch; }
.rp-h:lang(zh-Hans) { max-width: 13em; }
.rp-intro { display: grid; gap: var(--s-3); align-content: end; }
.rp-sub { margin: 0; font: 700 var(--fs-lead)/1.3 var(--font-sans); font-stretch: 112%; letter-spacing: .01em; }
.rp-lead { margin: 0; }

@media (min-width: 1280px) {
  .rp-body > .rp-head { grid-column: 1 / span 7; grid-row: 1; align-self: end; }
  .rp-body > .rp-intro { grid-column: 8 / -1; grid-row: 1; align-self: end; }
  .rp-body > .rp-fig { grid-column: 1 / span 7; grid-row: 2; }
  .rp-body > .rp-report { grid-column: 8 / -1; grid-row: 2; }
}

/* ---- plan figure: sticky beside (lg) or above (md, xs) the report column -------------------- */
/* Above the cards (md, xs) the pinned figure starts at the viewport top and paints the band over its tools (the md
   title-block chip sits in it), so cards never show through above the plan. --rp-band is that band, --rp-h the
   figure below it: 42vh (xs) or 46vh (md), never under a usable stage and never so tall that no card is left beside
   it. --rp-sm keeps a row and every control in it clear of the plan when it is scrolled or focused into view, on top
   of html's scroll-padding-top (16px; chip-h + 28px at md, which is about the band). */
.rp {
  --rp-band: var(--s-2); --rp-h: max(42vh, min(270px, 100vh - 240px));
  --rp-sm: calc(var(--rp-band) + var(--rp-h));
}
@media (min-width: 768px) and (max-width: 1279.98px) {
  .rp { --rp-band: calc(var(--chip-h) + 24px); --rp-h: max(46vh, min(320px, 100vh - 280px)); --rp-sm: calc(var(--rp-h) + var(--s-3)); }
}
@media (min-width: 1280px) { .rp { --rp-band: 0px; --rp-sm: var(--s-4); } }   /* rows align with the plan's top */
.rp-fig {
  position: sticky; top: 0; z-index: var(--z-sticky);
  display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto;
  grid-template-areas: "tools" "stage" "dt";
  height: calc(var(--rp-band) + var(--rp-h)); padding: var(--rp-band) 0 6px;
  container-type: inline-size; box-shadow: 0 10px 14px -12px color-mix(in srgb, var(--ink) 35%, transparent);
  /* the sheet's own paper and grain (B7.11), so the pinned figure reads as the sheet, not a panel on it */
  background: var(--paper) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .10  0 0 0 0 .09  0 0 0 0 .07  0 0 0 .05 0'/></filter><rect width='100%' height='100%' filter='url(%23g)'/></svg>");
}
.rp-body > .rp-fig { margin-top: calc(-1 * min(var(--rp-band), var(--s-6))); }   /* the band sits in the row gap */
.rp-fig > .illus__tag { top: var(--rp-band); }
@media (min-width: 1280px) {
  .rp-fig { top: var(--s-6); height: min(82vh, 900px); min-height: min(480px, 100vh - 2 * var(--s-6)); padding: 0; background: none; box-shadow: none; }
}
/* short landscape screens (phones turned sideways): the plan pins beside the cards, as at lg, instead of over them */
@media (min-width: 560px) and (max-width: 1279.98px) and (max-height: 520px) {
  .rp { --rp-band: 0px; --rp-sm: 0px; }
  .sheet__body.rp-body { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .rp-body > .rp-fig { grid-column: 1; grid-row: 3; top: var(--s-2); height: calc(100vh - 2 * var(--s-2)); box-shadow: none; }
  .rp-body > .rp-report { grid-column: 2; grid-row: 3; }
}
@media (min-width: 560px) and (max-width: 767.98px) and (max-height: 520px) {
  .rp-body > .rp-fig { height: calc(100vh - 2 * var(--s-2) - var(--bbar-h) - env(safe-area-inset-bottom)); }
}
@media (max-width: 559.98px) and (max-height: 520px) { .rp-fig { position: relative; } .rp { --rp-sm: 0px; } }
.rp-row, .rp-row button { scroll-margin-top: var(--rp-sm); }

.rp-tools { grid-area: tools; display: flex; justify-content: flex-end; align-items: center; gap: var(--s-2); min-height: 32px; margin-bottom: var(--s-2); }
@container (max-width: 560px) { .rp-tools { justify-content: flex-start; margin-top: 30px; } }
.rp-lvl { max-width: 100%; }
.rp-lvl > button { padding: 0 12px; }
@container (max-width: 300px) { .rp-lvl > button { padding: 0 6px; letter-spacing: 0; } }
.rp-stage {
  grid-area: stage; position: relative; min-height: 0; overflow: hidden;
  border: var(--bw-hair) solid var(--rule); background: var(--paper);
  -webkit-user-select: none; user-select: none;
}
.rp-stage > .rp-plan { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* until report.js draws the plan: its first plotter passes (Level 1 grid and walls) under this label (report.static.js) */
.rp-plotting {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); margin: 0; padding: 2px 8px; max-width: none;
  background: var(--paper); color: var(--fg-2); white-space: nowrap;
  font: 600 var(--fs-micro)/1.35 var(--font-mono); letter-spacing: .08em; text-transform: uppercase;
}
.rp-plotting :lang(zh-Hans) { letter-spacing: .02em; font-family: var(--font-sans); }
.rp[data-module-state="error"] .rp-plotting { display: none; }
/* zoom: over the stage's lower-right corner at every width, on paper buttons */
.rp-zoom { grid-area: stage; align-self: end; justify-self: end; z-index: 2; display: flex; gap: 4px; margin: var(--s-2); }
/* xs and short screens: no room for the drawing title; it stays the figure's (one-language) name */
@media (max-width: 767.98px), (max-width: 1279.98px) and (max-height: 520px) {
  .rp-dtitle { position: absolute; width: 1px; height: 1px; margin: 0; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
.rp-zb {
  display: inline-grid; place-items: center; min-width: 32px; height: 32px; padding: 0 8px;
  border: var(--bw-hair) solid var(--fg); border-radius: var(--r-1); background: var(--paper); color: var(--fg);
  font: 600 var(--fs-micro)/1 var(--font-mono); letter-spacing: .04em; text-transform: uppercase;
}
.rp-zb:lang(zh-Hans) { letter-spacing: 0; }
.rp-zi { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.rp-zb:focus-visible { box-shadow: 0 0 0 4px var(--paper); }
@media (hover: hover) { .rp-zb:hover { background: var(--hl); } }
@media (pointer: coarse) { .rp-zb { min-width: 44px; height: 44px; } }
.rp-dtitle { grid-area: dt; margin-top: var(--s-3); }

/* plan states (live SVG, ids and classes prefixed rp-) */
.rp-plan .rp-cloud, .rp-plan .rp-delta { cursor: pointer; }
.rp-plan .rp-cloud { pointer-events: stroke; }
.rp-plan .rp-cloud.is-dash { stroke-dasharray: 9 6; }
.rp-plan .rp-cloud.is-off { visibility: hidden; }
.rp-plan .rp-delta.is-dash .rp-delta__tri { stroke-dasharray: 6 4; }   /* dismissed, like its cloud; the number keeps its contrast */
.rp-pre .rp-cloud, .rp-pre .rp-delta { visibility: hidden; }
.rp-hl { pointer-events: none; transition: opacity var(--dur-3) var(--ease-out); }
.rp-hl.is-moving { opacity: 0; transition: none; }
.rp-hl text { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.rp-hg { fill: none; stroke: var(--ai); stroke-linecap: round; }
.rp-hb { fill: var(--ai); }
.rp-ht { fill: var(--paper); font-weight: 600; text-anchor: middle; }
.rp-hk { fill: var(--paper); fill-opacity: .94; }
.rp-hd { fill: var(--ai); font-weight: 600; }

/* ---- report column: one figure.illus.rp-report ------------------------------------------------ */
.rp-report { padding-top: 34px; container-type: inline-size; }
.rp-rhead { padding-bottom: var(--s-4); border-bottom: var(--bw-heavy) solid var(--fg); }
.rp-rh { margin: 0 0 var(--s-2); font: 700 clamp(1.125rem, 1rem + .45vw, 1.5rem)/1.1 var(--font-sans); font-stretch: 125%; letter-spacing: .06em; text-transform: uppercase; }
.rp-rh:lang(zh-Hans) { font-stretch: 100%; letter-spacing: .04em; }
.rp-meta { margin: 0 0 var(--s-2); max-width: none; font: 400 var(--fs-micro)/1.55 var(--font-mono); color: var(--fg-2); }
.rp-meta:lang(zh-Hans) { font-family: var(--font-sans); font-size: 13px; }
.rp-scope { margin: 0; padding-left: 10px; border-left: var(--bw-rule) solid var(--rule); font-size: var(--fs-small); line-height: 1.5; color: var(--fg-2); }

.rp-table, .rp-table > tbody { display: block; width: 100%; }
.rp-cap, .rp-thead { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* each finding row is a schedule card: Δ in the gutter, status and location, element, found / required, CBC, fix */
.rp-row {
  position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: 6px 10px;
  padding: var(--s-4) var(--s-3) var(--s-4) 54px; border-bottom: var(--bw-hair) solid var(--rule);
  cursor: default; outline-offset: -2px;   /* scroll-margin-top: --rp-sm, with the plan figure */
  transition: background-color var(--dur-3) var(--ease-out);
}
:where(.rp-row > td) { display: block; padding: 0; min-width: 0; }
.rp-td--d { position: absolute; left: 6px; top: 15px; }
.rp-td--st { grid-column: 1; grid-row: 1 / span 2; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.rp-td--sh, .rp-td--gr { grid-column: 2; justify-self: end; text-align: right; font: 500 var(--fs-micro)/1.35 var(--font-mono); color: var(--fg-2); font-variant-numeric: tabular-nums; }
.rp-td--sh { grid-row: 1; color: var(--fg); }
.rp-td--gr { grid-row: 2; }
.rp-td--el, .rp-td--fd, .rp-td--rq, .rp-td--cb, .rp-td--fx { grid-column: 1 / -1; }
.rp-td--el { margin-top: 2px; }
.rp-el { font: 650 1.0625rem/1.3 var(--font-sans); font-stretch: 104%; }
.rp-td--fd, .rp-td--rq, .rp-td--fx { display: grid; grid-template-columns: 108px minmax(0, 1fr); gap: 2px 10px; }
.rp-nb { white-space: nowrap; }
.rp-td--fd, .rp-td--rq { font: 400 var(--fs-mono)/1.5 var(--font-mono); font-variant-numeric: tabular-nums; }
.rp-td--fd :lang(zh-Hans), .rp-td--rq :lang(zh-Hans) { font-family: var(--font-sans); font-size: 13.5px; line-height: 1.65; }
.rp-td--fx { font-size: var(--fs-small); line-height: 1.5; }
.rp-td--fx :lang(zh-Hans) { line-height: 1.7; }
.rp-k { font: 600 var(--fs-micro)/1.6 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--fg-2); }
.rp-k :lang(zh-Hans) { letter-spacing: .02em; font-family: var(--font-sans); }
.rp-td--cb { display: flex; flex-wrap: wrap; gap: 6px; padding-top: 2px; }
@container (max-width: 380px) {
  .rp-td--fd, .rp-td--rq, .rp-td--fx { grid-template-columns: minmax(0, 1fr); }
  .rp-row { padding-left: 46px; }
}

/* Δ tag (B7.6): triangle in the status colour; fixed = highlighter fill and a check */
.rp-dt { position: relative; display: block; width: 40px; height: 22px; }
.rp-dt svg { position: absolute; inset: 0; width: 40px; height: 22px; overflow: visible; }
.rp-dt__t { fill: var(--paper); stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round; }
.rp-dt__c { display: none; fill: none; stroke: var(--fg); stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.rp-dt b { position: absolute; left: 1px; top: 7px; width: 23px; text-align: center; font: 600 11px/1 var(--font-mono); }
.rp-row.is-fixed .rp-dt__t { fill: var(--highlighter); }
.rp-row.is-fixed .rp-dt__c { display: inline; }

/* row states */
@media (hover: hover) { .rp-row:hover { background: color-mix(in srgb, var(--bg-2) 45%, transparent); } }
.rp-row[aria-current] { background: color-mix(in srgb, var(--bg-2) 72%, transparent); box-shadow: inset 3px 0 0 var(--fg); }
.rp-row:focus-visible { outline: 2px solid var(--focus); }
/* dismissed (demo): the text keeps full contrast; "Dismissed by you", a dashed rule down the left edge (ink on the
   current row) and a dashed Δ mark it, as the dashed cloud and Δ do on the plan */
.rp-row.is-dismissed::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: repeating-linear-gradient(var(--rp-dash, var(--fg-2)) 0 6px, transparent 6px 10px);
}
.rp-row.is-dismissed[aria-current] { box-shadow: none; --rp-dash: var(--fg); }
.rp-row.is-dismissed .rp-dt__t { stroke-dasharray: 3 2.4; }
.rp-dis { font: 600 var(--fs-micro)/1.25 var(--font-mono); letter-spacing: .04em; text-transform: uppercase; color: var(--fg-2); }
.rp-dis:lang(zh-Hans), .rp-dis :lang(zh-Hans) { letter-spacing: 0; }

/* row actions; the demo actions are dashed and sit beside the CAD note */
.rp-acts { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: var(--s-3); }
.rp-b {
  display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 5px 10px;
  border: var(--bw-hair) solid var(--fg); border-radius: var(--r-1); background: transparent; color: var(--fg);
  font: 600 13px/1.2 var(--font-sans); font-stretch: 104%; text-align: left;
  transition: background-color var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out);
}
.rp-b--show { background: var(--fg); color: var(--bg); }
.rp-b--demo { border-style: dashed; }
.rp-b[aria-pressed="true"] { border-style: solid; background: var(--hl); }
.rp-b[data-act="dismiss"][aria-pressed="true"] { background: var(--bg-2); }
.rp-bi { width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; }
.rp-chev { transition: transform var(--dur-3) var(--ease-out); }
.rp-b[aria-expanded="true"] .rp-chev { transform: rotate(180deg); }
@media (hover: hover) {
  .rp-b:not(.rp-b--show):not([aria-pressed="true"]):hover { background: color-mix(in srgb, var(--bg-2) 80%, transparent); }
  .rp-b--show:hover { background: color-mix(in srgb, var(--fg) 86%, var(--bg)); }
}
@media (pointer: coarse) { .rp-b { min-height: 44px; } }
.rp-cad { flex: 1 1 100%; margin: 2px 0 0; max-width: none; font: 400 var(--fs-micro)/1.5 var(--font-mono); color: var(--fg-2); }
.rp-cad:lang(zh-Hans), .rp-cad :lang(zh-Hans) { font-family: var(--font-sans); font-size: 13px; }

/* reasoning chain: the machine's trace, drawn as an OSNAP-marked leader in --ai */
.rp-chain { grid-column: 1 / -1; margin-top: var(--s-3); padding: var(--s-3) var(--s-3) var(--s-3) var(--s-4); border: var(--bw-hair) dashed var(--ai); background: color-mix(in srgb, var(--bg-2) 35%, transparent); }
.rp-steps { position: relative; display: grid; gap: var(--s-3); margin: 0; padding: 0; list-style: none; }
.rp-steps::before { content: ""; position: absolute; left: 4px; top: 8px; bottom: 8px; width: 1px; background: var(--ai); }
.rp-step { position: relative; display: grid; grid-template-columns: 8.4em minmax(0, 1fr); gap: 4px 10px; padding-left: 20px; }
.rp-step::before { content: ""; position: absolute; left: 0; top: 4px; width: 9px; height: 9px; border: 1.5px solid var(--ai); background: var(--paper); }
.rp-sk { font: 600 var(--fs-micro)/1.5 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--ai); }
.rp-sk :lang(zh-Hans) { letter-spacing: .02em; font-family: var(--font-sans); }
.rp-sv { display: flex; flex-wrap: wrap; gap: 6px; align-items: flex-start; font-size: var(--fs-small); line-height: 1.5; }
.rp-sv > span[lang] { display: inline; }
.rp-ev { display: block; width: 160px; height: 110px; border: var(--bw-hair) solid var(--rule); background: var(--paper); }
.rp-evl { flex: 1 1 100%; font: 500 var(--fs-micro)/1.4 var(--font-mono); color: var(--fg-2); }
.rp-para { display: block; flex: 1 1 100%; }
@container (max-width: 420px) { .rp-step { grid-template-columns: minmax(0, 1fr); } }

/* passing checks and also checked */
.rp-cks { margin-top: var(--s-6); }
.rp-ckh { margin: 0; padding-bottom: 6px; border-bottom: var(--bw-rule) solid var(--fg); font: 700 13px/1.3 var(--font-sans); font-stretch: 125%; letter-spacing: .06em; text-transform: uppercase; }
.rp-ckh:lang(zh-Hans) { font-stretch: 100%; letter-spacing: .02em; font-size: 15px; }
.rp-cl { display: grid; column-gap: var(--s-5); }
@container (min-width: 600px) { .rp-cks--also .rp-cl { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.rp-ck { display: grid; align-content: start; gap: 4px; padding: var(--s-3) 0; border-bottom: var(--bw-hair) solid var(--rule); }
.rp-ck > p { margin: 0; max-width: none; }
.rp-ck__top { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font: 500 var(--fs-micro)/1.3 var(--font-mono); color: var(--fg-2); }
.rp-ck__id { color: var(--fg); font-weight: 600; }
.rp-ck__el { font-weight: 650; font-stretch: 104%; }
.rp-ck__fr { display: grid; grid-template-columns: 108px minmax(0, 1fr); gap: 10px; font: 400 var(--fs-mono)/1.5 var(--font-mono); }
.rp-ck__fr :lang(zh-Hans) { font-family: var(--font-sans); }
.rp-ck__fr .rp-k { line-height: 1.5; }
.rp-ck__cb { display: flex; flex-wrap: wrap; gap: 6px; padding-top: 2px; }
.rp-ck__note { font-size: var(--fs-small); line-height: 1.5; color: var(--fg-2); }
@container (max-width: 380px) { .rp-ck__fr { grid-template-columns: minmax(0, 1fr); gap: 0; } }

.rp-foot { margin-top: var(--s-6); padding-top: var(--s-4); border-top: var(--bw-heavy) solid var(--fg); display: grid; gap: var(--s-3); }
.rp-decide { margin: 0; font-weight: 600; }
.rp-note { margin: 0; font: 400 var(--fs-micro)/1.55 var(--font-mono); color: var(--fg-2); }
.rp-note:lang(zh-Hans), .rp-note :lang(zh-Hans) { font-family: var(--font-sans); font-size: 13px; }

/* ---- no JS: static plans and the same report, side by side at lg -------------------------- */
.rp-ns { display: grid; gap: var(--s-7); }
@media (min-width: 1280px) { .rp-ns { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: var(--gutter); align-items: start; } }
.rp-nsfig { padding-top: 34px; display: grid; gap: var(--s-6); }
.rp-nsplan > .rp-plan { display: block; width: 100%; height: auto; aspect-ratio: 1204 / 960; border: var(--bw-hair) solid var(--rule); background: var(--paper); }
.rp-go { grid-column: 1 / -1; justify-self: start; margin-top: var(--s-2); font: 600 var(--fs-micro)/1.4 var(--font-mono); text-transform: uppercase; letter-spacing: .04em; }

/* ======================================================================== A4.0 building types */
.ty-body { row-gap: var(--s-6); }
.ty-hd { margin-bottom: 0; }
.ty-hd .sheet__h { max-width: 18ch; }
.ty-lead { margin: 0; }
.ty-sched { border: var(--bw-heavy) solid var(--fg); }
.ty-th { display: none; }
.ty-row { position: relative; }
.ty-row + .ty-row::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: var(--fg); opacity: .3; transform-origin: 0 50%;
}
.ty-sum { display: grid; gap: 6px var(--s-4); padding: var(--s-4); cursor: pointer; list-style: none; align-items: start; }
.ty-sum::-webkit-details-marker { display: none; }
.ty-sum::marker { content: ""; }
.ty-sum:focus-visible { outline: 2px solid var(--focus); outline-offset: -4px; }
.ty-c { display: block; min-width: 0; }
.ty-c--mk { grid-area: mk; }
.ty-c--iso { grid-area: iso; }
.ty-c--ty { grid-area: ty; }
.ty-c--oc { grid-area: oc; }
.ty-c--ex { grid-area: ex; }
.ty-c--cb { grid-area: cb; }
.ty-chev { grid-area: ch; justify-self: end; color: var(--fg-2); }
.ty-chev svg { display: block; width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; transition: transform var(--dur-4) var(--ease-out); }
.ty-row[open] .ty-chev svg { transform: rotate(180deg); }
html:not(.js) .ty-chev { visibility: hidden; }

/* labels: visible on cards and on an opened row; visually hidden in the schedule columns */
.ty-lbl { display: block; margin-bottom: 2px; font: 600 var(--fs-micro)/1.4 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--fg-2); }
.ty-lbl:lang(zh-Hans), .ty-lbl :lang(zh-Hans) { letter-spacing: .02em; font-family: var(--font-sans); }
.ty-c--mk .ty-lbl { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.ty-v { display: block; font-size: var(--fs-small); line-height: 1.5; font-stretch: 94%; }
.ty-v:lang(zh-Hans) { line-height: 1.7; font-stretch: 100%; }
.ty-name { font-size: 1.0625rem; font-weight: 700; font-stretch: 106%; line-height: 1.3; }
.ty-occ { font-weight: 600; }
.ty-cbc { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
.ty-cbk { font: 600 var(--fs-micro)/1 var(--font-mono); letter-spacing: .06em; margin-right: 2px; }
.ty-cbc .cite { min-height: 22px; padding: 1px 5px; font-size: var(--fs-micro); }

/* hexagon type mark (B7.8) */
.ty-hex { position: relative; display: grid; place-items: center; width: 44px; height: 38px; }
.ty-hex svg { position: absolute; inset: 0; width: 100%; height: 100%; fill: var(--paper); stroke: var(--fg); stroke-width: 1.5; stroke-linejoin: round; }
.ty-hex b { position: relative; font: 600 13px/1 var(--font-mono); }

/* isometrics: stroke-only line drawings; faces are filled with the paper so hidden lines drop out */
.ty-iso { display: block; width: 100%; height: auto; overflow: visible; color: var(--fg); transform-origin: 0 0; transition: transform var(--dur-4) var(--ease-out); }
.ty-ln path { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.ty-ln .ty-f { fill: var(--paper); }
.ty-ln .ty-d { stroke-width: .85; }
.ty-ln .ty-p { stroke: var(--ai); stroke-width: 1.1; stroke-dasharray: 3 2.5; }
.ty-ks { visibility: hidden; }
.ty-k circle { fill: var(--ai); }
.ty-k text { fill: var(--paper); font: 600 10px var(--font-mono); text-anchor: middle; }
.ty-k > * { transform-box: fill-box; transform-origin: center; }
:is(.ty-row[open], html:not(.js) .ty-row) .ty-ks { visibility: visible; }
.ty-row[open] .ty-k > * { animation: ty-pop 320ms var(--ease-snap) calc(200ms + var(--i, 0) * 70ms) both; }
@keyframes ty-pop { from { transform: scale(0); } }
/* the base motion guard shortens durations, not delays: markers and the 2× drawing are simply there */
html[data-motion="off"] .ty-row[open] :is(.ty-k > *, .ty-c--iso .ty-iso) { animation: none; }
@media (prefers-reduced-motion: reduce) { html .ty-row[open] :is(.ty-k > *, .ty-c--iso .ty-iso) { animation: none; } }
@media (hover: hover) and (pointer: fine) {
  .ty-row:not([open]) > .ty-sum:hover .ty-iso { transform: scale(1.05); }
  .ty-sum:hover .ty-name { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
}

/* plot-in, armed by types.js only when motion is on (no JS or reduced motion: drawn at once) */
@keyframes ty-draw { to { stroke-dashoffset: 0; } }
@keyframes ty-fade { from { opacity: 0; } }
@keyframes ty-rule { from { transform: scaleX(0); } }
.ty-armed .ty-row:not(.is-done) .ty-ln path:not(.ty-p) { stroke-dasharray: 1 1; stroke-dashoffset: 1; }
.ty-armed .ty-row.is-in:not(.is-done) .ty-ln path:not(.ty-p) { animation: ty-draw 1100ms var(--ease-out) var(--ty-d, 0ms) forwards; }
.ty-armed .ty-row.is-in:not(.is-done) .ty-ln .ty-d { animation-delay: calc(var(--ty-d, 0ms) + 380ms); }
.ty-armed .ty-row:not(.is-in) .ty-ln .ty-p { opacity: 0; }
.ty-armed .ty-row.is-in:not(.is-done) .ty-ln .ty-p { animation: ty-fade 400ms var(--ease-out) calc(var(--ty-d, 0ms) + 1000ms) both; }
.ty-armed .ty-row:not(.is-in)::before { transform: scaleX(0); }
.ty-armed .ty-row.is-in:not(.is-done)::before { animation: ty-rule 700ms var(--ease-out) var(--ty-d, 0ms) both; }

/* open panel: keys (CBC chips with their paraphrase; T1: elements + CRC only) */
.ty-panel { padding: 0 var(--s-4) var(--s-5); }
.ty-kl { display: flex; flex-wrap: wrap; gap: 10px 18px; margin: 0; padding: 0; list-style: none; }
.ty-ki { position: relative; display: inline-flex; align-items: center; gap: 7px; }
.ty-kn { display: inline-grid; place-items: center; flex: none; width: 20px; height: 20px; border-radius: 50%; background: var(--ai); color: var(--paper); font: 600 var(--fs-micro)/1 var(--font-mono); }
.ty-kt { font-size: var(--fs-small); font-weight: 600; }
.ty-cite:disabled { cursor: default; opacity: 1; }
.ty-pop { left: 27px; top: calc(100% + 6px); max-width: min(36ch, calc(100vw - 48px)); text-align: left; }   /* types.js keeps it on screen */
html.js .ty-pop:not(.is-open) { display: none; }
html:not(.js) .ty-kl { display: grid; gap: var(--s-3); }
html:not(.js) .ty-ki { display: grid; grid-template-columns: 20px auto; justify-items: start; }
html:not(.js) .ty-pop { position: static; grid-column: 2; width: auto; max-width: 60ch; padding: 0; border: 0; background: none; box-shadow: none; color: var(--fg-2); }
.ty-crcl { margin: 0 0 var(--s-3); }
.ty-crc { display: inline-block; padding: 2px 8px; border: var(--bw-hair) dashed var(--fg-2); border-radius: var(--r-1); font: 600 var(--fs-micro)/1.35 var(--font-mono); letter-spacing: .08em; color: var(--fg-2); }
.ty-more { margin: var(--s-3) 0 0; font-size: var(--fs-small); line-height: 1.55; color: var(--fg-2); }
html:not(.js) .ty-row::details-content { content-visibility: visible; display: block; }

/* xs: cards with the isometric on top */
.ty-sum { grid-template-columns: 44px minmax(0, 1fr) 20px; grid-template-areas: "iso iso iso" "mk ty ch" "oc oc oc" "ex ex ex" "cb cb cb"; }
.ty-c--iso { justify-self: center; width: 100%; max-width: 340px; margin-bottom: var(--s-2); }
.ty-c--mk { align-self: center; }
.ty-ln path { stroke-width: 1.25; }
.ty-ln .ty-d { stroke-width: .7; }

/* md: cards with the isometric at the left (xs and sm keep it on top) */
@media (min-width: 768px) {
  .ty-sum { grid-template-columns: 44px 210px minmax(0, 1fr) 20px; grid-template-areas: "mk iso ty ch" "mk iso oc ch" "mk iso ex ch" "mk iso cb ch"; grid-template-rows: auto auto auto 1fr; }
  .ty-c--iso { margin: 0; }
  .ty-c--mk { align-self: start; }
  .ty-panel { padding-left: calc(var(--s-4) + 44px + var(--s-4)); }
  .ty-ln path { stroke-width: 1.35; }
}
/* md, opened: the isometric doubles to span the text column, above the labeled lines */
@media (min-width: 768px) and (max-width: 1023.98px) {
  :is(.ty-row[open], html:not(.js) .ty-row) > .ty-sum {
    grid-template-columns: 44px minmax(0, 1fr) 20px; grid-template-areas: "mk iso ch" "mk ty ch" "mk oc ch" "mk ex ch" "mk cb ch"; grid-template-rows: auto;
  }
  :is(.ty-row[open], html:not(.js) .ty-row) .ty-c--iso { justify-self: start; max-width: 420px; margin-bottom: var(--s-2); }
  :is(.ty-row[open], html:not(.js) .ty-row) .ty-ln path { stroke-width: .95; }
  :is(.ty-row[open], html:not(.js) .ty-row) .ty-ln .ty-d { stroke-width: .5; }
  .ty-row[open] .ty-c--iso .ty-iso { animation: ty-grow var(--dur-5) var(--ease-out) both; }
}

/* lg: the schedule (2.5px outer rule, visual header, one row per type); an opened row expands to a detail card
   with the isometric at 2× */
@media (min-width: 1024px) {
  .ty-th, .ty-sum { grid-template-columns: 44px 168px minmax(0, 1fr) minmax(0, .72fr) minmax(0, 1.3fr) minmax(0, 1.45fr) 20px; column-gap: var(--s-4); }
  .ty-th {
    display: grid; padding: 10px var(--s-4); border-bottom: var(--bw-rule) solid var(--fg);
    font: 600 var(--fs-micro)/1.3 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--fg-2);
  }
  .ty-th :lang(zh-Hans) { letter-spacing: .02em; font-family: var(--font-sans); }
  html:not(.js) .ty-th { display: none; }
  .ty-th__mk { grid-column: 1 / span 2; }
  .ty-sum { grid-template-areas: "mk iso ty oc ex cb ch"; grid-template-rows: auto; padding: var(--s-4); }
  .ty-sum .ty-lbl { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .ty-ln path { stroke-width: 1.55; }
  .ty-ln .ty-d { stroke-width: .85; }
  :is(.ty-row[open], html:not(.js) .ty-row) > .ty-sum {
    grid-template-columns: 44px 336px minmax(0, 1fr) 20px; grid-template-areas: "mk iso ty ch" "mk iso oc ch" "mk iso ex ch" "mk iso cb ch";
    grid-template-rows: auto auto auto 1fr; row-gap: var(--s-3);
  }
  :is(.ty-row[open], html:not(.js) .ty-row) > .ty-sum .ty-c:not(.ty-c--mk) .ty-lbl { position: static; width: auto; height: auto; overflow: visible; clip-path: none; white-space: normal; }
  :is(.ty-row[open], html:not(.js) .ty-row) .ty-ln path { stroke-width: 1.05; }
  :is(.ty-row[open], html:not(.js) .ty-row) .ty-ln .ty-d { stroke-width: .6; }
  .ty-row[open] .ty-c--iso .ty-iso { animation: ty-grow var(--dur-5) var(--ease-out) both; }
  .ty-panel { padding: 0 var(--s-4) var(--s-5) calc(var(--s-4) * 3 + 44px + 336px); }
}
@keyframes ty-grow { from { transform: scale(.5); } }

.ty-cap { margin: calc(var(--s-3) - var(--s-6)) 0 0; max-width: none; font: 400 var(--fs-mono)/1.45 var(--font-mono); color: var(--fg-2); }
.ty-cap:lang(zh-Hans), .ty-cap :lang(zh-Hans) { font-family: var(--font-sans); font-size: var(--fs-small); }
.ty-notes { display: grid; gap: 6px; margin: 0; padding: var(--s-3) 0 0; list-style: none; border-top: var(--bw-hair) solid var(--rule); font-size: var(--fs-small); line-height: 1.55; max-width: 84ch; }
@media (min-width: 1024px) { .ty-cap, .ty-notes { padding-left: 0; } }

/* ==== build: css/sections/close.css ==== */
/* close.css: A5.0 Across the counter (ct-), A6.0 Responsibility (rs-), A7.0 Issue for pre-check (tx-).
   SPEC §D8-D10. Semantic tokens only; layouts: xs/sm single column, md 8 columns, lg 12 columns. */

:is(.ct, .rs, .tx) :is(p, li, figcaption) { text-wrap: pretty; }

/* =========================================================================================
   A5.0 Across the counter (ct-): model space; the queue model shows no numbers at all
   ========================================================================================= */
.ct-body { row-gap: var(--s-6); align-items: start; }
.ct-main { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: var(--s-6); align-items: start; }
.ct-head { margin-bottom: 0; }
.ct-h__s { display: inline-block; }
.ct-lead { margin: 0; font-size: var(--fs-body); }
.ct-fig { padding-top: 34px; }
.ct-tools { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-3); margin-bottom: var(--s-3); }
.ct-mode { display: inline-flex; flex-wrap: wrap; }
.ct-mode__o {
  display: inline-flex; align-items: center; gap: 8px; min-height: 36px; padding: 0 14px;
  border: 1px solid var(--fg); color: var(--fg); cursor: pointer; -webkit-tap-highlight-color: transparent;
  font: 600 var(--fs-micro)/1.1 var(--font-mono); letter-spacing: .05em; text-transform: uppercase; white-space: nowrap;
}
.ct-mode__o :lang(zh-Hans) { font-family: var(--font-sans); letter-spacing: .02em; }
.ct-mode__o + .ct-mode__o { border-left-width: 0; }
.ct-mode__o:first-child { border-radius: var(--r-1) 0 0 var(--r-1); }
.ct-mode__o:last-child { border-radius: 0 var(--r-1) var(--r-1) 0; }
.ct-mode__o input { appearance: none; -webkit-appearance: none; flex: none; width: 10px; height: 10px; margin: 0; border: 1.5px solid currentColor; border-radius: 50%; }
.ct-mode__o input:checked { background: currentColor; }
.ct-mode__o:has(:checked) { background: var(--fg); color: var(--bg); }
@media (hover: hover) { .ct-mode__o:not(:has(:checked)):hover { background: var(--hl); } }
@supports selector(:has(*)) {
  .ct-mode__o input:focus-visible { outline: none; }
  .ct-mode__o:has(:focus-visible) { position: relative; z-index: 1; outline: 2px solid var(--focus); outline-offset: 2px; }
}
.ct-play > button { display: inline-flex; align-items: center; gap: 6px; }
.ct-play svg { width: 10px; height: 10px; fill: currentColor; }
.ct-play :lang(zh-Hans) { font-family: var(--font-sans); }
@media (pointer: coarse) { .ct-mode__o { min-height: 44px; } }
/* the tools hold their row from the first paint, so the sheet keeps its height when the module boots (a sheet-index
   jump lands on target): shown once the module is ready, out again if it fails. Reduced motion: nothing to pause. */
.ct:not([data-module-state="ready"]) .ct-tools { visibility: hidden; }
.ct[data-module-state="error"] .ct-tools, html[data-motion="off"] .ct-play { display: none; }

/* stage: the stills (h 16:9 from md and on landscape phones, v 3:4 on portrait phones and in the no-JS pair). Live,
   the canvas sits between a still's fixed linework (z 0) and its labels (z 2), and the still's sample sets (.ct-dyn)
   step aside. counter.js picks its layout with the same media query as the switch below. */
.ct-fig > .illus__tag { pointer-events: auto; }
.ct-stage { position: relative; isolation: isolate; border: 1px solid var(--rule); background: var(--bg); }
.ct-canvas { position: absolute; inset: 0; z-index: 1; display: block; width: 100%; height: 100%; }
.ct-stage.is-live .ct-dyn { display: none; }
.ct-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.ct-still { position: relative; }
.ct-still__box { position: relative; aspect-ratio: 16 / 9; }
.ct-still--v .ct-still__box { aspect-ratio: 3 / 4; }
.ct-still__svg { position: absolute; inset: 0; z-index: 0; display: block; width: 100%; height: 100%; overflow: hidden; }
.ct-still__h { margin: 0; padding: var(--s-3) var(--s-3) 0; font: 600 var(--fs-micro)/1.3 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--fg); }
.ct-still__h :lang(zh-Hans) { font-family: var(--font-sans); letter-spacing: .02em; }
html.js .ct-still__h { display: none; }
.ct-still--v { display: none; }
@media (max-width: 767.98px) and (orientation: portrait) { .ct-still--h { display: none; } .ct-still--v { display: block; } }
html:not(.js) .ct-still--h { display: none; }
html:not(.js) .ct-still--v { display: block; }
html.js .ct-stage[data-mode="without"] .ct-still[data-mode="with"],
html.js .ct-stage[data-mode="with"] .ct-still[data-mode="without"] { display: none; }
@media (min-width: 768px), (orientation: landscape) { html:not(.js) .ct-stage { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--rule); } html:not(.js) .ct-still { background: var(--bg); } }
/* a phone turned sideways: the 16:9 stage fits the screen above the bottom bar (with html's 16px scroll-padding-top),
   so the applicant side, the counter, the queue and the desk show at once */
@media (max-width: 767.98px) and (orientation: landscape) {
  html.js .ct-fig { width: min(100%, calc((100svh - var(--bbar-h) - env(safe-area-inset-bottom) - var(--s-5)) * 16 / 9)); justify-self: center; }
}
/* the same for wider landscape phones (md layout): below the title chip, md's scroll-padding-top */
@media (min-width: 768px) and (max-width: 1279.98px) and (orientation: landscape) and (max-height: 500px) {
  html.js .ct-fig { width: min(100%, calc((100svh - var(--chip-h) - 28px - var(--s-5)) * 16 / 9)); justify-self: center; }
}

.ct-labs { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.ct-lab {
  position: absolute; white-space: nowrap;
  font: 600 var(--fs-micro)/1.2 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--fg-2);
}
.ct-lab :lang(zh-Hans) { font-family: var(--font-sans); letter-spacing: .02em; }
.ct-lab--applicant, .ct-lab--plancheck { color: var(--fg); }
.ct-lab--corr { color: var(--conflict); }
.ct-lab--done::before {
  content: ""; display: inline-block; width: 4px; height: 8px; margin: 0 7px 2px 2px;
  border: solid currentColor; border-width: 0 1.5px 1.5px 0; transform: rotate(45deg);
}

/* still linework (static; strokes in screen px) */
.ct-still__svg > g > :is(path, rect) { vector-effect: non-scaling-stroke; }
.ct-counter { fill: none; stroke: var(--fg); stroke-width: 2.5; }
.ct-win { fill: none; stroke: var(--fg); stroke-width: 1.25; }
.ct-rope { fill: none; stroke: var(--lyr-dims); stroke-width: 1; stroke-dasharray: 2 3; }
.ct-desk { fill: none; stroke: var(--lyr-fixt); stroke-width: 1.25; stroke-linejoin: round; }
.ct-barf { fill: none; stroke: var(--fg-2); stroke-width: 1; }
.ct-barv { fill: var(--fg-2); stroke: none; }
.ct-arc { fill: none; stroke: var(--conflict); stroke-width: 1.25; stroke-dasharray: 4 3; }
/* symbol strokes are in layout units (about 4 css px each at 1440), so the canvas sprites match */
.ct-s-top { fill: var(--bg-2); stroke: var(--fg); stroke-width: .26; stroke-linejoin: round; }
.ct-s-edge { fill: none; stroke: var(--fg-2); stroke-width: .24; stroke-linejoin: round; }
.ct-s-txt { fill: none; stroke: var(--fg-2); stroke-width: .22; stroke-linecap: round; }
.ct-s-delta { fill: var(--ai); stroke: none; }
.ct-s-stamp { fill: var(--bg); stroke: var(--conflict); stroke-width: .26; stroke-linejoin: round; }
.ct-s-stampt { fill: none; stroke: var(--conflict); stroke-width: .42; stroke-linecap: round; }
.ct-s-check { fill: none; stroke: var(--fg-2); stroke-width: .36; stroke-linecap: round; stroke-linejoin: round; }
.ct.is-paused .cmdline__caret { animation: none; }

/* general notes, the plan-checker callout, independence line, command line */
.ct-aside { display: grid; gap: var(--s-4); align-items: start; }
.ct-pts { counter-reset: ctn; display: grid; gap: var(--s-3); align-content: start; padding-top: var(--s-4); border-top: var(--bw-rule) solid var(--fg); }
.ct-pts > li { counter-increment: ctn; display: grid; grid-template-columns: 2.25em minmax(0, 1fr); font-size: 15px; line-height: 1.5; }
.ct-pts > li::before { content: counter(ctn) "."; font: 600 var(--fs-mono)/1.75 var(--font-mono); color: var(--fg-2); }
.ct-pts :lang(zh-Hans) { line-height: 1.75; }
.ct-pc { display: grid; gap: var(--s-3); justify-items: start; padding: var(--s-4); background: var(--bg-2); border: 1px solid var(--rule); border-radius: var(--r-1); }
.ct-pc__t { margin: 0; font-size: 15px; line-height: 1.45; }
.ct-ind { margin: 0; font: 400 var(--fs-micro)/1.5 var(--font-mono); color: var(--fg-2); }
.ct-ind :lang(zh-Hans) { font-family: var(--font-sans); line-height: 1.7; }
.ct-cmd { margin-top: var(--s-2); }
.ct-cmd > span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* lg (D8): body, general notes, plan-checker callout and independence line in cols 1-4; the model alone in
   cols 5-12. The headline keeps the full width: squeezed into 4 columns it breaks as "back- / and-forth".
   The notes column runs taller than a 16:9 figure below about 1900px, so the figure rides along (sticky,
   bounded by .ct-main so it stops above the command line); a taller figure grows the last row, not the gaps. */
@media (min-width: 1280px) {
  .ct-main { grid-template-columns: repeat(12, minmax(0, 1fr)); grid-template-rows: auto auto 1fr; column-gap: var(--gutter); }
  .ct-lead, .ct-pts, .ct-aside { grid-column: 1 / span 4; }
  .ct-fig { grid-column: 5 / -1; grid-row: 1 / -1; }
}
@media (min-width: 1280px) and (min-height: 700px) { .ct-fig { position: sticky; top: var(--s-6); } }
@media (min-width: 768px) and (max-width: 1279.98px) {
  .ct-pts { grid-template-columns: 1fr 1fr; column-gap: var(--s-6); }
  .ct-aside { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--gutter); }
}
@media (max-width: 599.98px) {
  .ct-mode { display: grid; grid-template-columns: 1fr 1fr; width: 100%; }
  .ct-mode__o { position: relative; justify-content: center; padding: 0 6px; }
  .ct-mode__o input { position: absolute; opacity: 0; width: 1px; height: 1px; }
  .ct-play { margin-left: auto; }
}

/* =========================================================================================
   A6.0 Responsibility (rs-)
   ========================================================================================= */
.rs-body { row-gap: var(--s-7); align-items: start; }
.rs-copy { display: grid; gap: var(--s-5); align-content: start; }
.rs-head { margin-bottom: var(--s-2); }
.rs-h__s { display: inline-block; }
.rs-lead { margin: 0; }
.rs-notes { counter-reset: rsn; display: grid; gap: var(--s-4); margin-top: var(--s-2); padding-top: var(--s-5); border-top: var(--bw-rule) solid var(--fg); }
.rs-notes > li { counter-increment: rsn; display: grid; grid-template-columns: 2.25em minmax(0, 1fr); }
.rs-notes > li::before { content: counter(rsn) "."; font: 600 var(--fs-mono)/1.75 var(--font-mono); color: var(--fg-2); }
.rs-notes p { margin: 0; font-size: 15px; line-height: 1.55; }
.rs-notes p:lang(zh-Hans), .rs-notes p :lang(zh-Hans) { line-height: 1.75; }

/* the title block, blown up to full size: a ruled strip, with the seal the AI never touches at its foot */
.rs-side { display: grid; gap: var(--s-3); align-content: start; min-width: 0; width: 100%; max-width: 27rem; }
@media (max-width: 767.98px) { .rs-side { max-width: none; } }   /* xs/sm: the panel runs full width */
.rs-tb {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr);
  border: var(--bw-heavy) solid var(--fg); background: var(--bg); box-shadow: 6px 6px 0 var(--rule);
}
.rs-cells { display: grid; min-width: 0; }
.rs-cell { min-width: 0; padding: 14px var(--s-5) 15px; border-top: 1px solid var(--fg); }
.rs-cell:first-child { border-top: 0; }
.rs-cell p { margin: 0; max-width: none; }
.rs-firm { padding-block: var(--s-5) 18px; }
.rs-mark { font: 800 clamp(1.625rem, 1.2rem + 1vw, 2.375rem)/1 var(--font-sans); font-stretch: 112%; letter-spacing: -.015em; }
.rs-sub { margin-top: 6px !important; font: 500 var(--fs-mono)/1.3 var(--font-mono); letter-spacing: .04em; color: var(--fg-2); }
.rs-sub:lang(zh-Hans), .rs-sub :lang(zh-Hans) { font-family: var(--font-sans); }
.rs-k { margin-bottom: 3px !important; font: 600 var(--fs-micro)/1.3 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--fg-2); }
.rs-v { font: 600 clamp(1.0625rem, 0.95rem + 0.4vw, 1.375rem)/1.2 var(--font-sans); font-stretch: 104%; }
.rs-row { display: grid; grid-template-columns: minmax(8em, 40%) minmax(0, 1fr); align-items: baseline; column-gap: var(--s-3); }
.rs-row .rs-k { margin: 0 !important; }
.rs-row > .rs-v { justify-self: start; }
.rs-row--ai .rs-v { color: var(--ai); font-family: var(--font-mono); font-weight: 600; letter-spacing: .02em; }

.rs-sealcell {
  position: relative; display: grid; justify-items: center; align-content: center; gap: var(--s-3);
  padding: var(--s-6) var(--s-5); border-top: var(--bw-rule) solid var(--fg);
}
html.js[data-motion="on"] .rs-sealcell { padding-bottom: 92px; }
.rs-seal { position: relative; width: 1.75in; height: 1.75in; border-radius: 50%; touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.rs-seal__svg { display: block; width: 100%; height: 100%; overflow: visible; }
/* r = 84 in a 168 box: the ring's centreline is 1.75in across; pathLength 528 = 48 even dash periods */
.rs-seal__ring { fill: none; stroke: var(--fg); stroke-width: 1.5; stroke-dasharray: 6 5; }
.rs-seal__t { fill: var(--fg-2); font: 600 var(--fs-micro) var(--font-mono); letter-spacing: .05em; }
.rs-seal__t--zh { font: 600 12px var(--font-sans); letter-spacing: .32em; }
.rs-seal:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; }
.rs-tip { margin: 0; max-width: 15rem; font-size: var(--fs-small); line-height: 1.45; text-align: center; color: var(--fg-2); }
.rs-tip:lang(zh-Hans), .rs-tip :lang(zh-Hans) { line-height: 1.65; }
/* with JS and motion on, the caption becomes a tooltip on hover, focus or tap */
html.js[data-motion="on"] .rs-tip {
  position: absolute; left: 50%; top: calc(50% + 0.875in + 6px); z-index: var(--z-popover);
  width: max-content; max-width: min(15rem, 76vw); padding: 8px 12px;
  background: var(--fg); color: var(--bg); border-radius: var(--r-1); box-shadow: var(--sh-pop);
  translate: -50% 0; transform: translate3d(0, 4px, 0); opacity: 0; pointer-events: none;
  transition: opacity var(--dur-3) var(--ease-out), transform var(--dur-3) var(--ease-out);
}
html.js[data-motion="on"] .rs-tip::before {
  content: ""; position: absolute; left: 50%; top: -5px; width: 10px; height: 10px; margin-left: -5px;
  background: inherit; transform: rotate(45deg);
}
html.js[data-motion="on"] :is(.rs-seal:focus-visible + .rs-tip, .rs-tip.is-on) { opacity: 1; transform: none; pointer-events: auto; }
@media (hover: hover) {
  html.js[data-motion="on"] .rs-sealcell:hover .rs-tip { opacity: 1; transform: none; pointer-events: auto; }
}
html.js[data-motion="on"] .rs-seal.is-quiet + .rs-tip:not(.is-on) { opacity: 0; pointer-events: none; }

/* the AI's loupe rim (decorative, fine pointers only): lime lives on a dark bezel, never on paper */
.rs-loupe {
  /* origin at the panel's border-box corner, the frame trust.js measures in */
  position: absolute; left: calc(var(--bw-heavy) * -1); top: calc(var(--bw-heavy) * -1); z-index: 3;
  width: 144px; height: 144px; border-radius: 50%;
  pointer-events: none; will-change: transform; transform: translate3d(-200px, 0, 0);
  background: radial-gradient(circle closest-side, color-mix(in srgb, var(--vision-ink) 7%, transparent) 0 82%, transparent 83%);
  box-shadow: 0 16px 30px -14px rgba(0,0,0,.5);
}
.rs-loupe__rim { display: block; width: 100%; height: 100%; overflow: visible; }
.rs-loupe__bezel { fill: none; stroke: var(--model); stroke-width: 12; }
.rs-loupe__tk { fill: none; stroke: var(--vision); stroke-width: 4; stroke-dasharray: .8 4.2; stroke-dashoffset: .4; }
.rs-loupe__tk--l { stroke-width: 8; stroke-dasharray: .9 29.1; stroke-dashoffset: .45; }
.rs-loupe__edge { fill: none; stroke: var(--vision); stroke-width: 1.5; }
.rs-loupe__edge--in { stroke-width: 1; opacity: .75; }
.rs-loupe__x { fill: none; stroke: var(--vision-ink); stroke-width: 1; }
.rs-loupe__tab {
  position: absolute; left: 50%; top: calc(100% - 20px); translate: -50% 0;
  padding: 2px 7px; border-radius: var(--r-1); white-space: nowrap;
  font: 600 11px/1.35 var(--font-mono); letter-spacing: .05em; color: var(--vision); background: var(--model-2);
  box-shadow: 0 0 0 1px var(--model);
}

.rs-dtitle { margin-top: var(--s-3); }
.rs-site { margin: 0; font-size: var(--fs-micro); color: var(--fg-2); }
.rs-site:lang(zh-Hans), .rs-site :lang(zh-Hans) { font-family: var(--font-sans); line-height: 1.7; }

/* md and lg: the copy beside the full-size title block (stacked under the copy, the 27rem panel left half the sheet
   blank at md); 8em keys keep the rows whole in the 313px panel at 768 */
@media (min-width: 768px) {
  .rs-copy { grid-column: 1 / span 4; grid-row: 1; }
  .rs-side { grid-column: 5 / -1; grid-row: 1; justify-self: end; }
}
@media (min-width: 1280px) {
  .rs-copy { grid-column: 1 / span 5; }
  .rs-side { grid-column: 6 / -1; }
  .rs-h { font-size: clamp(2.25rem, -0.625rem + 3.75vw, 4rem); }
}
@media (max-width: 599.98px) {
  .rs-tb { box-shadow: 4px 4px 0 var(--rule); }
  .rs-cell { padding-inline: var(--s-4); }
  .rs-row { grid-template-columns: minmax(0, 1fr); row-gap: 2px; }
}

/* =========================================================================================
   A7.0 Issue for pre-check (tx-)
   ========================================================================================= */
.tx { overflow-x: clip; }   /* the stamp lands from 1.9x: it may overhang the form, never the sheet or the page */
.tx-body { row-gap: var(--s-7); align-items: start; }
.tx-copy { display: grid; gap: var(--s-5); align-content: start; }
.tx-head { margin-bottom: var(--s-2); }
.tx-h__s { display: inline-block; }
.tx-lead { margin: 0; }

/* the always-visible address: the conversion path when a mail client does nothing */
.tx-direct { display: grid; gap: var(--s-2); padding: var(--s-4) 0 var(--s-4); border-top: var(--bw-rule) solid var(--fg); border-bottom: 1px solid var(--fg); }
.tx-direct__k { margin: 0; font-size: var(--fs-small); color: var(--fg-2); }
.tx-direct__row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-4); }
.tx-direct__addr { margin: 0; min-width: 0; }
.tx-addr {
  font: 500 clamp(1rem, 0.86rem + 0.5vw, 1.3125rem)/1.3 var(--font-mono); letter-spacing: -.01em;
  color: var(--fg); overflow-wrap: anywhere; user-select: all; -webkit-user-select: all;
}
.tx-copybtn__i { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linejoin: round; }
/* xs/sm and touch: 44px targets (D10) for the small buttons too */
@media (max-width: 767.98px), (pointer: coarse) { .tx-copybtn, .ct-pc .btn { min-height: 44px; } }
.tx-privacy { margin: 0; padding-left: var(--s-3); border-left: var(--bw-heavy) solid var(--fg); font-size: var(--fs-small); line-height: 1.5; }
.tx-privacy:lang(zh-Hans) { line-height: 1.75; }
.tx-disc { margin: 0; font-size: var(--fs-micro); color: var(--fg-2); max-width: 52ch; }
.tx-disc:lang(zh-Hans) { font-family: var(--font-sans); line-height: 1.7; }

/* ---- the transmittal: a printed form with ruled rows ---------------------------------- */
.tx-side { min-width: 0; }
/* the form and Copy address hold their place from the moment core starts (html.frames; A7.0 keeps its height through
   boot) and show once the module is ready; without JS the noscript mailto links stand in, if core or the module
   fails the address */
html:not(.frames) :is(.tx-form, .tx-copybtn), #issue[data-module-state="error"] :is(.tx-form, .tx-copybtn) { display: none; }
html.frames #issue:not([data-module-state="ready"]) :is(.tx-form, .tx-copybtn) { visibility: hidden; }
.tx-form {
  position: relative; max-width: 44rem;
  border: var(--bw-heavy) solid var(--fg); background: var(--bg);
  box-shadow: 6px 6px 0 var(--rule);
}
.tx-form__top {
  position: relative; display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--s-2) var(--s-5);
  padding: var(--s-5) var(--s-5) var(--s-3); border-bottom: var(--bw-heavy) solid var(--fg);
}
.tx-form__top::after { content: ""; position: absolute; left: 0; right: 0; bottom: -6.5px; height: 1px; background: var(--fg); }
.tx-form__h {
  margin: 0; font: 700 clamp(1.375rem, 1.1rem + 0.8vw, 1.875rem)/1 var(--font-sans); font-stretch: 125%;
  letter-spacing: .1em; text-transform: uppercase;
}
.tx-form__h:lang(zh-Hans) { font-stretch: 100%; letter-spacing: .08em; }
.tx-form__date { margin: 0; display: grid; justify-items: end; gap: 2px; }
.tx-form__k { font: 600 var(--fs-micro)/1.2 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--fg-2); }
/* written at boot: until then it keeps one line's height and the 10-character width (both formats), and a baseline
   (the row aligns on baselines below 600px) */
.tx-form__d { min-height: 1.2em; min-width: 10ch; font: 500 var(--fs-mono)/1.2 var(--font-mono); font-variant-numeric: tabular-nums; }
.tx-form__d:empty::before { content: "\a0"; }
.tx-form__to { margin: 7px 0 0; padding: var(--s-3) var(--s-5); max-width: none; border-bottom: 1px solid var(--fg); font: 500 var(--fs-mono)/1.45 var(--font-mono); }
.tx-form__to :lang(zh-Hans) { font-family: var(--font-sans); font-size: var(--fs-small); }
.tx-nw { white-space: nowrap; }

.tx-fs { padding: var(--s-4) var(--s-5) var(--s-4); border-bottom: 1px solid var(--rule); }
.tx-fs__k {
  float: left; width: 100%; padding: 0; margin: 0 0 var(--s-2);
  font: 600 var(--fs-micro)/1.3 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--fg-2);
}
.tx-fs__k:lang(zh-Hans) { letter-spacing: .04em; }
.tx-opts { clear: both; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 10.5rem), 1fr)); gap: 4px var(--s-3); }
.tx-opts--2 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr)); }
.tx-opt {
  display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 6px 10px 6px 8px;
  border: 1px solid transparent; border-radius: var(--r-1); cursor: pointer;
  font-size: 15px; line-height: 1.25; -webkit-tap-highlight-color: transparent;
}
.tx-opt:has(:checked) { border-color: var(--fg); }
@media (hover: hover) { .tx-opt:hover { background: var(--bg-2); } }
.tx-opt input {
  appearance: none; -webkit-appearance: none; flex: none; display: grid; place-content: center;
  width: 18px; height: 18px; margin: 0; border: var(--bw-rule) solid var(--fg); border-radius: 1px; background: var(--bg); cursor: pointer;
}
.tx-opt input[type="radio"] { border-radius: 50%; }
.tx-opt input::before { content: ""; width: 8px; height: 8px; background: var(--fg); transform: scale(0); transition: transform var(--dur-2) var(--ease-snap); }
.tx-opt input[type="radio"]::before { border-radius: 50%; }
.tx-opt input[type="checkbox"]::before {
  width: 12px; height: 12px;
  clip-path: polygon(16% 0, 50% 34%, 84% 0, 100% 16%, 66% 50%, 100% 84%, 84% 100%, 50% 66%, 16% 100%, 0 84%, 34% 50%, 0 16%);
}
.tx-opt input:checked::before { transform: scale(1); }
@supports selector(:has(*)) {
  .tx-opt input:focus-visible { outline: none; }
  .tx-opt:has(:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
}

/* signature line: the pen signs on issue, then the stamp lands */
.tx-foot { display: grid; gap: var(--s-4); padding: var(--s-5); }
.tx-sign { position: relative; display: flex; align-items: flex-end; gap: var(--s-2); height: 46px; }
.tx-sign__x { font: 500 20px/1 var(--font-mono); padding-bottom: 4px; }
.tx-sign__line { flex: 1 1 auto; height: 1px; margin-bottom: 6px; background: var(--fg); }
.tx-sign__ink { position: absolute; left: 28px; bottom: 3px; width: min(62%, 240px); height: 44px; overflow: visible; }
.tx-sign__ink path {
  fill: none; stroke: var(--fg); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 300ms var(--ease-in-out);
}
.tx.is-signed .tx-sign__ink path { stroke-dashoffset: 0; }
.tx-submit { width: 100%; }
.tx-submit__p { display: inline-block; }
.tx-after { margin: 0; padding-left: var(--s-3); border-left: var(--bw-heavy) solid var(--fg); font-size: var(--fs-small); line-height: 1.5; }
.tx-after:lang(zh-Hans), .tx-after :lang(zh-Hans) { line-height: 1.75; }
.tx-after:empty { padding: 0; border: 0; }

/* ISSUED FOR PRE-CHECK (B7.10): ink filter, -6 degrees, slams on after a submit */
.tx-stamp {
  position: absolute; left: 50%; top: 44%; z-index: 2; width: min(84%, 400px);
  translate: -50% -50%; transform: rotate(-6deg);
  color: var(--conflict); mix-blend-mode: multiply; pointer-events: none;
}
.tx-stamp__svg { display: block; width: 100%; height: auto; overflow: visible; }
.tx-stamp__t { font: 800 30px/1 var(--font-sans); font-stretch: 125%; stroke: currentColor; stroke-width: .9px; paint-order: stroke; }
.tx.is-issued .tx-stamp { animation: tx-slam 320ms var(--ease-stamp) both; }
.tx.is-issued .tx-form { animation: tx-thud 240ms var(--ease-out) 170ms both; }
@keyframes tx-slam {
  0% { opacity: 0; transform: rotate(-6deg) scale(1.9); }
  55% { opacity: 1; }
  100% { opacity: 1; transform: rotate(-6deg) scale(1); }
}
@keyframes tx-thud { 0%, 100% { transform: none; } 35% { transform: translate3d(0, 2px, 0); } }
html[data-motion="off"] .tx.is-issued :is(.tx-stamp, .tx-form) { animation: none; }

/* no JS: two plain mailto links (the address above stays visible) */
.tx-nojs { display: flex; flex-wrap: wrap; gap: var(--s-3); padding: var(--s-5); border: 1px dashed var(--fg-2); }

@media (min-width: 768px) {
  .tx-copy { grid-column: 1 / span 6; }
  .tx-side { grid-column: 1 / -1; }
}
@media (min-width: 1280px) {
  .tx-copy { grid-column: 1 / span 5; grid-row: 1; }
  .tx-side { grid-column: 6 / -1; grid-row: 1; padding-top: var(--s-2); }
  .tx-form { margin-left: auto; }
  .tx-h { font-size: clamp(2.25rem, -0.625rem + 3.75vw, 4rem); }
}
@media (max-width: 599.98px) {
  .tx-form__top, .tx-form__to, .tx-fs { padding-inline: var(--s-4); }
  .tx-form__date { display: flex; align-items: baseline; gap: var(--s-2); }
  .tx-foot { padding: var(--s-4); }
  .tx-opts { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px var(--s-2); }
  .tx-opts--2 { grid-template-columns: minmax(0, 1fr); }
  .tx-opt { font-size: 14px; padding-inline: 6px; gap: 8px; }
  .tx-form { box-shadow: 4px 4px 0 var(--rule); }
  .tx-stamp { width: 92%; }
}
