/* Cutaway — styles.
 * The page frame: white page (cool charcoal at night), Archivo throughout, one steel link colour, hairlines.
 * The inside (body.ex-world: book pages and concept lessons) keeps the Exhibit Label structure (2026-10-11): every
 * card is a hands-on exhibit with its label docked beside it (see "the exhibit and its label" below). Since 2026-10-12
 * it wears the system map's glass, so the front and the inside read as one site: the exhibit is a rounded glass stage
 * on the map's mesh, the label and every overlay frosted panels, the controls the map's pills and switch; request
 * blue is the one action colour, teal is fixed, red only a fault. Outside the card the same glass answers "where am I":
 * the rail, the you-are-here bar, the contents, cheat sheets and quizzes ("the inside's pages" below).
 * The landing's live card keeps the older sandbox frame.
 * Brand tokens (--cut, --steel, --case-*) also draw the mark and the isometric front.
 */

/* Archivo, self-hosted (SIL OFL, fonts/OFL.txt): one variable family, width 62–125%, weight 100–900. */
@font-face {
  font-family: 'Archivo'; font-style: normal; font-weight: 100 900; font-stretch: 62% 125%; font-display: swap;
  src: url('../fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Archivo'; font-style: normal; font-weight: 100 900; font-stretch: 62% 125%; font-display: swap;
  src: url('../fonts/archivo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --font-system: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-body: 'Archivo', var(--font-system);
  --font-display: var(--font-body);
  /* text inside live diagrams: Archivo too (the 2026-10-10 sweep of every card at desktop and phone width was clean) */
  --font-diagram: var(--font-body);
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

  /* type roles */
  --fs-micro: 12px;   /* counts, meta */
  --fs-small: 13px;   /* hints, secondary UI */
  --fs-ui: 14px;      /* controls, dense lists */
  --fs-body-s: 15px;  /* list titles, options */
  --fs-body: 16px;    /* reading text */
  --fs-lead: 18px;    /* ledes */

  --ease-out: cubic-bezier(.22, 1, .36, 1);

  --bg: #ffffff;
  --wash: #f6f7f9;
  --surface: #ffffff;
  --surface-2: #f2f4f7;
  --surface-3: #e5e8ee;
  --text: #16181d;
  --text-2: #444b57;
  --text-3: #5d6574;
  --border: #e4e7ec;
  --border-strong: #cdd2da;
  --link: #3d6e9e;
  --link-hover: #2e5579;
  --accent: var(--link);
  --accent-ink: var(--link);
  --accent-bg: #eaf0f6;
  --on-accent: #ffffff;
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, .06);
  --shadow: 0 1px 2px rgba(16, 24, 40, .05), 0 10px 28px -12px rgba(16, 24, 40, .16);
  --shadow-pop: 0 2px 6px rgba(16, 24, 40, .06), 0 18px 40px -12px rgba(16, 24, 40, .24);
  --focus-ring: 2px solid var(--link);
  --mark: rgba(255, 200, 40, .38);
  --scrim: rgba(16, 24, 40, .38);
  --selection: rgba(61, 110, 158, .18);
  /* legacy names still read by the viz kit and the search: all resolve to the one link blue */
  --lab: var(--link);
  --lab-bg: var(--accent-bg);

  /* brand: cut red only ever marks a cut face or a fault; steel draws links and callouts;
     casings are three greys (top light, left mid, right dark) plus two for the inside of a cut */
  --cut: #d7322a;
  --steel: var(--link);
  --paper: var(--bg);
  --ink: var(--text);
  --case-1: #ffffff; --case-2: #c9ced6; --case-3: #8a929e;
  --case-in-1: #eef0f3; --case-in-2: #c9ced6;

  /* diagram kinds: fill / stroke / ink */
  --k-neutral-f: #f3f4f6; --k-neutral-s: #6b7280; --k-neutral-i: #1f2937;
  --k-primary-f: #eef0ff; --k-primary-s: #5b5ff0; --k-primary-i: #2e2a86;
  --k-good-f: #e8f8f0;    --k-good-s: #0f9f6e;    --k-good-i: #065f46;
  --k-bad-f: #fdeeee;     --k-bad-s: #e5484d;     --k-bad-i: #97191d;
  --k-warn-f: #fff6e0;    --k-warn-s: #d99a06;    --k-warn-i: #7a4a02;
  --k-info-f: #eaf3ff;    --k-info-s: #2f80ed;    --k-info-i: #123f85;
  --k-data-f: #fff1e6;    --k-data-s: #ef7a2a;    --k-data-i: #8a3a0b;
  --k-ghost-f: transparent; --k-ghost-s: #a0a7b3; --k-ghost-i: #5d6574;

  /* the inside's world (body.ex-world): the system map's glass brought inside (2026-10-12). Request blue is the one
     action colour (the lit step's ring and glow, the filled primary pill, seen marks), teal means fixed or good, red only
     a fault. Text tokens keep 4.5:1 on the page, the panels and the stage's mesh; white on the filled pill is 4.7:1. */
  --ex-ink: var(--gl-ink); --ex-ink-2: var(--gl-ink-2); --ex-ink-3: #56617f;
  --ex-stage-ink-3: #4d5873;   /* quiet text inside a drawing, over the mesh's brightest blob (5:1) */
  --ex-stage-fixed: #08694f; --ex-stage-fault: #b8241d;   /* teal and red words on the stage's mesh (5:1 or better) */
  --ex-req: var(--gl-req); --ex-req-ink: #1858c4; --ex-glow: var(--gl-req-glow);
  --ex-btn: #1f6fe8; --ex-btn-hover: #1a5fd0; --ex-on-btn: #ffffff;
  --ex-wash: rgba(31, 111, 232, .09);
  --ex-fixed: #0a7d65; --ex-on-fixed: #ffffff;   /* teal text 5.1:1; white on the teal chip 5.1:1 */
  --ex-fault: #d7322a; --ex-fault-fill: #d7322a; --ex-on-fault: #ffffff;
  --ex-panel: #f5f8fd; --ex-panel-edge: var(--gl-tip-edge);
  --ex-panel-shadow: 0 12px 32px -16px rgba(20, 40, 100, .34), 0 1px 3px rgba(20, 40, 100, .07), inset 0 1px 0 rgba(255, 255, 255, .8);
  --ex-chip: #ffffff;
  --ex-chip-shadow: 0 4px 14px -6px rgba(20, 40, 100, .28), 0 1px 2px rgba(20, 40, 100, .07), inset 0 1px 0 rgba(255, 255, 255, .8);
  --ex-tile: var(--gl-tag-bg); --ex-tile-edge: var(--gl-tag-edge);
  --ex-hair: rgba(14, 22, 48, .09); --ex-hover: rgba(14, 22, 48, .045);
  --ex-line: #c9d1e0; --ex-line-hover: #8d98b2; --ex-track: #d9e0ec; --ex-dot: #8a94ab;
  --ex-stage-edge: rgba(40, 70, 140, .10);
  /* the stage: the map's mesh, its blobs softer and pushed to the corners, since the drawing sits straight on it */
  --ex-mesh:
    radial-gradient(55% 60% at 10% 14%, color-mix(in srgb, var(--gl-blob1) 55%, transparent), transparent 72%),
    radial-gradient(50% 55% at 94% 90%, color-mix(in srgb, var(--gl-blob2) 55%, transparent), transparent 72%),
    radial-gradient(40% 42% at 72% 0%, color-mix(in srgb, var(--gl-blob3) 60%, transparent), transparent 72%),
    var(--gl-bg);
  --ex-label-w: 340px;
  --ex-page-w: 1280px;   /* one module width for every page inside (rail pages and pages without one) */

  --radius: 10px;
  --radius-lg: 16px;
  --sidebar-w: 272px;
  --topbar-h: 56px;
  --page-w: 900px;
  --tap: 36px;
  color-scheme: light;
}

/* Night reading: cool charcoal, same blue brightened for contrast. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #16181d; --wash: #1b1e24; --surface: #16181d; --surface-2: #20242c; --surface-3: #2b303a;
    --text: #eceff4; --text-2: #b6bdc9; --text-3: #939cab;
    --border: #272c35; --border-strong: #3a414d;
    --link: #8db6e0; --link-hover: #b3cfeb; --accent-bg: rgba(141, 182, 224, .14); --on-accent: #0b1422;
    --cut: #e5483e;
    --case-1: #2c3139; --case-2: #1c1f24; --case-3: #15181c; --case-in-1: #3a404a; --case-in-2: #2c3139;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow: 0 1px 2px rgba(0, 0, 0, .35), 0 12px 32px -12px rgba(0, 0, 0, .7);
    --shadow-pop: 0 2px 6px rgba(0, 0, 0, .4), 0 20px 44px -12px rgba(0, 0, 0, .8);
    --mark: rgba(255, 196, 0, .28); --scrim: rgba(0, 0, 0, .55); --selection: rgba(141, 182, 224, .3);
    --k-neutral-f: #1f232b; --k-neutral-s: #8b95a5; --k-neutral-i: #eceff4;
    --k-primary-f: #211f45; --k-primary-s: #8b8ff8; --k-primary-i: #dcdcff;
    --k-good-f: #0b2a1f;    --k-good-s: #35c68f;    --k-good-i: #a8f0d0;
    --k-bad-f: #3a1618;     --k-bad-s: #f2696d;     --k-bad-i: #ffc9ca;
    --k-warn-f: #33260a;    --k-warn-s: #e8b23a;    --k-warn-i: #f8dea0;
    --k-info-f: #0f2440;    --k-info-s: #5aa7ff;    --k-info-i: #c7e0ff;
    --k-data-f: #36200f;    --k-data-s: #f4924d;    --k-data-i: #fdd3b6;
    --k-ghost-s: #555e6c; --k-ghost-i: #939cab;
    --ex-ink-3: #8f9bbd; --ex-stage-ink-3: #a3acc0; --ex-stage-fixed: #55e3c0; --ex-stage-fault: #ff6b61; --ex-req-ink: #8cc0ff; --ex-btn: #2563d9; --ex-btn-hover: #2f6fe6;
    --ex-wash: rgba(121, 182, 255, .14); --ex-fixed: #55e3c0; --ex-on-fixed: #04261d; --ex-fault: #ff6b61; --ex-fault-fill: #c8352c;
    --ex-panel: #1b2132; --ex-panel-shadow: 0 12px 32px -16px rgba(0, 0, 0, .7), inset 0 1px 0 rgba(255, 255, 255, .06);
    --ex-chip: #232a3e; --ex-chip-shadow: 0 4px 14px -6px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .07);
    --ex-hair: rgba(255, 255, 255, .09); --ex-hover: rgba(255, 255, 255, .06);
    --ex-line: #3a4460; --ex-line-hover: #6c7a9c; --ex-track: #343d55; --ex-dot: #6a7592; --ex-stage-edge: rgba(255, 255, 255, .07);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #16181d; --wash: #1b1e24; --surface: #16181d; --surface-2: #20242c; --surface-3: #2b303a;
  --text: #eceff4; --text-2: #b6bdc9; --text-3: #939cab;
  --border: #272c35; --border-strong: #3a414d;
  --link: #8db6e0; --link-hover: #b3cfeb; --accent-bg: rgba(141, 182, 224, .14); --on-accent: #0b1422;
  --cut: #e5483e;
  --case-1: #2c3139; --case-2: #1c1f24; --case-3: #15181c; --case-in-1: #3a404a; --case-in-2: #2c3139;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow: 0 1px 2px rgba(0, 0, 0, .35), 0 12px 32px -12px rgba(0, 0, 0, .7);
  --shadow-pop: 0 2px 6px rgba(0, 0, 0, .4), 0 20px 44px -12px rgba(0, 0, 0, .8);
  --mark: rgba(255, 196, 0, .28); --scrim: rgba(0, 0, 0, .55); --selection: rgba(141, 182, 224, .3);
  --k-neutral-f: #1f232b; --k-neutral-s: #8b95a5; --k-neutral-i: #eceff4;
  --k-primary-f: #211f45; --k-primary-s: #8b8ff8; --k-primary-i: #dcdcff;
  --k-good-f: #0b2a1f;    --k-good-s: #35c68f;    --k-good-i: #a8f0d0;
  --k-bad-f: #3a1618;     --k-bad-s: #f2696d;     --k-bad-i: #ffc9ca;
  --k-warn-f: #33260a;    --k-warn-s: #e8b23a;    --k-warn-i: #f8dea0;
  --k-info-f: #0f2440;    --k-info-s: #5aa7ff;    --k-info-i: #c7e0ff;
  --k-data-f: #36200f;    --k-data-s: #f4924d;    --k-data-i: #fdd3b6;
  --k-ghost-s: #555e6c; --k-ghost-i: #939cab;
  --ex-ink-3: #8f9bbd; --ex-stage-ink-3: #a3acc0; --ex-stage-fixed: #55e3c0; --ex-stage-fault: #ff6b61; --ex-req-ink: #8cc0ff; --ex-btn: #2563d9; --ex-btn-hover: #2f6fe6;
  --ex-wash: rgba(121, 182, 255, .14); --ex-fixed: #55e3c0; --ex-on-fixed: #04261d; --ex-fault: #ff6b61; --ex-fault-fill: #c8352c;
  --ex-panel: #1b2132; --ex-panel-shadow: 0 12px 32px -16px rgba(0, 0, 0, .7), inset 0 1px 0 rgba(255, 255, 255, .06);
  --ex-chip: #232a3e; --ex-chip-shadow: 0 4px 14px -6px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .07);
  --ex-hair: rgba(255, 255, 255, .09); --ex-hover: rgba(255, 255, 255, .06);
  --ex-line: #3a4460; --ex-line-hover: #6c7a9c; --ex-track: #343d55; --ex-dot: #6a7592; --ex-stage-edge: rgba(255, 255, 255, .07);
  color-scheme: dark;
}
@media (pointer: coarse) {
  :root { --tap: 44px; }
}
/* phones: what is focused or jumped to stops above the dock and the pager that ride the bottom edge */
@media (max-width: 640px) {
  html:has(body.ex-world) { scroll-padding-bottom: 200px; }
}

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scrollbar-color: var(--border-strong) var(--bg); scroll-padding-top: calc(var(--topbar-h) + 16px); }
body {
  margin: 0; min-height: 100vh;
  font-family: var(--font-body); font-size: var(--fs-body); line-height: 1.6;
  color: var(--text); background: var(--bg);
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
}
::selection { background: var(--selection); color: inherit; }
button, input, select { font: inherit; color: inherit; }
a { color: var(--link); text-decoration: none; }
a:hover { color: var(--link-hover); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
:focus-visible { outline: var(--focus-ring); outline-offset: 2px; }
.search-input:focus-visible { outline: none; }
input, textarea { caret-color: var(--link); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip-link {
  position: fixed; left: 12px; top: 10px; z-index: 100;
  padding: 10px 16px; border-radius: 999px; background: var(--link); color: var(--on-accent);
  font-weight: 600; font-size: var(--fs-ui);
  transform: translateY(-160%); transition: transform .2s var(--ease-out);
}
.skip-link:focus { transform: none; color: var(--on-accent); text-decoration: none; }
h1, h2, h3 { font-family: var(--font-display); font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; margin: 0; text-wrap: balance; color: var(--text); }
p { text-wrap: pretty; }
kbd {
  font-family: var(--font-mono); font-size: 0.8em; padding: 1px 6px; border-radius: 6px;
  border: 1px solid var(--border-strong); background: var(--surface); color: var(--text-2);
}
.theme-switching *, .theme-switching *::before, .theme-switching *::after { transition: none !important; }

/* buttons: pills; the filled one is the view's single primary action */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 40px; padding: 0 18px; border-radius: 999px;
  border: 1px solid var(--border-strong); background: var(--surface); color: var(--text);
  font-size: var(--fs-body-s); font-weight: 600; cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background .15s, border-color .15s, color .15s, transform .08s;
}
.btn:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.btn:active { transform: scale(.98); }
.btn svg { width: 16px; height: 16px; flex: none; }
.btn.primary { background: var(--link); border-color: var(--link); color: var(--on-accent); }
.btn.primary:hover { background: var(--link-hover); border-color: var(--link-hover); color: var(--on-accent); }
.btn[disabled] { opacity: .45; cursor: default; }
.icon-btn {
  display: inline-grid; place-items: center; flex: none;
  width: max(36px, var(--tap)); height: max(36px, var(--tap));
  border-radius: 999px; border: 0; background: transparent; cursor: pointer; color: var(--text-2);
  transition: background .15s, color .15s;
}
.icon-btn:hover { background: var(--surface-2); color: var(--text); }
.icon-btn svg { width: 19px; height: 19px; }

/* ---------- top bar ---------- */
.topbar {
  position: sticky; top: 0; z-index: 30;
  height: var(--topbar-h);
  display: flex; align-items: center; gap: 14px;
  padding: 0 20px;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  -webkit-backdrop-filter: saturate(1.6) blur(10px); backdrop-filter: saturate(1.6) blur(10px);
  border-bottom: 1px solid var(--border);
}
.menu-btn { display: none; }
.brand { display: flex; align-items: center; gap: 10px; color: var(--text); border-radius: 8px; flex: none; }
.brand:hover { color: var(--text); text-decoration: none; }
.site-mark { width: 26px; height: 28px; flex: none; }
.brand-name { font-weight: 800; font-size: 18px; letter-spacing: -0.025em; white-space: nowrap; }
.crumb-sep { color: var(--border-strong); font-size: 20px; font-weight: 300; line-height: 1; flex: none; }
.topbar .spacer { flex: 1; }
.book-chip {
  display: inline-flex; align-items: center; min-height: 30px; padding: 0 12px; flex: none;
  border: 1px solid var(--border-strong); border-radius: 999px;
  font-size: var(--fs-ui); font-weight: 600; color: var(--text-2); white-space: nowrap;
}
.book-chip:hover { color: var(--link); border-color: var(--link); text-decoration: none; }
.top-nav { display: flex; align-items: center; gap: 2px; }
.top-link {
  display: inline-flex; align-items: center; min-height: 36px; padding: 0 12px; border-radius: 999px;
  font-size: var(--fs-ui); font-weight: 600; color: var(--text-2); white-space: nowrap;
}
.top-link:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.top-link.active { color: var(--link); background: var(--accent-bg); }
.overall { font-size: var(--fs-small); color: var(--text-3); white-space: nowrap; font-variant-numeric: tabular-nums; padding: 0 4px; }
.search-toggle { display: none; }
/* the section links of pages with no sidebar: in the header above 640px, behind a Menu button below it */
.site-links { display: flex; align-items: center; gap: 2px; }
.site-menu-btn {
  display: none; align-items: center; gap: 6px; min-height: 36px; padding: 0 10px 0 14px; border-radius: 999px;
  border: 1px solid var(--border-strong); background: transparent; color: var(--text-2);
  font: inherit; font-size: var(--fs-ui); font-weight: 600; cursor: pointer;
}
.site-menu-btn:hover { background: var(--surface-2); color: var(--text); }
.site-menu-btn svg { width: 16px; height: 16px; transition: transform .2s var(--ease-out); }
.site-nav.is-open .site-menu-btn { color: var(--link); border-color: var(--link); }
.site-nav.is-open .site-menu-btn svg { transform: rotate(180deg); }

/* ---------- search ---------- */
.search { position: relative; flex: 0 1 380px; min-width: 0; margin-left: 12px; }
.search-ic { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--text-3); display: grid; pointer-events: none; }
.search-ic svg { width: 16px; height: 16px; }
.search-input {
  width: 100%; height: 38px; padding: 0 40px 0 38px; border-radius: 999px;
  border: 1px solid transparent; background: var(--surface-2); color: var(--text);
  font-size: var(--fs-ui); outline: none; -webkit-appearance: none; appearance: none;
  transition: border-color .15s, background .15s, box-shadow .15s;
}
.search-input::-webkit-search-cancel-button { -webkit-appearance: none; }
.search-input::placeholder { color: var(--text-3); }
.search-input:hover { border-color: var(--border-strong); }
.search-input:focus { background: var(--surface); border-color: var(--link); box-shadow: 0 0 0 3px var(--accent-bg); }
.search-kbd { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); font-size: 11px; pointer-events: none; }
.search.open .search-kbd { display: none; }
.search-close { display: none; }
.search-pop {
  display: none; position: absolute; top: calc(100% + 8px); left: 0; z-index: 60;
  width: min(560px, calc(100vw - 32px)); max-height: min(70vh, 560px); overflow-y: auto; overscroll-behavior: contain;
  padding: 6px; border-radius: 14px; background: var(--surface); border: 1px solid var(--border);
  box-shadow: var(--shadow-pop);
}
.search.open .search-pop { display: block; }
.search-head {
  display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; justify-content: space-between;
  padding: 6px 10px; font-size: var(--fs-micro); font-weight: 600; color: var(--text-3);
}
.search-keys { font-weight: 500; }
.search-keys kbd { font-size: 10.5px; padding: 0 5px; margin: 0 1px; }
.search-empty { padding: 10px; color: var(--text-2); font-size: var(--fs-ui); }
.search-empty .search-head { padding: 0 0 8px; }
.search-none { margin: 0 0 12px; line-height: 1.5; }
.search-none b { color: var(--text); }
.search-tips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip.tag {
  display: inline-flex; align-items: center; min-height: 30px; padding: 0 12px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface); font-size: var(--fs-small); color: var(--text-2); cursor: pointer;
}
.chip.tag:hover { border-color: var(--link); color: var(--link); }
.search-map { display: inline-flex; align-items: center; gap: 8px; margin-top: 14px; min-height: var(--tap); font-weight: 600; font-size: var(--fs-ui); }
.search-map svg { width: 16px; height: 16px; }
.search-item { display: flex; gap: 12px; align-items: flex-start; padding: 9px 10px; border-radius: 10px; color: var(--text); }
.search-item:hover { color: var(--text); text-decoration: none; }
.search-item.sel { background: var(--accent-bg); }
.search-badge {
  flex: none; width: 28px; height: 28px; border-radius: 8px; display: grid; place-items: center; margin-top: 1px;
  background: var(--surface-2); color: var(--text-2); font-weight: 700; font-size: var(--fs-small); font-variant-numeric: tabular-nums;
}
.search-item.sel .search-badge { background: var(--surface); color: var(--link); }
.search-badge.term { background: transparent; border: 1px dashed var(--border-strong); }
.search-badge.lab svg { width: 16px; height: 16px; }
.search-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.search-title { font-weight: 600; font-size: var(--fs-body-s); line-height: 1.35; }
.search-meta { font-size: var(--fs-micro); color: var(--text-3); }
.search-snip { font-size: var(--fs-small); color: var(--text-2); line-height: 1.45; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.search-item mark { background: var(--mark); color: inherit; border-radius: 3px; padding: 0 1px; }
.search-group { padding: 10px 10px 4px; font-size: var(--fs-micro); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--text-3); }
.search-badge.concept { background: var(--accent-bg); color: var(--link); }
.search-badge.concept svg { width: 16px; height: 16px; }
.search-badge.system { background: var(--accent-bg); color: var(--link); }
.search-badge.system svg { width: 16px; height: 16px; }

/* ---------- concepts ---------- */
.page.concepts, .page.concept { max-width: 1000px; }
.concept-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 10px; }
.concept-row { display: grid; gap: 2px; height: 100%; padding: 14px 16px; border: 1px solid var(--border); border-radius: var(--radius); color: var(--text); background: var(--surface); }
.concept-row:hover { border-color: var(--link); text-decoration: none; color: var(--text); }
.concept-name { font-weight: 700; font-size: var(--fs-body); letter-spacing: -0.01em; }
.concept-line { font-size: var(--fs-small); color: var(--text-2); line-height: 1.45; }
.concept-books { font-size: var(--fs-micro); color: var(--text-3); font-weight: 600; margin-top: 4px; }
.concept-title { font-size: clamp(34px, 4.6vw, 46px); font-weight: 800; letter-spacing: -0.03em; margin-top: 4px; }
.concept-appears { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 14px; font-size: var(--fs-small); color: var(--text-3); }
.concept-appears .lbl { font-weight: 600; }
.concept-cards { margin-top: 40px; }
.concept-card + .concept-card { margin-top: 64px; padding-top: 40px; border-top: 1px solid var(--border); }
.concept-card .card-title { font-size: 26px; }
@media (max-width: 640px) {
  /* a concept lesson: the block before each card's stage stays short */
  .concept-title { font-size: 32px; }
  .concept-appears { margin-top: 10px; }
  .concept-cards { margin-top: 24px; }
  .concept-card + .concept-card { margin-top: 40px; padding-top: 28px; }
  .ex-world .concept-card .card-title { font-size: 22px; }
  .concept-card .cc-meta { margin-top: 6px; }
}
.concept-chips { display: flex; flex-wrap: wrap; gap: 6px; }

/* ---------- layout ---------- */
.layout { display: grid; grid-template-columns: var(--sidebar-w) minmax(0, 1fr); min-height: calc(100vh - var(--topbar-h)); }
.sidebar {
  position: sticky; top: var(--topbar-h); align-self: start;
  height: calc(100vh - var(--topbar-h));
  overflow-y: auto; overscroll-behavior: contain;
  padding: 20px 14px 40px;
  border-right: 1px solid var(--border);
  scrollbar-width: thin;
}

.main { min-width: 0; padding: 40px 48px 96px; overflow-x: clip; }
.main:focus-visible { outline: none; }
.scrim { display: none; }
.page { max-width: var(--page-w); margin: 0 auto; animation: page-in .28s var(--ease-out); }
@keyframes page-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ---------- shared docs pieces ---------- */
/* 56ch of the system face is about 70 characters a line */
.lede { margin: 14px 0 0; font-size: var(--fs-lead); line-height: 1.6; color: var(--text-2); max-width: 56ch; }
.page-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-top: 10px; font-size: var(--fs-small); color: var(--text-3); }
.page-meta a { color: var(--text-2); font-weight: 500; }
.page-meta a:hover { color: var(--link); }
.page-meta .sep { color: var(--border-strong); }
.callout {
  display: flex; gap: 14px; align-items: flex-start; margin-top: 24px; padding: 16px 20px;
  border-radius: var(--radius-lg); background: var(--wash); color: var(--text-2); font-size: var(--fs-body-s); line-height: 1.55;
}
.callout > svg { flex: none; width: 20px; height: 20px; margin-top: 2px; color: var(--text-3); }
.callout b { color: var(--text); }
.callout.note { background: var(--accent-bg); }
.callout.note > svg { color: var(--link); }

/* ---------- home ---------- */
.hero { padding: 12px 0 8px; }
.hero h1 { font-size: clamp(38px, 5vw, 52px); font-weight: 800; letter-spacing: -0.035em; line-height: 1.05; }
.hero .lede { font-size: 20px; max-width: 54ch; }
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; margin-top: 28px; }
.hero-actions .btn { min-height: 44px; padding: 0 22px; font-size: var(--fs-body); }
.hero-alt { font-size: var(--fs-body-s); font-weight: 600; }
.hero-resume { display: block; margin-top: 16px; font-size: var(--fs-ui); color: var(--text-3); line-height: 1.45; }
.hero-resume b { color: var(--text-2); font-weight: 600; }
.legend { display: flex; flex-wrap: wrap; gap: 10px 22px; margin-top: 8px; }
/* "Reading the drawings": a quiet key under the hero, set between hairlines rather than in a tip box */
.legend-key { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 22px; margin-top: 32px; padding: 14px 0; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.legend-key .legend { margin-top: 0; }
.legend-t { font-size: var(--fs-small); font-weight: 600; color: var(--text-3); }
.legend-pill { display: inline-flex; align-items: center; gap: 8px; font-size: var(--fs-ui); color: var(--text-2); }
.legend-pill svg { width: 24px; height: 24px; flex: none; }
.legend-pill b { color: var(--text); font-weight: 600; }
.home-sec { margin-top: 56px; }
.home-sec > h2 { font-size: 26px; letter-spacing: -0.025em; }
.home-sec > .lede { margin-top: 6px; font-size: var(--fs-body); }
.contents-part { margin-top: 26px; }
.contents-part-t { font-size: var(--fs-ui); font-weight: 600; color: var(--text-3); letter-spacing: 0; padding-bottom: 8px; border-bottom: 1px solid var(--border); }

/* the chapter as a strip of stops under a card's meta line: where you are, what you've opened, jump anywhere */
.card-strip { display: flex; flex-wrap: wrap; align-items: center; margin: 10px 0 0 -6px; }
.cs-stop { display: inline-grid; place-items: center; width: 20px; height: 28px; border-radius: 6px; }
.cs-stop i { display: block; width: 8px; height: 8px; border-radius: 50%; background: var(--border-strong); transition: background-color .15s; }
.cs-stop.end i { border-radius: 2px; }
.cs-stop.seen i { background: color-mix(in srgb, var(--link) 50%, var(--border-strong)); }
.cs-stop.now { width: 30px; }
.cs-stop.now i { width: 20px; border-radius: 4px; background: var(--link); }
.cs-stop:hover i { background: var(--text-3); }
.cs-stop.now:hover i { background: var(--link-hover); }
/* one filled blue per demo: when the demo has its own primary action, the stepper's Next steps back */
.vz:has(.vz-controls .vz-btn.primary) .vz-stepper .vz-btn.primary { background: var(--surface); border-color: var(--border-strong); color: var(--text); }
.vz:has(.vz-controls .vz-btn.primary) .vz-stepper .vz-btn.primary:hover { background: var(--surface-2); border-color: var(--border-strong); }
.lab-rows { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: 16px; margin-top: 20px; }

/* ---------- shelf (the root page: one row per book) ---------- */
.shelf-main { padding: 48px 48px 96px; }
.page.shelf { max-width: 1000px; }

/* Continue: the one card the reader stopped on, across every book */
.shelf-resume-slot:empty { display: none; }
.shelf-resume {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 16px;
  margin-top: 28px; padding: 14px 14px 14px 16px; border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface); color: var(--text); transition: border-color .15s;
}
.shelf-resume:hover { text-decoration: none; color: var(--text); border-color: var(--border-strong); }
.shelf-resume .book-mark svg { width: 40px; height: 40px; }
.sr-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sr-title { font-size: var(--fs-body); color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sr-title b { color: var(--text); font-weight: 650; }
.sr-where { font-size: var(--fs-small); color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* the books: rows on hairlines, not a grid of tiles */
.shelf-list { list-style: none; margin: 14px 0 0; padding: 0; border-top: 1px solid var(--border); }
.shelf-list > li { border-bottom: 1px solid var(--border); }
.book-row {
  display: grid; grid-template-columns: 52px minmax(0, 1fr) auto; gap: 4px 22px; align-items: start;
  margin: 0 -16px; padding: 26px 16px; border-radius: var(--radius-lg); color: var(--text); transition: background-color .15s;
}
.book-row:hover { background: var(--wash); color: var(--text); text-decoration: none; }
.book-row:hover .book-title, .book-row:hover .book-go { color: var(--link); }
.book-mark svg { width: 52px; height: 52px; display: block; }
.book-main { display: flex; flex-direction: column; min-width: 0; }
.book-title-line { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 12px; }
.book-title { margin: 0; font-size: 21px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.25; transition: color .15s; }
.book-flag { font-size: var(--fs-micro); font-weight: 600; color: var(--k-warn-i); background: var(--k-warn-f); padding: 3px 10px; border-radius: 999px; white-space: nowrap; }
.book-facts { margin-top: 3px; font-size: var(--fs-small); color: var(--text-3); font-variant-numeric: tabular-nums; }
.book-blurb { margin: 10px 0 0; max-width: 62ch; font-size: var(--fs-body-s); line-height: 1.55; color: var(--text-2); }
/* one tick per chapter, parts set apart; each fills as the chapter is read */
.book-strip { display: flex; flex-wrap: wrap; gap: 6px 10px; margin-top: 16px; }
.bs-part { display: flex; gap: 3px; }
.bs-tick {
  width: 14px; height: 9px; border-radius: 2px;
  background: linear-gradient(to right, var(--link) calc(var(--p, 0) * 100%), var(--border-strong) 0);
}
.book-row:hover .bs-tick { background: linear-gradient(to right, var(--link) calc(var(--p, 0) * 100%), var(--text-3) 0); }
.book-side { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; padding-top: 2px; white-space: nowrap; }
.book-state { font-size: var(--fs-small); color: var(--text-3); font-variant-numeric: tabular-nums; }
.book-state.done { color: var(--k-good-i); font-weight: 600; }
.book-go { display: inline-flex; align-items: center; gap: 2px; font-size: var(--fs-ui); font-weight: 600; color: var(--text-2); transition: color .15s; }
.book-go svg { width: 16px; height: 16px; }

.site-foot { margin-top: 64px; padding-top: 20px; border-top: 1px solid var(--border); font-size: var(--fs-small); color: var(--text-3); max-width: 76ch; }
.site-foot p { margin: 0 0 8px; }
.site-foot-brand { display: flex; align-items: center; gap: 8px; color: var(--text); font-weight: 800; letter-spacing: -0.02em; }
.site-foot-brand .site-mark { width: 18px; height: 20px; }

/* ---------- card page ---------- */
.card-title { font-size: clamp(30px, 3.6vw, 40px); font-weight: 800; letter-spacing: -0.03em; line-height: 1.12; }
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
.chip {
  display: inline-flex; align-items: center; gap: 8px; min-height: 30px; padding: 3px 12px;
  border-radius: 999px; font-size: var(--fs-small); line-height: 1.35; border: 1px solid transparent;
}
.chip .lbl { font-weight: 700; }
.chip.problem { background: var(--k-bad-f); color: var(--k-bad-i); border-color: color-mix(in srgb, var(--k-bad-s) 22%, transparent); }
.chip.fix { background: var(--k-good-f); color: var(--k-good-i); border-color: color-mix(in srgb, var(--k-good-s) 22%, transparent); }
.chip svg { width: 14px; height: 14px; flex: none; }

/* the sandbox: the live diagram's frame, like an inline code example */
.sandbox { margin-top: 26px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); box-shadow: var(--shadow); overflow: hidden; }
.sandbox-bar {
  display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 8px 0 16px;
  background: var(--wash); border-bottom: 1px solid var(--border); font-size: var(--fs-small); color: var(--text-3);
}
.sandbox-bar .live { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; color: var(--text-2); }
.sandbox-bar .live i { width: 7px; height: 7px; border-radius: 50%; background: var(--k-good-s); transition: background .2s; }
.sandbox-bar .live.idle { color: var(--text-3); }
.sandbox-bar .live.idle i { background: var(--border-strong); }
.sandbox-bar .grow { flex: 1; }
.sandbox-bar .frame-btn { display: inline-flex; align-items: center; gap: 6px; min-height: 30px; padding: 0 10px; border: 0; border-radius: 999px; background: transparent; color: var(--text-2); font-size: var(--fs-small); font-weight: 600; cursor: pointer; }
.sandbox-bar .frame-btn:hover { background: var(--surface-3); color: var(--text); }
.sandbox-bar .frame-btn svg { width: 14px; height: 14px; }
.turn-hint { display: none; margin: 0; padding: 10px 16px; font-size: var(--fs-small); color: var(--text-2); background: var(--accent-bg); border-bottom: 1px solid var(--border); }

/* expanded: the frame takes the whole screen; turned sideways, a phone roughly doubles the text */
body.frame-open { overflow: hidden; }
/* doubled class: beats the phone rules that pull the frame edge to edge with negative margins */
.sandbox.expanded.expanded {
  position: fixed; inset: 0; z-index: 90; margin: 0; border: 0; border-radius: 0; box-shadow: none;
  display: flex; flex-direction: column; overflow: auto; overscroll-behavior: contain;
  animation: frame-in .22s var(--ease-out);
}
@keyframes frame-in { from { opacity: 0; transform: scale(.985); } to { opacity: 1; transform: none; } }
.sandbox.expanded .sandbox-bar { position: sticky; top: 0; z-index: 2; padding-top: env(safe-area-inset-top); padding-left: max(16px, env(safe-area-inset-left)); padding-right: max(8px, env(safe-area-inset-right)); }
.sandbox.expanded .stage { flex: 1 0 auto; display: flex; flex-direction: column; justify-content: center; width: 100%; max-width: 1240px; margin: 0 auto; padding: 24px max(20px, env(safe-area-inset-right)) 28px max(20px, env(safe-area-inset-left)); }
.sandbox.expanded .vz-svg { max-width: 100%; }
@media (orientation: portrait) and (max-width: 640px) {
  .sandbox.expanded .turn-hint { display: block; }
}
.stage { padding: 26px 26px 22px; }

.card-foot { display: flex; flex-wrap: wrap; gap: 12px 24px; align-items: center; margin-top: 18px; }
.card-wild { margin: 0; font-size: var(--fs-ui); color: var(--text-3); }
.card-wild .lbl { font-weight: 600; color: var(--text-2); }
.lab-link {
  display: inline-flex; align-items: center; gap: 8px; min-height: var(--tap);
  font-size: var(--fs-ui); font-weight: 600;
}
.lab-link svg { width: 16px; height: 16px; flex: none; }
.lab-link span { color: var(--text-2); font-weight: 500; }
.lab-link span b { color: var(--link); font-weight: 600; }
.lab-link:hover span b { text-decoration: underline; text-underline-offset: 3px; }
.lab-link:hover { text-decoration: none; }

.pager { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 48px; }
.pager-link {
  display: flex; flex-direction: column; gap: 2px; padding: 14px 18px; min-height: 72px; justify-content: center;
  border: 1px solid var(--border); border-radius: var(--radius-lg); color: var(--text); background: var(--surface);
  transition: border-color .15s, box-shadow .15s; cursor: pointer; font: inherit; text-align: left;
}
.pager-link:hover { border-color: var(--link); box-shadow: var(--shadow-sm); text-decoration: none; color: var(--text); }
.pager-link small { font-size: var(--fs-small); color: var(--text-3); display: inline-flex; align-items: center; gap: 4px; }
.pager-link small svg { width: 14px; height: 14px; }
.pager-link b { font-weight: 600; font-size: var(--fs-body); color: var(--link); line-height: 1.35; }
.pager-link.next { text-align: right; align-items: flex-end; grid-column: 2; }
.pager-link.back { grid-column: 1; }
.pager-link[disabled] { visibility: hidden; }
.pager-link .short { display: none; }
.pager-count { grid-column: 1 / -1; display: flex; justify-content: center; align-items: center; gap: 10px; font-size: var(--fs-small); color: var(--text-3); font-variant-numeric: tabular-nums; }
.pager-count kbd { font-size: 11px; }
/* the keys under the pager, legible chips (a wide screen with a pointer that hovers only) */
@media (hover: hover) and (min-width: 641px) { .ex-world .pager-count kbd { display: inline-grid; } }
.ex-world .pager-count kbd { place-items: center; min-width: 26px; height: 24px; padding: 0 7px; border-radius: 8px; border-color: var(--ex-line); background: var(--ex-chip); color: var(--ex-ink-2); font-family: var(--font-body); font-size: 13px; font-weight: 700; }
.demo-error { padding: 16px 18px; border-radius: var(--radius); background: var(--k-bad-f); color: var(--k-bad-i); font-size: var(--fs-ui); line-height: 1.5; }
.demo-error details { margin-top: 8px; }
.demo-error code { font-family: var(--font-mono); font-size: var(--fs-micro); word-break: break-word; }

/* ---------- the exhibit and its label (body.ex-world, js/card.js) ---------- */
/* The inside wears the system map's glass (2026-10-12): the exhibit is a rounded glass stage on the map's mesh, the label
   a frosted panel beside it with sentence-case heads, and every control is one of the map's (36px pills, the break switch,
   thin sliders, frosted buttons). Request blue is the one action colour; teal is fixed; red only a fault. Focus is the
   map's ring: 2px request blue. */
.ex-world { --focus-ring: 2px solid var(--gl-req); }
/* the kit's kinds, inside: the drawings' palette moved into the map's family (blue, teal and violet for primary, info and data;
   green for good; a warm hue only for warn, red only for bad), so a drawing sits on the glass stage like a part on the map.
   Every ink holds 4.5:1 on its fill and on the stage's mesh, in both themes; chapter files keep their kind names. */
.ex-world {
  --k-neutral-f: #f3f5fa; --k-neutral-s: #6b7690; --k-neutral-i: #1e2840;
  --k-primary-f: #e7effd; --k-primary-s: #3477e6; --k-primary-i: #123d8c;
  --k-info-f: #e0f6f3;    --k-info-s: #129e8f;    --k-info-i: #0a5148;
  --k-data-f: #efeafe;    --k-data-s: #8560e6;    --k-data-i: #43249a;
  --k-good-f: #e3f6ec;    --k-good-s: #17a06a;    --k-good-i: #075a3b;
  --k-bad-f: #fdeceb;     --k-bad-s: #e0443c;     --k-bad-i: #98191a;
  --k-ghost-s: #98a1b3;   --k-ghost-i: #4f5a72;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .ex-world {
    --k-neutral-f: #1d2333; --k-neutral-s: #8a95ad; --k-neutral-i: #e8edf7;
    --k-primary-f: #15264a; --k-primary-s: #6aa5ff; --k-primary-i: #cfe2ff;
    --k-info-f: #0d2e2d;    --k-info-s: #3cc9b5;    --k-info-i: #b4f0e6;
    --k-data-f: #251d47;    --k-data-s: #a58bff;    --k-data-i: #e2d9ff;
    --k-good-f: #0b2a1f;    --k-good-s: #35c68f;    --k-good-i: #a8f0d0;
    --k-bad-f: #3a1618;     --k-bad-s: #f2696d;     --k-bad-i: #ffc9ca;
    --k-ghost-s: #5d6880;   --k-ghost-i: #a3acc0;
  }
}
:root[data-theme="dark"] .ex-world {
  --k-neutral-f: #1d2333; --k-neutral-s: #8a95ad; --k-neutral-i: #e8edf7;
  --k-primary-f: #15264a; --k-primary-s: #6aa5ff; --k-primary-i: #cfe2ff;
  --k-info-f: #0d2e2d;    --k-info-s: #3cc9b5;    --k-info-i: #b4f0e6;
  --k-data-f: #251d47;    --k-data-s: #a58bff;    --k-data-i: #e2d9ff;
  --k-good-f: #0b2a1f;    --k-good-s: #35c68f;    --k-good-i: #a8f0d0;
  --k-bad-f: #3a1618;     --k-bad-s: #f2696d;     --k-bad-i: #ffc9ca;
  --k-ghost-s: #5d6880;   --k-ghost-i: #a3acc0;
}
.ex-world ::selection { background: color-mix(in srgb, var(--gl-req) 22%, transparent); color: inherit; }
.ex-world .page.chapter, .ex-world .page.concept, .ex-world .page.concepts, .ex-world .page.home, .ex-world .page.lab-hub, .ex-world .lab { max-width: var(--ex-page-w); }
.ex-world .page.chapter > .card:not(.ex-card) { max-width: none; }
.ex-card [hidden] { display: none !important; }
/* a frosted panel: the label, the band under the exhibit, the contents' "where you stopped", the cheat sheet, the quiz,
   the Playground's entry and the pager (the map's follow card, a breath of the stage's blue in it) */
.ex-label, .ex-under, .home-go, .cheat-sheet, .ex-world .quiz, .lab-entry, .ex-world .pager-link {
  background: var(--ex-panel); color: var(--ex-ink); border: 1px solid var(--ex-panel-edge); border-radius: 16px; box-shadow: var(--ex-panel-shadow);
}
/* a frosted chip: the numbers that say where you are (the bar's, the contents', the pager's, a concept lesson's) */
.yah-no, .go-no, .pg-no, .cc-no, .lab-hall-no {
  display: grid; place-items: center; background: var(--ex-panel); color: var(--ex-ink); border: 1px solid var(--ex-panel-edge); box-shadow: var(--ex-chip-shadow);
  font-weight: 800; line-height: 1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
}

/* you are here: the number as a frosted chip, beside the crumbs and the chapter's strip of dots */
.yah { display: flex; align-items: center; gap: 14px; margin: 0 0 26px; }
.yah-no { flex: none; min-width: 58px; height: 48px; padding: 0 14px; border-radius: 14px; font-size: 22px; }
.yah-where { min-width: 0; display: flex; flex-direction: column; gap: 12px; }
.yah-crumbs { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 0 6px; font-size: var(--fs-ui); font-weight: 600; line-height: 1.4; color: var(--ex-ink-2); }
.yah-crumbs a { color: var(--ex-ink); }
.yah-crumbs a:hover { color: var(--ex-req-ink); text-decoration: underline; }
.yah-sep { display: inline-grid; color: var(--ex-ink-3); }
.yah-sep svg { width: 14px; height: 14px; }
.yah-chn { font-variant-numeric: tabular-nums; }
.yah-at { color: var(--ex-ink-3); font-weight: 500; }
/* one row that scrolls sideways (js/card.js stripScroll opens it with here in its middle); each mark is a 44px-tall target
   drawn in a 24px row (the row's negative margins give the height back) */
.yah-marks {
  list-style: none; display: flex; flex-wrap: nowrap; align-items: center; min-width: 0; margin: -10px 0 -10px -4px; padding: 0;
  overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none;
}
.yah-marks::-webkit-scrollbar { display: none; }
.yah-marks > li { flex: none; }
/* a dot per slide, like the minimap's parts: a ring until seen, then filled blue; here is larger with a glow ring; a teal
   flag where the reader stopped; a cheat sheet or a quiz is a diamond */
.yah-mark { position: relative; display: grid; place-items: center; width: 24px; height: 44px; color: var(--ex-ink); border-radius: 999px; }
.yah-mark i { display: block; width: 8px; height: 8px; border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--ex-dot); transition: background-color .15s, box-shadow .15s; }
.yah-mark.is-end i { width: 7px; height: 7px; border-radius: 1.5px; transform: rotate(45deg); }
.yah-mark.is-seen i { background: var(--ex-req); box-shadow: none; }
.yah-mark.is-now { width: 30px; }
.yah-mark.is-now i { width: 12px; height: 12px; background: var(--ex-req); box-shadow: 0 0 0 3px var(--ex-glow); }
.yah-mark.is-end.is-now i { width: 10px; height: 10px; border-radius: 2px; }
.yah-mark.is-stop i { display: none; }
.yah-mark.is-stop svg { width: 15px; height: 15px; color: var(--ex-fixed); }
.yah-mark:not(.is-seen):not(.is-now):hover i { box-shadow: inset 0 0 0 1.5px var(--ex-req); }
.yah-mark:hover { text-decoration: none; }

/* the card: title and one line on top, then the exhibit beside its label (stacked in a narrow card) */
.ex-body { container-type: inline-size; margin-top: 24px; }
.ex-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; align-items: start; }
@container (min-width: 860px) {
  .ex-grid { grid-template-columns: minmax(0, 1fr) var(--ex-label-w); gap: 24px; }
  /* beside each other, whichever of the exhibit and the label fits the screen stays in view while the other scrolls
     (js/card.js stickFit marks it .ex-fits); one that is taller than the screen scrolls with the page, never in a box of its own */
  .ex-main.ex-fits, .ex-label.ex-fits { position: sticky; top: calc(var(--topbar-h) + 16px); }
}
.ex-main { min-width: 0; display: flex; flex-direction: column; gap: 16px; }
/* an exhibit that grew to meet a much taller label (js/card.js band): its drawing sits in the middle of the room */
.ex-exhibit.is-grown { display: flex; flex-direction: column; }
.ex-exhibit.is-grown > .stage { flex: 1 0 auto; display: flex; flex-direction: column; justify-content: center; }
/* a label much taller than the exhibit hands its read-only sections to a band under the exhibit (js/card.js band) */
.ex-under { display: none; --ex-ground: var(--ex-panel); }
.ex-under:has(> .ex-sec:not([hidden])) { display: block; }
.ex-under > .ex-sec + .ex-sec { border-top: 1px solid var(--ex-hair); }
.ex-under .ex-about { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 28px; align-items: start; }
.ex-under .ex-about > .ex-h, .ex-under .ex-about > .card-wild, .ex-under .ex-about > .lab-link { grid-column: 1 / -1; }
.ex-under .ex-about:not(:has(.ex-fix)) .ex-breaks, .ex-under .ex-about:not(:has(.ex-breaks)) .ex-fix { grid-column: 1 / -1; }
/* the exhibit: a rounded glass stage on the map's mesh, clipped; the kit's drawings keep their kind colours on it, and the
   quiet inks a drawing uses are a step darker (light) or brighter (night) so they hold 4.5:1 over the blobs */
.ex-exhibit {
  --ex-ground: var(--gl-bg); --text-3: var(--ex-stage-ink-3); --k-ghost-i: var(--ex-stage-ink-3); --ex-fixed: var(--ex-stage-fixed); --ex-fault: var(--ex-stage-fault);
  position: relative; min-width: 0; border-radius: 16px; overflow: hidden; background: var(--ex-mesh); box-shadow: inset 0 0 0 1px var(--ex-stage-edge);
}
/* Restart and Expand: the map's frosted 12px buttons, in the stage's top corner */
.ex-acts { display: flex; justify-content: flex-end; gap: 6px; padding: 10px 10px 0; }
.ex-act {
  display: inline-flex; align-items: center; gap: 6px; min-height: 34px; padding: 0 12px 0 10px; border: 1px solid var(--gl-tag-edge); border-radius: 12px;
  background: var(--gl-tag-bg); color: var(--gl-ink); cursor: pointer; font-size: var(--fs-small); font-weight: 650;
  -webkit-backdrop-filter: blur(12px) saturate(160%); backdrop-filter: blur(12px) saturate(160%);
  box-shadow: 0 2px 8px -4px rgba(20, 40, 100, .28); transition: background .15s var(--ease-out), opacity .15s;
}
.ex-act:hover { background: var(--gl-tip-edge); }
.ex-act svg { width: 15px; height: 15px; }
.ex-act[disabled] { opacity: .45; cursor: not-allowed; }
.ex-act[disabled]:hover { background: var(--gl-tag-bg); }
.ex-card .stage { padding: 6px 24px 24px; }
.ex-card .ex-exhibit .vz-svg { max-width: 880px; }
.ex-exhibit .vz-panel { border-color: var(--gl-tip-edge); background: var(--gl-tip-bg); box-shadow: 0 6px 18px -12px rgba(20, 40, 100, .35); }
/* what docking left behind: rows and slots that only hold a marker comment */
.ex-exhibit .vz-row:empty, .ex-exhibit .vz:empty, .ex-exhibit .vz-grid:empty { display: none; }

/* the label: a frosted panel; each section under a small sentence-case head */
.ex-label { --ex-ground: var(--ex-panel); min-width: 0; }
.ex-sec { padding: 16px 18px 18px; }
.ex-sec + .ex-sec { border-top: 1px solid var(--ex-hair); }
.ex-h { margin: 0 0 10px; font-size: var(--fs-small); font-weight: 700; letter-spacing: 0; line-height: 1.3; color: var(--ex-ink-2); }
.ex-keep { margin: 0 0 6px; font-size: var(--fs-ui); line-height: 1.5; color: var(--ex-ink-2); }

/* To do: numbered steps in round chips; ticked (teal) once used, the next unused one lit (a blue ring with a soft glow) */
.ex-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.ex-step { display: grid; grid-template-columns: 28px minmax(0, 1fr); gap: 12px; align-items: start; margin: 0 -10px; padding: 8px 10px; border-radius: 14px; transition: background-color .2s; }
.ex-step.is-lit { background: var(--ex-wash); }
.ex-num {
  display: grid; place-items: center; width: 28px; height: 28px; margin-top: max(0px, calc((max(36px, var(--tap)) - 28px) / 2)); border-radius: 50%;
  border: 1.5px solid var(--ex-line); background: var(--ex-chip); color: var(--ex-ink-2); font-size: 13px; font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1;
  transition: background-color .2s, border-color .2s, box-shadow .2s;
}
.ex-num svg { display: none; width: 15px; height: 15px; stroke-width: 3; }
.ex-step.is-done .ex-num { background: var(--ex-fixed); border-color: var(--ex-fixed); color: var(--ex-on-fixed); }
.ex-step.is-done .ex-num .ex-n { display: none; }
.ex-step.is-done .ex-num svg { display: block; }
.ex-step.is-lit .ex-num { border: 2px solid var(--ex-req); background: var(--ex-chip); color: var(--ex-req-ink); box-shadow: 0 0 0 4px var(--ex-glow); animation: ex-light .45s var(--ease-out); }
/* the one authored moment: the next step lights */
@keyframes ex-light { from { transform: scale(.6); box-shadow: 0 0 0 0 var(--ex-glow); } to { transform: none; } }
.ex-ctl { min-width: 0; }
/* a To do whose only step rides in the dock has nothing left to show in the label */
.ex-todo:not(:has(.ex-step, .ex-next:not([hidden]), .ex-keep:not([hidden]))) { display: none; }
/* a control the demo hid takes its step with it */
.ex-step:has(> .ex-ctl > [style*="display: none"]:only-child) { display: none; }

/* one control language, docked or in place: the system map's */
.ex-card .vz-controls { gap: 8px; }
.ex-card .vz-btn {
  min-height: 36px; border-radius: 999px; border: 1px solid var(--ex-line); background: var(--ex-chip); color: var(--ex-ink); font-weight: 650;
  transition: background .15s, border-color .15s, color .15s, opacity .15s, transform .08s;
}
.ex-card .vz-btn:hover { background: var(--ex-chip); border-color: var(--ex-line-hover); }
/* unavailable: faded and not-allowed (the lab's status line or the row's note says why) */
.ex-card .vz-btn[disabled] { opacity: .45; cursor: not-allowed; }
.ex-card .vz-btn[disabled]:hover { background: var(--ex-chip); border-color: var(--ex-line); }
.ex-card .vz-btn.primary { background: var(--ex-chip); border-color: var(--ex-req); color: var(--ex-req-ink); box-shadow: inset 0 0 0 1px var(--ex-req); }
.ex-card .vz-btn.primary:hover, .ex-card .vz-btn.primary[disabled]:hover { background: linear-gradient(var(--ex-wash), var(--ex-wash)), var(--ex-chip); border-color: var(--ex-req); }
.ex-card .vz-btn.danger { border-color: color-mix(in srgb, var(--ex-fault) 45%, var(--ex-line)); color: var(--ex-fault); }
.ex-card .vz-btn.good { border-color: color-mix(in srgb, var(--ex-fixed) 45%, var(--ex-line)); color: var(--ex-fixed); }
.ex-card .vz-btn.ghost { border-color: transparent; background: transparent; color: var(--ex-ink-2); }
.ex-card .vz-btn.ghost:hover { background: var(--ex-hover); color: var(--ex-ink); }
/* the lit step's first (or primary) button, and the stepper's Next step, are the card's one filled pill */
.ex-card :is(.is-lit .vz-controls, .vz-controls.is-lit) > .vz-btn.primary,
.ex-card :is(.is-lit .vz-controls, .vz-controls.is-lit):not(:has(> .vz-btn.primary)) > .vz-btn:first-child,
.ex-card .vz-stepper .vz-btn.primary { background: var(--ex-btn); border-color: var(--ex-btn); color: var(--ex-on-btn); box-shadow: 0 8px 18px -10px var(--ex-glow); }
.ex-card :is(.is-lit .vz-controls, .vz-controls.is-lit) > .vz-btn.primary:hover,
.ex-card :is(.is-lit .vz-controls, .vz-controls.is-lit):not(:has(> .vz-btn.primary)) > .vz-btn:first-child:hover,
.ex-card .vz-stepper .vz-btn.primary:hover { background: var(--ex-btn-hover); border-color: var(--ex-btn-hover); }
.ex-card .vz-stepper .vz-btn.primary[disabled]:hover { background: var(--ex-btn); border-color: var(--ex-btn); }
/* options: the map's 36px pills, the chosen one pressed (a blue border, an inset ring and a light blue wash); they grow to
   fill their row, so a wrapped row never ends in an empty cell */
.ex-card .vz-seg { display: flex; flex-wrap: wrap; gap: 6px; width: 100%; padding: 0; border: 0; border-radius: 0; background: none; }
.ex-card .vz-seg button {
  flex: 1 1 76px; min-height: 36px; padding: 6px 14px; border: 1px solid var(--ex-line); border-radius: 999px; background: var(--ex-chip); color: var(--ex-ink-2);
  white-space: normal; line-height: 1.2; text-align: center; transition: background .15s, border-color .15s, color .15s, box-shadow .15s;
}
.ex-card .vz-seg button:hover:not(.on):not([disabled]) { border-color: var(--ex-line-hover); color: var(--ex-ink); }
.ex-card .vz-seg button.on, .ex-card .vz-seg button.on[class*="k-"] { border-color: var(--ex-req); background: linear-gradient(var(--ex-wash), var(--ex-wash)), var(--ex-chip); color: var(--ex-req-ink); box-shadow: inset 0 0 0 1px var(--ex-req); }
.ex-card .vz-seg button[disabled] { opacity: .45; cursor: not-allowed; }
/* a switch: the map's break switch in its pill (32 by 18), on in request blue */
.ex-card .vz-toggle {
  display: flex; width: 100%; justify-content: flex-start; gap: 10px; min-height: 36px; padding: 0 14px 0 8px;
  border: 1px solid var(--ex-line); border-radius: 999px; background: var(--ex-chip); color: var(--ex-ink); font-weight: 650; transition: border-color .15s, color .15s;
}
.ex-card .vz-toggle:hover { border-color: var(--ex-line-hover); }
.ex-card .vz-toggle .sw { order: 0; width: 32px; height: 18px; border-radius: 999px; background: var(--ex-track); box-shadow: none; }
.ex-card .vz-toggle .sw::after { top: 2px; left: 2px; width: 14px; height: 14px; background: #ffffff; box-shadow: 0 1px 2px rgba(16, 24, 40, .3); }
.ex-card .vz-toggle input:checked + .sw { background: var(--ex-req); }
.ex-card .vz-toggle input:checked + .sw::after { transform: translateX(14px); }
.ex-card .vz-toggle:has(input:checked) { border-color: var(--ex-req); color: var(--ex-req-ink); }
/* a slider: its name and value on one line (tabular figures), a thin track with a blue thumb under them */
.ex-card .vz-slider { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 12px; width: 100%; color: var(--ex-ink); font-weight: 650; }
.ex-card .vz-slider > span { grid-column: 1; grid-row: 1; }
.ex-card .vz-slider output { grid-column: 2; grid-row: 1; font-family: var(--font-body); font-weight: 800; font-variant-numeric: tabular-nums; text-align: right; color: var(--ex-req-ink); }
.ex-card .vz-slider input {
  grid-column: 1 / -1; grid-row: 2; width: 100%; min-width: 0; height: 28px; margin: 0; background: transparent; cursor: pointer;
  -webkit-appearance: none; appearance: none; accent-color: var(--ex-req);
}
.ex-card .vz-slider input::-webkit-slider-runnable-track { height: 4px; border-radius: 999px; background: var(--ex-track); }
.ex-card .vz-slider input::-webkit-slider-thumb { -webkit-appearance: none; width: 18px; height: 18px; margin-top: -7px; border-radius: 50%; border: 2px solid var(--ex-chip); background: var(--ex-req); box-shadow: 0 1px 4px rgba(20, 40, 100, .35); }
.ex-card .vz-slider input::-moz-range-track { height: 4px; border-radius: 999px; background: var(--ex-track); }
.ex-card .vz-slider input::-moz-range-progress { height: 4px; border-radius: 999px; background: var(--ex-req); }
.ex-card .vz-slider input::-moz-range-thumb { width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--ex-chip); background: var(--ex-req); box-shadow: 0 1px 4px rgba(20, 40, 100, .35); }
/* a row with its own words (a label, a typed value) */
.ex-card .ex-ctl > .vz-row { gap: 8px; }
.ex-card .ex-ctl > .vz-row > .vz-seg { flex: 1 1 160px; width: auto; }
.ex-card .ex-ctl input[type="text"], .ex-card .ex-ctl input:not([type]), .ex-card .ex-ctl input[type="number"] {
  min-height: 36px; padding: 0 14px; border: 1px solid var(--ex-line); border-radius: 999px; background: var(--ex-chip); color: var(--ex-ink);
}
/* the stepper as the label's transport: Back, "3 of 7", Next step (filled); Play and Restart; the steps as a thin bar */
.ex-card .vz-stepper { display: grid; grid-template-columns: auto auto minmax(0, 1fr); gap: 8px; width: 100%; align-items: center; }
.ex-card .vz-stepper > :nth-child(1) { grid-column: 3; grid-row: 2; justify-self: end; }
.ex-card .vz-stepper > :nth-child(2) { grid-column: 1; grid-row: 1; }
.ex-card .vz-stepper .pos { grid-column: 2; grid-row: 1; min-width: 4.5em; font-family: var(--font-body); font-size: var(--fs-ui); font-weight: 800; color: var(--ex-ink); font-variant-numeric: tabular-nums; }
.ex-card .vz-stepper > :nth-child(4) { grid-column: 3; grid-row: 1; justify-content: center; }
.ex-card .vz-stepper > :nth-child(5) { grid-column: 1 / 3; grid-row: 2; justify-self: start; }
.ex-card .vz-stepper .pips { grid-column: 1 / -1; grid-row: 3; display: flex; gap: 4px; margin: 4px 0 0; }
.ex-card .vz-stepper .pips i { flex: 1; width: auto; height: 4px; border-radius: 999px; background: var(--ex-track); }
.ex-card .vz-stepper .pips i.on { background: color-mix(in srgb, var(--ex-req) 45%, var(--ex-track)); }
.ex-card .vz-stepper .pips i.on:not(:has(+ i.on)) { background: var(--ex-req); }
/* wins and costs: the options row, then a thin rounded meter per measure (blue fill, a tick for each other option) */
.ex-card .vz-tradeoff { gap: 12px; padding-top: 0; border-top: 0; }
.ex-card .ex-exhibit .vz-tradeoff { padding-top: 14px; border-top: 1px solid var(--ex-hair); }
.ex-card .to-title { margin: 0; font-size: var(--fs-ui); font-weight: 700; color: var(--ex-ink); }
.ex-card .to-head { flex-direction: column; align-items: stretch; gap: 8px; }
.ex-card .to-pin { align-self: flex-start; min-height: 34px; border-radius: 999px; border: 1px solid var(--ex-line); background: var(--ex-chip); color: var(--ex-ink-2); }
.ex-card .to-pin:hover { border-color: var(--ex-line-hover); color: var(--ex-ink); }
.ex-card .to-pin.on { border-color: var(--ex-req); background: linear-gradient(var(--ex-wash), var(--ex-wash)), var(--ex-chip); color: var(--ex-req-ink); box-shadow: inset 0 0 0 1px var(--ex-req); }
.ex-card .to-row { grid-template-columns: minmax(0, 1fr) auto; gap: 4px 12px; }
.ex-card .to-track { grid-column: 1 / -1; grid-row: 2; height: 6px; border-radius: 999px; background: var(--ex-track); }
.ex-card .to-fill { border-radius: 999px; background: var(--ex-req); clip-path: inset(0 var(--rest, 100%) 0 0 round 999px); }
.ex-card .to-tick { top: -3px; bottom: -3px; background: var(--ex-ink-3); }
.ex-card .to-tick.pinned { background: var(--ex-ink); }
.ex-card .to-name { color: var(--ex-ink); }
.ex-card .to-name small { color: var(--ex-ink-3); }
.ex-card .to-val { font-family: var(--font-body); font-weight: 800; color: var(--ex-ink); }
.ex-card .to-delta, .ex-card .to-delta.k-good, .ex-card .to-delta.k-bad, .ex-card .to-sum .k-good, .ex-card .to-sum .k-bad { color: var(--ex-ink-2); }
.ex-card .to-sum { border-top-color: var(--ex-hair); color: var(--ex-ink-2); }
.ex-card .to-sum > b, .ex-card .to-sum span > b { color: var(--ex-ink); }
/* in-place steps (a demo whose controls stay beside its drawings): the same chip, tick and light */
.ex-card .ex-inplace { position: relative; padding-left: 40px; min-height: var(--tap); }
.ex-card .ex-inplace::before {
  content: attr(data-n); position: absolute; left: 0; top: max(0px, calc((max(36px, var(--tap)) - 28px) / 2)); display: grid; place-items: center;
  width: 28px; height: 28px; border-radius: 50%; border: 1.5px solid var(--ex-line); background: var(--ex-chip); color: var(--ex-ink-2);
  font-size: 13px; font-weight: 800; line-height: 1; box-sizing: border-box;
}
.ex-card .ex-inplace.is-done::before { content: ""; background: var(--ex-fixed); border-color: var(--ex-fixed); }
/* the tick: the kit's check, on the teal chip */
.ex-card .ex-inplace.is-done::after {
  content: ""; position: absolute; left: 6px; top: calc(max(0px, calc((max(36px, var(--tap)) - 28px) / 2)) + 6px); width: 16px; height: 16px; background: var(--ex-on-fixed);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 16px no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 16px no-repeat;
}
.ex-card .ex-inplace.is-lit::before { border: 2px solid var(--ex-req); color: var(--ex-req-ink); box-shadow: 0 0 0 4px var(--ex-glow); }
/* a control with its own frame (the options, a switch) sets its chip outside that frame */
.ex-card :is(.vz-seg, .vz-toggle).ex-inplace { margin-left: 40px; width: calc(100% - 40px); }
.ex-card .vz-seg.ex-inplace { padding-left: 0; }
.ex-card .vz-toggle.ex-inplace { width: auto; max-width: calc(100% - 40px); padding-left: 8px; }
.ex-card .vz-seg.ex-inplace::before { left: -40px; }
.ex-card .vz-toggle.ex-inplace::before { left: -41px; top: max(-1px, calc((max(36px, var(--tap)) - 30px) / 2)); }
.ex-card .vz-seg.ex-inplace.is-done::after { left: -34px; }
.ex-card .vz-toggle.ex-inplace.is-done::after { left: -35px; top: calc(max(-1px, calc((max(36px, var(--tap)) - 30px) / 2)) + 6px); }

/* Notice: what just happened, a glass caption line: a request-blue dot (a tick or a warning for a good or bad line) and the
   line in ink; earlier lines step back (still aria-live) */
.ex-lines { display: flex; flex-direction: column; gap: 6px; }
.ex-line { display: grid; grid-template-columns: 16px minmax(0, 1fr); column-gap: 8px; align-items: start; }
.ex-line::before { content: ""; grid-column: 1; grid-row: 1; justify-self: center; width: 8px; height: 8px; margin-top: 8px; border-radius: 50%; background: var(--ex-dot); }
.ex-line.is-latest::before { background: var(--ex-req); box-shadow: 0 0 0 3px var(--ex-glow); }
.ex-line:has(.vz-caption:empty)::before, .ex-line:has(.vz-caption.k-bad)::before, .ex-line:has(.vz-caption.k-good)::before { display: none; }
.ex-line > svg { display: none; grid-column: 1; grid-row: 1; width: 16px; height: 16px; margin-top: 4px; }
.ex-line:has(.vz-caption.k-bad) > svg:first-of-type { display: block; color: var(--ex-fault); }
.ex-line:has(.vz-caption.k-good) > svg:nth-of-type(2) { display: block; color: var(--ex-fixed); }
.ex-line > .ex-ctl { grid-column: 2; grid-row: 1; }
/* inline, so a line that wraps counts its lines (the dock keeps only a one-line Notice: js/card.js oneLine); a kind
   colours the words, never a background */
.ex-line .ex-ctl .vz-caption {
  display: inline; min-height: 0; margin: 0; padding: 0; border-radius: 0; background: none; text-align: left;
  font-size: var(--fs-body-s); line-height: 1.55; color: var(--ex-ink-2);
}
.ex-line.is-latest .ex-ctl .vz-caption { color: var(--ex-ink); font-weight: 600; }
.ex-line .ex-ctl .vz-caption.k-bad { color: var(--ex-fault); }
.ex-line .ex-ctl .vz-caption.k-good { color: var(--ex-fixed); }
.ex-line .ex-ctl .vz-caption.k-warn { color: var(--k-warn-i); }
/* narration kept beside its drawing: the map's follow caption, a frosted card on the stage */
.ex-exhibit .vz-caption { border-radius: 12px; background: transparent; color: var(--ex-ink-2); text-align: left; }
.ex-exhibit .vz-caption:not(:empty) {
  background: var(--gl-tip-bg); color: var(--gl-ink); border: 1px solid var(--gl-tip-edge); font-weight: 550;
  box-shadow: 0 8px 22px -12px rgba(20, 40, 100, .38), inset 0 1px 0 rgba(255, 255, 255, .5);
  -webkit-backdrop-filter: blur(16px) saturate(180%); backdrop-filter: blur(16px) saturate(180%);
}
.ex-exhibit .vz-caption.k-bad:not(:empty) { color: var(--ex-fault); }
.ex-exhibit .vz-caption.k-good:not(:empty) { color: var(--ex-fixed); }
.ex-exhibit .vz-caption.k-warn:not(:empty) { color: var(--k-warn-i); }

/* Notice leads the label. A label taller than the screen scrolls with the page, and Notice stays under the header
   with it, so what a press did is never below the fold (a stacked label keeps it in the flow: the dock carries it) */
.ex-notice { position: sticky; top: var(--topbar-h); z-index: 4; padding: 14px 18px 14px; background: var(--ex-panel); border-radius: 15px 15px 0 0; border-bottom: 1px solid var(--ex-hair); }
.ex-notice + .ex-sec { border-top: 0; }
.ex-notice > .ex-h { margin-bottom: 6px; }
@container (max-width: 859px) { .ex-notice { position: static; } }
.ex-body.expanded .ex-notice { top: 0; }

/* Readouts: the map's counter tiles, frosted, the numbers in tabular figures; hot is blue, a fault red */
.ex-stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 96px), 1fr)); gap: 8px; }
.ex-stat-slot, .ex-stats .vz-row { display: contents; }
.ex-card .vz-stat { border-radius: 12px; background: var(--ex-tile); border: 1px solid var(--ex-tile-edge); box-shadow: 0 4px 12px -8px rgba(20, 40, 100, .30); }
.ex-stats .vz-stat { align-items: flex-start; min-width: 0; padding: 8px 12px; }
.ex-card .vz-stat b { color: var(--ex-ink); font-size: 20px; font-weight: 800; font-variant-numeric: tabular-nums; }
.ex-card .vz-stat span { color: var(--ex-ink-3); }
.ex-stats .vz-stat span { text-align: left; line-height: 1.3; }
.ex-card .vz-stat.k-good b { color: var(--ex-fixed); }
.ex-card .vz-stat.k-bad { border-color: color-mix(in srgb, var(--ex-fault) 40%, var(--ex-tile-edge)); }
.ex-card .vz-stat.k-bad b { color: var(--ex-fault); }
.ex-card .vz-stat.k-warn b { color: var(--k-warn-i); }
.ex-card .vz-stat.k-primary b, .ex-card .vz-stat.k-info b { color: var(--ex-req-ink); }

/* What's going on: what breaks and the fix, in two short lines; in the wild; the lab */
.ex-why { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 8px; margin: 0 0 8px; font-size: var(--fs-body-s); line-height: 1.45; color: var(--ex-ink-2); }
.ex-why svg { width: 18px; height: 18px; margin-top: 2px; }
.ex-why b { margin-right: 2px; color: var(--ex-ink); font-weight: 750; }
.ex-breaks svg { color: var(--ex-fault); }
.ex-fix svg, .ex-fix b { color: var(--ex-fixed); }
.ex-about .card-wild { margin-top: 10px; font-size: var(--fs-small); color: var(--ex-ink-3); }
.ex-about .card-wild .lbl { color: var(--ex-ink-2); }
.ex-about .lab-link { margin-top: 6px; font-size: var(--fs-small); color: var(--ex-req-ink); }
.ex-about .lab-link span b { color: var(--ex-req-ink); }

/* Next exhibit: offered once the steps are done; the lit, filled blue pill when nothing else is left */
.ex-next { margin-top: 12px; }
.ex-next-btn {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px; width: 100%; min-height: 48px; padding: 9px 20px;
  border: 1px solid var(--ex-line); border-radius: 24px; background: var(--ex-chip); color: var(--ex-ink); text-align: left; font: inherit; cursor: pointer;
  transition: background .15s, border-color .15s;
}
.ex-next-btn:hover { color: var(--ex-ink); border-color: var(--ex-req); text-decoration: none; }
.ex-next-t { display: inline-flex; align-items: center; gap: 8px; font-size: var(--fs-body-s); font-weight: 750; }
.ex-next-t svg { width: 18px; height: 18px; }
.ex-next-sub { font-size: var(--fs-small); color: var(--ex-ink-2); }
.ex-next.is-lit .ex-next-btn { background: var(--ex-btn); border-color: var(--ex-btn); color: var(--ex-on-btn); box-shadow: 0 8px 20px -10px var(--ex-glow); animation: ex-light .45s var(--ease-out); }
.ex-next.is-lit .ex-next-btn:hover { background: var(--ex-btn-hover); border-color: var(--ex-btn-hover); }
.ex-next.is-lit .ex-next-sub { color: inherit; }

/* the dock: a stacked label's lit step rides the bottom edge while the card is in view, on a frosted glass bar. One compact
   row: the lit step's control (a row of options scrolls sideways, its continuing edge faded) and, when it fits one line, the
   latest Notice. */
.ex-pin {
  --ex-ground: var(--ex-panel); position: sticky; bottom: var(--ex-pin-bottom, 0px); z-index: 15; margin-top: 12px; padding: 8px 12px 10px;
  background: var(--gl-tip-bg); color: var(--ex-ink); border: 1px solid var(--gl-tip-edge); border-radius: 16px;
  -webkit-backdrop-filter: blur(16px) saturate(180%); backdrop-filter: blur(16px) saturate(180%);
  box-shadow: 0 -8px 26px -14px rgba(20, 40, 100, .40), inset 0 1px 0 rgba(255, 255, 255, .5);
}
.ex-pin:empty { display: none; }
/* what scrolls under the dock fades out above it, so a heading is never cut in half at a hard edge */
.ex-pin::before { content: ""; position: absolute; left: -1px; right: -1px; bottom: calc(100% + 1px); height: 22px; background: linear-gradient(to bottom, transparent, var(--bg)); pointer-events: none; }
.ex-pin > .ex-step { margin: 0; padding: 0; background: none; }
.ex-pin > .ex-step.is-lit { background: none; }
.ex-pin > .ex-line { margin: 0 0 6px; }
.ex-pin > .ex-next { margin: 0; }
.ex-pin > .ex-next .ex-next-btn { min-height: 44px; }
.ex-pin .vz-seg, .ex-pin .vz-controls { flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
.ex-pin .vz-seg::-webkit-scrollbar, .ex-pin .vz-controls::-webkit-scrollbar { display: none; }
.ex-pin :is(.vz-seg, .vz-controls) :focus-visible { outline-offset: -3px; }
.ex-card .ex-pin .vz-seg button { flex: 1 0 auto; white-space: nowrap; }
.ex-card .ex-pin .vz-controls > * { flex: 0 0 auto; }
/* a picker of four to eight options takes two rows in the dock (js/card.js rowsFor), each option whole and growing to fill its row */
.ex-pin .vz-seg.is-rows { flex-wrap: wrap; gap: 4px; overflow: visible; }
.ex-card .ex-pin .vz-seg.is-rows button { flex: 1 0 calc((100% - (var(--cols, 3) - 1) * 4px) / var(--cols, 3)); min-width: 0; min-height: 36px; padding: 4px 6px; white-space: normal; line-height: 1.15; }
/* the pinned transport takes one row: Back, "3 of 7", Next step, then Play and Restart as icons */
.ex-pin .vz-stepper { grid-template-columns: auto auto minmax(0, 1fr) auto auto; gap: 6px; }
.ex-pin .vz-stepper > :nth-child(1) { grid-column: 5; grid-row: 1; }
.ex-pin .vz-stepper > :nth-child(5) { grid-column: 4; grid-row: 1; width: max(36px, var(--tap)); padding: 0; gap: 0; justify-content: center; font-size: 0; }
.ex-pin .vz-stepper .pos { min-width: 3.6em; text-align: center; }
.ex-pin .vz-stepper .pips { grid-row: 2; }
.ex-pin .vz-stepper .pips i { height: 3px; }

/* a row that continues past its edge fades that edge (js/viz.js scrollCue sets data-more) */
[data-more="right"] { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent); }
[data-more="left"] { -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 32px), transparent); mask-image: linear-gradient(to left, #000 calc(100% - 32px), transparent); }
[data-more="both"] { -webkit-mask-image: linear-gradient(to right, transparent, #000 32px, #000 calc(100% - 32px), transparent); mask-image: linear-gradient(to right, transparent, #000 32px, #000 calc(100% - 32px), transparent); }

/* Expand: the exhibit and its label take the whole screen */
.ex-body.expanded.expanded {
  position: fixed; inset: 0; z-index: 90; margin: 0; overflow: auto; overscroll-behavior: contain; background: var(--bg);
  padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
  animation: frame-in .22s var(--ease-out);
}
.ex-body.expanded .ex-main.ex-fits, .ex-body.expanded .ex-label.ex-fits { top: 0; }
.ex-body.expanded .turn-hint { margin: 0 0 10px; border-radius: 12px; background: var(--ex-panel); color: var(--ex-ink-2); border: 1px solid var(--ex-panel-edge); box-shadow: var(--ex-chip-shadow); }
@media (orientation: portrait) and (max-width: 640px) { .ex-body.expanded .turn-hint { display: block; } }

/* the pager in the world: frosted panels, the number each leads to as a chip */
.ex-world .pager-link:hover { border-color: var(--ex-req); box-shadow: var(--ex-panel-shadow); }
.ex-world .pager-link small { font-weight: 600; color: var(--ex-ink-3); }
.ex-world .pager-link b { color: var(--ex-ink); }

@media (max-width: 640px) {
  /* the bar is one row: the chip, then the last crumb and the page on one line over the strip of dots (the count is left out:
     the page says "card 3 of 14") */
  .yah { gap: 12px; margin-bottom: 14px; }
  .yah-where { gap: 10px; }
  .yah-no { min-width: 50px; height: 42px; padding: 0 10px; border-radius: 12px; font-size: 19px; }
  .yah-crumbs { flex-wrap: nowrap; white-space: nowrap; }
  .yah-crumbs > * { flex: none; }
  .yah-crumbs > :not(:nth-last-child(-n+3)) { display: none; }
  .yah-crumbs > .yah-at { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .yah-count { display: none; }
  .yah-marks { margin-left: -6px; }
  /* the title and its line stay short, so the stage is in the first screen: the line is two lines (a tap shows it all) */
  .ex-world .card-title { font-size: 26px; }
  .ex-lede { margin-top: 8px; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; cursor: pointer; }
  .ex-lede.is-open { display: block; -webkit-line-clamp: none; line-clamp: none; cursor: auto; }
  .ex-body { margin-top: 14px; }
  /* the stage hugs its drawing: no minimum height, so a short drawing is not left with an empty tint under it, and the label
     starts right under the stage */
  /* phones: the stage runs edge to edge, so the drawing is as wide as the screen (its text stays legible); the label nearly so,
     a 6px margin keeping its rounded corners */
  .ex-exhibit { margin-left: -16px; margin-right: -16px; border-radius: 0; box-shadow: inset 0 1px 0 var(--ex-stage-edge), inset 0 -1px 0 var(--ex-stage-edge); }
  .ex-label { margin-left: -10px; margin-right: -10px; border-radius: 14px; }
  .ex-notice { border-radius: 13px 13px 0 0; }
  .ex-card .stage { padding: 4px 4px 14px; }
  .ex-card .stage > .vz > :not(.vz-svg-wrap), .ex-card .stage > :not(.vz):not(.vz-svg-wrap) { margin-left: 8px; margin-right: 8px; }
  .ex-sec { padding: 14px 16px 16px; }
  /* the dock: a frosted bar the width of the screen, rounded at its top */
  .ex-pin { margin-left: -16px; margin-right: -16px; border-radius: 16px 16px 0 0; border-left: 0; border-right: 0; border-bottom: 0; }
  /* a book page's pager already rides the bottom edge: the pin sits just above it */
  .ex-world .page.chapter { --ex-pin-bottom: calc(61px + env(safe-area-inset-bottom)); }
  .ex-world .page.chapter .ex-pin { border-radius: 16px 16px 0 0; }
  .ex-world .page.concept .ex-pin { padding-bottom: calc(10px + env(safe-area-inset-bottom)); }
  .ex-world .pager {
    background: var(--gl-tip-bg); border-top: 1px solid var(--ex-hair);
    -webkit-backdrop-filter: blur(16px) saturate(180%); backdrop-filter: blur(16px) saturate(180%);
  }
  .ex-world .pager-link { border-radius: 999px; box-shadow: var(--ex-chip-shadow); }
}
@media (pointer: coarse) {
  .ex-act, .ex-card .vz-seg button, .ex-card .vz-toggle, .ex-card .vz-btn { min-height: var(--tap); }
  .yah-mark { width: 32px; } .yah-mark.is-now { width: 36px; }
}

/* ---------- cheat sheet ---------- */
.cheat { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr)); gap: 0 40px; margin: 28px 0 0; }
.cheat-item { padding: 16px 0; border-top: 1px solid var(--border); }
.cheat-item dt { font-weight: 600; font-size: var(--fs-body); color: var(--text); }
.cheat-item dd { margin: 4px 0 0; font-size: var(--fs-body-s); color: var(--text-2); line-height: 1.55; }
.cheat-link { display: inline-flex; margin-left: 8px; font-size: var(--fs-small); font-weight: 600; white-space: nowrap; }

/* ---------- quiz ---------- */
.quiz { margin-top: 26px; padding: 26px 28px 28px; border-radius: var(--radius-lg); background: var(--wash); border: 1px solid var(--border); }
.quiz-progress { display: flex; align-items: center; gap: 14px; }
.quiz-bars { display: flex; gap: 4px; }
.quiz-bars i { width: 26px; height: 4px; border-radius: 2px; background: var(--surface-3); }
.quiz-bars i.cur { background: var(--link); }
.quiz-bars i.ok { background: var(--k-good-s); }
.quiz-bars i.no { background: var(--k-bad-s); }
.quiz-count { font-size: var(--fs-small); color: var(--text-3); font-variant-numeric: tabular-nums; }
.quiz-q { margin: 18px 0 0; font-size: 20px; font-weight: 600; line-height: 1.4; letter-spacing: -0.01em; max-width: 60ch; }
.quiz-opts { display: flex; flex-direction: column; gap: 8px; margin-top: 18px; }
.quiz-opt {
  display: flex; align-items: flex-start; gap: 12px; width: 100%; padding: 12px 14px;
  border-radius: 12px; border: 1px solid var(--border-strong); background: var(--surface);
  text-align: left; font-size: var(--fs-body-s); line-height: 1.45; cursor: pointer; color: var(--text);
  transition: border-color .15s, background .15s;
}
.quiz-opt:hover:not([disabled]) { border-color: var(--link); }
.quiz-opt .letter {
  flex: none; width: 24px; height: 24px; border-radius: 7px; display: grid; place-items: center;
  background: var(--surface-2); color: var(--text-2); font-size: var(--fs-micro); font-weight: 700;
}
.quiz-opt[disabled] { cursor: default; }
.quiz-opt[disabled]:not(.right):not(.wrong) { opacity: .6; }
.quiz-opt.right { border-color: var(--k-good-s); background: var(--k-good-f); color: var(--k-good-i); }
/* letter badges use the kind's ink (dark green / dark red) so the letter keeps 4.5:1 */
.quiz-opt.right .letter { background: var(--k-good-i); color: var(--k-good-f); }
.quiz-opt.wrong { border-color: var(--k-bad-s); background: var(--k-bad-f); color: var(--k-bad-i); }
.quiz-opt.wrong .letter { background: var(--k-bad-i); color: var(--k-bad-f); }
.quiz-opt:not([disabled]):active { transform: scale(.99); }
.quiz-why { display: flex; gap: 10px; align-items: baseline; margin-top: 14px; padding: 12px 14px; border-radius: 12px; font-size: var(--fs-body-s); line-height: 1.5; }
.quiz-why b { display: inline-flex; align-items: center; gap: 6px; flex: none; }
.quiz-why b svg { width: 15px; height: 15px; }
.quiz-why.k-good { background: var(--k-good-f); color: var(--k-good-i); }
.quiz-why.k-bad { background: var(--k-bad-f); color: var(--k-bad-i); }
.quiz-foot { display: flex; justify-content: flex-end; margin-top: 18px; }
.quiz-score { display: flex; flex-direction: column; gap: 6px; margin-top: 18px; outline: none; }
.quiz-score .quiz-total { font-size: 34px; font-weight: 800; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.quiz-score.k-good .quiz-total { color: var(--k-good-i); }
.quiz-score.k-warn .quiz-total { color: var(--k-warn-i); }
.quiz-score.k-bad .quiz-total { color: var(--k-bad-i); }
.quiz-score.k-neutral .quiz-total { color: var(--text); }
.quiz-review .rc { display: inline-flex; align-items: center; gap: 2px; margin-top: 6px; font-size: var(--fs-small); font-weight: 600; }
.quiz-review .rc svg { width: 14px; height: 14px; }
.quiz-score .big { margin: 0; font-size: var(--fs-lead); color: var(--text-2); }
.quiz-done { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-size: var(--fs-ui); color: var(--k-good-i); }
.quiz-done svg { width: 15px; height: 15px; }
.quiz-score .quiz-foot { justify-content: flex-start; margin-top: 8px; }
.quiz-review { list-style: none; margin: 22px 0 0; padding: 0; border-top: 1px solid var(--border); }
.quiz-review li { display: flex; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--border); }
.quiz-review .mark { flex: none; width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; margin-top: 2px; }
.quiz-review .mark svg { width: 13px; height: 13px; }
.quiz-review li.ok .mark { background: var(--k-good-f); color: var(--k-good-i); }
.quiz-review li.no .mark { background: var(--k-bad-f); color: var(--k-bad-i); }
.quiz-review p { margin: 0; }
.quiz-review .rq { font-weight: 600; font-size: var(--fs-body-s); line-height: 1.45; }
.quiz-review .ra { margin-top: 4px; font-size: var(--fs-ui); color: var(--text-2); }
.quiz-review .rp { color: var(--text-3); }
.quiz-review .rw { margin-top: 4px; font-size: var(--fs-ui); color: var(--text-3); line-height: 1.5; }

/* ---------- the inside's pages: the rail, the contents, cheat sheets, quizzes, concepts (body.ex-world) ---------- */
/* The same glass as the card's label: frosted panels, rows on hairlines, pill rows, round number chips, thin rounded bars.
   Request blue is where you are and what you have seen; teal is done. */
.ex-world .btn { border-color: var(--ex-line); background: var(--ex-chip); color: var(--ex-ink); font-weight: 650; }
.ex-world .btn:hover { border-color: var(--ex-line-hover); background: var(--ex-chip); color: var(--ex-ink); }
.ex-world .btn.primary { background: var(--ex-btn); border-color: var(--ex-btn); color: var(--ex-on-btn); box-shadow: 0 8px 20px -10px var(--ex-glow); }
.ex-world .btn.primary:hover { background: var(--ex-btn-hover); border-color: var(--ex-btn-hover); color: var(--ex-on-btn); }
.ex-world .chip.tag { border-color: var(--ex-line); background: var(--ex-chip); color: var(--ex-ink-2); font-weight: 600; }
.ex-world .chip.tag:hover { border-color: var(--ex-req); color: var(--ex-req-ink); }

/* a mark: one card, a dot; a ring until seen, filled blue once seen, lit where you are, a teal flag where you stopped,
   a diamond for a cheat sheet or a quiz. The strip's dots (above) and the rail's and the contents' share these shapes. */
.mk { position: relative; display: block; flex: none; width: var(--mk, 8px); height: var(--mk, 8px); border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--ex-dot); }
.is-end .mk { border-radius: 1.5px; transform: rotate(45deg) scale(.88); }
.is-seen .mk { background: var(--ex-req); box-shadow: none; }
.is-now .mk { background: var(--ex-req); box-shadow: 0 0 0 3px var(--ex-glow); }
.is-stop .mk { box-shadow: none; background: transparent; }
.is-stop .mk::after {
  content: ""; position: absolute; inset: -4px; background: var(--ex-fixed);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.5 21V4M5.5 4.5h11l-2.2 4 2.2 4h-11'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.5 21V4M5.5 4.5h11l-2.2 4 2.2 4h-11'/%3E%3C/svg%3E") center / contain no-repeat;
}
/* a gauge: a thin rounded bar filled from the left by --p (a chapter among chapters, a lab among labs) */
.gauge { display: block; flex: none; width: var(--gw, 22px); height: var(--gh, 4px); border-radius: 999px; background: var(--ex-track); }
.gauge.done { background: var(--ex-req); }
.gauge[style] { background: linear-gradient(to right, var(--ex-req) calc(var(--p) * 100%), var(--ex-track) 0); }
/* a chapter among chapters in the bar's strip: its dot fills like a pie as its cards are seen */
.yah-mark.is-part i { background: conic-gradient(var(--ex-req) calc(var(--p) * 360deg), transparent 0); box-shadow: inset 0 0 0 1.5px var(--ex-req); }
/* the bar's strip: dots, then the count */
.yah-strip { display: flex; flex-wrap: nowrap; align-items: center; column-gap: 12px; min-width: 0; }
.yah-count { flex: none; }
.yah-count { font-size: var(--fs-small); font-weight: 600; color: var(--ex-ink-2); font-variant-numeric: tabular-nums; }
.yah-no svg { width: 26px; height: 26px; display: block; color: var(--ex-req-ink); }
button.yah-mark { padding: 0; border: 0; background: none; cursor: pointer; font: inherit; }

/* the rail: the hall directory, a quiet white column (charcoal at night). The book on top with its count and one thin bar
   per part; the chapters as pill rows with a round number chip and cards seen of total; the open chapter's cards as dots,
   its cheat sheet and quiz. Here is a light blue pill with blue words, like the header's current link. */
.ex-world .sidebar { padding: 0 0 40px; background: var(--bg); border-right: 1px solid var(--border); }
.rail-head { padding: 18px 16px 16px; border-bottom: 1px solid var(--ex-hair); }
.rail-book { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.rail-name { font-size: 22px; font-weight: 800; line-height: 1.1; letter-spacing: -0.025em; color: var(--ex-ink); }
.rail-toggle { display: inline-grid; place-items: center; flex: none; width: max(34px, var(--tap)); height: max(34px, var(--tap)); margin: -4px -6px -4px 0; border: 0; border-radius: 10px; background: transparent; color: var(--ex-ink-2); cursor: pointer; }
.rail-toggle:hover { background: var(--ex-hover); color: var(--ex-ink); }
.rail-toggle svg { width: 19px; height: 19px; }
.rail-count { margin: 6px 0 10px; font-size: var(--fs-small); color: var(--ex-ink-2); font-variant-numeric: tabular-nums; }
.rail-count b { color: var(--ex-ink); font-weight: 800; }
/* the book's progress: one thin rounded bar per part, as long as its share of the book's exhibits; a chapter's stretch of it
   (as long as its own share) fills with blue as its cards are seen. Legible at 224 exhibits: never a mark per exhibit */
.rail-gauges { display: flex; gap: 0 6px; height: 6px; }
.rg-part { display: flex; flex: var(--n, 1) 1 0; min-width: 0; border-radius: 999px; overflow: hidden; background: var(--ex-track); }
.rail-gauges .gauge { flex: var(--c, 1) 1 0; width: auto; min-width: 2px; height: 6px; border-radius: 0; background: var(--ex-track); }
.rail-gauges .gauge.done { background: var(--ex-req); }
.rail-gauges .gauge[style*="--p"] { background: linear-gradient(to right, var(--ex-req) calc(var(--p) * 100%), var(--ex-track) 0); }
.rail-links { padding: 10px 10px 0; }
.rail-link {
  display: flex; align-items: center; gap: 10px; min-height: 36px; padding: 6px 12px; border-radius: 999px;
  font-size: var(--fs-ui); font-weight: 600; line-height: 1.3; color: var(--ex-ink-2);
}
.rail-link:hover { background: var(--ex-hover); color: var(--ex-ink); text-decoration: none; }
.rail-link.is-open { color: var(--ex-ink); }
.rail-link.is-here, .rail-link.is-here:hover { background: var(--ex-wash); color: var(--ex-req-ink); }
.rail-ic { display: grid; flex: none; }
.rail-ic svg { width: 18px; height: 18px; }
.rail-link .t { flex: 1; min-width: 0; }
.rail-note { margin-left: auto; padding-left: 8px; font-size: var(--fs-micro); font-weight: 600; color: var(--ex-ink-3); font-variant-numeric: tabular-nums; white-space: nowrap; }
.is-here .rail-note, .is-now .rail-note { color: inherit; }
.rail-part { padding: 18px 10px 0; }
.rail-part-t { margin: 0 12px 6px; font-size: var(--fs-micro); font-weight: 700; line-height: 1.3; color: var(--ex-ink-3); }
.rail-part-t .rp-no { color: var(--ex-ink-2); }
.rail-ch {
  display: grid; grid-template-columns: 24px minmax(0, 1fr) auto; gap: 10px; align-items: center; min-height: 36px; padding: 6px 10px 6px 8px; border-radius: 18px;
  font-size: var(--fs-ui); line-height: 1.3; color: var(--ex-ink-2);
}
.rail-ch:hover { background: var(--ex-hover); color: var(--ex-ink); text-decoration: none; }
.rail-ch.is-open { color: var(--ex-ink); font-weight: 700; }
.rail-no {
  display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; border: 1px solid var(--ex-line); background: var(--ex-chip); color: var(--ex-ink-2);
  font-size: 12px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums;
}
.rail-ch.is-open .rail-no { background: var(--ex-btn); border-color: var(--ex-btn); color: var(--ex-on-btn); }
.rail-prog { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-micro); font-weight: 600; color: var(--ex-ink-3); font-variant-numeric: tabular-nums; white-space: nowrap; }
.rail-prog .gauge { --gw: 18px; }
.rail-cards { list-style: none; margin: 2px 0 4px 10px; padding: 0; }
.rail-ends { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--ex-hair); }
.rail-card {
  display: grid; grid-template-columns: 10px 20px minmax(0, 1fr) auto; column-gap: 8px; align-items: start; padding: 6px 10px; border-radius: 14px;
  font-size: 13.5px; line-height: 1.35; color: var(--ex-ink-2); --mk: 7px;
}
.rail-card .mk { margin: 5px 0 0 1px; }
.rail-card .n { font-weight: 700; color: var(--ex-ink-3); font-variant-numeric: tabular-nums; text-align: right; }
/* the cheat sheet and the quiz take the contents page's drawn icons in the number's place */
.rail-card .n.is-ic { display: grid; place-items: center end; height: 19px; }
.rail-card .n.is-ic svg { width: 15px; height: 15px; }
.rail-card:hover { background: var(--ex-hover); color: var(--ex-ink); text-decoration: none; }
.rail-card.is-now, .rail-card.is-now:hover { background: var(--ex-wash); color: var(--ex-req-ink); font-weight: 650; }
.rail-card.is-now .n { color: inherit; }
.rail-card.is-stop .t { color: var(--ex-ink); }
@media (pointer: coarse) {
  .rail-link, .rail-ch { min-height: var(--tap); }
  .rail-card { min-height: var(--tap); align-items: center; }
  .rail-card .mk, .rail-card .n { margin-top: 0; }
}
/* on a wide screen the rail can close so the exhibit takes the width; the menu button in the header opens it again */
@media (min-width: 901px) {
  body.rail-collapsed .layout { grid-template-columns: 0 minmax(0, 1fr); }
  body.rail-collapsed .sidebar { visibility: hidden; overflow: hidden; border-right: 0; }
  body.rail-collapsed .menu-btn { display: inline-grid; }
}
@media (max-width: 900px) {
  .rail-toggle { display: none; }
  /* the drawer fills the screen under the header (a fit-content height ran past the bottom on a long chapter) */
  .ex-world .sidebar { align-self: stretch; height: calc(100vh - var(--topbar-h)); height: calc(100dvh - var(--topbar-h)); }
}

/* the contents: the book as a hall directory; "where you stopped" is a frosted panel with the one filled blue pill */
.home-hero { display: grid; grid-template-columns: minmax(0, 1fr) var(--ex-label-w); gap: 24px 48px; align-items: start; padding: 4px 0 0; }
.home-hero .lede { margin-top: 14px; }
.home-go { padding: 16px 18px 18px; }
.go-where { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 14px; align-items: center; margin: 2px 0 14px; }
.go-no { min-width: 58px; height: 48px; padding: 0 12px; border-radius: 14px; font-size: 22px; background: var(--ex-chip); }
.go-where p { display: flex; flex-direction: column; gap: 1px; margin: 0; line-height: 1.3; }
.go-where b { font-size: var(--fs-body); font-weight: 700; color: var(--ex-ink); }
.go-where p span { font-size: var(--fs-small); color: var(--ex-ink-3); }
.go-btn { width: 100%; min-height: 48px; font-size: var(--fs-body); }
.go-count { margin: 10px 0 0; font-size: var(--fs-small); color: var(--ex-ink-3); font-variant-numeric: tabular-nums; }
.go-count b { color: var(--ex-ink); font-weight: 800; }
.ex-world .home-sec { margin-top: 48px; }
.ex-world .home-sec > h2 { font-size: 30px; font-weight: 800; letter-spacing: -0.025em; }
.contents-part { margin-top: 24px; }
.contents-part-t {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; padding: 10px 0 8px; border-bottom: 1px solid var(--ex-hair);
  font-size: var(--fs-body-s); font-weight: 700; letter-spacing: -0.005em; color: var(--ex-ink);
}
.cp-no { color: var(--ex-ink-3); font-weight: 600; }
.cp-t { color: var(--ex-ink); }
.cp-n { margin-left: auto; font-size: var(--fs-small); font-weight: 600; color: var(--ex-ink-3); font-variant-numeric: tabular-nums; }
.contents-list { list-style: none; margin: 0; padding: 0; }
.hall-row {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr) 236px 164px; gap: 8px 20px; align-items: center;
  margin: 0; padding: 12px 10px; border-bottom: 1px solid var(--ex-hair); --mk: 7px;
}
.hall-row:not(.planned):hover { background: var(--ex-hover); }
.hall-main { display: grid; grid-template-columns: 40px minmax(0, 1fr); gap: 14px; align-items: center; color: var(--ex-ink); }
.hall-main:hover { color: var(--ex-ink); text-decoration: none; }
/* the whole row opens the chapter; the cheat sheet and quiz links sit above that */
a.hall-main::after { content: ""; position: absolute; inset: 0; }
.hall-no {
  display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--ex-line); background: var(--ex-chip); color: var(--ex-ink);
  font-size: 16px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; box-shadow: 0 2px 6px -4px rgba(20, 40, 100, .3);
}
.hall-row.is-done .hall-no { border: 2px solid var(--ex-fixed); color: var(--ex-fixed); }
.hall-t { display: flex; flex-direction: column; min-width: 0; }
.hall-name { font-size: 17px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.3; color: var(--ex-ink); }
.hall-row:not(.planned):hover .hall-name { color: var(--ex-req-ink); }
.hall-tag { font-size: var(--fs-ui); color: var(--ex-ink-2); }
.hall-next { margin-top: 2px; font-size: var(--fs-small); color: var(--ex-ink-3); }
.hall-prog { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.hall-marks { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; min-height: 8px; }
.hall-marks .gauge { --gw: 100%; flex: 1 1 auto; }
.hall-m { display: block; }
.hall-count { display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-small); font-weight: 600; color: var(--ex-ink-3); font-variant-numeric: tabular-nums; }
.hall-count svg { width: 14px; height: 14px; color: var(--ex-fixed); }
.hall-ex { position: relative; z-index: 1; display: flex; flex-direction: column; gap: 4px; }
.hall-x {
  display: flex; align-items: center; gap: 8px; min-height: 32px; padding: 0 12px 0 4px; border: 1px solid var(--ex-line); border-radius: 999px; background: var(--ex-chip);
  font-size: var(--fs-small); font-weight: 650; color: var(--ex-ink);
}
.hall-x:hover { border-color: var(--ex-req); color: var(--ex-req-ink); text-decoration: none; }
.hall-xn { display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--ex-wash); color: var(--ex-req-ink); }
.hall-xn svg { width: 14px; height: 14px; }
.hall-best { margin-left: auto; font-weight: 600; color: var(--ex-ink-3); font-variant-numeric: tabular-nums; }
.hall-x:hover .hall-best { color: inherit; }
.hall-row.planned { color: var(--ex-ink-3); }
.hall-row.planned .hall-no { border-style: dashed; color: var(--ex-ink-3); box-shadow: none; }
.hall-row.planned .hall-name { color: var(--ex-ink-3); }
.hall-row.planned .hall-count { grid-column: auto; }
.lab-entry { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 28px; margin-top: 16px; padding: 16px 18px; }
.lab-names { display: flex; flex-wrap: wrap; gap: 4px 20px; margin: 0; padding: 0; list-style: none; font-size: var(--fs-ui); font-weight: 600; }
.lab-names a { display: inline-flex; align-items: center; min-height: 32px; color: var(--ex-ink); text-decoration: underline; text-decoration-color: var(--ex-line-hover); text-decoration-thickness: 1px; text-underline-offset: 3px; }
.lab-names a:hover { color: var(--ex-req-ink); text-decoration-color: currentColor; }
@media (max-width: 1100px) {
  .hall-row { grid-template-columns: minmax(0, 1fr) auto; }
  .hall-main { grid-column: 1 / -1; }
  .hall-ex { flex-direction: row; justify-self: end; }
  .home-hero { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
  .home-hero { gap: 18px; }
  .ex-world .home-sec > h2 { font-size: 26px; }
  .home-go { margin: 0 -10px; }
  .hall-row { grid-template-columns: minmax(0, 1fr); }
  .hall-ex { justify-self: stretch; }
  .hall-x { flex: 1; }
  .lab-entry { margin: 16px -10px 0; }
  .cp-n { margin-left: 0; flex-basis: 100%; }
}
@media (pointer: coarse) {
  .hall-x, .lab-names a, .go-btn { min-height: var(--tap); }
}

/* the pager: a frosted panel with the chip of the number it leads to */
.pg-row { display: flex; align-items: center; gap: 10px; min-width: 0; }
.pager-link.next .pg-row { flex-direction: row-reverse; }
.pg-no { flex: none; min-width: 44px; height: 28px; padding: 0 8px; border-radius: 999px; font-size: 14px; background: var(--ex-chip); }
@media (max-width: 640px) {
  .pager-link .pg-row { gap: 8px; }
  .pg-no { min-width: 36px; height: 26px; font-size: 13px; }
}

/* a cheat sheet: a frosted sheet, each term in sentence case over its line, the exhibit that draws it as a chip on the right */
.cheat-sheet { margin-top: 28px; padding: 2px 22px; }
.cheat { gap: 0 48px; margin: 0; }
.cheat-item { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 3px 14px; align-content: start; padding: 14px 0 16px; border-top: 0; border-bottom: 1px solid var(--ex-hair); }
.cheat-item dt { grid-column: 1; font-size: var(--fs-body); font-weight: 700; letter-spacing: -0.01em; line-height: 1.35; color: var(--ex-ink); }
.cheat-item dd { grid-column: 1; margin: 0; font-size: var(--fs-body-s); line-height: 1.55; color: var(--ex-ink-2); }
.cheat-link {
  grid-column: 2; grid-row: 1 / span 2; align-self: start; display: grid; place-items: center; min-width: 44px; height: 28px; margin: 0; padding: 0 10px;
  border: 1px solid var(--ex-line); border-radius: 999px; background: var(--ex-chip); color: var(--ex-req-ink); box-shadow: 0 2px 6px -4px rgba(20, 40, 100, .3);
  font-size: var(--fs-small); font-weight: 800; font-variant-numeric: tabular-nums;
}
.cheat-link:hover { border-color: var(--ex-req); background: linear-gradient(var(--ex-wash), var(--ex-wash)), var(--ex-chip); text-decoration: none; }
@media (pointer: coarse) { .cheat-link { min-height: var(--tap); min-width: var(--tap); } }
@media (max-width: 640px) {
  .cheat-sheet { margin-left: -10px; margin-right: -10px; padding: 0 16px; }
}

/* a quiz: a frosted panel, one question at a time, the questions as round chips; the options are large pill rows and right
   and wrong are a real check (a tick and a cross as well as teal and red), apart from the cards' scenario controls */
.ex-world .quiz { margin-top: 28px; padding: 16px 22px 24px; }
.quiz-progress { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px; padding-bottom: 14px; border-bottom: 1px solid var(--ex-hair); }
.quiz-bars { gap: 6px; }
.quiz-bars i {
  display: grid; place-items: center; width: 28px; height: 28px; border: 1.5px solid var(--ex-line); border-radius: 50%; background: var(--ex-chip);
  font-size: var(--fs-small); font-weight: 800; font-style: normal; line-height: 1; color: var(--ex-ink-2); font-variant-numeric: tabular-nums;
}
.quiz-bars i svg { width: 15px; height: 15px; stroke-width: 3; }
.quiz-bars i.cur { border: 2px solid var(--ex-req); background: var(--ex-chip); color: var(--ex-req-ink); box-shadow: 0 0 0 4px var(--ex-glow); }
.quiz-bars i.ok { background: var(--ex-fixed); border-color: var(--ex-fixed); color: var(--ex-on-fixed); }
.quiz-bars i.no { background: var(--ex-fault-fill); border-color: var(--ex-fault-fill); color: var(--ex-on-fault); }
.quiz-count { font-size: var(--fs-ui); font-weight: 700; color: var(--ex-ink-2); }
.quiz-q { margin-top: 18px; font-size: 22px; font-weight: 700; line-height: 1.35; color: var(--ex-ink); }
.quiz-opts { gap: 8px; }
.quiz-opt {
  align-items: center; min-height: 52px; padding: 9px 18px 9px 10px; border: 1px solid var(--ex-line); border-radius: 26px; background: var(--ex-chip); color: var(--ex-ink);
  box-shadow: 0 2px 8px -6px rgba(20, 40, 100, .3);
}
.quiz-opt:hover:not([disabled]) { border-color: var(--ex-req); background: linear-gradient(var(--ex-wash), var(--ex-wash)), var(--ex-chip); }
.quiz-opt .letter { width: 30px; height: 30px; border: 1px solid var(--ex-line); border-radius: 50%; background: transparent; color: var(--ex-ink-2); font-size: var(--fs-small); font-weight: 800; }
.quiz-opt .tick { display: grid; margin-left: auto; flex: none; }
.quiz-opt .tick svg { width: 18px; height: 18px; stroke-width: 3; }
.quiz-opt[disabled]:not(.right):not(.wrong) { opacity: .5; }
.quiz-opt.right { border: 2px solid var(--ex-fixed); background: color-mix(in srgb, var(--ex-fixed) 9%, var(--ex-chip)); color: var(--ex-ink); }
.quiz-opt.right .tick { color: var(--ex-fixed); }
.quiz-opt.right .letter { background: var(--ex-fixed); border-color: var(--ex-fixed); color: var(--ex-on-fixed); }
.quiz-opt.wrong { border: 2px solid var(--ex-fault); background: color-mix(in srgb, var(--ex-fault) 8%, var(--ex-chip)); color: var(--ex-ink); }
.quiz-opt.wrong .tick { color: var(--ex-fault); }
.quiz-opt.wrong .letter { background: var(--ex-fault-fill); border-color: var(--ex-fault-fill); color: var(--ex-on-fault); }
.quiz-why { border-radius: 14px; }
.quiz-why.k-good { border: 1px solid color-mix(in srgb, var(--ex-fixed) 40%, transparent); }
.quiz-why.k-bad { border: 1px solid color-mix(in srgb, var(--ex-fault) 40%, transparent); }
.quiz-score .quiz-total { font-size: 44px; font-weight: 800; line-height: 1; letter-spacing: -0.03em; }
.quiz-score.k-neutral .quiz-total { color: var(--ex-ink); }
.quiz-score .big { color: var(--ex-ink-2); }
.quiz-review { border-top-color: var(--ex-hair); }
.quiz-review li { border-bottom-color: var(--ex-hair); }
.quiz-review .mark { width: 24px; height: 24px; border-radius: 50%; }
.quiz-review li.ok .mark { background: var(--ex-fixed); color: var(--ex-on-fixed); }
.quiz-review li.no .mark { background: var(--ex-fault-fill); color: var(--ex-on-fault); }
@media (max-width: 640px) {
  .ex-world .quiz { margin-left: -10px; margin-right: -10px; padding: 14px 16px 22px; border-radius: 14px; }
  .quiz-q { font-size: 20px; }
}

/* concepts: a row of jump pills to the areas, then the areas as rows of concepts (an area's head on the left, its concepts on hairlines under one another) */
.concept-jump { display: flex; flex-wrap: wrap; gap: 6px; margin: 22px 0 0; padding: 0; list-style: none; }
.concept-jump button {
  display: inline-flex; align-items: center; min-height: 36px; padding: 6px 14px; border: 1px solid var(--ex-line); border-radius: 999px; background: var(--ex-chip); color: var(--ex-ink-2);
  font: inherit; font-size: var(--fs-ui); font-weight: 600; line-height: 1.2; cursor: pointer; transition: border-color .15s, color .15s;
}
.concept-jump button:hover { border-color: var(--ex-line-hover); color: var(--ex-ink); }
@media (pointer: coarse) { .concept-jump button { min-height: var(--tap); } }
.ex-world .concept-area { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 0 32px; align-items: start; margin-top: 40px; }
.ex-world .concept-area > h2 { padding-top: 12px; border-top: 1px solid var(--ex-hair); font-size: 18px; font-weight: 750; letter-spacing: -0.015em; line-height: 1.25; }
.concept-n { display: block; margin-top: 4px; font-size: var(--fs-small); font-weight: 600; letter-spacing: 0; color: var(--ex-ink-3); }
.ex-world .concept-list { display: block; border-top: 1px solid var(--ex-hair); }
.ex-world .concept-row {
  display: grid; grid-template-columns: minmax(130px, 200px) minmax(0, 1fr) auto; gap: 2px 20px; align-items: baseline; height: auto;
  margin: 0; padding: 12px 10px; border: 0; border-bottom: 1px solid var(--ex-hair); border-radius: 0; background: none; color: var(--ex-ink);
}
.ex-world .concept-row:hover { border-color: var(--ex-hair); background: var(--ex-hover); color: var(--ex-ink); }
.ex-world .concept-row:hover .concept-name { color: var(--ex-req-ink); }
.ex-world .concept-name { font-size: var(--fs-body); font-weight: 700; }
.ex-world .concept-line { font-size: var(--fs-ui); color: var(--ex-ink-2); }
.ex-world .concept-books { margin: 0; font-size: var(--fs-micro); font-weight: 600; color: var(--ex-ink-3); white-space: nowrap; }
/* a card on a concept lesson: its exhibit number in its own book, as a chip, then where it lives */
.cc-meta { gap: 4px 10px; margin-top: 12px; color: var(--ex-ink-3); }
.cc-no { display: inline-grid; min-height: 28px; padding: 0 12px; border-radius: 999px; font-size: var(--fs-small); background: var(--ex-chip); }
.cc-meta a { color: var(--ex-ink); font-weight: 600; text-decoration: underline; text-decoration-color: var(--ex-line-hover); text-underline-offset: 3px; text-decoration-thickness: 1px; }
.cc-meta a:hover { color: var(--ex-req-ink); text-decoration-color: currentColor; }
.ex-world .concept-card + .concept-card { border-top-color: var(--ex-hair); }
@media (max-width: 900px) {
  .ex-world .concept-area { grid-template-columns: minmax(0, 1fr); }
  .ex-world .concept-area > h2 { margin-bottom: 0; }
  .ex-world .concept-list { border-top: 0; }
  .ex-world .concept-row { grid-template-columns: minmax(0, 1fr); padding-inline: 0; }
}

/* ---------- viz kit ---------- */
.vz { display: flex; flex-direction: column; gap: 14px; }
.vz-controls { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.vz-btn {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: var(--tap); padding: 0 14px; border-radius: 999px;
  border: 1px solid var(--border-strong); background: var(--surface);
  font-size: var(--fs-ui); font-weight: 600; cursor: pointer; color: var(--text); white-space: nowrap;
  transition: background .15s, border-color .15s, color .15s, opacity .15s, transform .08s;
}
.vz-btn:hover { background: var(--surface-2); }
.vz-btn:active { transform: scale(.97); }
.vz-btn[disabled] { opacity: .42; cursor: default; }
.vz-btn[disabled]:hover { background: var(--surface); }
.vz-btn.primary { background: var(--link); border-color: var(--link); color: var(--on-accent); }
.vz-btn.primary:hover { background: var(--link-hover); border-color: var(--link-hover); }
.vz-btn.primary[disabled]:hover { background: var(--link); }
.vz-btn.danger { border-color: color-mix(in srgb, var(--k-bad-s) 50%, transparent); color: var(--k-bad-i); background: var(--k-bad-f); }
.vz-btn.danger:hover { border-color: var(--k-bad-s); background: var(--k-bad-f); }
.vz-btn.good { border-color: color-mix(in srgb, var(--k-good-s) 50%, transparent); color: var(--k-good-i); background: var(--k-good-f); }
.vz-btn.ghost { border-color: transparent; background: transparent; color: var(--text-2); }
.vz-btn.ghost:hover { background: var(--surface-2); color: var(--text); }
.vz-btn .ic { display: inline-grid; place-items: center; line-height: 1; }
.vz-btn .ic svg, .lab-textbtn .ic svg { width: 15px; height: 15px; }
.vz-btn.icon-only { padding: 0; width: var(--tap); justify-content: center; }
.ic.flip svg { transform: scaleX(-1); }
.vz-icon { display: block; flex: none; }

.vz-seg { display: inline-flex; padding: 3px; border-radius: 999px; background: var(--surface-2); gap: 2px; flex-wrap: wrap; max-width: 100%; }
.vz-seg button {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-width: 34px;
  border: 0; background: transparent; padding: 0 12px; min-height: calc(var(--tap) - 6px); border-radius: 999px; cursor: pointer;
  font-size: var(--fs-ui); font-weight: 600; color: var(--text-2); white-space: nowrap;
  transition: background .15s, color .15s, box-shadow .15s;
}
.vz-seg button:hover:not(.on):not([disabled]) { color: var(--text); }
.vz-seg button.on { background: var(--surface); color: var(--link); box-shadow: var(--shadow-sm), 0 0 0 1px var(--border); }
.vz-seg button[disabled] { opacity: .4; cursor: default; }
.vz-seg button[class*="k-"]::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--k-neutral-s); }
.vz-seg button.k-bad::before { background: var(--k-bad-s); }
.vz-seg button.k-good::before { background: var(--k-good-s); }
.vz-seg button.k-warn::before { background: var(--k-warn-s); }
.vz-seg button.k-info::before { background: var(--k-info-s); }
.vz-seg button.k-primary::before { background: var(--k-primary-s); }
.vz-seg button.k-data::before { background: var(--k-data-s); }
.vz-seg button.on.k-bad { color: var(--k-bad-i); }
.vz-seg button.on.k-good { color: var(--k-good-i); }

.vz-slider { display: flex; align-items: center; gap: 10px; font-size: var(--fs-ui); color: var(--text-2); font-weight: 600; flex-wrap: wrap; }
.vz-slider input { flex: 1; min-width: 120px; accent-color: var(--link); }
.vz-slider output { font-family: var(--font-mono); font-weight: 600; color: var(--text); min-width: 3ch; }

.vz-toggle { display: inline-flex; align-items: center; gap: 8px; min-height: var(--tap); font-size: var(--fs-ui); font-weight: 600; cursor: pointer; user-select: none; color: var(--text-2); }
.vz-toggle input { position: absolute; opacity: 0; pointer-events: none; }
.vz-toggle .sw { width: 36px; height: 20px; border-radius: 10px; background: var(--surface-3); position: relative; transition: background .2s; flex: none; }
.vz-toggle .sw::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(16, 24, 40, .3); transition: transform .2s var(--ease-out); }
.vz-toggle input:checked + .sw { background: var(--link); }
.vz-toggle input:checked + .sw::after { transform: translateX(16px); }
.vz-toggle input:focus-visible + .sw { outline: var(--focus-ring); outline-offset: 2px; }

.vz-svg-wrap { display: flex; justify-content: center; }
.vz-svg { display: block; width: 100%; height: auto; max-width: 720px; overflow: visible; font-family: var(--font-diagram); }
/* a drawing that cannot show its text at a legible size on a phone scrolls sideways inside its frame (js/viz.js fitPhone). The cue
   is the line under the drawing, outside the picture: a chevron at each end where the drawing continues (a tap moves it most of
   a screen) and the words until the reader has slid it; nothing is laid over the drawing */
.vz-pan { display: none; align-items: center; justify-content: space-between; gap: 6px; margin: 0; font-size: var(--fs-ui); font-weight: 650; color: var(--ex-ink-2, var(--text-2)); }
.vz-pan svg { width: 16px; height: 16px; }
.vz-pan-t { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-width: 0; text-align: center; }
.vz-pan-btn { display: none; }
@media (max-width: 640px) {
  .ex-world .vz-svg-wrap { justify-content: flex-start; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
  .ex-world .vz-svg-wrap::-webkit-scrollbar { display: none; }
  .ex-world .vz-svg-wrap > .vz-svg { flex: none; margin-inline: auto; }
  .ex-world .vz-svg-wrap[data-more] { -webkit-mask-image: none; mask-image: none; }
  .ex-world .vz-svg-wrap[data-more] + .vz-pan { display: flex; }
  .ex-world .vz-svg-wrap[data-panned] + .vz-pan .vz-pan-t { visibility: hidden; }
  .ex-world .vz-svg-wrap:is([data-more="right"], [data-more="both"]) + .vz-pan .vz-pan-r,
  .ex-world .vz-svg-wrap:is([data-more="left"], [data-more="both"]) + .vz-pan .vz-pan-l { visibility: visible; }
  /* an end with nothing beyond it keeps its width unseen, so the words stay centred and the line does not jump */
  .ex-world .vz-pan-btn {
    display: grid; visibility: hidden; flex: none; place-items: center; width: 32px; height: 32px; padding: 0; cursor: pointer;
    border: 1px solid var(--gl-tag-edge); border-radius: 50%; background: var(--gl-tag-bg); color: var(--gl-ink); box-shadow: 0 4px 12px -6px rgba(20, 40, 100, .4);
    -webkit-backdrop-filter: blur(12px) saturate(160%); backdrop-filter: blur(12px) saturate(160%);
  }
  .ex-world .vz-pan-l { order: -1; }
  .ex-world .vz-pan-l svg { transform: scaleX(-1); }
  .ex-world .vz-pan-btn svg { width: 18px; height: 18px; stroke-width: 2.5; }
  .ex-world .vz-pan-btn:active { background: var(--gl-tip-edge); }
}
.vz-svg text { font-family: var(--font-diagram); }
.vz-node { transition: opacity .3s; }
.vz-node .vz-shape { stroke-width: 1.75; }
.vz-node .vz-label { font-size: 15px; font-weight: 600; text-anchor: middle; dominant-baseline: middle; }
.vz-node .vz-sub { font-size: 12px; text-anchor: middle; dominant-baseline: middle; opacity: .85; }
.vz-node.mono .vz-label, .vz-node.mono .vz-sub { font-family: var(--font-mono); }
.vz-node.dim { opacity: .3; }
.vz-node.is-down .vz-shape { stroke-dasharray: 5 4; }
.vz-node.is-down { opacity: .55; }
.vz-node .vz-badge-c { stroke-width: 1.5; }
/* role icons inside nodes: the node's own stroke colour, a touch lighter than the label */
.vz-node .vz-role { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; stroke: var(--k-neutral-s); }
.vz-node.k-primary .vz-role { stroke: var(--k-primary-s); }
.vz-node.k-good .vz-role { stroke: var(--k-good-s); }
.vz-node.k-bad .vz-role { stroke: var(--k-bad-s); }
.vz-node.k-warn .vz-role { stroke: var(--k-warn-s); }
.vz-node.k-info .vz-role { stroke: var(--k-info-s); }
.vz-node.k-data .vz-role { stroke: var(--k-data-s); }
.vz-node.k-ghost .vz-role { stroke: var(--k-ghost-s); }
.vz-node .vz-badge-t { font-size: 12px; font-weight: 700; text-anchor: middle; dominant-baseline: central; font-family: var(--font-mono); }
.vz-flash { animation: vz-flash .7s ease; }
@keyframes vz-flash { 0% { filter: none; } 30% { filter: brightness(1.15) saturate(1.2); } 100% { filter: none; } }

.vz-link { stroke-width: 1.75; fill: none; transition: stroke .3s, opacity .3s; }
.vz-link.dashed { stroke-dasharray: 6 5; }
.vz-link.dotted { stroke-dasharray: 2 5; stroke-linecap: round; }
.vz-link.thin { stroke-width: 1.3; }
.vz-link.thick { stroke-width: 3; }
.vz-link-label, .vz-halo { paint-order: stroke; stroke: var(--surface); stroke-width: 5px; stroke-linejoin: round; }
.vz-link-label { font-size: 12.5px; font-weight: 600; text-anchor: middle; dominant-baseline: middle; }
.vz-marker { stroke: none; }

.vz-packet rect, .vz-packet circle { stroke-width: 1.5; }
.vz-packet text { font-size: 12px; font-weight: 700; font-family: var(--font-mono); text-anchor: middle; dominant-baseline: central; }
.vz-box rect { fill: none; stroke-width: 1.5; stroke-dasharray: 6 5; }
.vz-box.solid rect { stroke-dasharray: none; }
.vz-box.filled rect { stroke-dasharray: none; fill-opacity: .45; }
.vz-box text { font-size: 12.5px; font-weight: 600; }
.vz-text { dominant-baseline: middle; }
.vz-text.mono { font-family: var(--font-mono) !important; }

/* kind colors for svg */
.k-neutral .vz-shape, .vz-shape.k-neutral, .vz-packet.k-neutral .vz-shape { fill: var(--k-neutral-f); stroke: var(--k-neutral-s); }
.k-primary .vz-shape, .vz-shape.k-primary, .vz-packet.k-primary .vz-shape { fill: var(--k-primary-f); stroke: var(--k-primary-s); }
.k-good .vz-shape, .vz-shape.k-good, .vz-packet.k-good .vz-shape { fill: var(--k-good-f); stroke: var(--k-good-s); }
.k-bad .vz-shape, .vz-shape.k-bad, .vz-packet.k-bad .vz-shape { fill: var(--k-bad-f); stroke: var(--k-bad-s); }
.k-warn .vz-shape, .vz-shape.k-warn, .vz-packet.k-warn .vz-shape { fill: var(--k-warn-f); stroke: var(--k-warn-s); }
.k-info .vz-shape, .vz-shape.k-info, .vz-packet.k-info .vz-shape { fill: var(--k-info-f); stroke: var(--k-info-s); }
.k-data .vz-shape, .vz-shape.k-data, .vz-packet.k-data .vz-shape { fill: var(--k-data-f); stroke: var(--k-data-s); }
.k-ghost .vz-shape, .vz-shape.k-ghost, .vz-packet.k-ghost .vz-shape { fill: var(--surface); stroke: var(--k-ghost-s); stroke-dasharray: 5 4; }
.k-neutral .vz-ink, .vz-ink.k-neutral { fill: var(--k-neutral-i); }
.k-primary .vz-ink, .vz-ink.k-primary { fill: var(--k-primary-i); }
.k-good .vz-ink, .vz-ink.k-good { fill: var(--k-good-i); }
.k-bad .vz-ink, .vz-ink.k-bad { fill: var(--k-bad-i); }
.k-warn .vz-ink, .vz-ink.k-warn { fill: var(--k-warn-i); }
.k-info .vz-ink, .vz-ink.k-info { fill: var(--k-info-i); }
.k-data .vz-ink, .vz-ink.k-data { fill: var(--k-data-i); }
.k-ghost .vz-ink, .vz-ink.k-ghost { fill: var(--k-ghost-i); }
.vz-ink.k-muted { fill: var(--text-3); }
.vz-ink.k-text { fill: var(--text); }
.vz-ink.k-text2 { fill: var(--text-2); }
.vz-ink.k-accent { fill: var(--link); }
.vz-stroke.k-neutral { stroke: var(--k-neutral-s); } .vz-marker.k-neutral { fill: var(--k-neutral-s); }
.vz-stroke.k-primary { stroke: var(--k-primary-s); } .vz-marker.k-primary { fill: var(--k-primary-s); }
.vz-stroke.k-good { stroke: var(--k-good-s); } .vz-marker.k-good { fill: var(--k-good-s); }
.vz-stroke.k-bad { stroke: var(--k-bad-s); } .vz-marker.k-bad { fill: var(--k-bad-s); }
.vz-stroke.k-warn { stroke: var(--k-warn-s); } .vz-marker.k-warn { fill: var(--k-warn-s); }
.vz-stroke.k-info { stroke: var(--k-info-s); } .vz-marker.k-info { fill: var(--k-info-s); }
.vz-stroke.k-data { stroke: var(--k-data-s); } .vz-marker.k-data { fill: var(--k-data-s); }
.vz-stroke.k-ghost { stroke: var(--k-ghost-s); } .vz-marker.k-ghost { fill: var(--k-ghost-s); }
.vz-stroke.k-muted { stroke: var(--text-3); } .vz-marker.k-muted { fill: var(--text-3); }
.vz-stroke.k-accent { stroke: var(--link); } .vz-marker.k-accent { fill: var(--link); }

/* html pieces */
.vz-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.vz-row.center { justify-content: center; }
.vz-grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--min, 220px)), 1fr)); }
.vz-panel { border: 1px solid var(--border); border-radius: 12px; padding: 12px 14px; background: var(--surface); min-width: 0; }
.vz-panel-title { font-size: var(--fs-small); font-weight: 600; color: var(--text-2); margin-bottom: 8px; }
.vz-tape { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.vz-cell {
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  min-width: 34px; min-height: 32px; padding: 3px 8px; border-radius: 8px;
  font-family: var(--font-mono); font-size: 13px; font-weight: 600;
  border: 1.5px solid var(--k-neutral-s); background: var(--k-neutral-f); color: var(--k-neutral-i);
  transition: background .3s, border-color .3s, color .3s, opacity .3s, transform .3s;
}
.vz-cell.sm { min-width: 24px; min-height: 24px; font-size: 11.5px; padding: 1px 5px; border-radius: 6px; }
.vz-cell.k-primary { border-color: var(--k-primary-s); background: var(--k-primary-f); color: var(--k-primary-i); }
.vz-cell.k-good { border-color: var(--k-good-s); background: var(--k-good-f); color: var(--k-good-i); }
.vz-cell.k-bad { border-color: var(--k-bad-s); background: var(--k-bad-f); color: var(--k-bad-i); }
.vz-cell.k-warn { border-color: var(--k-warn-s); background: var(--k-warn-f); color: var(--k-warn-i); }
.vz-cell.k-info { border-color: var(--k-info-s); background: var(--k-info-f); color: var(--k-info-i); }
.vz-cell.k-data { border-color: var(--k-data-s); background: var(--k-data-f); color: var(--k-data-i); }
.vz-cell.k-ghost { border-style: dashed; border-color: var(--k-ghost-s); background: transparent; color: var(--k-ghost-i); }
.vz-cell.dim { opacity: .3; }
.vz-cell.strike { text-decoration: line-through; opacity: .5; }
.vz-cell.pop { animation: vz-pop .4s var(--ease-out); }
@keyframes vz-pop { from { transform: scale(.7); opacity: 0; } to { transform: none; opacity: 1; } }
.vz-arrow { color: var(--text-3); font-weight: 700; }

.vz-caption {
  min-height: 1.5em; font-size: var(--fs-body-s); color: var(--text-2); text-align: center; line-height: 1.5;
  padding: 10px 14px; border-radius: 12px; background: var(--wash);
  transition: background .3s, color .3s;
}
.vz-caption.k-bad { background: var(--k-bad-f); color: var(--k-bad-i); }
.vz-caption.k-good { background: var(--k-good-f); color: var(--k-good-i); }
.vz-caption.k-warn { background: var(--k-warn-f); color: var(--k-warn-i); }
.vz-caption.k-info { background: var(--k-info-f); color: var(--k-info-i); }
.vz-caption.k-primary { background: var(--k-primary-f); color: var(--k-primary-i); }
.vz-caption.fade { animation: vz-fade .35s; }
@keyframes vz-fade { from { opacity: .2; } to { opacity: 1; } }

.vz-log { font-family: var(--font-mono); font-size: 12.5px; display: flex; flex-direction: column; gap: 4px; }
.vz-log-title { font-family: var(--font-body); font-size: var(--fs-small); font-weight: 600; color: var(--text-2); }
.vz-log-line { padding: 5px 10px; border-radius: 8px; background: var(--k-neutral-f); color: var(--k-neutral-i); animation: vz-pop .3s; }
.vz-log-line.k-good { background: var(--k-good-f); color: var(--k-good-i); }
.vz-log-line.k-bad { background: var(--k-bad-f); color: var(--k-bad-i); }
.vz-log-line.k-warn { background: var(--k-warn-f); color: var(--k-warn-i); }
.vz-log-line.k-info { background: var(--k-info-f); color: var(--k-info-i); }
.vz-log-line.k-primary { background: var(--k-primary-f); color: var(--k-primary-i); }
.vz-log-line.k-data { background: var(--k-data-f); color: var(--k-data-i); }

/* ----- trade-off: what each option wins and costs (v.tradeoff) ----- */
/* a section of the sandbox, set off by a hairline: never a card inside the frame */
.vz-tradeoff { display: flex; flex-direction: column; gap: 14px; padding-top: 16px; border-top: 1px solid var(--border); }
.to-title { margin-bottom: -6px; font-size: var(--fs-small); font-weight: 600; color: var(--text-3); }
.to-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; }
.to-pin {
  display: inline-flex; align-items: center; gap: 6px; min-height: var(--tap); padding: 0 14px;
  border: 1px solid var(--border-strong); border-radius: 999px; background: var(--surface);
  font-size: var(--fs-small); font-weight: 600; color: var(--text-2); cursor: pointer; transition: background .15s, border-color .15s, color .15s;
}
.to-pin:hover { background: var(--surface-2); color: var(--text); }
.to-pin.on { border-color: var(--link); background: var(--accent-bg); color: var(--link); }
.to-pin .ic svg { width: 14px; height: 14px; }
.to-meters { display: grid; gap: 12px; }
.to-row { display: grid; grid-template-columns: minmax(120px, 28%) minmax(0, 1fr) minmax(96px, max-content); align-items: center; gap: 6px 14px; }
.to-name { display: flex; flex-direction: column; font-size: var(--fs-ui); font-weight: 600; color: var(--text); line-height: 1.3; }
.to-name small { font-size: var(--fs-micro); font-weight: 400; color: var(--text-3); }
.to-track { position: relative; height: 12px; border-radius: 6px; background: var(--surface-2); }
.to-fill { position: absolute; inset: 0; border-radius: 6px; background: var(--link); clip-path: inset(0 var(--rest, 100%) 0 0 round 6px); transition: clip-path .4s var(--ease-out); }
/* where the other options land; the pinned one in amber */
.to-tick { position: absolute; top: -4px; bottom: -4px; width: 2px; margin-left: -1px; border-radius: 1px; background: var(--text-3); }
.to-tick.pinned { width: 3px; margin-left: -1.5px; background: var(--k-warn-s); }
.to-val { display: flex; flex-direction: column; align-items: flex-end; gap: 1px; font-family: var(--font-mono); font-size: 13px; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.to-delta { font-family: var(--font-body); font-size: var(--fs-micro); font-weight: 600; color: var(--text-3); white-space: nowrap; }
.to-delta.k-good, .to-sum .k-good { color: var(--k-good-i); }
.to-delta.k-bad, .to-sum .k-bad { color: var(--k-bad-i); }
.to-sum { margin: 0; padding-top: 12px; border-top: 1px solid var(--border); font-size: var(--fs-small); line-height: 1.5; color: var(--text-2); }
.to-sum > b { color: var(--text); }

.vz-bars { display: grid; gap: 8px; }
.vz-bar { display: grid; grid-template-columns: minmax(70px, max-content) minmax(0, 1fr) minmax(52px, max-content); gap: 10px; align-items: center; font-size: 14px; }
.vz-bar .lbl { color: var(--text-2); font-weight: 600; }
.vz-bar .track { height: 20px; border-radius: 6px; background: var(--surface-2); overflow: hidden; }
.vz-bar .fill { height: 100%; border-radius: 6px; background: var(--k-neutral-s); clip-path: inset(0 100% 0 0 round 6px); transition: clip-path .5s var(--ease-out); }
.vz-bar .val { font-family: var(--font-mono); font-size: 13px; font-weight: 600; text-align: right; }
.vz-bar.k-primary .fill { background: var(--k-primary-s); }
.vz-bar.k-good .fill { background: var(--k-good-s); }
.vz-bar.k-bad .fill { background: var(--k-bad-s); }
.vz-bar.k-warn .fill { background: var(--k-warn-s); }
.vz-bar.k-info .fill { background: var(--k-info-s); }
.vz-bar.k-data .fill { background: var(--k-data-s); }

.vz-table-wrap { overflow-x: auto; }
.vz-table { border-collapse: separate; border-spacing: 0; width: 100%; font-size: 14px; }
.vz-table th { text-align: left; font-size: var(--fs-small); color: var(--text-2); font-weight: 600; padding: 6px 10px; border-bottom: 1px solid var(--border-strong); }
.vz-table td { padding: 7px 10px; border-bottom: 1px solid var(--border); font-family: var(--font-mono); font-size: 13px; transition: background .3s; }
.vz-table tr.k-good td { background: var(--k-good-f); color: var(--k-good-i); }
.vz-table tr.k-bad td { background: var(--k-bad-f); color: var(--k-bad-i); }
.vz-table tr.k-warn td { background: var(--k-warn-f); color: var(--k-warn-i); }
.vz-table tr.k-info td { background: var(--k-info-f); color: var(--k-info-i); }
.vz-table tr.k-primary td { background: var(--k-primary-f); color: var(--k-primary-i); }
.vz-table tr.k-data td { background: var(--k-data-f); color: var(--k-data-i); }
.vz-table tr.dim td { opacity: .35; }
.vz-table td.k-good { color: var(--k-good-i); background: var(--k-good-f); }
.vz-table td.k-bad { color: var(--k-bad-i); background: var(--k-bad-f); }
.vz-table td.k-warn { color: var(--k-warn-i); background: var(--k-warn-f); }
.vz-table td.k-primary { color: var(--k-primary-i); background: var(--k-primary-f); }
.vz-table td.k-info { color: var(--k-info-i); background: var(--k-info-f); }
.vz-table td.k-data { color: var(--k-data-i); background: var(--k-data-f); }

.vz-stepper { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.vz-stepper .pos { font-family: var(--font-mono); font-size: var(--fs-small); color: var(--text-2); min-width: 44px; text-align: center; }
.vz-stepper .pips { display: flex; gap: 4px; margin-left: 4px; }
.vz-stepper .pips i { width: 14px; height: 4px; border-radius: 2px; background: var(--surface-3); transition: background .2s; }
.vz-stepper .pips i.on { background: var(--link); }

.vz-stat { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 10px 16px; border-radius: 12px; background: var(--wash); min-width: 100px; }
.vz-stat b { font-size: 24px; font-weight: 700; line-height: 1.15; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.vz-stat span { font-size: var(--fs-micro); color: var(--text-2); font-weight: 500; text-align: center; }
.vz-stat.k-good b { color: var(--k-good-i); }
.vz-stat.k-bad b { color: var(--k-bad-i); }
.vz-stat.k-warn b { color: var(--k-warn-i); }
.vz-stat.k-primary b { color: var(--k-primary-i); }
.vz-stat.k-info b { color: var(--k-info-i); }

.vz-muted { color: var(--text-3); font-size: var(--fs-small); }
.vz-mono { font-family: var(--font-mono); }

/* ---------- playground: the hub, a hall of labs (the glass inside; js/lab-nav.js hall()) ---------- */
/* One row per lab: its number as a frosted chip, its sketch on a small glass stage, the name (a link) with the chapters and
   every scenario as links of their own, and the learner's progress as the same dots as a chapter strip. */
.lab-hub .hero { margin: 4px 0 0; }
.lab-hub-foot { margin: 28px 0 0; max-width: 64ch; color: var(--ex-ink-3); font-size: var(--fs-ui); line-height: 1.6; }
.yah-ic svg { width: 26px; height: 26px; }
.lab-hall { list-style: none; margin: 28px 0 0; padding: 0; border-top: 1px solid var(--ex-hair); }
.lab-hall-row {
  position: relative; display: grid; grid-template-columns: 56px 216px minmax(0, 1fr) 176px; gap: 8px 24px; align-items: start;
  padding: 22px 0; border-bottom: 1px solid var(--ex-hair);
}
.lab-hall-no { min-width: 56px; height: 46px; border-radius: 14px; font-size: 20px; }
.lab-hall-sketch { display: block; padding: 10px 12px; border-radius: 14px; background: var(--ex-mesh); box-shadow: inset 0 0 0 1px var(--ex-stage-edge); transition: box-shadow .15s; }
.lab-hall-sketch svg { display: block; width: 100%; max-width: 220px; height: auto; margin: 0 auto; font-family: var(--font-mono); }
.lab-hall-row:hover .lab-hall-sketch { box-shadow: inset 0 0 0 1.5px var(--ex-req); }
.lab-hall-body { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.lab-hall-t { margin: 0; font-size: 24px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.2; }
.lab-hall-link { color: var(--ex-ink); }
.lab-hall-link:hover { color: var(--ex-req-ink); text-decoration: none; }
/* the whole row opens the lab; the scenario links sit above it */
.lab-hall-link::after { content: ""; position: absolute; inset: 0; }
.lab-hall-tag { margin: 0; font-size: var(--fs-body-s); line-height: 1.5; color: var(--ex-ink-2); }
.lab-hall-ch { margin: 0; font-size: var(--fs-small); line-height: 1.5; color: var(--ex-ink-3); }
.lab-hall-scns { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0 16px; }
.lab-hall-scn {
  position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 7px; min-height: 28px;
  font-size: var(--fs-small); font-weight: 600; color: var(--ex-ink-2);
}
.lab-hall-scn::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--ex-dot); }
.lab-hall-scn.is-ch::before { width: 7px; height: 7px; border-radius: 1.5px; transform: rotate(45deg); }
.lab-hall-scn.is-seen::before { background: var(--ex-req); box-shadow: none; }
.lab-hall-scn:hover { color: var(--ex-req-ink); text-decoration: underline; text-underline-offset: 3px; }
.lab-hall-prog { font-size: var(--fs-small); line-height: 1.45; color: var(--ex-ink-2); font-variant-numeric: tabular-nums; }
.lab-hall-prog p { margin: 0; }
.lab-hall-prog b { color: var(--ex-ink); font-weight: 800; }
.lab-hall-prog .is-won b { color: var(--ex-fixed); }
.lab-hall-marks { margin: 0 0 8px -4px; pointer-events: none; }

/* ---------- playground: the lab page, a free-world exhibit (js/lab.js renderPage; it wears .ex-card, so the kit's
   controls take the card's control language) ---------- */
.lab { margin: 0 auto; animation: page-in .28s var(--ease-out); }
.yah-lab { color: var(--ex-ink-2); }
.lab-label > .ex-sec ~ .ex-sec { border-top: 1px solid var(--ex-hair); }
.lab-label .ex-h, .lab-under .ex-h { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.lab-label .ex-h small, .lab-under .ex-h small { font-size: var(--fs-micro); font-weight: 600; color: var(--ex-ink-3); font-variant-numeric: tabular-nums; }
.lab-textbtn { display: inline-flex; align-items: center; gap: 6px; border: 0; background: none; padding: 0; margin-top: 10px; font-size: var(--fs-small); font-weight: 700; color: var(--ex-req-ink); cursor: pointer; }
.lab-textbtn:hover { text-decoration: underline; text-underline-offset: 3px; }
.lab-textbtn.inline { margin: 0 0 0 6px; }

/* the stage's corner is a card's: the lamp and the run on screen at the left, Reset (a card's Restart) and Expand at the right, the
   same frosted buttons. Under them the transport is one quiet row, in the same place on every lab and visible in the first state:
   Run, the next run, the speed. While the question is open its buttons wait (faded, not-allowed) with the reason beside them. */
.lab-acts { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 8px 6px; padding: 10px 10px 0 16px; }
.lab-acts > .lab-status { grid-column: 1; }
.lab-acts > .lab-tools { grid-column: 1 / -1; }
.lab-tb {
  display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 12px 0 9px; border: 0; border-radius: 10px;
  background: color-mix(in srgb, var(--gl-tag-bg) 60%, transparent); color: var(--ex-ink); cursor: pointer; font-size: var(--fs-small); font-weight: 650;
  transition: background .15s var(--ease-out), opacity .15s;
}
.lab-tb svg { width: 15px; height: 15px; }
.lab-tb:hover:not([disabled]) { background: var(--gl-tag-bg); }
.lab-tb[disabled] { opacity: .5; cursor: not-allowed; }
.lab-tools-sep { flex: none; align-self: center; width: 1px; height: 18px; margin: 0 4px; background: var(--ex-hair); }
.lab-wait { display: none; flex: 1 1 auto; align-items: center; gap: 6px; min-height: 32px; padding: 0 4px; color: var(--ex-ink-2); font-size: var(--fs-small); font-weight: 650; }
.lab-wait .ic svg { width: 14px; height: 14px; }
.lab.is-asking .lab-wait { display: inline-flex; }
.lab-status { display: flex; align-items: center; flex-wrap: wrap; gap: 0 14px; min-width: 0; font-size: var(--fs-small); color: var(--ex-ink-2); }
.lab-status .live { display: inline-flex; align-items: center; gap: 8px; font-weight: 700; color: var(--ex-ink); }
.lab-status .live i { width: 8px; height: 8px; border-radius: 50%; background: var(--gl-res); box-shadow: 0 0 0 3px var(--gl-res-glow); }
.lab-status .live.idle i { background: transparent; box-shadow: inset 0 0 0 1.5px var(--ex-ink-3); }
.lab-input { color: var(--ex-ink-3); font-variant-numeric: tabular-nums; }
.lab-tools { display: flex; align-items: center; flex-wrap: wrap; justify-content: flex-start; gap: 4px 6px; min-width: 0; }
.ex-card .lab-speed { width: auto; flex: none; gap: 4px; margin: 0; }
.ex-card .lab-speed button { flex: 0 0 auto; min-width: 36px; min-height: 32px; padding: 0 10px; font-size: var(--fs-micro); font-weight: 700; }
.lab-stage { padding-top: 6px; }
/* a view's own line under its drawing is a quiet note */
.lab-stage .vz-caption:not(:empty) {
  margin-top: 8px; padding: 10px 0 0; border: 0; border-top: 1px solid var(--ex-hair); border-radius: 0; background: none; box-shadow: none;
  -webkit-backdrop-filter: none; backdrop-filter: none; color: var(--ex-ink-2); text-align: left; font-size: var(--fs-ui); font-weight: 400;
}
/* the tape under the drawing: the newest line is a glass caption, like Notice */
.lab-stage .vz-log { gap: 4px; min-height: 96px; margin-top: 6px; padding-top: 12px; border-top: 1px solid var(--ex-hair); }
.lab-stage .vz-log-title { margin-bottom: 2px; font-size: var(--fs-small); font-weight: 700; color: var(--ex-ink-2); }
.lab-stage .vz-log:not(:has(.vz-log-line))::after { content: "Operations show up here as the model runs."; font-family: var(--font-body); font-size: var(--fs-small); color: var(--ex-ink-3); padding: 6px 0; }
.lab-stage .vz-log-line { padding: 5px 10px; border-radius: 10px; background: none; color: var(--ex-ink-2); }
.lab-stage .vz-log-line.k-good { color: var(--ex-fixed); }
.lab-stage .vz-log-line.k-bad { color: var(--ex-fault); }
.lab-stage .vz-log-line.k-warn { color: var(--k-warn-i); }
.lab-stage .vz-log-title + .vz-log-line { background: var(--gl-tip-bg); color: var(--gl-ink); box-shadow: inset 0 0 0 1px var(--gl-tip-edge), 0 6px 16px -10px rgba(20, 40, 100, .35); }
.lab-stage .vz-log-title + .vz-log-line.k-bad { color: var(--ex-fault); }
.lab-stage .vz-log-title + .vz-log-line.k-good { color: var(--ex-fixed); }
.lab-stage .vz-log-title + .vz-log-line.k-warn { color: var(--k-warn-i); }

/* Scenario: the one on screen with its line, and the numbered list of them all */
.lab-scn-now { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; gap: 12px; align-items: start; }
.lab-n {
  display: grid; place-items: center; flex: none; width: 28px; height: 28px; border-radius: 50%; border: 1.5px solid var(--ex-line); background: var(--ex-chip); color: var(--ex-ink-2);
  font-size: 13px; font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1;
}
.lab-n svg { width: 15px; height: 15px; stroke-width: 3; }
/* a ring until the learner has been through it, filled blue after (teal with a tick when it was right or passed); a bang
   for a missed prediction; dashed for a solution seen; the one on screen is lit */
.lab-n.s-ran, .lab-n.s-tried { background: var(--ex-btn); border-color: var(--ex-btn); color: var(--ex-on-btn); }
.lab-n.s-right, .lab-n.s-passed { background: var(--ex-fixed); border-color: var(--ex-fixed); color: var(--ex-on-fixed); }
.lab-n.s-missed { border-color: var(--ex-fault); color: var(--ex-fault); }
.lab-n.s-seen { border-style: dashed; }
.lab-n.is-here { border: 2px solid var(--ex-req); box-shadow: 0 0 0 4px var(--ex-glow); }
.lab-n.is-here:not(.s-ran):not(.s-tried):not(.s-right):not(.s-passed) { background: var(--ex-chip); color: var(--ex-req-ink); }
.lab-scn-name { min-width: 0; }
.lab-scn-name p { margin: 0; }
.lab-scn-t { display: flex; align-items: center; gap: 6px; font-size: var(--fs-body-s); font-weight: 700; line-height: 1.3; color: var(--ex-ink); }
.lab-scn-t .ic { display: inline-grid; }
.lab-scn-t .ic svg { width: 14px; height: 14px; }
.lab-scn-b { margin-top: 2px; font-size: var(--fs-ui); line-height: 1.45; color: var(--ex-ink-2); }
.lab-scn-toggle {
  display: inline-flex; align-items: center; gap: 2px; min-height: 32px; padding: 0 8px 0 12px; border: 1px solid var(--ex-line); border-radius: 999px; background: var(--ex-chip); color: var(--ex-ink); cursor: pointer;
  font-size: var(--fs-small); font-weight: 650;
}
.lab-scn-toggle:hover { border-color: var(--ex-line-hover); }
.lab-scn-toggle .ic { display: inline-grid; transition: transform .2s var(--ease-out); }
.lab-scn-toggle .ic svg { width: 16px; height: 16px; }
.lab-scn.is-open .lab-scn-toggle { border-color: var(--ex-req); color: var(--ex-req-ink); }
.lab-scn.is-open .lab-scn-toggle .ic { transform: rotate(90deg); }
.lab-scn-list { margin-top: 12px; padding-top: 8px; border-top: 1px solid var(--ex-hair); }
.lab-strip { list-style: none; margin: 0; padding: 0; }
.lab-scn-row {
  display: grid; grid-template-columns: 28px minmax(0, 1fr); gap: 12px; align-items: center; min-height: 36px; margin: 0 -10px; padding: 4px 10px; border-radius: 18px;
  font-size: var(--fs-ui); font-weight: 600; line-height: 1.3; color: var(--ex-ink-2);
}
.lab-scn-row .lab-scn-t { font-size: var(--fs-ui); font-weight: 600; color: inherit; }
.lab-scn-row:hover { background: var(--ex-hover); color: var(--ex-ink); text-decoration: none; }
.lab-scn-row.is-current { background: var(--ex-wash); color: var(--ex-req-ink); font-weight: 700; }
.lab-scn-sub { display: flex; align-items: center; gap: 8px; margin: 12px 0 4px; font-size: var(--fs-small); font-weight: 700; color: var(--ex-ink-2); }
.lab-scn-sub .ic svg { width: 14px; height: 14px; }
.lab-scn-sub small { margin-left: auto; font-size: var(--fs-micro); font-weight: 600; color: var(--ex-ink-3); }

/* Parameters: one row per control, in the card's control language; what the scenario holds sits in a box under a lock chip
   with its reason */
.lab-param { padding: 9px 0; }
.lab-param:first-child { padding-top: 0; }
.lab-param-n { display: flex; align-items: baseline; gap: 6px; font-size: var(--fs-ui); font-weight: 700; color: var(--ex-ink); }
.lab-param-n .sym { font-family: var(--font-mono); font-size: var(--fs-small); font-weight: 500; font-style: italic; color: var(--ex-ink-3); }
.lab-param.inline { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 0 12px; }
.lab-param.inline .lab-param-note { grid-column: 1 / -1; }
.ex-card .lab-param.inline .vz-seg { width: auto; flex-wrap: nowrap; gap: 4px; }
.ex-card .lab-param.inline .vz-seg button { flex: 0 0 auto; min-width: 36px; padding: 6px 10px; }
.lab-param.block .vz-seg, .lab-param.list .vz-seg { margin-top: 6px; }
.ex-card .lab-param.block .vz-seg { gap: 4px; }
.ex-card .lab-param.block .vz-seg button { flex: 1 1 0; min-width: 0; padding-inline: 6px; }
.ex-card .lab-param.list .vz-seg { flex-direction: column; flex-wrap: nowrap; }
.ex-card .lab-param.list .vz-seg button { flex: none; width: 100%; justify-content: flex-start; text-align: left; border-radius: 18px; }
/* an option the setup rules out: faded and not-allowed, and the row's note says why */
.ex-card .lab-param .vz-seg button[disabled] { opacity: .45; cursor: not-allowed; }
.lab-param-note { margin: 6px 0 0; font-size: var(--fs-small); line-height: 1.45; color: var(--ex-ink-3); }
.lab-slots { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.lab-slot {
  display: inline-flex; align-items: center; gap: 7px; min-height: 34px; padding: 0 12px; border: 1px solid var(--ex-line); border-radius: 999px; background: var(--ex-chip);
  font-size: var(--fs-small); font-weight: 600; color: var(--ex-ink); cursor: pointer; transition: border-color .15s;
}
.lab-slot:hover { border-color: var(--ex-line-hover); }
.lab-slot i { width: 9px; height: 9px; border-radius: 50%; background: var(--k-neutral-s); }
.lab-slot b { font-weight: 800; font-variant-numeric: tabular-nums; }
.lab-slot.k-good i { background: var(--k-good-s); } .lab-slot.k-warn i { background: var(--k-warn-s); }
.lab-slot.k-info i { background: var(--k-info-s); } .lab-slot.k-bad i { background: var(--k-bad-s); }
.lab-slot[disabled] { opacity: .45; cursor: not-allowed; }
.lab-slot[disabled]:hover { border-color: var(--ex-line); }
.lab-label .lab-order-title, .lab-under .lab-order-title { display: none; }
.lab-order-param { padding-top: 12px; }
/* what is held or still locked: the same controls in a quiet box, under one lock line that says why ("Locked until you
   predict", "Held by this scenario"); they read in ink, the value in force in a grey ring, and take no clicks */
.lab-held, .lab-setup { margin-top: 10px; border: 1px solid var(--ex-hair); border-radius: 14px; background: var(--ex-hover); }
.lab-setup { margin-top: 0; }
.lab-held-why { margin: 0; padding: 8px 10px 2px; }
.lab-held-why > span {
  display: inline-flex; align-items: center; gap: 6px; min-height: 26px; padding: 0 10px 0 8px; border: 1px solid var(--ex-line); border-radius: 999px; background: var(--ex-chip);
  font-size: var(--fs-small); font-weight: 650; color: var(--ex-ink-2);
}
.lab-held-why .ic svg { width: 14px; height: 14px; }
.lab-held .lab-param, .lab-setup .lab-param { padding: 9px 12px; border-top: 1px solid var(--ex-hair); }
.lab-held .lab-param:first-child, .lab-setup .lab-param:first-child { padding-top: 9px; border-top: 0; }
.lab-held-why + .lab-param { border-top: 0; }
.lab-held .lab-textbtn.inline { margin: 0 0 0 auto; }
.lab-held .lab-param.inline .lab-param-n { grid-column: 1; }
.ex-card .lab-param .vz-seg.is-locked button[disabled] { opacity: 1; border-color: var(--ex-hair); background: transparent; color: var(--ex-ink-2); }
.ex-card .lab-param .vz-seg.is-locked button.on[disabled] { border-color: var(--ex-ink-3); background: var(--ex-chip); color: var(--ex-ink); box-shadow: inset 0 0 0 1px var(--ex-ink-3); }
.lab-setup .lab-slot[disabled], .lab-held .lab-slot[disabled] { opacity: 1; border-color: var(--ex-hair); background: transparent; }
/* the setup under the stage (js/lab.js, when the label is much taller): its controls in two columns */
.lab-under .lab-params-body, .lab-under .lab-setup, .lab-under .lab-held { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 28px; align-items: start; }
.lab-under .lab-params-body > :is(.lab-setup, .lab-held, .lab-param-note, .lab-order-param), .lab-under .lab-held > .lab-held-why, .lab-under .lab-setup > .lab-held-why { grid-column: 1 / -1; }
.lab-under .lab-setup, .lab-under .lab-held { gap: 0; }
.lab-under .lab-setup > .lab-param, .lab-under .lab-held > .lab-param { margin: 0; }
.lab-order-param .lab-order-hint { font-size: var(--fs-small); color: var(--ex-ink-3); }

/* Predict, then Run: the question about the setup on screen, its answers as pills, then the one filled action */
.lab-q { margin: 0; font-size: var(--fs-body); font-weight: 700; line-height: 1.4; color: var(--ex-ink); }
.lab-opts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin-top: 12px; }
.lab-opt {
  min-height: calc(var(--tap) + 6px); padding: 6px 10px; border: 1px solid var(--ex-line); border-radius: 999px; background: var(--ex-chip); color: var(--ex-ink);
  font-size: var(--fs-ui); font-weight: 650; line-height: 1.2; cursor: pointer; transition: border-color .15s, color .15s;
}
.lab-opt:hover { border-color: var(--ex-req); background: linear-gradient(var(--ex-wash), var(--ex-wash)), var(--ex-chip); color: var(--ex-req-ink); }
.lab-runrow { display: flex; flex-wrap: wrap; gap: 8px; }
.ex-card .lab-runrow .vz-btn { min-height: 44px; justify-content: center; }
.ex-card .vz-btn.lab-go { flex: 1 1 0; background: var(--ex-btn); border-color: var(--ex-btn); color: var(--ex-on-btn); box-shadow: 0 8px 20px -10px var(--ex-glow); font-size: 16px; }
.ex-card .vz-btn.lab-go:hover { background: var(--ex-btn-hover); border-color: var(--ex-btn-hover); }
.ex-card .vz-btn.lab-go[disabled]:hover { background: var(--ex-btn); border-color: var(--ex-btn); }
.lab-nudge { display: flex; gap: 8px; align-items: flex-start; margin: 12px 0 0; font-size: var(--fs-ui); line-height: 1.5; color: var(--ex-ink-2); }
.lab-nudge svg { flex: none; width: 16px; height: 16px; margin-top: 2px; color: var(--ex-req-ink); }

/* Notice: what the run did (a dot and the line, like the card's Notice), then how the prediction fared; Readouts after it */
.lab-line {
  display: inline; margin: 0; padding: 0; font-size: var(--fs-body-s); font-weight: 600; line-height: 1.55; color: var(--ex-ink);
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
}
.lab-line:not(:empty)::before { content: ""; display: inline-block; width: 8px; height: 8px; margin: 0 9px 1px 2px; border-radius: 50%; background: var(--ex-req); box-shadow: 0 0 0 3px var(--ex-glow); vertical-align: middle; }
.lab-line.pending { font-weight: 400; color: var(--ex-ink-2); }
.lab-line.pending::before { background: var(--ex-dot); box-shadow: none; }
.lab-line.k-bad { color: var(--ex-fault); }
.lab-line.k-bad::before { background: var(--ex-fault); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ex-fault) 25%, transparent); }
.lab-line.k-good { color: var(--ex-fixed); }
.lab-line.k-good::before { background: var(--ex-fixed); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ex-fixed) 25%, transparent); }
.lab-line.k-warn { color: var(--k-warn-i); }
.lab-pinnote { display: none; }
.lab-said { margin-top: 10px; }
.lab-say { margin: 0; font-size: var(--fs-ui); line-height: 1.55; color: var(--ex-ink-2); }
.lab-say b { display: inline-flex; align-items: center; gap: 4px; color: var(--ex-ink); font-weight: 750; }
.lab-say b svg { width: 14px; height: 14px; }
.lab-say.k-good > b { color: var(--ex-fixed); }
.lab-say.k-bad > b { color: var(--ex-fault); }
.lab-stats { grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); }
.lab-stats .vz-stat b { font-variant-numeric: tabular-nums; }
.lab-all-note { margin: 10px 0 0; font-size: var(--fs-small); color: var(--ex-ink-3); }
.lab-cells { display: grid; grid-template-columns: repeat(20, minmax(0, 1fr)); gap: 3px; }
.lab-cell { aspect-ratio: 1; border: 0; border-radius: 3px; padding: 0; background: var(--k-good-s); opacity: .45; cursor: pointer; transition: opacity .15s; }
.lab-cell:hover { opacity: 1; }
.lab-cell.k-bad { background: var(--k-bad-s); opacity: 1; }
.lab-cell.k-warn { background: var(--k-warn-s); opacity: 1; }
.lab-cell.cur { outline: 2px solid var(--ex-req); outline-offset: 1px; opacity: 1; }
.lab-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 10px 0 0; font-size: var(--fs-small); color: var(--ex-ink-2); }
.lab-legend-item { display: inline-flex; align-items: center; gap: 6px; font-variant-numeric: tabular-nums; }
.lab-legend-item i { width: 9px; height: 9px; border-radius: 2px; background: var(--k-good-s); opacity: .45; }
.lab-legend-item i.k-bad { background: var(--k-bad-s); opacity: 1; }
.lab-legend-item i.k-warn { background: var(--k-warn-s); opacity: 1; }
.lab-seen ul { list-style: none; margin: 0; padding: 0; }
.lab-seen a { display: flex; align-items: center; gap: 6px; min-height: var(--tap); font-size: var(--fs-small); font-weight: 600; color: var(--ex-req-ink); }
.lab-seen a svg { flex: none; width: 14px; height: 14px; }

/* Challenge: the goal, the pass checklist (round chips: teal ticks, red crosses); Test is the filled action in the Run block */
.lab-goal { margin: 0; font-size: var(--fs-body); font-weight: 600; line-height: 1.45; color: var(--ex-ink); }
.lab-check-t { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin: 14px 0 8px; font-size: var(--fs-small); font-weight: 700; color: var(--ex-ink-2); }
.lab-check-t small { font-size: var(--fs-micro); font-weight: 600; color: var(--ex-ink-3); }
.lab-criteria { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.lab-criteria li { display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: 10px; align-items: start; font-size: var(--fs-ui); line-height: 1.45; color: var(--ex-ink); }
.lab-criteria .mark { display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; border: 1.5px solid var(--ex-line); background: var(--ex-chip); }
.lab-criteria .mark svg { width: 14px; height: 14px; stroke-width: 3; }
.lab-criteria .mark-open { display: none; }
.lab-criteria li.ok .mark { background: var(--ex-fixed); border-color: var(--ex-fixed); color: var(--ex-on-fixed); }
.lab-criteria li.no .mark { border-color: var(--ex-fault); color: var(--ex-fault); }
.lab-criteria b { font-weight: 700; }
.lab-criteria .why { color: var(--ex-ink-3); font-weight: 400; }
.lab-passbox { margin-top: 14px; }
.lab-passbox .lab-say { margin-bottom: 8px; }
.lab-passed { display: inline-flex; align-items: center; gap: 5px; margin: 12px 0 0; font-size: var(--fs-small); font-weight: 700; color: var(--ex-fixed); }
.lab-passed svg { width: 14px; height: 14px; }
.lab-solution { margin: 12px 0 0; padding: 10px 12px; border: 1px solid var(--ex-tile-edge); border-radius: 12px; background: var(--ex-tile); font-size: var(--fs-ui); line-height: 1.5; color: var(--ex-ink-2); }
.lab-solution b { color: var(--ex-ink); }
.lab-test-sum { margin: 10px 0 0; font-size: var(--fs-ui); font-weight: 700; }
.lab-test-sum.k-good { color: var(--ex-fixed); }
.lab-test-sum.k-bad { color: var(--ex-fault); }
.lab-help { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 18px; margin-top: 12px; }
.lab-help:empty { display: none; }
.lab-help .lab-textbtn { margin: 0; }
.lab-hint { font-size: var(--fs-ui); color: var(--ex-ink-2); }
.lab-hint summary { cursor: pointer; font-weight: 700; color: var(--ex-req-ink); }
.lab-hint p { margin: 6px 0 0; line-height: 1.5; }

/* the Run block pinned to the bottom edge of a stacked label (it rides there like a card's lit step) */
.ex-pin .lab-act { padding: 0; border: 0; }
.ex-pin .lab-act > .ex-h, .ex-pin .lab-nudge { display: none; }
.ex-pin .lab-q { font-size: var(--fs-ui); line-height: 1.35; }
.ex-pin .lab-opts { margin-top: 0; }
/* the question, then the options with Skip beside them: the whole block is two compact rows */
.ex-pin .lab-actbody:has(.lab-opts) { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px 12px; align-items: stretch; }
.ex-pin .lab-actbody:has(.lab-opts) > .lab-q { grid-column: 1 / -1; }
.ex-pin .lab-actbody:has(.lab-opts) > .lab-textbtn { margin: 0; align-self: center; text-align: left; line-height: 1.2; max-width: 5.5em; }
.ex-pin .lab-pinnote { display: block; margin: 0 0 8px; }
.ex-pin .lab-textbtn { margin-top: 6px; }
.ex-pin .lab-test-sum { margin-top: 6px; }
.ex-pin .lab-opt { min-height: 44px; }

/* the hub and the lab page on narrow screens and touch */
@media (max-width: 1100px) {
  .lab-hall-row { grid-template-columns: 56px 200px minmax(0, 1fr); }
  .lab-hall-prog { grid-column: 3; }
}
@media (max-width: 640px) {
  /* the number as a chip of its own above the sketch (never over the drawing), the name and its lines beside them both */
  .lab-hall-row { grid-template-columns: 104px minmax(0, 1fr); grid-template-areas: "no body" "sketch body" "prog prog"; grid-template-rows: auto 1fr auto; gap: 8px 14px; padding: 18px 0; }
  .lab-hall-no { grid-area: no; justify-self: start; min-width: 44px; height: 34px; padding: 0 10px; border-radius: 12px; font-size: 16px; }
  .lab-hall-sketch { grid-area: sketch; padding: 6px; align-self: start; border-radius: 12px; }
  .lab-hall-body { grid-area: body; }
  .lab-hall-prog { grid-area: prog; }
  .lab-hall-t { font-size: 21px; }
  .lab-hall-scns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 12px; }
  .lab-hall-scn { line-height: 1.25; }
  .lab-acts { gap: 6px; padding: 8px 8px 0 12px; }
  .lab-tools { gap: 2px 4px; }
  .lab-tb { gap: 5px; padding: 0 10px 0 8px; }
  .ex-card .lab-speed button { min-width: 32px; padding: 0 6px; }
  .lab-cells { grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 3px; }
  .lab-stage .vz-log { min-height: 88px; }
}
@media (pointer: coarse) {
  .lab-scn-row, .lab-scn-toggle, .lab-slot, .lab-hall-scn, .lab-held-row, .lab-textbtn, .lab-hint summary { min-height: var(--tap); }
  .lab-cell:hover { opacity: .45; }
  .lab-cell.k-bad:hover, .lab-cell.k-warn:hover { opacity: 1; }
  .lab-step, .lab-tb, .ex-card .lab-speed button { min-height: var(--tap); }
}

/* isolation lab: the step table */
.iso-table { display: flex; flex-direction: column; gap: 5px; }
.iso-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.05fr); gap: 8px; align-items: center; }
.iso-row.pop { animation: vz-pop .35s var(--ease-out); }
.iso-head { padding-bottom: 6px; border-bottom: 1px solid var(--border-strong); font-size: var(--fs-small); font-weight: 600; color: var(--text-2); }
.iso-head .iso-t1 { color: var(--k-primary-i); }
.iso-head .iso-t2 { color: var(--k-data-i); }
.iso-chip {
  justify-self: start; display: inline-flex; align-items: center; max-width: 100%; padding: 4px 10px; border-radius: 8px;
  border: 1.5px solid var(--k-neutral-s); background: var(--k-neutral-f); color: var(--k-neutral-i);
  font-family: var(--font-mono); font-size: 13px; font-weight: 600; line-height: 1.3;
}
.iso-chip.k-primary { border-color: var(--k-primary-s); background: var(--k-primary-f); color: var(--k-primary-i); }
.iso-chip.k-data { border-color: var(--k-data-s); background: var(--k-data-f); color: var(--k-data-i); }
.iso-chip.k-good { border-color: var(--k-good-s); background: var(--k-good-f); color: var(--k-good-i); }
.iso-chip.k-bad { border-color: var(--k-bad-s); background: var(--k-bad-f); color: var(--k-bad-i); }
.iso-chip.k-warn { border-color: var(--k-warn-s); background: var(--k-warn-f); color: var(--k-warn-i); }
.iso-chip.k-ghost { border-style: dashed; border-color: var(--k-ghost-s); background: transparent; color: var(--k-ghost-i); }
.iso-note { font-size: var(--fs-small); color: var(--text-2); line-height: 1.35; min-height: 1.3em; }
.iso-note.k-bad { color: var(--k-bad-i); }
.iso-note.k-warn { color: var(--k-warn-i); }
.iso-empty { padding: 18px 0; text-align: center; color: var(--text-3); font-size: var(--fs-ui); }
.iso-final { margin-top: 6px; font-weight: 700; font-size: var(--fs-body-s); }
.iso-final.k-good { color: var(--k-good-i); }
.iso-final.k-bad { color: var(--k-bad-i); }

/* timeline order editor: pill chips in the map's language (T1 purple and T2 orange are diagram colours) */
.lab-order { display: flex; flex-direction: column; gap: 8px; }
.lab-order-head { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; }
.lab-order-title { font-size: var(--fs-small); font-weight: 700; color: var(--ex-ink); }
.lab-order-hint { font-size: var(--fs-small); color: var(--ex-ink-3); }
.lab-order-strip { display: flex; flex-wrap: wrap; gap: 6px; }
.lab-step {
  display: inline-flex; align-items: center; gap: 6px; min-height: 34px; padding: 0 12px; border-radius: 999px;
  border: 1.5px solid var(--k-neutral-s); background: var(--k-neutral-f); color: var(--k-neutral-i);
  font-size: var(--fs-small); font-weight: 600; cursor: pointer;
}
.lab-step b { font-family: var(--font-mono); font-size: 11.5px; }
.lab-step.t1 { border-color: var(--k-primary-s); background: var(--k-primary-f); color: var(--k-primary-i); }
.lab-step.t2 { border-color: var(--k-data-s); background: var(--k-data-f); color: var(--k-data-i); }
.lab-step.sel { outline: 2px solid var(--gl-req); outline-offset: 2px; }
.lab-step[disabled] { cursor: not-allowed; opacity: .45; }
.lab-order-bar { display: flex; gap: 8px; }

/* ---------- responsive ---------- */
@media (max-width: 1180px) {
  .main { padding: 32px 32px 88px; }
}
@media (max-width: 1040px) {
  .overall { display: none; }
}
@media (max-width: 900px) {
  .layout { grid-template-columns: minmax(0, 1fr); }
  .menu-btn { display: inline-grid; }
  .topbar { padding: 0 12px 0 8px; gap: 8px; }
  .sidebar {
    position: fixed; top: var(--topbar-h); left: 0; bottom: 0; z-index: 40;
    width: min(320px, 86vw); height: auto;
    background: var(--bg); box-shadow: var(--shadow-pop); border-right: 0;
    transform: translateX(-104%); visibility: hidden;
    transition: transform .28s var(--ease-out), visibility 0s linear .28s;
  }
  body.drawer-open .sidebar { transform: none; visibility: visible; transition: transform .28s var(--ease-out); }
  body.drawer-open .scrim { display: block; position: fixed; inset: var(--topbar-h) 0 0 0; z-index: 35; background: var(--scrim); }
  .top-nav { display: none; }
  /* pages without a sidebar keep their section links on phones, behind the Menu button below 641px */
  .topbar .site-nav { display: flex; }
}
@media (max-width: 640px) {
  .main { padding: 22px 16px 28px; }
  .shelf-main { padding: 22px 16px 40px; }
  .to-row { grid-template-columns: minmax(0, 1fr) auto; }
  .to-track { grid-column: 1 / -1; grid-row: 2; }
  .book-row { grid-template-columns: 40px minmax(0, 1fr); gap: 2px 14px; margin: 0 -12px; padding: 22px 12px; }
  .book-mark svg { width: 40px; height: 40px; }
  .book-title { font-size: 19px; }
  .bs-tick { width: 10px; }
  .book-side { grid-column: 2; flex-direction: row; justify-content: space-between; align-items: center; margin-top: 14px; padding-top: 0; }
  .shelf-resume { grid-template-columns: auto minmax(0, 1fr); gap: 12px 14px; padding: 14px; }
  .shelf-resume .sr-go { grid-column: 1 / -1; }
  .sr-title { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
  .topbar:has(.book-chip) .brand-name { display: none; }
  .search-toggle { display: inline-grid; margin-left: auto; }
  .site-nav { margin-left: auto; }
  .site-nav + .search-toggle { margin-left: 0; }
  .site-menu-btn { display: inline-flex; }
  .site-links {
    display: none; position: absolute; right: 12px; top: 100%; z-index: 45; min-width: 200px; margin-top: 6px; padding: 6px;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-pop);
  }
  .site-nav.is-open .site-links { display: flex; }
  .site-links .top-link { min-height: 44px; padding: 0 14px; border-radius: 8px; font-size: var(--fs-body); }
  .search { display: none; }
  body.search-open .search {
    display: block; position: fixed; left: 0; right: 0; top: 0; z-index: 60; margin: 0;
    padding: 9px 60px 10px 12px; background: var(--bg); border-bottom: 1px solid var(--border); box-shadow: var(--shadow-pop);
  }
  body.search-open .search-ic { left: 26px; top: 31px; }
  body.search-open .search-input { height: 44px; font-size: var(--fs-body); }
  body.search-open .search-kbd { display: none; }
  body.search-open .search-close { display: inline-grid; position: absolute; right: 10px; top: 10px; }
  .search-pop { position: static; width: auto; margin-top: 8px; max-height: calc(100dvh - 90px); box-shadow: none; border: 0; }

  .hero .lede { font-size: var(--fs-lead); }
  .hero-actions { flex-direction: column; align-items: stretch; }
  .hero-resume { text-align: center; max-width: none; }
  .card-title { font-size: 28px; }
  .lede { font-size: var(--fs-body); }
  .sandbox { margin-left: -16px; margin-right: -16px; border-radius: 0; border-left: 0; border-right: 0; box-shadow: none; }
  .quiz { margin-left: -16px; margin-right: -16px; border-radius: 0; border-left: 0; border-right: 0; padding: 22px 16px; }
  .cheat { grid-template-columns: minmax(0, 1fr); }

  /* pager: a thumb-reachable bar pinned to the bottom edge */
  .pager { position: sticky; bottom: 0; z-index: 20; grid-template-columns: auto minmax(0, 1fr) auto; gap: 8px; align-items: center; margin: 32px -16px 0; padding: 8px 12px calc(8px + env(safe-area-inset-bottom)); background: color-mix(in srgb, var(--bg) 92%, transparent); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); border-top: 1px solid var(--border); }
  .pager-link { min-height: 44px; padding: 0 14px; border-radius: 999px; }
  .pager-link.back { grid-column: 1; grid-row: 1; }
  .pager-link.next { grid-column: 3; grid-row: 1; max-width: 62vw; }
  .pager-link small { display: none; }
  .pager-link b { font-size: var(--fs-ui); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
  .pager-link .full { display: none; }
  .pager-link .short { display: inline; }
  .pager-count { grid-column: 2; grid-row: 1; }
  .pager-count kbd { display: none; }

  .stage { padding: 16px 4px 14px; }
  .stage > .vz > :not(.vz-svg-wrap), .stage > :not(.vz):not(.vz-svg-wrap) { margin-left: 8px; margin-right: 8px; }
  .vz-node .vz-label { font-size: 19px; }
  .vz-node .vz-sub { font-size: 15px; }
  .vz-btn.icon-sm { font-size: 0; gap: 0; padding: 0; width: var(--tap); justify-content: center; }
  .vz-link-label { font-size: 15px; }
  /* free labels (st.text) scale like link labels: 12px becomes 15px, about 10px on screen instead of 8 */
  .vz-svg .vz-text { font-size: calc(var(--fs, 14) * 1.25px); }
  .vz-svg .vz-text.vz-fit { font-size: calc(var(--fs, 14) * 1px); }
  .vz-packet text { font-size: 14px; }
  .vz-box text { font-size: 15px; }

  .iso-row { gap: 5px; }
  .iso-chip { padding: 4px 6px; font-size: 12.5px; }
  .iso-note { font-size: 12px; }
}
@media (pointer: coarse) {
}
@media (hover: none) {
  .search-kbd, .pager-count kbd { display: none; }
}
/* touch screens: every tappable control reaches the 44px commitment, whatever its drawn size */
@media (pointer: coarse) {
  .cs-stop { width: 30px; height: var(--tap); } .cs-stop.now { width: 40px; }
  .sandbox-bar .frame-btn, .vz-seg button, .chip.tag,
  .book-chip, .brand, .top-link, .site-menu-btn { min-height: var(--tap); }
  .brand { min-width: var(--tap); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}

/* ----- structure blocks (viz-structs.js, viz-systems.js) ----- */
/* centred by default; an explicit text-anchor attribute wins (CSS would otherwise override it) */
.vz-blk text { font-family: var(--font-mono); font-weight: 600; dominant-baseline: middle; }
.vz-blk text:not([text-anchor]) { text-anchor: middle; }
.vz-blk .vz-shape { stroke-width: 1.5; }
.vz-blk .vz-cell { transition: opacity .3s; }
.vz-blk .vz-tick { stroke: var(--k-ghost-s); stroke-width: 1; }
.vz-blk .vz-axis { stroke: var(--k-neutral-s); stroke-width: 1.5; fill: none; }
.vz-blk text.vz-axis-t { font-family: var(--font-body); font-weight: 500; fill: var(--text-2); }
.vz-blk .vz-ptr { stroke: var(--k-primary-s); stroke-width: 2; }
.vz-blk .vz-bracket { fill: none; stroke-width: 1.5; }
.vz-blk .vz-strike { stroke: var(--k-bad-s); stroke-width: 2; }
.vz-blk .vz-focus { fill: none; stroke: var(--k-warn-s); stroke-width: 3; }
/* strong heat cells take the page surface colour for text, weak ones the text colour: right in both themes */
.vz-blk text.vz-heat-t.lo { fill: var(--text); }
.vz-blk text.vz-heat-t.hi { fill: var(--surface); }
.vz-blk .vz-heat { stroke: var(--surface); stroke-width: 1.5; }
/* a heat cell with a kind keeps its heat fill and gets that kind's outline (mark a row or a cell) */
.vz-blk .k-primary > .vz-heat { stroke: var(--k-primary-s); stroke-width: 2.5; }
.vz-blk .k-good > .vz-heat { stroke: var(--k-good-s); stroke-width: 2.5; }
.vz-blk .k-bad > .vz-heat { stroke: var(--k-bad-s); stroke-width: 2.5; }
.vz-blk .k-warn > .vz-heat { stroke: var(--k-warn-s); stroke-width: 2.5; }
.vz-blk .k-info > .vz-heat { stroke: var(--k-info-s); stroke-width: 2.5; }
.vz-blk .k-data > .vz-heat { stroke: var(--k-data-s); stroke-width: 2.5; }
.vz-blk .vz-series { fill: none; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.vz-blk .vz-life { stroke: var(--k-ghost-s); stroke-dasharray: 4 4; stroke-width: 1.5; }
.vz-blk .vz-lane { stroke: var(--k-ghost-s); stroke-width: 1; }
.vz-blk text.vz-label-t { font-family: var(--font-body); font-weight: 600; }

/* ---------- isometric cutaways ---------- */
/* DDIA.isoScene (js/viz-iso.js). One pen: 1.1px ink on every face at any size; three casing greys (top light,
   left mid, right dark) and two for the inside of a cut; cut red only on the cut floor and on faults; steel
   for links in focus, callouts and packets. Dark mode comes through the tokens; --iso-dim is the grey a part
   drops to out of focus (the dark casing grey would vanish on the dark page, so night gets a lighter one). */
.iso { --iso-dim: var(--case-3); width: 100%; height: auto; display: block; margin: 0 auto; overflow: visible; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .iso { --iso-dim: #6b7381; } }
:root[data-theme="dark"] .iso { --iso-dim: #6b7381; }
.iso text { font-family: var(--font-body); }
.iso-face { stroke: var(--ink); stroke-width: 1.1; stroke-linejoin: round; vector-effect: non-scaling-stroke; transition: fill .2s var(--ease-out), stroke .2s var(--ease-out); }
.iso-top { fill: var(--case-1); }
.iso-left { fill: var(--case-2); }
.iso-right { fill: var(--case-3); }
.iso-in-1 { fill: var(--case-in-1); }
.iso-in-2 { fill: var(--case-in-2); }
/* the cut floor: the hatch is cut red over a pale wash of it, so parts and routes still read on top */
.iso-hatch-bg { fill: color-mix(in srgb, var(--cut) 13%, var(--paper)); }
.iso-hatch-line { stroke: var(--cut); stroke-width: 1.2; opacity: .75; }
/* a large floor (a whole teardown) gets a sparser, thinner hatch on a paler wash: still the cut face, but quiet */
.iso-floor-lg .iso-hatch-bg { fill: color-mix(in srgb, var(--cut) 6%, var(--paper)); }
.iso-floor-lg .iso-hatch-line { stroke-width: .9; opacity: .5; }
.iso-icon { fill: none; stroke: var(--ink); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.iso-label { fill: var(--ink); font-stretch: 75%; font-weight: 600; font-size: 13px; text-transform: uppercase; letter-spacing: .04em; }
.iso-label-s { font-size: 11.5px; }
/* floor routes: ink on a paper halo, so they read over the hatch; in focus they turn steel and thicken */
.iso-link-halo { fill: none; stroke: var(--paper); stroke-width: 5; stroke-opacity: .9; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; transition: stroke-opacity .2s var(--ease-out), stroke-width .2s var(--ease-out); }
.iso-link { fill: none; stroke: var(--ink); stroke-width: 1.6; stroke-opacity: .72; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; transition: stroke .2s var(--ease-out), stroke-opacity .2s var(--ease-out), stroke-width .2s var(--ease-out); }
.iso-link.is-focus { stroke: var(--steel); stroke-opacity: 1; stroke-width: 2.6; }
.iso-link-halo.is-focus { stroke-width: 7; stroke-opacity: 1; }
.iso-link.is-dim { stroke-opacity: .22; }
.iso-link-halo.is-dim { stroke-opacity: .5; }
.iso-leader { stroke: var(--steel); stroke-width: 1; vector-effect: non-scaling-stroke; }
.iso-dot { fill: var(--steel); }
.iso-balloon { fill: var(--paper); stroke: var(--steel); stroke-width: 1.3; vector-effect: non-scaling-stroke; }
.iso-num { fill: var(--steel); font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; }
.iso-callout { transition: opacity .2s var(--ease-out); }
.iso-callout.is-dim { opacity: .4; }
.iso-packet { fill: var(--steel); stroke: var(--paper); stroke-width: 1.5; }
.iso-fault-ring { fill: color-mix(in srgb, var(--cut) 10%, transparent); stroke: var(--cut); }
.iso-fault-badge { fill: var(--cut); }
.iso-fault-bang { stroke: var(--paper); stroke-width: 2.2; stroke-linecap: round; }
/* focus: the parts in focus take a steel tint; the rest drop to grey linework */
.iso-part.is-focus .iso-top { fill: color-mix(in srgb, var(--steel) 22%, var(--case-1)); }
.iso-part.is-focus .iso-left { fill: color-mix(in srgb, var(--steel) 34%, var(--case-2)); }
.iso-part.is-focus .iso-right { fill: color-mix(in srgb, var(--steel) 46%, var(--case-3)); }
.iso-part.is-dim .iso-face { fill: var(--paper); stroke: color-mix(in srgb, var(--iso-dim) 60%, transparent); }
.iso-part.is-dim .iso-icon { stroke: color-mix(in srgb, var(--iso-dim) 60%, transparent); }
.iso-part.is-dim .iso-label { fill: var(--iso-dim); }
/* a scene that answers clicks: parts lift a little under the pointer */
.iso-pickable .iso-part, .iso-pickable .iso-callout { cursor: pointer; }
.iso-pickable .iso-part { transition: transform .15s ease-out; }
.iso-pickable .iso-part:hover { transform: translateY(-2px); }
@media (prefers-reduced-motion: reduce) { .iso-pickable .iso-part:hover { transform: none; } }

/* live traffic, technical skin (scene.dots, counter, pulse, load, duct hit areas) */
.iso-hit { fill: none; stroke: transparent; stroke-width: 16; stroke-linecap: round; pointer-events: none; }
.iso-tips .iso-hit { pointer-events: stroke; cursor: pointer; }
.iso-mover { pointer-events: none; }
.iso-mover.req { fill: var(--steel); stroke: var(--paper); stroke-width: 1.5; }
.iso-mover.res { fill: color-mix(in srgb, var(--steel) 22%, var(--paper)); stroke: var(--steel); stroke-width: 1.4; }
.iso-mover.is-trace { stroke-width: 2; }
.iso-tracing .iso-mover:not(.is-trace) { opacity: .35; }
.iso-pulse { pointer-events: none; }
.iso-part > .iso-pulse { fill: var(--steel); }
.iso-part.is-hot .iso-top { fill: color-mix(in srgb, var(--steel) 14%, var(--case-1)); }
.iso-tag rect { fill: var(--paper); stroke: var(--steel); stroke-width: 1; }
.iso-tag text { fill: var(--steel); font-size: 10.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.iso-tag.is-hot rect { stroke-width: 1.8; }
.iso-tag.is-fault rect { stroke: var(--cut); }
.iso-tag.is-fault text { fill: var(--cut); }
.iso-tips .iso-part { cursor: pointer; outline: none; }
.iso-tips .iso-part:focus-visible .iso-top { stroke: var(--steel); stroke-width: 2.2; }

/* ---------- the glass skin (DDIA.isoScene with skin: 'glass'; the look the owner chose on 2026-10-10) ----------
   Frosted, translucent parts on a rounded glass floor over a mesh-gradient backdrop (the svg's own background,
   so it stays inside the scene). Requests glow steel-blue, responses teal; red only for faults. Light mode gets
   a darker label ink with a soft paper halo, so names stay readable over glowing traffic behind the glass. */
:root {
  --gl-bg: #eaf0fa;
  --gl-blob1: rgba(90, 145, 255, .42); --gl-blob2: rgba(165, 120, 255, .30); --gl-blob3: rgba(40, 200, 185, .26);
  --gl-plate-a: rgba(255, 255, 255, .78); --gl-plate-b: rgba(255, 255, 255, .34);
  --gl-plate-edge: rgba(255, 255, 255, .95); --gl-plate-line: rgba(40, 70, 140, .09);
  --gl-slab: rgba(110, 140, 210, .30); --gl-shadow: rgba(30, 50, 110, .22);
  --gl-top-a: rgba(255, 255, 255, .88); --gl-top-b: rgba(232, 240, 255, .56);
  --gl-left-a: rgba(205, 222, 255, .62); --gl-left-b: rgba(170, 196, 248, .40);
  --gl-right-a: rgba(140, 168, 228, .56); --gl-right-b: rgba(105, 136, 208, .44);
  --gl-hi: rgba(255, 255, 255, .98); --gl-edge: rgba(28, 48, 100, .26); --gl-back: rgba(40, 70, 140, .22);
  --gl-ink: #0e1630; --gl-ink-2: #3e4a6b; --gl-halo: rgba(255, 255, 255, .78);
  --gl-req: #1f6fe8; --gl-req-glow: rgba(31, 111, 232, .42);
  --gl-res: #0b9f80; --gl-res-glow: rgba(11, 159, 128, .38);
  --gl-glow: rgba(70, 135, 255, .60); --gl-pulse-edge: rgba(120, 170, 255, .30);
  --gl-fault: #d7322a; --gl-fault-glow: rgba(229, 62, 52, .55); --gl-fault-tint: rgba(240, 70, 60, .30);
  --gl-tube: rgba(80, 120, 215, .15); --gl-tube-core: rgba(60, 110, 215, .28); --gl-tube-hi: rgba(255, 255, 255, .95);
  --gl-chev: rgba(40, 80, 170, .38);
  --gl-tag-bg: rgba(255, 255, 255, .80); --gl-tag-edge: rgba(255, 255, 255, 1); --gl-tag-ink: #0e1630;
  --gl-tag-hot-bg: #1f6fe8; --gl-tag-fault-bg: #d7322a;   /* white text on these: 4.7:1 and 4.8:1 */
  --gl-frost: rgba(234, 240, 251, .74);
  --gl-tip-bg: rgba(255, 255, 255, .72); --gl-tip-edge: rgba(255, 255, 255, .92);
  /* the system map's domain zones (graded floor -> rim; ink for zone labels, 4.5:1 or better on the floor and the rim) */
  --map-blue-floor: rgba(72, 128, 240, 0.13); --map-blue-rim: rgba(52, 108, 232, 0.42); --map-blue-ink: #17398a;
  --map-green-floor: rgba(40, 175, 120, 0.14); --map-green-rim: rgba(28, 160, 105, 0.42); --map-green-ink: #0b5236;
  --map-violet-floor: rgba(140, 100, 240, 0.14); --map-violet-rim: rgba(120, 84, 228, 0.42); --map-violet-ink: #3f2388;
  --map-amber-floor: rgba(235, 160, 40, 0.16); --map-amber-rim: rgba(215, 140, 20, 0.46); --map-amber-ink: #703f05;
  --map-teal-floor: rgba(30, 180, 180, 0.14); --map-teal-rim: rgba(20, 160, 165, 0.42); --map-teal-ink: #0a4f52;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --gl-bg: #0a0e1b;
    --gl-blob1: rgba(55, 95, 255, .40); --gl-blob2: rgba(145, 75, 255, .30); --gl-blob3: rgba(20, 175, 165, .22);
    --gl-plate-a: rgba(255, 255, 255, .11); --gl-plate-b: rgba(255, 255, 255, .03);
    --gl-plate-edge: rgba(255, 255, 255, .30); --gl-plate-line: rgba(180, 200, 255, .07);
    --gl-slab: rgba(90, 120, 230, .20); --gl-shadow: rgba(0, 0, 0, .55);
    --gl-top-a: rgba(255, 255, 255, .24); --gl-top-b: rgba(200, 215, 255, .08);
    --gl-left-a: rgba(150, 180, 255, .17); --gl-left-b: rgba(120, 150, 240, .07);
    --gl-right-a: rgba(80, 100, 190, .30); --gl-right-b: rgba(45, 65, 150, .22);
    --gl-hi: rgba(255, 255, 255, .58); --gl-edge: rgba(0, 0, 0, .40); --gl-back: rgba(200, 215, 255, .20);
    --gl-ink: #f2f5ff; --gl-ink-2: #a9b5d6; --gl-halo: rgba(8, 12, 30, .55);
    --gl-req: #79b6ff; --gl-req-glow: rgba(80, 160, 255, .55);
    --gl-res: #55e3c0; --gl-res-glow: rgba(60, 220, 180, .45);
    --gl-glow: rgba(90, 150, 255, .62); --gl-pulse-edge: rgba(90, 150, 255, .62);
    --gl-fault: #ff5a4f; --gl-fault-glow: rgba(255, 80, 70, .55); --gl-fault-tint: rgba(255, 80, 70, .26);
    --gl-tube: rgba(120, 160, 255, .11); --gl-tube-core: rgba(120, 165, 255, .30); --gl-tube-hi: rgba(255, 255, 255, .30);
    --gl-chev: rgba(170, 200, 255, .40);
    --gl-tag-bg: rgba(22, 30, 56, .66); --gl-tag-edge: rgba(255, 255, 255, .24); --gl-tag-ink: #eef2ff;
    --gl-tag-hot-bg: #1f4fb8; --gl-tag-fault-bg: #b3261e;   /* white text on these: 7.3:1 and 6.5:1 */
    --gl-frost: rgba(14, 20, 40, .70);
    --gl-tip-bg: rgba(24, 32, 60, .62); --gl-tip-edge: rgba(255, 255, 255, .20);
    /* the system map's domain zones (graded floor -> rim; ink for zone labels, 4.5:1 or better on the floor and the rim) */
    --map-blue-floor: rgba(90, 150, 255, 0.16); --map-blue-rim: rgba(100, 160, 255, 0.34); --map-blue-ink: #c4daff;
    --map-green-floor: rgba(50, 210, 150, 0.14); --map-green-rim: rgba(60, 220, 160, 0.3); --map-green-ink: #b4f1d6;
    --map-violet-floor: rgba(165, 125, 255, 0.17); --map-violet-rim: rgba(175, 140, 255, 0.34); --map-violet-ink: #dacbff;
    --map-amber-floor: rgba(245, 180, 70, 0.14); --map-amber-rim: rgba(250, 190, 80, 0.3); --map-amber-ink: #fadfa6;
    --map-teal-floor: rgba(40, 205, 200, 0.14); --map-teal-rim: rgba(60, 220, 210, 0.3); --map-teal-ink: #b2f1ec;
  }
}
:root[data-theme="dark"] {
  --gl-bg: #0a0e1b;
  --gl-blob1: rgba(55, 95, 255, .40); --gl-blob2: rgba(145, 75, 255, .30); --gl-blob3: rgba(20, 175, 165, .22);
  --gl-plate-a: rgba(255, 255, 255, .11); --gl-plate-b: rgba(255, 255, 255, .03);
  --gl-plate-edge: rgba(255, 255, 255, .30); --gl-plate-line: rgba(180, 200, 255, .07);
  --gl-slab: rgba(90, 120, 230, .20); --gl-shadow: rgba(0, 0, 0, .55);
  --gl-top-a: rgba(255, 255, 255, .24); --gl-top-b: rgba(200, 215, 255, .08);
  --gl-left-a: rgba(150, 180, 255, .17); --gl-left-b: rgba(120, 150, 240, .07);
  --gl-right-a: rgba(80, 100, 190, .30); --gl-right-b: rgba(45, 65, 150, .22);
  --gl-hi: rgba(255, 255, 255, .58); --gl-edge: rgba(0, 0, 0, .40); --gl-back: rgba(200, 215, 255, .20);
  --gl-ink: #f2f5ff; --gl-ink-2: #a9b5d6; --gl-halo: rgba(8, 12, 30, .55);
  --gl-req: #79b6ff; --gl-req-glow: rgba(80, 160, 255, .55);
  --gl-res: #55e3c0; --gl-res-glow: rgba(60, 220, 180, .45);
  --gl-glow: rgba(90, 150, 255, .62); --gl-pulse-edge: rgba(90, 150, 255, .62);
  --gl-fault: #ff5a4f; --gl-fault-glow: rgba(255, 80, 70, .55); --gl-fault-tint: rgba(255, 80, 70, .26);
  --gl-tube: rgba(120, 160, 255, .11); --gl-tube-core: rgba(120, 165, 255, .30); --gl-tube-hi: rgba(255, 255, 255, .30);
  --gl-chev: rgba(170, 200, 255, .40);
  --gl-tag-bg: rgba(22, 30, 56, .66); --gl-tag-edge: rgba(255, 255, 255, .24); --gl-tag-ink: #eef2ff;
  --gl-tag-hot-bg: #1f4fb8; --gl-tag-fault-bg: #b3261e;
  --gl-frost: rgba(14, 20, 40, .70);
  --gl-tip-bg: rgba(24, 32, 60, .62); --gl-tip-edge: rgba(255, 255, 255, .20);
  /* the system map's domain zones (graded floor -> rim; ink for zone labels, 4.5:1 or better on the floor and the rim) */
  --map-blue-floor: rgba(90, 150, 255, 0.16); --map-blue-rim: rgba(100, 160, 255, 0.34); --map-blue-ink: #c4daff;
  --map-green-floor: rgba(50, 210, 150, 0.14); --map-green-rim: rgba(60, 220, 160, 0.3); --map-green-ink: #b4f1d6;
  --map-violet-floor: rgba(165, 125, 255, 0.17); --map-violet-rim: rgba(175, 140, 255, 0.34); --map-violet-ink: #dacbff;
  --map-amber-floor: rgba(245, 180, 70, 0.14); --map-amber-rim: rgba(250, 190, 80, 0.3); --map-amber-ink: #fadfa6;
  --map-teal-floor: rgba(40, 205, 200, 0.14); --map-teal-rim: rgba(60, 220, 210, 0.3); --map-teal-ink: #b2f1ec;
}
.iso-glass {
  border-radius: 14px;
  background:
    radial-gradient(60% 55% at 18% 28%, var(--gl-blob1), transparent 70%),
    radial-gradient(55% 60% at 85% 72%, var(--gl-blob2), transparent 70%),
    radial-gradient(45% 45% at 62% 8%, var(--gl-blob3), transparent 70%),
    var(--gl-bg);
}
.iso-glass .s-plate-a { stop-color: var(--gl-plate-a); } .iso-glass .s-plate-b { stop-color: var(--gl-plate-b); }
.iso-glass .s-top-a { stop-color: var(--gl-top-a); } .iso-glass .s-top-b { stop-color: var(--gl-top-b); }
.iso-glass .s-left-a { stop-color: var(--gl-left-a); } .iso-glass .s-left-b { stop-color: var(--gl-left-b); }
.iso-glass .s-right-a { stop-color: var(--gl-right-a); } .iso-glass .s-right-b { stop-color: var(--gl-right-b); }
.iso-glass .s-glow { stop-color: var(--gl-glow); } .iso-glass .s-glow-0 { stop-color: var(--gl-glow); stop-opacity: 0; }
.iso-glass .s-fault { stop-color: var(--gl-fault-glow); } .iso-glass .s-fault-0 { stop-color: var(--gl-fault-glow); stop-opacity: 0; }
.iso-glass .s-shadow { stop-color: var(--gl-shadow); } .iso-glass .s-shadow-0 { stop-color: var(--gl-shadow); stop-opacity: 0; }
.iso-glass .s-req { stop-color: var(--gl-req-glow); } .iso-glass .s-req-0 { stop-color: var(--gl-req-glow); stop-opacity: 0; }
.iso-glass .s-res { stop-color: var(--gl-res-glow); } .iso-glass .s-res-0 { stop-color: var(--gl-res-glow); stop-opacity: 0; }
.iso-glass .s-spec { stop-color: #fff; stop-opacity: 0; } .iso-glass .s-spec-1 { stop-color: #fff; stop-opacity: .55; }
.iso-glass .s-pulse { stop-color: #fff; stop-opacity: .9; } .iso-glass .s-pulse-0 { stop-color: var(--gl-pulse-edge); }
.iso-glass .iso-floor-shadow { opacity: .7; }
.iso-glass .iso-slab { fill: var(--gl-slab); }
.iso-glass .iso-plate-edge { fill: none; stroke: var(--gl-plate-edge); stroke-width: 1.2; }
.iso-glass .iso-plate-grid line { stroke: var(--gl-plate-line); stroke-width: 1; }
.iso-glass .iso-contact { opacity: .55; }
.iso-glass .iso-halo { pointer-events: none; transition: opacity .25s var(--ease-out); }
.iso-under .iso-tube { fill: none; stroke: var(--gl-tube); stroke-linecap: round; stroke-linejoin: round; transition: stroke .2s var(--ease-out); }
.iso-under .iso-tube-core { fill: none; stroke: var(--gl-tube-core); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.iso-under .iso-tube-hi { fill: none; stroke: var(--gl-tube-hi); stroke-width: 1; stroke-linecap: round; stroke-linejoin: round; opacity: .8; }
.iso-under .iso-chev { fill: none; stroke: var(--gl-chev); stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
.iso-under .iso-duct { transition: opacity .2s var(--ease-out); }
.iso-under .iso-duct.is-tip .iso-tube { stroke: var(--gl-glow); }
.iso-under .iso-duct.is-dim { opacity: .35; }
.iso-under .iso-mover, .iso-under .iso-mover.req, .iso-under .iso-mover.res { fill: none; stroke: none; }
.iso-under .iso-mover.req .iso-mover-core { fill: var(--gl-req); }
.iso-under .iso-mover.res .iso-mover-core { fill: var(--gl-res); }
.iso-under .iso-mover-spark { fill: #fff; opacity: .85; }
.iso-under .iso-mover.is-trace .iso-mover-core { stroke: #fff; stroke-width: 1; }
.iso-under .iso-mover.is-trace .iso-mover-glow { opacity: 1; }
.iso-glass.iso-tracing .iso-mover:not(.is-trace) { opacity: .4; }
.iso-glass .iso-frost { fill: var(--gl-frost); }
.iso-glass .iso-back { stroke: var(--gl-back); stroke-width: 1; }
.iso-glass .iso-gf { stroke: none; }
.iso-glass .iso-spec { opacity: .55; }
.iso-glass .iso-pulse { fill-opacity: 1; }
.iso-glass .iso-tint { fill: var(--gl-fault-tint); opacity: 0; transition: opacity .3s var(--ease-out); }
.iso-glass .iso-hl { fill: none; stroke: var(--gl-hi); stroke-width: 1.1; stroke-linecap: round; opacity: .9; }
.iso-glass .iso-top-rim { fill: none; stroke: var(--gl-hi); stroke-width: 1.2; opacity: .4; }
.iso-glass .iso-rim-out { fill: none; stroke: var(--gl-edge); stroke-width: 2.6; }
.iso-glass .iso-rim-in { fill: none; stroke: var(--gl-hi); stroke-width: 1.1; }
.iso-glass .iso-icon { stroke: var(--gl-ink); opacity: .88; }
.iso-glass .iso-label {
  fill: var(--gl-ink); font-stretch: 100%; text-transform: none; letter-spacing: -0.005em; font-weight: 650; font-size: 12px;
  paint-order: stroke; stroke: var(--gl-halo); stroke-width: 3px; stroke-linejoin: round;
}
.iso-glass .iso-label-s { font-size: 11px; }
.iso-glass .iso-part { transition: opacity .2s var(--ease-out); }
.iso-glass .iso-part.is-fault .iso-tint { opacity: 1; }
.iso-glass .iso-part.is-dim { opacity: .55; }
.iso-glass .iso-part.is-focus .iso-rim-in { stroke: var(--gl-req); stroke-width: 1.6; }
.iso-glass .iso-focus-ring { fill: none; stroke: var(--gl-req); stroke-width: 2; opacity: 0; }
.iso-glass .iso-part:focus-visible .iso-focus-ring { opacity: 1; }
.iso-glass.iso-tips .iso-part:focus-visible .iso-top { stroke: none; }
.iso-glass.iso-pickable .iso-part:hover { transform: none; }
.iso-glass .iso-tag rect { fill: var(--gl-tag-bg); stroke: var(--gl-tag-edge); stroke-width: 1; }
.iso-glass .iso-tag text { fill: var(--gl-tag-ink); }
.iso-glass .iso-tag.is-hot rect { fill: var(--gl-tag-hot-bg); stroke: rgba(255, 255, 255, .7); stroke-width: 1; }
.iso-glass .iso-tag.is-hot text { fill: #fff; }
.iso-glass .iso-tag.is-fault rect { fill: var(--gl-tag-fault-bg); stroke: rgba(255, 255, 255, .7); }
.iso-glass .iso-tag.is-fault text { fill: #fff; }
.iso-glass .iso-leader { stroke: var(--gl-ink-2); }
.iso-glass .iso-callout .iso-dot { fill: var(--gl-ink-2); }
.iso-glass .iso-balloon { fill: var(--gl-tag-bg); stroke: var(--gl-ink-2); }
.iso-glass .iso-num { fill: var(--gl-ink); }
/* low quality: no blurred copy of the traffic behind the glass (translucency and gradients stay).
   The ducts' and dots' rules hang off .iso-under, not .iso-glass: the see-through is a <use> of that group, and
   its shadow copy has .iso-under as its root but no .iso-glass ancestor (an unmatched rule left the copy's bent
   ducts filled black). */
.iso-glass.iso-q-low .iso-see { display: none; }

/* ---------- the system map pieces (zones, the canvas dots layer, a camera's view, shells, fades) ----------
   Zones: a domain is a floor region graded from --map-<hue>-floor to its brighter rim (glass) or a flat tint inside
   an ink hairline (technical); a boundary is a dashed rounded frame. Their names lie flat on the floor just outside
   the back edge, condensed uppercase like every drawing label: the hue's ink on glass, ink on technical. */
.iso-zone.hue-blue, .map-hue.hue-blue { --zf: var(--map-blue-floor); --zr: var(--map-blue-rim); --zi: var(--map-blue-ink); }
.iso-zone.hue-green, .map-hue.hue-green { --zf: var(--map-green-floor); --zr: var(--map-green-rim); --zi: var(--map-green-ink); }
.iso-zone.hue-violet, .map-hue.hue-violet { --zf: var(--map-violet-floor); --zr: var(--map-violet-rim); --zi: var(--map-violet-ink); }
.iso-zone.hue-amber, .map-hue.hue-amber { --zf: var(--map-amber-floor); --zr: var(--map-amber-rim); --zi: var(--map-amber-ink); }
.iso-zone.hue-teal, .map-hue.hue-teal { --zf: var(--map-teal-floor); --zr: var(--map-teal-rim); --zi: var(--map-teal-ink); }
.iso-glass .s-zf-blue { stop-color: var(--map-blue-floor); } .iso-glass .s-zr-blue { stop-color: var(--map-blue-rim); }
.iso-glass .s-zf-green { stop-color: var(--map-green-floor); } .iso-glass .s-zr-green { stop-color: var(--map-green-rim); }
.iso-glass .s-zf-violet { stop-color: var(--map-violet-floor); } .iso-glass .s-zr-violet { stop-color: var(--map-violet-rim); }
.iso-glass .s-zf-amber { stop-color: var(--map-amber-floor); } .iso-glass .s-zr-amber { stop-color: var(--map-amber-rim); }
.iso-glass .s-zf-teal { stop-color: var(--map-teal-floor); } .iso-glass .s-zr-teal { stop-color: var(--map-teal-rim); }
.iso-zone { pointer-events: none; }
.iso-zone-title { fill: var(--ink); font-stretch: 75%; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; paint-order: stroke; stroke: var(--paper); stroke-width: 3px; stroke-linejoin: round; }
.iso-zone-title.is-small { font-weight: 650; letter-spacing: .08em; }
.iso-zone-domain .iso-zone-fill { fill: var(--zf); }
.iso-zone-rim { fill: none; stroke: var(--ink); stroke-opacity: .32; stroke-width: 1.1; stroke-linejoin: round; }
.iso-zone-frame { fill: none; stroke: var(--ink); stroke-opacity: .7; stroke-width: 1.1; stroke-dasharray: 6 4; stroke-linejoin: round; }
.iso-glass .iso-zone-rim { stroke: var(--zr); stroke-opacity: 1; stroke-width: 1.6; }
.iso-glass .iso-zone-hi { fill: none; stroke: var(--gl-plate-edge); stroke-width: 1; opacity: .5; }
.iso-glass .iso-zone-frame { fill: color-mix(in srgb, var(--zr) 14%, transparent); stroke: var(--zi); stroke-opacity: .5; stroke-width: 1.4; stroke-dasharray: 7 5; stroke-linecap: round; }
.iso-glass .iso-zone-title { fill: var(--zi); stroke: var(--gl-halo); stroke-width: 2.5px; }
/* the dots canvas sits exactly over the svg (js/viz-iso.js places and sizes it); a camera's svg fills its parent */
.iso-stack { position: relative; }
.iso-stack.iso-stack-viewed { width: 100%; height: 100%; }
.iso-dots-canvas { position: absolute; left: 0; top: 0; pointer-events: none; }
.iso.iso-viewed { width: 100%; height: 100%; max-width: none; overflow: hidden; }
/* a shell: the part's outline, dashed, over a faint frost, so the components inside it read */
.iso-shell { display: none; }
.iso-part.is-shell > :not(.iso-shell):not(.iso-focus-ring):not(.iso-shell-title) { display: none; }
.iso-part.is-shell > .iso-focus-ring:has(~ .iso-shell.is-open) { display: none; }
.iso-part.is-shell > .iso-shell { display: inline; fill: color-mix(in srgb, var(--paper) 35%, transparent); stroke: var(--ink); stroke-opacity: .6; stroke-width: 1.1; stroke-dasharray: 5 4; stroke-linejoin: round; }
.iso-glass .iso-part.is-shell > .iso-shell { fill: var(--gl-plate-b); stroke: var(--gl-ink-2); stroke-opacity: .75; stroke-width: 1.3; }
.iso-tips .iso-part.is-shell:focus-visible > .iso-shell { stroke: var(--steel); stroke-opacity: 1; stroke-dasharray: none; }
.iso-glass.iso-tips .iso-part.is-shell:focus-visible > .iso-shell { stroke: var(--gl-req); }
.iso-glass .iso-contact.is-shell, .iso-glass .iso-halo.is-shell, .iso-tag.is-shell { display: none; }
/* an opened shell (shell(id, true, { at, size, title })): a dashed frame on the floor, its title flat behind it */
.iso-glass .iso-part.is-shell > .iso-shell.is-open { fill: color-mix(in srgb, var(--gl-plate-a) 22%, transparent); stroke: var(--gl-ink-2); stroke-opacity: .6; stroke-width: 1.4; stroke-dasharray: 7 5; stroke-linecap: round; }
.iso-shell-title { fill: var(--ink); }
.iso-glass .iso-shell-title { fill: var(--gl-ink-2); stroke: var(--gl-halo); stroke-width: 2.5px; }
/* labelScale(): far out, the names keep a halo wide enough to read over ducts and zones */
.iso-labels-big .iso-label { paint-order: stroke; stroke: var(--paper); stroke-width: 3px; stroke-linejoin: round; }
.iso-glass.iso-labels-big .iso-label { stroke: var(--gl-halo); }
/* show(ids, on): a short fade, then hidden (no pointer, no focus) */
.iso .iso-fade { transition: opacity .22s var(--ease-out), visibility 0s linear 0s, transform .15s ease-out; }
.iso .iso-fade.is-off { opacity: 0; visibility: hidden; pointer-events: none; transition: opacity .22s var(--ease-out), visibility 0s linear .22s; }
@media (prefers-reduced-motion: reduce) { .iso .iso-fade, .iso .iso-fade.is-off { transition: none; } }

/* tooltips on parts and ducts: fixed to the viewport, so a scrolling or panned drawing never clips them */
.iso-tip {
  position: fixed; left: 0; top: 0; z-index: 1000; max-width: 260px; pointer-events: none;
  opacity: 0; visibility: hidden; transform: translateY(3px);
  transition: opacity .14s var(--ease-out), transform .14s var(--ease-out), visibility 0s linear .14s;
  font-family: var(--font-body); font-size: 13px; line-height: 1.4;
}
.iso-tip.on { opacity: 1; visibility: visible; transform: none; transition: opacity .14s var(--ease-out), transform .14s var(--ease-out); }
.iso-tip.on { pointer-events: auto; }   /* hoverable: the pointer can travel from the part onto the card and its link */
.iso-tip [hidden] { display: none; }
.iso-tip .t-name { display: block; font-weight: 700; }
.iso-tip .t-role { display: block; margin-top: 2px; }
.iso-tip .t-num { display: block; margin-top: 5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.iso-tip .t-learn { display: inline-block; margin-top: 6px; font-weight: 600; }
.iso-tip-technical { background: var(--paper); color: var(--ink); border: 1px solid var(--ink); border-radius: 3px; padding: 8px 10px; }
.iso-tip-technical .t-name { font-stretch: 75%; text-transform: uppercase; letter-spacing: .05em; }
.iso-tip-technical .t-role { color: var(--text-2); }
.iso-tip-technical .t-num { color: var(--steel); }
.iso-tip-technical .t-num.bad { color: var(--cut); }
.iso-tip-glass {
  color: var(--gl-ink); background: var(--gl-tip-bg); border: 1px solid var(--gl-tip-edge); border-radius: 14px; padding: 10px 13px;
  -webkit-backdrop-filter: blur(16px) saturate(180%); backdrop-filter: blur(16px) saturate(180%);
  box-shadow: 0 10px 30px -10px rgba(20, 40, 100, .40), inset 0 1px 0 rgba(255, 255, 255, .55);
}
.iso-tip-glass .t-role { color: var(--gl-ink-2); }
.iso-tip-glass .t-num { color: var(--gl-req); }
.iso-tip-glass .t-num.bad { color: var(--gl-fault); }
.iso-tip-glass .t-learn { color: var(--gl-req); }
@media (prefers-reduced-motion: reduce) {
  .iso-tip, .iso-tip.on, .iso-glass .iso-halo, .iso-glass .iso-tint, .iso-glass .iso-part, .iso-under .iso-tube, .iso-under .iso-duct { transition: none; }
}

/* ---------- teardown page (systems/<id>/, js/system.js) ---------- */
/* The bold front: a big Archivo headline, wide space, the map large. Still calm: hairlines, no fills for show.
   One column: the title block, the map (its control bar, the stage, the follow caption and a break's numbers), the
   Services index, the sources. */
.system-main { padding: 64px 48px 96px; }
.page.system { max-width: 1320px; }
.sys-kicker { margin: 0 0 16px; font-size: var(--fs-small); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3); }
.sys-title { font-size: clamp(40px, 6.2vw, 80px); font-weight: 800; letter-spacing: -0.04em; line-height: 1; max-width: 13ch; }
.sys-lede { margin-top: 24px; font-size: 21px; line-height: 1.5; max-width: 46ch; color: var(--text-2); }
.sys-truth { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin: 20px 0 0; font-size: var(--fs-small); color: var(--text-3); }
.sys-truth .sep { color: var(--border-strong); }
.sys-truth a { font-weight: 600; }
.sys-h2 { font-size: 26px; letter-spacing: -0.025em; }
.sys-sub { margin: 6px 0 0; font-size: var(--fs-body-s); color: var(--text-2); line-height: 1.5; }

.sys-truth-2 { margin-top: 6px; }
/* picked in the parts list or the drawing: a steel outline on the part (glass: its focus ring) */
.iso-part.is-picked .iso-face { stroke: var(--steel); stroke-width: 2.2; }
.iso-glass .iso-part.is-picked .iso-focus-ring { opacity: 1; }
/* the live traffic bar on the stage: what the dots are, and Pause / Play */
.sys-live { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; margin: 0 0 0 auto; font-size: var(--fs-small); color: var(--text-2); }
.sys-live-l { font-weight: 700; color: var(--text); }
.sys-key { display: inline-flex; align-items: center; gap: 6px; color: var(--text-3); }
.sys-key i { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-left: 4px; }
.sys-key i.req { background: var(--gl-req); box-shadow: 0 0 0 3px var(--gl-req-glow); }
.sys-key i.res { background: var(--gl-res); box-shadow: 0 0 0 3px var(--gl-res-glow); margin-left: 10px; }
.sys-play { min-height: 36px; padding: 6px 14px 6px 10px; gap: 6px; }
.sys-play svg { width: 16px; height: 16px; }

/* the system map (js/map.js): a control bar, the stage (one glass scene under a camera, with zoom buttons, a minimap
   and a hint over it), the follow caption and a break's numbers under it. The stage is the machine: its overlays may
   use the glass tokens; everything around it stays paper and hairlines. */
.sys-map { margin-top: 44px; }
.map-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 32px; margin: 0 0 14px; }
.map-group { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.map-group-l { margin-right: 4px; font-size: var(--fs-small); font-weight: 700; color: var(--text); }
.map-chip {
  min-height: 36px; padding: 6px 14px; border: 1px solid var(--border-strong); border-radius: 999px; background: var(--surface); color: var(--text-2);
  font: inherit; font-size: var(--fs-ui); font-weight: 600; line-height: 1.2; cursor: pointer; transition: border-color .15s, color .15s;
}
.map-chip:hover { border-color: var(--text-3); color: var(--text); }
.map-chip[aria-pressed="true"] { border-color: var(--steel); color: var(--text); box-shadow: inset 0 0 0 1px var(--steel); }
.map-bar .sys-break-btn { min-height: 36px; gap: 10px; padding: 0 14px 0 8px; font-size: var(--fs-ui); }
.map-wrap { position: relative; }
.map-stage {
  position: relative; height: clamp(420px, 76vh, 860px); border-radius: 16px; overflow: hidden; background: var(--gl-bg);
  /* one finger scrolls the page past the map (pan-y), two fingers move and pinch it (js/map.js); no zoom or pan by the browser */
  container: map / inline-size; touch-action: pan-y; cursor: grab; user-select: none; -webkit-user-select: none; outline: none;
}
.map-stage:focus-visible { box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--steel); }
.map-stage.is-dragging { cursor: grabbing; }
.map-canvas { position: absolute; inset: 0; }
.map-canvas .iso-glass { border-radius: 0; }
/* far out the names grow (labelScale) and the role icons step aside, so a name never runs into its counter */
.map-stage.is-far .iso-part .iso-icon { display: none; }
.map-ui { position: absolute; z-index: 2; margin: 0; }
.map-zoom { top: 12px; left: 12px; display: flex; flex-direction: column; gap: 6px; }
.map-btn {
  display: grid; place-items: center; width: 38px; height: 38px; padding: 0; border: 1px solid var(--gl-tag-edge); border-radius: 12px;
  background: var(--gl-tag-bg); color: var(--gl-ink); cursor: pointer; transition: background .15s var(--ease-out);
  -webkit-backdrop-filter: blur(12px) saturate(160%); backdrop-filter: blur(12px) saturate(160%);
}
.map-btn:hover { background: var(--gl-tip-edge); }
.map-btn:focus-visible { outline: 2px solid var(--gl-req); outline-offset: 2px; }
.map-btn svg { width: 18px; height: 18px; }
.map-btn-l { display: none; }
/* a narrow stage opens on the watch path, so Fit says what it does while the whole system is not showing */
.map-stage.is-narrow:not(.is-fit) .map-fit { display: flex; flex-direction: row; justify-content: center; align-items: center; align-self: flex-start; width: auto; gap: 6px; padding: 0 12px 0 10px; font-size: var(--fs-micro); font-weight: 700; }
.map-stage.is-narrow:not(.is-fit) .map-fit .map-btn-l { display: inline; white-space: nowrap; }
.map-mini {
  left: 12px; bottom: 12px; width: 188px; padding: 6px; border: 1px solid var(--gl-tag-edge); border-radius: 12px;
  background: var(--gl-tag-bg); cursor: pointer; touch-action: none;
  -webkit-backdrop-filter: blur(12px) saturate(160%); backdrop-filter: blur(12px) saturate(160%);
}
.map-mini svg { display: block; width: 100%; height: auto; overflow: hidden; }
.mm-dom { fill: var(--zf); stroke: var(--zr); stroke-width: 1.2; vector-effect: non-scaling-stroke; }
.mm-part { fill: var(--gl-ink-2); }
.mm-view { fill: color-mix(in srgb, var(--gl-req) 12%, transparent); stroke: var(--gl-req); stroke-width: 1.6; vector-effect: non-scaling-stroke; }
.map-hint {
  right: 12px; bottom: 12px; max-width: calc(100% - 230px); padding: 6px 12px; border-radius: 999px; background: var(--gl-tag-bg); color: var(--gl-ink-2);
  font-size: var(--fs-micro); font-weight: 600; line-height: 1.35; pointer-events: none; transition: opacity .4s var(--ease-out);
}
.map-hint.is-gone { opacity: 0; }
.sys-map.is-following .map-hint { display: none; }
/* a brief message over the middle of the stage when the page took the gesture ("Use Ctrl + scroll to zoom") */
.map-gesture {
  top: 50%; left: 50%; translate: -50% -50%; max-width: calc(100% - 48px); padding: 10px 18px; border-radius: 999px; background: var(--gl-tip-bg); color: var(--gl-ink);
  border: 1px solid var(--gl-tip-edge); font-size: var(--fs-small); font-weight: 700; line-height: 1.35; text-align: center; pointer-events: none; opacity: 0;
  transition: opacity .25s var(--ease-out); -webkit-backdrop-filter: blur(12px) saturate(160%); backdrop-filter: blur(12px) saturate(160%);
}
.map-gesture.is-on { opacity: 1; }
/* a boundary's small name is left out where it would be under 10px on screen (js/map.js); an opened service's own title stays */
.map-stage .iso-zone-boundary .iso-zone-title { transition: opacity .2s; }
.map-stage.is-bnd-quiet .iso-zone-boundary .iso-zone-title:not(.iso-shell-title) { opacity: 0; }
/* the traffic key and Pause: a frosted strip over the stage's top right corner */
.map-live.sys-live {
  top: 12px; right: 12px; max-width: calc(100% - 86px); justify-content: flex-end; gap: 4px 14px; margin: 0; padding: 4px 4px 4px 14px;
  border: 1px solid var(--gl-tag-edge); border-radius: 999px; background: var(--gl-tag-bg); color: var(--gl-ink-2);
  -webkit-backdrop-filter: blur(12px) saturate(160%); backdrop-filter: blur(12px) saturate(160%);
}
.map-live .sys-live-l { color: var(--gl-ink); }
.map-live .sys-key { color: var(--gl-ink-2); }
.map-live .sys-play { min-height: 34px; border-color: transparent; }
/* following a request: a caption card at the bottom of the stage, the step in steel, Back / Next / Explore freely */
.map-follow {
  left: 50%; bottom: 12px; transform: translateX(-50%); width: min(780px, calc(100% - 24px)); box-sizing: border-box;
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 10px 20px; padding: 14px 14px 14px 18px;
  border: 1px solid var(--gl-tip-edge); border-radius: 16px; background: var(--gl-tip-bg); color: var(--gl-ink);
  -webkit-backdrop-filter: blur(16px) saturate(180%); backdrop-filter: blur(16px) saturate(180%);
  box-shadow: 0 10px 30px -10px rgba(20, 40, 100, .40), inset 0 1px 0 rgba(255, 255, 255, .55);
  cursor: auto; user-select: text; -webkit-user-select: text;
}
@media (min-width: 480px) {
  .map-follow { left: calc(12px + 188px + 12px); right: 12px; width: auto; max-width: 780px; transform: none; margin: 0; }
}
.map-follow[hidden], .map-beacon[hidden] { display: none; }
.map-beacon {
  left: 0; top: 0; z-index: 1; width: 34px; height: 34px; margin: -17px 0 0 -17px; border: 2px solid var(--gl-req); border-radius: 50%;
  pointer-events: none; animation: map-beacon 1.6s var(--ease-out) infinite;
}
@keyframes map-beacon { from { opacity: .95; scale: .6; } to { opacity: .15; scale: 1.3; } }
.map-follow-k { margin: 0; font-size: var(--fs-small); color: var(--gl-ink-2); }
.map-follow-j { font-weight: 700; color: var(--gl-ink); }
.map-follow .sys-count { color: var(--gl-req); white-space: nowrap; }
.map-follow .sys-step-text { min-height: 0; margin-top: 2px; font-size: 17px; color: var(--gl-ink); }
.map-follow .sys-step-nav { flex-wrap: nowrap; }
.map-exit { min-height: 44px; }
/* a stage under 700px wide (a phone, a small tablet) stacks the caption over its buttons, so the card stays short */
@container map (max-width: 700px) {
  .map-follow { grid-template-columns: minmax(0, 1fr); padding: 12px; }
  .map-follow .sys-step-nav .btn { flex: 1; padding-inline: 12px; }
}
/* touch screens: every control over and around the stage reaches the 44px commitment (--tap) */
@media (pointer: coarse) {
  .map-btn { width: var(--tap); height: var(--tap); }
  .map-chip, .map-bar .sys-break-btn, .map-live .sys-play { min-height: var(--tap); }
  .map-mini { min-width: var(--tap); min-height: var(--tap); padding: 10px; }
}
/* a break's numbers, under the map */
.sys-map .sys-break { margin-top: 18px; }
.sys-map .sys-break[hidden] { display: none; }
.sys-break-k { margin: 0; font-size: var(--fs-body-s); font-weight: 700; color: var(--text); }
.sys-break.is-broken .sys-break-k { color: var(--cut); }
.sys-map .sys-metrics { margin-top: 12px; }
@media (min-width: 1100px) {
  /* the part panel sits over the map's right edge */
  .map-wrap > .sys-panel { position: absolute; z-index: 3; top: 62px; right: 12px; width: 360px; max-height: calc(100% - 74px); margin: 0; overflow-y: auto; overscroll-behavior: contain; box-shadow: var(--shadow-pop); }
}
@media (max-width: 479px) { .map-mini { display: none; } .map-hint { max-width: calc(100% - 24px); } }

/* the numbered balloons of the list match the drawing's */
.sys-num {
  display: inline-grid; place-items: center; flex: none; width: 24px; height: 24px; border-radius: 50%;
  border: 1.3px solid var(--steel); color: var(--steel); background: var(--paper);
  font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1;
}
.sys-tag { flex: none; padding: 1px 8px; border: 1px dashed var(--border-strong); border-radius: 999px; font-size: var(--fs-micro); font-weight: 600; color: var(--text-3); white-space: nowrap; line-height: 1.5; }

/* the Services index: every part, grouped by its domain on the map (a swatch in the domain's hue) */
.sys-services { margin-top: 72px; }
.sys-svc-groups { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 290px), 1fr)); gap: 32px 40px; margin-top: 24px; }
.sys-svc-h { display: flex; align-items: center; gap: 10px; margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }
.sys-svc-sw { flex: none; width: 14px; height: 14px; border-radius: 999px; background: var(--zf); box-shadow: inset 0 0 0 1.5px var(--zr); }
.sys-svc-ic { flex: none; width: 20px; height: 20px; fill: none; stroke: var(--text-2); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.sys-part-list { list-style: none; margin: 12px 0 0; padding: 0; border-top: 1px solid var(--border); }
.sys-part-btn {
  display: flex; align-items: center; gap: 12px; width: 100%; min-height: 46px; padding: 8px 10px;
  border: 0; border-bottom: 1px solid var(--border); background: transparent; color: var(--text);
  font-size: var(--fs-body-s); font-weight: 600; text-align: left; cursor: pointer; transition: background .15s;
}
.sys-part-btn:hover { background: var(--wash); }
.sys-part-btn[aria-expanded="true"] { background: var(--accent-bg); }
.sys-part-l { flex: 1; min-width: 0; }

/* the part panel: inline above the list on wide screens, a bottom sheet below 1100px */
.sys-panel { margin-top: 18px; padding: 18px 18px 16px; border: 1px solid var(--border-strong); border-radius: var(--radius-lg); background: var(--surface); }
.sys-panel[hidden] { display: none; }
.sys-panel-head { display: flex; align-items: center; gap: 12px; }
.sys-panel-t { flex: 1; min-width: 0; font-size: 22px; font-weight: 800; letter-spacing: -0.02em; outline: none; }
.sys-panel-close { margin: -6px -8px -6px 0; }
.sys-panel-where { margin: 2px 0 0; font-size: var(--fs-small); font-weight: 600; color: var(--text-3); }
.sys-panel-where:empty { display: none; }
.sys-panel-line { margin: 10px 0 0; font-size: var(--fs-body); line-height: 1.55; color: var(--text); }
.sys-learn { display: inline-flex; align-items: center; min-height: 44px; margin-top: 6px; font-size: var(--fs-body); font-weight: 700; }
.sys-learn-arrow { margin-left: .35em; }
/* the systems index: one large row per teardown, a plain-box drawing beside its name */
.page.systems { max-width: 1000px; }
.sys-rows { list-style: none; margin: 48px 0 0; padding: 0; display: flex; flex-direction: column; gap: 16px; }
.sys-row {
  display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); align-items: center; gap: 12px 32px;
  padding: 20px 28px 20px 20px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text);
}
.sys-row:hover { border-color: var(--link); text-decoration: none; color: var(--text); }
.sys-thumb { min-width: 0; }
.sys-thumb .iso { width: 100%; height: auto; pointer-events: none; }
.sys-row-body { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.sys-row-meta { font-size: var(--fs-small); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3); }
.sys-row-name { margin: 0; font-size: clamp(28px, 4vw, 44px); font-weight: 800; letter-spacing: -0.035em; line-height: 1.05; }
.sys-row-blurb { font-size: var(--fs-lead); line-height: 1.45; color: var(--text-2); }
.sys-row-go { display: inline-flex; align-items: center; gap: .4em; min-height: 44px; font-weight: 700; color: var(--link); }
.sys-row:hover .sys-row-go span { transform: translateX(3px); }
.sys-row-go span { transition: transform .18s var(--ease-out); }
.sys-books { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 4px; }
.sys-books .lbl { margin-right: 4px; font-size: var(--fs-small); font-weight: 600; color: var(--text-3); }
.sys-basis { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 6px; margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--border); font-size: var(--fs-small); color: var(--text-2); line-height: 1.5; }
.sys-basis-k { font-weight: 700; color: var(--text); }
.sys-basis .sys-src-meta { color: var(--text-3); }

/* journeys */
.sys-seg { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 18px; }
.sys-seg button {
  display: flex; align-items: flex-start; gap: 10px; min-height: 56px; padding: 12px 14px;
  border: 1px solid var(--border-strong); border-radius: 12px; background: var(--surface); color: var(--text-2);
  font-size: var(--fs-ui); font-weight: 600; line-height: 1.35; text-align: left; cursor: pointer; transition: border-color .15s, color .15s;
}
.sys-seg button:hover { border-color: var(--text-3); color: var(--text); }
.sys-seg button[aria-pressed="true"] { border-color: var(--steel); color: var(--text); box-shadow: inset 0 0 0 1px var(--steel); }
.sys-seg-n { flex: none; min-width: 1ch; color: var(--steel); font-weight: 800; font-variant-numeric: tabular-nums; }
.sys-stepper { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 16px 24px; margin-top: 20px; padding: 18px 0 20px; border-top: 1px solid var(--border); }
.sys-count { font-size: var(--fs-small); font-weight: 700; color: var(--steel); font-variant-numeric: tabular-nums; }
.sys-step-text { margin: 4px 0 0; min-height: 2.9em; font-size: 19px; line-height: 1.45; color: var(--text); }
.sys-step-nav { display: flex; gap: 8px; }
.sys-step-nav .btn { min-height: 44px; }
.sys-step-nav .btn svg { width: 18px; height: 18px; }
.sys-step-nav .btn[aria-disabled="true"] { opacity: .45; cursor: default; }
.sys-step-nav .btn[aria-disabled="true"]:active { transform: none; }

/* break it: the switch, the metrics in fixed slots (values jump, never count), the one-line caption */
.sys-break { padding-top: 20px; border-top: 1px solid var(--border); }
.sys-break-btn {
  display: inline-flex; align-items: center; gap: 12px; min-height: 44px; padding: 0 16px 0 10px;
  border: 1px solid var(--border-strong); border-radius: 999px; background: var(--surface); color: var(--text);
  font-size: var(--fs-body-s); font-weight: 700; cursor: pointer; transition: border-color .15s, color .15s;
}
.sys-break-btn:hover { border-color: var(--text-3); }
.sys-switch { position: relative; flex: none; width: 32px; height: 18px; border-radius: 999px; background: var(--surface-3); transition: background .15s; }
.sys-switch::after { content: ""; position: absolute; left: 2px; top: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--paper); box-shadow: 0 0 0 1px var(--border-strong); transition: transform .15s var(--ease-out); }
.sys-break-btn[aria-pressed="true"] { border-color: var(--cut); color: var(--cut); }
.sys-break-btn[aria-pressed="true"] .sys-switch { background: var(--cut); }
.sys-break-btn[aria-pressed="true"] .sys-switch::after { transform: translateX(14px); box-shadow: none; }
.sys-metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; margin-top: 16px; }
.sys-metric { display: grid; gap: 2px; padding: 14px 16px; border: 1px solid var(--border); border-radius: 12px; }
.sys-metric-l { font-size: var(--fs-small); font-weight: 600; color: var(--text-3); }
.sys-metric-v { font-variant-numeric: tabular-nums; white-space: nowrap; }
.sys-metric-v b { font-size: 30px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.15; color: var(--text); }
.sys-metric-u { font-size: var(--fs-small); color: var(--text-2); }
.sys-metric.is-broken { border-color: color-mix(in srgb, var(--cut) 40%, var(--border)); }
.sys-metric.is-broken b { color: var(--cut); }
.sys-bar { display: block; height: 4px; margin-top: 8px; border-radius: 2px; background: var(--surface-3); overflow: hidden; }
.sys-bar i { display: block; height: 100%; background: var(--steel); }
.sys-metric.is-broken .sys-bar i { background: var(--cut); }
.sys-break-cap { margin: 12px 0 0; font-size: var(--fs-body-s); color: var(--text-2); }
.sys-journeys.is-broken .sys-break-cap { color: var(--text); font-weight: 600; }
.sys-note { margin: 4px 0 0; font-size: var(--fs-micro); color: var(--text-3); }

/* sources */
.sys-sources { margin-top: 80px; padding-top: 28px; border-top: 1px solid var(--border); outline: none; }
.sys-src-list { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); gap: 0 40px; margin: 20px 0 0; padding: 0; }
.sys-src-list li { display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: 10px; padding: 12px 0; border-bottom: 1px solid var(--border); }
.sys-src-id { font-size: var(--fs-small); font-weight: 700; color: var(--steel); font-variant-numeric: tabular-nums; line-height: 1.6; }
.sys-src-body a { font-weight: 600; color: var(--text); }
.sys-src-body a:hover { color: var(--link); }
.sys-src-meta { display: block; font-size: var(--fs-small); color: var(--text-3); }

@media (max-width: 1099px) {
  /* the bottom sheet is modal: the page behind it stays put, and a scrim sits between */
  body.sys-sheet-open { overflow: hidden; }
  .sys-scrim { position: fixed; inset: 0; z-index: 49; background: rgba(0, 0, 0, .45); }
  .sys-panel {
    position: fixed; z-index: 50; bottom: 0; left: max(0px, calc(50% - 360px)); right: max(0px, calc(50% - 360px));
    max-height: 70vh; margin: 0; overflow-y: auto; overscroll-behavior: contain;
    padding: 18px 16px calc(16px + env(safe-area-inset-bottom));
    border-radius: 16px 16px 0 0; border-bottom: 0; box-shadow: var(--shadow-pop);
  }
}
@media (max-width: 640px) {
  .system-main { padding: 28px 16px 40px; }
  .sys-rows { margin-top: 32px; }
  .sys-row { grid-template-columns: minmax(0, 1fr); padding: 14px 16px 6px; }
  .sys-lede { margin-top: 16px; font-size: var(--fs-lead); }
  .sys-map { margin-top: 28px; }
  /* the map: its own strip, 70% of the screen; one finger pans it, two pinch, the page scrolls outside it */
  .map-stage { height: max(360px, 70vh); }
  .map-bar { gap: 10px; }
  .map-group { width: 100%; gap: 6px; }
  .map-group-l { flex-basis: 100%; }
  .map-live.sys-live { justify-content: flex-start; border-radius: 16px; padding: 6px 4px 6px 12px; font-size: var(--fs-micro); }
  .map-live .sys-key { order: 3; flex-basis: 100%; margin-bottom: 2px; }
  .map-live .sys-play { margin-left: auto; }
  .map-follow { grid-template-columns: minmax(0, 1fr); padding: 12px; }
  /* the caption is at most three lines (the full sentence is in the live region); the card stays small enough to keep the request in view */
  .map-follow .sys-step-text { font-size: 15px; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden; }
  /* while following, the traffic strip is just a Pause button (its words stay for assistive technology) */
  .sys-map.is-following .map-live.sys-live { padding: 3px; gap: 0; border-radius: 999px; }
  .sys-map.is-following .map-live .sys-key { display: none; }
  .sys-map.is-following .map-live .sys-live-l, .sys-map.is-following .map-live .sys-play span {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  }
  .sys-map.is-following .map-live .sys-play { width: max(34px, var(--tap)); height: max(34px, var(--tap)); min-height: 0; padding: 0; justify-content: center; margin: 0; }
  .map-follow .sys-step-nav .btn { padding-inline: 12px; }
  .map-hint { max-width: calc(100% - 24px); }
  .sys-step-text { font-size: 17px; }
  .sys-step-nav .btn { flex: 1; }
  .sys-services { margin-top: 56px; }
  .sys-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .sys-metric { padding: 12px; }
  .sys-metric-v { white-space: normal; }
  .sys-metric-v b { font-size: 24px; }
  .sys-sources { margin-top: 56px; }
}
