/* ═══════════════════════════════════════════════════════════
   Google Cloud Services Explained — shared.css
   ─────────────────────────────────────────────────────────── */

/* ── Variables ───────────────────────────────────────────────
   Unified IT Playbook design tokens (shared vocabulary with
   portal.css). Light is the default (:root); dark overrides live
   in [data-theme="dark"]. Brand accents (violet #7C3AED / blue
   #4285F4 / cyan) are constant across themes.
   Derived from the Claude Design "IT Playbook" handoff.
   ──────────────────────────────────────────────────────────── */
:root{
  /* ---- Brand (constant across themes) ---- */
  --accent-violet:#7c3aed;--accent-blue:#4285f4;--accent-cyan:#15b6cf;
  --grad-brand:linear-gradient(135deg,#7c3aed 0%,#4285f4 100%);
  --grad-audio:linear-gradient(90deg,#15b6cf,#4285f4);

  /* ---- Surfaces / text / borders (LIGHT) ---- */
  --bg-deep:#eef0f6;--bg-raised:#ffffff;--surface:#ffffff;--surface-hover:#f1f3f9;
  --fg:#0c1018;--fg-muted:#4a5365;--fg-subtle:#5b6478;
  --border:rgba(12,16,24,.10);--border-strong:rgba(12,16,24,.18);--border-bright:rgba(124,58,237,.45);
  --primary:#4285f4;--primary-hover:#3b78e0;--primary-press:#2f66c8;--on-primary:#ffffff;
  /* ---- Code blocks (LIGHT) ---- */
  --code-bg:#f6f8fb;--code-fg:#1f2533;--code-bd:rgba(12,16,24,.12);
  --code-cmt:#7a8595;--code-k:#0550ae;--code-s:#0a7b34;--code-n:#953800;--code-nm:#6f42c1;--code-path:#9a3d00;--code-ds:#0550ae;

  /* ---- Radii ---- */
  --r-xs:6px;--r-sm:8px;--r-md:12px;--r-lg:16px;--r-xl:22px;--r-2xl:28px;--r-pill:999px;
  /* ---- Spacing (4px base) ---- */
  --s-1:4px;--s-2:8px;--s-3:12px;--s-4:16px;--s-5:20px;--s-6:24px;
  --s-8:32px;--s-10:40px;--s-12:48px;--s-16:64px;--s-20:80px;--s-24:96px;
  /* ---- Elevation (LIGHT) ---- */
  --shadow-sm:0 1px 2px rgba(20,30,60,.08);
  --shadow-md:0 6px 18px -6px rgba(20,30,60,.14);
  --shadow-lg:0 20px 50px -16px rgba(20,30,60,.22);
  --shadow-card:0 1px 0 rgba(255,255,255,.7) inset,0 14px 34px -20px rgba(20,30,60,.30);
  /* ---- Motion ---- */
  --ease-out:cubic-bezier(.2,.7,.2,1);--ease-spring:cubic-bezier(.34,1.56,.64,1);
  --dur-fast:.14s;--dur:.24s;--dur-slow:.5s;
  /* ---- Themed scrollbar (LIGHT) ---- */
  --sb-track:var(--bg-deep);--sb-thumb:var(--border-strong);--sb-thumb-hover:var(--fg-subtle);
  /* ---- Reading scale (text-size control, Phase 4) ---- */
  --reading-scale:1;

  /* ---- Legacy course aliases (retuned to the new palette) ---- */
  --bg:#f6f7fb;--bg-sb:#f1f3f9;--bg-surf:#eef0f6;
  --bd:#d9dee8;--bd2:#e7eaf1;
  --tx:#0c1018;--tx2:#4a5365;--tx3:#5b6478;
  --ac:#1a64d4;--ac-dim:#e9f0fe;--ac-dk:#14509f;--tip-bg:#ffffff;--tip-tx:#0c1018;--tip-bd:#e3e5e8;
  --c-err:#c5221f;--c-err-bg:#fce8e6;--c-err-bd:#f5c6c5;
  --c-ok:#137333;--c-ok-bg:#e6f4ea;--c-ok-bd:#a8d5b5;
  --c-warn:#e37400;--c-warn-bg:#fef9e7;--c-warn-bd:#fcd380;--flame:#f97316;
  --c-info:#1557b0;--c-info-bg:#e8f0fe;--c-info-bd:#aecbfa;
  --tag-compute-bg:#e3f2fd;--tag-compute-tx:#0d47a1;
  --tag-storage-bg:#fce4ec;--tag-storage-tx:#880e4f;
  --tag-db-bg:#e8eaf6;--tag-db-tx:#283593;
  --tag-serverless-bg:#e8f5e9;--tag-serverless-tx:#1b5e20;
  --tag-managed-bg:#f1f3f4;--tag-managed-tx:#5f6368;
  --tag-infra-bg:#f3e5f5;--tag-infra-tx:#4a148c;
  --tag-analytics-bg:#e0f2f1;--tag-analytics-tx:#004d40;
  --tag-nosql-bg:#fff8e1;--tag-nosql-tx:#e65100;
  --fn:'Plus Jakarta Sans',-apple-system,sans-serif;
  --fd:'Instrument Serif',Georgia,serif;
  --fm:'JetBrains Mono',monospace;
  --sw:268px;--hh:58px;--cw:880px;--rw:280px;
}

/* Dark is the DEFAULT theme: these values apply unless the user explicitly
   picks light ([data-theme="light"]). data-theme="dark" still matches this,
   so the JS toggle + all [data-theme="dark"] component rules keep working. */
:root:not([data-theme="light"]){
  /* ---- Brand tints shift slightly brighter on dark ---- */
  --accent-cyan:#22d3ee;
  --grad-audio:linear-gradient(90deg,#22d3ee,#6e8bff);
  /* ---- Surfaces / text / borders (DARK) ---- */
  --bg-deep:#07090e;--bg-raised:#11141e;--surface:#1b2030;--surface-hover:#232a3c;
  --fg:#eef1f8;--fg-muted:#98a2b8;--fg-subtle:#79839a;
  --border:rgba(255,255,255,.08);--border-strong:rgba(255,255,255,.15);--border-bright:rgba(124,58,237,.55);
  --primary:#6e8bff;--primary-hover:#8aa0ff;--primary-press:#5572f0;--on-primary:#0a0c12;
  /* ---- Code blocks (DARK) ---- */
  --code-bg:#0e1320;--code-fg:#c9d4e6;--code-bd:rgba(255,255,255,.10);
  --code-cmt:#6b7689;--code-k:#79b8ff;--code-s:#7ee787;--code-n:#ffa657;--code-nm:#d2a8ff;--code-path:#ffb38a;--code-ds:#79b8ff;
  /* ---- Elevation (DARK) ---- */
  --shadow-sm:0 1px 2px rgba(0,0,0,.4);
  --shadow-md:0 6px 18px -6px rgba(0,0,0,.55);
  --shadow-lg:0 20px 50px -16px rgba(0,0,0,.7);
  --shadow-card:0 1px 0 rgba(255,255,255,.04) inset,0 12px 32px -16px rgba(0,0,0,.7);

  /* ---- Legacy course aliases (DARK) ---- */
  --bg:#0b0e16;--bg-sb:#0f131d;--bg-surf:#161a25;
  --bd:#2a3142;--bd2:#222838;
  --tx:#eef1f8;--tx2:#98a2b8;--tx3:#79839a;
  --ac:#6e8bff;--ac-dim:#1c2742;--ac-dk:#8aa0ff;--tip-bg:#1b2030;--tip-tx:#eef1f8;--tip-bd:#2a3142;
  --c-err:#ff6b6b;--c-err-bg:#2d1a1a;--c-err-bd:#5c2b2b;
  --c-ok:#69db7c;--c-ok-bg:#1a2d1e;--c-ok-bd:#2b5c36;
  --c-warn:#e89c00;--c-warn-bg:#2a2000;--c-warn-bd:#5c4500;--flame:#fb923c;
  --c-info:#4dabf7;--c-info-bg:#1c3a5e;--c-info-bd:#2d5a8e;
  --tag-compute-bg:#1c2a3a;--tag-compute-tx:#74b8f7;
  --tag-storage-bg:#2a1a20;--tag-storage-tx:#f7a8c4;
  --tag-db-bg:#1e1c3a;--tag-db-tx:#9e9ef7;
  --tag-serverless-bg:#1a2a1e;--tag-serverless-tx:#69db7c;
  --tag-managed-bg:#25262b;--tag-managed-tx:#909296;
  --tag-infra-bg:#2a1a30;--tag-infra-tx:#c99ef0;
  --tag-analytics-bg:#1a2a28;--tag-analytics-tx:#63d4c5;
  --tag-nosql-bg:#2a2010;--tag-nosql-tx:#f0c070;
}

/* ── Icon toggle ─────────────────────────────────────────── */
.icon-sun{display:none}
[data-theme="dark"] .icon-sun{display:block}
[data-theme="dark"] .icon-moon{display:none}

/* ── Reset ───────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;font-size:17px}
body{font-family:var(--fn);color:var(--tx);background:var(--bg);line-height:1.8;-webkit-font-smoothing:antialiased}
a{color:var(--ac);text-decoration:none}
a:hover{text-decoration:underline}
img{display:block}

/* ── Themed scrollbars (follow light/dark) ───────────────── */
html{scrollbar-width:thin;scrollbar-color:var(--sb-thumb) var(--sb-track)}
::-webkit-scrollbar{width:12px;height:12px}
::-webkit-scrollbar-track{background:var(--sb-track)}
::-webkit-scrollbar-thumb{background:var(--sb-thumb);border-radius:7px;border:3px solid var(--sb-track);background-clip:padding-box}
::-webkit-scrollbar-thumb:hover{background:var(--sb-thumb-hover);background-clip:padding-box}

/* ── Header ──────────────────────────────────────────────── */
.site-header{position:fixed;top:0;left:0;right:0;height:var(--hh);background:var(--bg);border-bottom:1px solid var(--bd);display:flex;align-items:center;padding:0 1.25rem 0 calc(var(--sw) + 1.5rem);z-index:200;gap:1rem}
.header-brand{display:flex;align-items:center;gap:.6rem;position:fixed;left:0;top:0;width:var(--sw);height:var(--hh);padding:0 1.25rem;border-bottom:1px solid var(--bd);background:var(--bg);z-index:201}
/* Portal brand (logo + name) in the top-left, mirroring the dashboard. */
.header-brand .brand-link{display:flex;align-items:center;gap:9px;text-decoration:none;color:var(--tx)}
.header-brand .brand-mark{height:20px;width:auto;display:block}
.header-brand .brand-name{font-family:var(--fn);font-weight:700;font-size:16px;letter-spacing:-.01em;color:var(--tx)}
.header-brand .brand-link:hover .brand-name{color:var(--primary)}
/* The portal logo also rides the top-right as .academy-home — but that's a
   duplicate once the left shows the portal brand, so hide it on desktop; the
   mobile header (no left brand) brings it back (see the ≤767 block). */
.academy-home{display:none;align-items:center;flex:none;text-decoration:none;order:1}
.academy-home img{height:17px;width:auto;display:block}
.academy-home:hover{opacity:.82}
.brand-title{font-size:13px;font-weight:600;color:var(--tx);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.3}
.brand-sub{font-size:11px;color:var(--tx3)}
.hc{display:flex;align-items:center;justify-content:center;gap:.45rem;font-size:13px;color:var(--tx2);flex:1;overflow:hidden}
.hc a{color:var(--ac);white-space:nowrap}
.hc-sep{color:var(--tx3)}
.hc-cur{color:var(--tx);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* icon-only theme toggle (mirrors the dashboard) */
.theme-btn{width:36px;height:36px;padding:0;border:1px solid var(--bd);border-radius:var(--r-md);color:var(--tx2);background:var(--bg-sb);display:grid;place-items:center;cursor:pointer;flex-shrink:0;transition:background .15s,color .15s}
.theme-btn:hover{background:var(--bg-surf);color:var(--tx)}
.theme-btn svg{width:16px;height:16px}
.theme-btn #theme-label{display:none}   /* icon only — hide the Light/Dark word */
.auth-chip-wrap{position:relative;flex-shrink:0}
/* avatar pill (mirrors the dashboard user button) */
.auth-chip{font:inherit;font-size:13px;font-weight:500;display:inline-flex;align-items:center;gap:8px;padding:4px 11px 4px 4px;border:1px solid var(--bd);border-radius:var(--r-pill);color:var(--tx);background:var(--bg-sb);cursor:pointer;text-decoration:none;transition:background .15s}
.auth-chip:hover{background:var(--bg-surf);text-decoration:none}
.auth-chip img,.auth-chip .ac-av{width:28px;height:28px;border-radius:50%;flex-shrink:0}
.auth-chip .ac-av{background:var(--grad-brand);color:#fff;font-size:11px;font-weight:700;display:grid;place-items:center}
.auth-chip .ac-name{max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.goal-star{display:grid;place-items:center;color:var(--flame);margin:0 1px}
.goal-star svg{width:14px;height:14px}
.goal-star[hidden]{display:none}
.auth-chip .ac-chev{display:grid;place-items:center;color:var(--tx3);flex-shrink:0}
.auth-chip .ac-chev svg{width:14px;height:14px}
.auth-chip.signin{padding:7px 15px;font-weight:600;color:var(--tx2)}
.auth-menu{position:absolute;right:0;top:calc(100% + 8px);width:248px;background:var(--bg-raised);border:1px solid var(--bd);border-radius:var(--r-lg);box-shadow:0 14px 32px -12px rgba(0,0,0,.45);padding:8px;display:none;flex-direction:column;z-index:210}
.auth-menu.open{display:flex}
.auth-menu .menu-head{display:flex;gap:11px;align-items:center;padding:10px 10px 12px}
.auth-menu .ac-av.lg{width:40px;height:40px;border-radius:50%;background:var(--grad-brand);color:#fff;font-size:14px;font-weight:700;display:grid;place-items:center;flex:none}
.auth-menu .menu-id{min-width:0}
.auth-menu .menu-id b{display:block;font-size:14px;font-weight:600;color:var(--tx);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.auth-menu .menu-id span{display:block;font-size:12px;color:var(--tx3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.auth-menu a,.auth-menu button{display:flex;align-items:center;gap:11px;width:100%;font:inherit;font-size:14px;text-align:left;padding:9px 11px;border:none;background:none;color:var(--tx2);border-radius:var(--r-md);cursor:pointer;text-decoration:none}
.auth-menu a:hover,.auth-menu button:hover{background:var(--bg-surf);color:var(--tx);text-decoration:none}
.auth-menu a svg,.auth-menu button svg{width:16px;height:16px;flex:none}
.auth-menu .menu-sep{height:1px;background:var(--bd);margin:6px 4px}
.auth-menu .auth-menu-out{color:var(--c-err)}
body.paywalled{overflow:hidden}
/* Scrolls when the card is taller than the viewport (short phones + the
   signed-in variant, which adds the plan picker). `margin:auto` centres the
   card in both axes without the top-clipping that align-items:center causes
   inside an overflowing flex container. */
.paywall{position:fixed;inset:0;z-index:500;display:flex;padding:24px;overflow-y:auto;background:rgba(0,0,0,.55);backdrop-filter:blur(8px)}
.paywall-card:focus{outline:2px solid var(--ac);outline-offset:4px}
.paywall-card{max-width:420px;width:100%;margin:auto;background:var(--bg-surf,var(--bg));border:1px solid var(--bd);border-radius:16px;padding:36px 32px;text-align:center;box-shadow:0 30px 80px -20px rgba(0,0,0,.5)}
.paywall-badge{display:inline-block;font-size:12px;font-weight:700;letter-spacing:.5px;color:#fff;background:var(--ac);padding:5px 14px;border-radius:999px;margin-bottom:16px}
.paywall-card h2{font-size:24px;margin:0 0 10px;color:var(--tx)}
.paywall-card p{color:var(--tx2);line-height:1.5;margin:0 0 24px;font-size:15px}
.paywall-plans{display:flex;gap:10px;margin:0 0 18px}
.pw-opt{flex:1;display:flex;flex-direction:column;gap:2px;align-items:center;padding:12px;border:1px solid var(--bd);border-radius:12px;background:transparent;color:var(--tx2);cursor:pointer;font:inherit;transition:border-color .15s,background .15s}
.pw-opt b{font-size:15px;color:var(--tx)}
.pw-opt span{font-size:13px}
.pw-opt.is-active{border-color:var(--ac);background:rgba(125,125,125,.10)}
.pw-opt.is-active b{color:var(--ac)}
.paywall-cta{width:100%;font:inherit;font-weight:700;font-size:16px;padding:14px;border:none;border-radius:12px;color:#fff;background:var(--ac);cursor:pointer;transition:background .15s}
.paywall-cta:hover{background:var(--ac-dk,var(--ac))}
.paywall-cta:disabled{opacity:.7;cursor:default}
.paywall-note{font-size:13px;color:var(--tx3,var(--tx2));margin:14px 0 0}
.paywall-alt{display:block;margin-top:10px;width:100%;box-sizing:border-box;font-weight:600;font-size:15px;padding:13px;border:1px solid var(--bd);border-radius:12px;color:var(--tx);text-decoration:none;transition:border-color .15s,background .15s}
.paywall-alt:hover{border-color:var(--ac);background:rgba(125,125,125,.10)}
.paywall-back{display:inline-block;margin-top:18px;font-size:14px;color:var(--ac);text-decoration:none}
.paywall-back:hover{text-decoration:underline}
.ch-nav{display:flex;gap:.4rem;flex-shrink:0}
.ch-nav a{font-size:12px;font-weight:600;padding:6px 13px;border:1px solid var(--bd);border-radius:var(--r-pill);color:var(--tx2);display:flex;align-items:center;gap:5px;transition:background .15s,border-color .15s;white-space:nowrap;text-decoration:none}
.ch-nav a:hover{background:var(--bg-sb);text-decoration:none}
.ch-nav a svg{width:14px;height:14px}

/* ── Sidebar ─────────────────────────────────────────────── */
.sidebar{position:fixed;top:var(--hh);left:0;bottom:0;width:var(--sw);background:var(--bg-sb);border-right:1px solid var(--bd);overflow-y:auto;z-index:100;padding:1rem 0 3rem;transition:transform .25s}
.sidebar::-webkit-scrollbar{width:4px}
.sidebar::-webkit-scrollbar-thumb{background:var(--bd);border-radius:4px}
.sb-course{display:flex;align-items:center;gap:.6rem;font-family:var(--fn);font-weight:700;font-size:15px;line-height:1.25;color:var(--tx);text-decoration:none;padding:.1rem 1.25rem .8rem;margin-bottom:.25rem;border-bottom:1px solid var(--bd)}
.sb-course-ic{flex:none;width:30px;height:30px;display:grid;place-items:center}
.sb-course-ic svg{width:30px;height:30px;display:block}
.sb-course-mono{border-radius:8px;color:#fff;font-weight:800;font-size:15px;line-height:1;box-shadow:0 2px 6px -2px rgba(0,0,0,.4)}
.sb-course-tt{min-width:0}
.sb-label{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--tx3);padding:.75rem 1.25rem .25rem}
.ch-list{list-style:none}
.ch-list>li{border-bottom:1px solid var(--bd2)}
.ch-head{position:relative;display:flex;align-items:center;gap:.5rem;padding:.6rem 1.25rem;font-size:13px;font-weight:600;color:var(--tx2);cursor:pointer;transition:background .1s;text-decoration:none;border:none;background:none;width:100%;text-align:left;font-family:var(--fn)}
.ch-head:hover{background:var(--bg-surf);text-decoration:none}
/* Chapter roll-up rail — a thin bar down the left edge of the chapter button,
   so a COLLAPSED chapter still says whether it is finished. Same colour
   language as the per-lesson badges below it: green = every lesson's quiz
   passed, amber = every page in the chapter heard in full. The two are
   mutually exclusive in renderSidebar — green wins, because passing the
   quizzes is the stronger claim. */
.ch-head.ch-heard::before,.ch-head.ch-passed::before{content:"";position:absolute;left:0;top:5px;bottom:5px;width:3px;border-radius:0 3px 3px 0}
.ch-head.ch-heard::before{background:var(--c-warn)}
.ch-head.ch-passed::before{background:var(--c-ok)}
.ch-head.cur,.ch-head.par{color:var(--ac-dk);background:var(--ac-dim)}
.ch-arr{width:13px;height:13px;color:var(--tx3);flex-shrink:0;margin-left:auto;transition:transform .2s}
.ch-head.open .ch-arr{transform:rotate(90deg)}
.svc-list{list-style:none;display:none;border-top:1px solid var(--bd2);padding:.2rem 0 .35rem}
.svc-list.open{display:block}
.svc-list a{display:flex;align-items:center;gap:.5rem;padding:.38rem 1.2rem .38rem 1.5rem;font-size:12.5px;color:var(--tx2);transition:background .1s;line-height:1.4;text-decoration:none}
.svc-list a:hover{background:var(--bg-surf);text-decoration:none}
.svc-list a.cur{color:var(--ac-dk);background:var(--ac-dim);font-weight:600;border-radius:8px;margin:0 .45rem;padding-left:1.05rem}
.svc-n{font-size:10px;font-weight:700;color:var(--tx3);min-width:18px;text-align:center;font-family:var(--fm);flex-shrink:0}
.svc-list a.cur .svc-n{color:var(--ac)}
.sb-done{flex-shrink:0;width:18px;height:18px;border-radius:50%;background:var(--c-ok);color:#fff;font-size:11px;font-weight:700;display:inline-flex;align-items:center;justify-content:center;line-height:1}
.sb-heard{flex-shrink:0;width:18px;height:18px;border-radius:50%;background:var(--c-warn);color:#fff;display:inline-flex;align-items:center;justify-content:center;line-height:1}
/* dark theme: amber is bright → use a dark headphone glyph for contrast */
[data-theme="dark"] .sb-heard{color:#2a1d00}
.sb-lock{display:inline-flex;align-items:center;color:var(--tx3);margin-left:auto;padding-left:.4rem;flex-shrink:0;line-height:1}
.sb-lock svg{width:12px;height:12px}
.sb-free{color:var(--ac);font-size:9px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;margin-left:auto;padding-left:.4rem;flex-shrink:0;line-height:1}
.sb-done + .sb-free,.sb-heard + .sb-free{margin-left:.35rem;padding-left:0}

/* ── Main layout ─────────────────────────────────────────── */
.main{margin-left:var(--sw);padding-top:var(--hh);min-height:100vh;padding-bottom:calc(60px + env(safe-area-inset-bottom));transition:margin .25s,padding-bottom .25s}
/* Right "On this page" panel reserves a column; collapsing it widens reading. */
body.has-onpage:not(.op-hidden) .main{margin-right:var(--rw)}
.wrap{max-width:var(--cw);margin:0 auto;padding:2.5rem 3rem 6rem}

/* ── Right panel: On this page (TOC) ─────────────────────── */
.onpage{position:fixed;top:var(--hh);right:0;bottom:0;width:var(--rw);background:var(--bg);border-left:1px solid var(--bd);overflow-y:auto;z-index:90;padding:1.4rem 1.25rem 3rem;transition:transform .25s}
.onpage::-webkit-scrollbar{width:4px}
.onpage::-webkit-scrollbar-thumb{background:var(--bd);border-radius:4px}
body.op-hidden .onpage{transform:translateX(100%)}
.op-label{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--tx3);margin-bottom:.6rem}
.op-list{list-style:none;display:flex;flex-direction:column;gap:1px;border-left:1px solid var(--bd)}
.op-list a{display:block;padding:.3rem .8rem;font-size:12.5px;line-height:1.4;color:var(--tx2);border-left:2px solid transparent;margin-left:-1px;transition:color .12s,border-color .12s}
.op-list a:hover{color:var(--tx);text-decoration:none}
.op-list a.cur{color:var(--ac-dk);border-left-color:var(--ac);font-weight:600}
.op-toggle{position:fixed;top:calc(var(--hh) + 16px);right:calc(var(--rw) - 1px);z-index:110;width:18px;height:32px;background:var(--bg);border:1px solid var(--bd);border-right:none;border-radius:6px 0 0 6px;cursor:pointer;color:var(--tx3);font-size:14px;display:flex;align-items:center;justify-content:center;padding:0;transition:right .25s}
.op-toggle:hover{color:var(--tx)}
body.op-hidden .op-toggle{right:0;border-right:1px solid var(--bd);border-radius:6px 0 0 6px}
@media(max-width:1080px){.onpage,.op-toggle{display:none}body.has-onpage:not(.op-hidden) .main,body.has-onpage .main{margin-right:0}}

/* ── Current-lesson status pills (under the title) ───────── */
/* audio duration chip beside the tags */
.tag-dur{display:inline-flex;align-items:center;gap:.3rem;font-size:11px;font-family:var(--fm);color:var(--tx3);line-height:1;margin-left:.15rem}
.tag-dur svg{flex:none}
.tag-share{display:inline-flex;align-items:center;gap:.3rem;font-size:11px;font-family:var(--fm);color:var(--tx3);line-height:1;margin-left:.15rem;padding:2px 6px;border:1px solid var(--bd);border-radius:20px;background:transparent;cursor:pointer}
.tag-share:hover{color:var(--tx);border-color:var(--tx3)}
.tag-share:focus-visible{outline:2px solid var(--ac);outline-offset:2px}
.tag-share svg{flex:none}

/* ── Top-bar trial CTA (non-subscribers) ─────────────────── */
.trial-cta{order:0;flex:none;font-size:12px;font-weight:700;padding:6px 14px;border-radius:var(--r-pill);background:var(--grad-brand);color:#fff;text-decoration:none;white-space:nowrap;box-shadow:var(--shadow-sm);transition:filter .15s}
.trial-cta:hover{text-decoration:none;filter:brightness(1.07)}
/* Free-course-of-the-month variant: emerald "Sign in — free this month". */
.trial-cta-free{background:#34d399;color:#04231a}

/* ── Service page header ─────────────────────────────────── */
.svc-hd{display:flex;align-items:flex-start;gap:1.25rem;margin-bottom:1.5rem}
.svc-icon{flex-shrink:0;width:60px;height:60px;background:var(--bg-surf);border:1px solid var(--bd);border-radius:14px;display:flex;align-items:center;justify-content:center;padding:10px}
.svc-icon img{width:100%;height:100%;object-fit:contain}
.svc-hd-txt{flex:1}
.svc-num{font-size:11px;font-weight:700;font-family:var(--fm);letter-spacing:.08em;text-transform:uppercase;color:var(--ac);margin-bottom:.25rem}
.svc-title{font-family:var(--fn);font-size:2.35rem;font-weight:700;color:var(--tx);line-height:1.12;letter-spacing:-.025em;margin-bottom:.6rem}
.tags{display:flex;gap:.4rem;flex-wrap:wrap;align-items:center}

/* ── Overview / intro page headers ──────────────────────── */
.eyebrow{font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--ac);margin-bottom:.5rem}
.page-title{font-family:var(--fn);font-size:clamp(2.2rem,4vw,3rem);font-weight:700;line-height:1.12;color:var(--tx);letter-spacing:-.025em;margin-bottom:.9rem}
/* The first paragraph of an intro or overview page reads as body text: the
   same size, colour and reading-scale as .body (owner, 2026-09-21) - it was
   smaller and muted, and the text-size setting left it alone. */
.page-sub{font-size:calc(17px * var(--reading-scale));color:var(--tx);max-width:660px;line-height:1.7;margin-bottom:1.5rem}
.page-meta{display:flex;gap:1rem;flex-wrap:wrap;padding-bottom:2rem;border-bottom:1px solid var(--bd);margin-bottom:2.5rem}
.meta-item{display:flex;align-items:center;gap:.4rem;font-size:13px;color:var(--tx3)}
.meta-item svg{width:14px;height:14px}

/* ── Body copy ───────────────────────────────────────────── */
/* Lesson body + in-lesson headings scale with the reading-size control
   (--reading-scale, set on <html> from Settings). TOC / sidebar / nav do NOT.
   Tables (.tbl), prerequisite lists and the glossary bubble scale with the
   body: they are the densest reading on the page, and A+ left them at 55-59%
   of the text around them (RDR-07).

   Everything the learner READS scales, wherever it lives: lesson prose, the
   callout-box bodies (Common Confusions, Why It Matters), and the quiz —
   question text, options and the per-option explanations. A reader who needs
   bigger type needs it for the quiz too, not just the paragraphs above it.

   What deliberately does NOT scale: section headings and the boxes' uppercase
   labels (already large enough, and scaling them costs vertical space), the
   "Knowledge Check" heading, buttons and the "Why?" affordance, and figure
   titles/captions — a caption cannot grow while the diagram around it stays
   fixed without the figure falling apart. */
.body{font-size:calc(17px * var(--reading-scale));color:var(--tx)}
.body p{margin-bottom:1.1rem;line-height:1.85}
.body h2{font-family:var(--fn);font-size:calc(1.6rem * var(--reading-scale));font-weight:700;color:var(--tx);margin:2.6rem 0 1rem;letter-spacing:-.02em;line-height:1.25}
.body h3{font-size:calc(14px * var(--reading-scale));font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--tx3);margin:2rem 0 .7rem;display:flex;align-items:center;gap:.5rem}
.body h3::after{content:'';flex:1;height:1px;background:var(--bd)}
.body ul,.body ol{padding-left:1.5rem;margin-bottom:1.1rem}
.body li{margin-bottom:.45rem;line-height:1.8}
.body strong{font-weight:600}
code{font-family:var(--fm);font-size:.85em;background:var(--bg-surf);color:var(--c-err);padding:2px 6px;border-radius:4px;border:1px solid var(--bd)}
/* JetBrains Mono draws != >= -> as single glyphs by default; code shows the characters a reader types */
code,pre,kbd,samp{font-variant-ligatures:none}

/* ── Code blocks (doc-style boxes) ───────────────────────────
   <div class="code-cap">caption</div> sits directly above its <pre class="code">.
   Syntax spans: .cmt comment · .k keyword/command · .s string · .n flag/name ·
   .nm number/shebang · .path path · .ds annotation. */
.code-cap{font-family:var(--fm);font-size:11.5px;font-weight:600;letter-spacing:.02em;color:var(--fg-subtle);
  background:var(--code-bg);border:1px solid var(--code-bd);border-bottom:none;
  border-radius:12px 12px 0 0;padding:.6rem 1.1rem .5rem;margin:1.6rem 0 0;display:block;
  position:relative;padding-left:calc(1.1rem + 48px)}
/* mac-style window dots on the caption bar — dots end at left(1.1rem)+30px+9px; pad clears them */
.code-cap::before{content:"";position:absolute;left:1.1rem;top:50%;transform:translateY(-50%);
  width:9px;height:9px;border-radius:50%;background:#ff5f57;
  box-shadow:15px 0 0 #febc2e,30px 0 0 #28c840;opacity:.85}
pre.code{font-family:var(--fm);font-size:calc(13.5px * var(--reading-scale));line-height:1.7;
  background:var(--code-bg);color:var(--code-fg);border:1px solid var(--code-bd);
  border-radius:12px;padding:1.05rem 1.25rem;margin:1.6rem 0;overflow-x:auto;white-space:pre;
  tab-size:2;-webkit-overflow-scrolling:touch;box-shadow:0 1px 2px rgba(0,0,0,.05)}
/* a pre right after its caption joins it into one box (square the shared edge) */
.code-cap + pre.code{border-radius:0 0 12px 12px;margin-top:0}
pre.code code{background:none;border:none;padding:0;color:inherit;font-size:1em}
pre.code .cmt{color:var(--code-cmt);font-style:italic}
pre.code .k{color:var(--code-k);font-weight:600}
pre.code .s{color:var(--code-s)}
pre.code .n{color:var(--code-n)}
pre.code .nm{color:var(--code-nm)}
pre.code .path{color:var(--code-path)}
pre.code .ds{color:var(--code-ds)}

/* ── Callout boxes ───────────────────────────────────────── */
.box{border-radius:10px;padding:1.1rem 1.25rem;margin:1.5rem 0;border:1px solid}
.box-hd{display:flex;align-items:center;gap:.5rem;font-size:11px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;margin-bottom:.6rem}
.box-hd svg{width:14px;height:14px;flex-shrink:0}
.box-bd{font-size:calc(15px * var(--reading-scale));line-height:1.75}
.box-bd p{margin-bottom:.6rem}
.box-bd p:last-child{margin-bottom:0}
.box-bd ul{padding-left:1.3rem}
.box-bd li{margin-bottom:.3rem}
.box-err{background:var(--c-err-bg);border-color:var(--c-err-bd)}.box-err .box-hd{color:var(--c-err)}
.box-ok{background:var(--c-ok-bg);border-color:var(--c-ok-bd)}.box-ok .box-hd{color:var(--c-ok)}
.box-warn{background:var(--c-warn-bg);border-color:var(--c-warn-bd)}.box-warn .box-hd{color:var(--c-warn)}
.box-info{background:var(--c-info-bg);border-color:var(--c-info-bd)}.box-info .box-hd{color:var(--c-info)}

/* ── Tables ──────────────────────────────────────────────── */
.tbl{width:100%;border-collapse:collapse;font-size:calc(14px * var(--reading-scale));margin:1.25rem 0}
.tbl th{background:var(--bg-surf);padding:.6rem .8rem;text-align:left;font-size:calc(11px * var(--reading-scale));font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--tx3);border:1px solid var(--bd)}
.tbl td{padding:.6rem .8rem;border:1px solid var(--bd2);color:var(--tx);vertical-align:top;line-height:1.6}
.tbl tr:nth-child(even) td{background:var(--bg-surf)}
.tbl tr:hover td{background:var(--ac-dim)}

/* ── Comparable services ─────────────────────────────────── */
.comp-row{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-top:2rem;padding-top:1rem;border-top:1px solid var(--bd)}
.comp-lbl{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:var(--tx3)}
.comp-badge{font-size:13px;padding:3px 10px;border:1px solid var(--bd);border-radius:20px;color:var(--tx2);background:var(--bg-surf)}
.comp-badge strong{font-weight:600;color:var(--tx)}

/* ── Prev / Next navigation ──────────────────────────────── */
.pn{display:flex;justify-content:space-between;align-items:stretch;margin-top:4rem;padding-top:2rem;border-top:1px solid var(--bd);gap:1rem}
.pn-btn{display:flex;flex-direction:column;gap:.2rem;padding:.9rem 1.2rem;border:1px solid var(--bd);border-radius:10px;color:var(--tx);flex:1;max-width:280px;transition:background .15s;text-decoration:none}
.pn-btn:hover{background:var(--bg-sb);text-decoration:none}
.pn-btn.right{text-align:right;align-items:flex-end;margin-left:auto}
.pn-dir{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--tx3);display:flex;align-items:center;gap:.3rem}
.pn-dir svg{width:12px;height:12px}
.pn-title{font-size:15px;font-weight:600;color:var(--ac)}

/* ── Service grid (chapter overviews) ────────────────────── */
.svc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:1rem;margin:1.5rem 0}
.svc-card{border:1px solid var(--bd);border-radius:10px;padding:1.1rem 1.2rem;background:var(--bg-sb);transition:border-color .15s;text-decoration:none;display:block}
.svc-card:hover{border-color:var(--ac);text-decoration:none}
.svc-card-num{font-size:11px;font-weight:700;font-family:var(--fm);color:var(--ac);letter-spacing:.08em;text-transform:uppercase;margin-bottom:.25rem}
.svc-card-name{font-size:16px;font-weight:600;color:var(--tx);margin-bottom:.4rem}
.svc-card-desc{font-size:14px;color:var(--tx2);line-height:1.55}
.svc-card-tags{display:flex;gap:.3rem;flex-wrap:wrap;margin-top:.5rem}

/* ── Glossary ────────────────────────────────────────────── */
.gloss-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:1rem;margin:1.25rem 0}
.gloss-item{background:var(--bg-sb);border:1px solid var(--bd2);border-radius:10px;padding:.9rem 1.1rem}
.gloss-term{font-size:11px;font-weight:700;font-family:var(--fm);color:var(--ac);text-transform:uppercase;letter-spacing:.05em;margin-bottom:.3rem}
.gloss-def{font-size:15px;color:var(--tx2);line-height:1.6}

/* ── Philosophy cards ────────────────────────────────────── */
.phil-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:1rem;margin:1.5rem 0}
.phil-card{border-left:3px solid var(--ac);background:var(--ac-dim);border-radius:0 10px 10px 0;padding:1rem 1.1rem}
.phil-title{font-size:14px;font-weight:700;color:var(--ac-dk);margin-bottom:.4rem}
.phil-body{font-size:14px;color:var(--tx2);line-height:1.6}

/* ── Chapter cards (intro page) ──────────────────────────── */
.ch-card-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:1rem;margin:1.5rem 0}
.ch-card{border:1px solid var(--bd);border-radius:10px;padding:1rem 1.1rem;background:var(--bg-sb);transition:border-color .15s}
.ch-card:hover{border-color:var(--ac)}
.ch-card-num{font-size:11px;font-weight:700;font-family:var(--fm);color:var(--ac);text-transform:uppercase;letter-spacing:.08em;margin-bottom:.25rem}
.ch-card-title{font-size:15px;font-weight:600;color:var(--tx);margin-bottom:.3rem}
.ch-card-desc{font-size:13px;color:var(--tx2);line-height:1.5}
.ch-card-icons{display:flex;flex-wrap:wrap;align-items:center;gap:.45rem;margin-top:.7rem}
.ch-card-icons img{width:24px;height:24px;display:block;object-fit:contain}

/* ── Spectrum figure (e.g. compute IaaS→serverless) ──────── */
.fig-spectrum{margin:1.75rem 0}
.fig-spectrum .fig-title{text-align:center;font-weight:700;color:var(--ac);font-size:1rem;margin-bottom:1.25rem}
.spectrum-row{display:flex;gap:.7rem;align-items:stretch}
.spectrum-card{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;text-align:center;gap:.5rem;border:1px solid var(--bd);border-radius:10px;background:var(--bg-sb);padding:1rem .75rem}
.spectrum-card img{width:42px;height:42px;object-fit:contain}
.spectrum-name{font-weight:600;color:var(--tx);font-size:.92rem;line-height:1.2}
.spectrum-desc{font-size:.78rem;font-style:italic;color:var(--tx2);line-height:1.4}
.spectrum-arrow{display:flex;align-items:center;margin:1rem .25rem .4rem}
.spectrum-arrow::before,.spectrum-arrow::after{content:"";flex:none;width:0;height:0;border-top:5px solid transparent;border-bottom:5px solid transparent}
.spectrum-arrow::before{border-right:8px solid var(--ac)}
.spectrum-arrow::after{border-left:8px solid var(--ac)}
.spectrum-arrow .ln{flex:1;height:2px;background:var(--ac);opacity:.5}
.spectrum-ends{display:flex;justify-content:space-between;font-size:.8rem;font-style:italic;color:var(--tx2)}
.spectrum-notes{display:flex;justify-content:space-between;gap:1rem;margin-top:.55rem}
.spectrum-notes span{font-size:.74rem;color:var(--tx2);max-width:42%}
.spectrum-notes span:last-child{text-align:right}
@media(max-width:640px){.spectrum-row{flex-wrap:wrap}.spectrum-card{flex:1 1 40%}}

/* ── Multi-column comparison figure (optional mini-topology) ── */
.fig-cols{display:flex;flex-wrap:wrap;gap:1rem;margin:1.75rem 0}.fig-cols>.fig-title{width:100%;flex-shrink:0;margin-bottom:0}
.fig-cols .fig-col{flex:1 1 0;min-width:0;display:flex;flex-direction:column;gap:.7rem;border:1px solid var(--bd);border-radius:10px;background:var(--bg-sb);padding:1.1rem 1rem}
.fig-col-hd{display:flex;align-items:center;gap:.55rem}
.fig-col-hd img{width:34px;height:34px;object-fit:contain;flex:none}
.fig-col-hd .nm{font-weight:600;color:var(--tx);font-size:.95rem;line-height:1.15}
.fig-col-hd .nm small{display:block;font-weight:500;color:var(--tx2);font-size:.72rem;margin-top:.1rem}
.fig-topo{display:flex;flex-direction:column;align-items:center;gap:.28rem;padding:.6rem 0;border-top:1px solid var(--bd);border-bottom:1px solid var(--bd)}
.fig-topo .row{display:flex;gap:.3rem;justify-content:center;flex-wrap:wrap}
.fig-topo .node{font-size:.66rem;font-family:var(--fm);color:var(--tx2);border:1px solid var(--bd);border-radius:6px;padding:.12rem .38rem;background:var(--bg)}
.fig-topo .conn{width:2px;height:13px;background:var(--ac);opacity:.5}
.fig-topo .store{font-size:.7rem;font-weight:600;color:var(--ac);border:1px solid var(--ac);border-radius:6px;padding:.18rem .5rem;background:var(--bg)}
.fig-col-cap{font-size:.78rem;color:var(--tx2);line-height:1.45}
.fig-col-cap strong{color:var(--tx);font-weight:600}
@media(max-width:640px){.fig-cols{flex-direction:column}}

/* ── 2D decision matrix figure ───────────────────────────── */
.fig-matrix{margin:1.75rem 0}
.fig-matrix .fig-title{text-align:center;font-weight:700;color:var(--ac);font-size:1rem;margin-bottom:1rem}
.matrix-area{display:grid;grid-template-columns:1.5rem 1fr;grid-template-rows:1fr 2.6rem;gap:.35rem;max-width:700px;margin:0 auto}
.matrix-yaxis{grid-row:1;grid-column:1;writing-mode:vertical-rl;transform:rotate(180deg);display:flex;align-items:center;justify-content:center;font-size:.72rem;font-weight:600;color:var(--tx2);letter-spacing:.03em}
.matrix-grid{grid-row:1;grid-column:2;display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,minmax(66px,1fr));border-left:2px solid var(--ac);border-bottom:2px solid var(--ac)}
.matrix-cell{border-right:1px dashed var(--bd);border-top:1px dashed var(--bd);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.3rem;padding:.4rem}
.matrix-chip{display:flex;align-items:center;gap:.32rem;font-size:.8rem;font-weight:600;color:var(--tx);white-space:nowrap}
.matrix-chip img{width:20px;height:20px;object-fit:contain;flex:none}
.matrix-xaxis{grid-row:2;grid-column:2;display:grid;grid-template-columns:repeat(3,1fr);font-size:.72rem;color:var(--tx2);text-align:center;padding-top:.3rem}
.matrix-xaxis b{display:block;color:var(--tx);font-size:.76rem}
.fig-cap{font-size:.78rem;font-style:italic;color:var(--tx2);text-align:center;margin-top:.9rem}
@media(max-width:640px){.matrix-chip{font-size:.7rem}.matrix-chip img{width:16px;height:16px}}

/* ── Layered stack figure ────────────────────────────────── */
.fig-stack{max-width:720px;margin:1.75rem auto;display:flex;flex-direction:column;gap:.5rem}
.fig-stack .fig-title{text-align:center;font-weight:700;color:var(--ac);font-size:1rem;margin-bottom:.5rem}
.stack-layer{border:1px solid var(--bd);border-radius:10px;background:var(--bg-sb);padding:.85rem 1rem}
.stack-layer-hd{display:flex;align-items:center;gap:.5rem;font-weight:600;color:var(--tx);font-size:.92rem}
.stack-layer-hd img{width:26px;height:26px;object-fit:contain;flex:none}
.stack-layer-sub{font-size:.76rem;color:var(--tx2);margin-top:.25rem}
.stack-subnets{display:flex;gap:.4rem;margin-top:.6rem}
.stack-subnet{flex:1;border:1px dashed var(--bd);border-radius:6px;padding:.35rem;text-align:center;font-size:.68rem;font-family:var(--fm);color:var(--tx2)}
.stack-row{display:flex;gap:.5rem;flex-wrap:wrap}
.stack-mini{flex:1 1 0;min-width:88px;border:1px solid var(--bd);border-radius:8px;background:var(--bg);padding:.55rem .4rem;text-align:center;display:flex;flex-direction:column;align-items:center;gap:.3rem}
.stack-mini img{width:24px;height:24px;object-fit:contain}
.stack-mini .nm{font-size:.72rem;font-weight:600;color:var(--tx);line-height:1.15}
.stack-mini .ds{font-size:.64rem;color:var(--tx2);line-height:1.25}
@media(max-width:640px){.stack-mini{flex:1 1 40%}}

/* ── Left-to-right flow figure ───────────────────────────── */
.fig-flow-wrap{margin:1.75rem 0}
.fig-flow-wrap .fig-title{text-align:center;font-weight:700;color:var(--ac);font-size:1rem;margin-bottom:1rem}
.fig-flow{display:flex;align-items:stretch;justify-content:center;flex-wrap:wrap;gap:.35rem}
.fig-flow+.fig-flow{margin-top:1.75rem}
.flow-step{flex:1 1 110px;min-width:min-content;max-width:156px;border:1px solid var(--bd);border-radius:10px;background:var(--bg-sb);padding:.8rem .6rem;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.35rem}
.flow-step img{width:30px;height:30px;object-fit:contain}
.flow-step .nm{font-size:.82rem;font-weight:600;color:var(--tx);line-height:1.18}
.flow-step .ds{font-size:.68rem;color:var(--tx2);line-height:1.3}
.flow-arrow{display:flex;align-items:center;justify-content:center;color:var(--ac);font-size:1.2rem;font-weight:700;flex:none;padding:0 .1rem}
.flow-step.ok{border-color:#34a853}
.flow-step.fail{border-color:#ea4335}
.flow-step .badge{font-size:.62rem;font-weight:700;font-family:var(--fm)}
.flow-step.ok .badge{color:#34a853}
.flow-step.fail .badge{color:#ea4335}
@media(max-width:640px){.flow-step{flex:1 1 100%;max-width:none}.flow-arrow{transform:rotate(90deg);width:100%;padding:.15rem 0}}

/* ── Decision list figure (condition → service) ──────────── */
.fig-decide{max-width:700px;margin:1.75rem auto;display:flex;flex-direction:column;gap:.5rem}
.fig-decide .fig-title{text-align:center;font-weight:700;color:var(--ac);font-size:1rem;margin-bottom:.5rem}
.decide-row{display:flex;align-items:center;gap:.7rem;border:1px solid var(--bd);border-radius:8px;background:var(--bg-sb);padding:.6rem .85rem}
.decide-q{flex:1;font-size:.82rem;color:var(--tx);line-height:1.35}
.decide-arrow{color:var(--ac);font-weight:700;flex:none}
.decide-svc{display:flex;align-items:center;gap:.4rem;font-size:.82rem;font-weight:600;color:var(--tx);flex:none;min-width:142px}
.decide-svc img{width:22px;height:22px;object-fit:contain;flex:none}
@media(max-width:560px){.decide-row{flex-wrap:wrap}.decide-svc{min-width:0}}

/* ── Topology kit (regions / zones / replicas) ───────────── */
.fig-topo2{margin:1.75rem 0}
.fig-topo2 .fig-title{text-align:center;font-weight:700;color:var(--ac);font-size:1rem;margin-bottom:1rem}
.topo-frame{border:2px solid var(--ac);border-radius:12px;padding:.9rem;background:var(--bg-sb);max-width:720px;margin:0 auto}
.topo-frame-label{font-size:.72rem;font-weight:700;color:var(--ac);text-transform:uppercase;letter-spacing:.04em;margin-bottom:.6rem}
.topo-cp{border:1px solid var(--ac);border-radius:6px;padding:.35rem .5rem;background:var(--bg);font-size:.74rem;font-weight:600;color:var(--ac);text-align:center;margin-bottom:.6rem}
.topo-cols{display:flex;gap:.6rem}
.topo-zone{flex:1;min-width:0;border:1px dashed var(--bd);border-radius:8px;padding:.6rem .5rem;background:var(--bg);display:flex;flex-direction:column;gap:.4rem;align-items:center}
.topo-zone-label{font-size:.66rem;font-family:var(--fm);color:var(--tx2);text-align:center}
.topo-node{font-size:.72rem;font-weight:600;color:var(--tx);border:1px solid var(--bd);border-radius:6px;padding:.25rem .45rem;background:var(--bg-sb);display:flex;align-items:center;gap:.3rem;width:100%;justify-content:center}
.topo-node img{width:18px;height:18px;object-fit:contain;flex:none}
.topo-band{text-align:center;font-size:.72rem;font-style:italic;color:var(--tx2);margin-top:.6rem;padding-top:.55rem;border-top:1px dashed var(--bd)}
@media(max-width:560px){.topo-cols{flex-direction:column}}

/* ── Nested hierarchy figure (e.g. IAM resource tree) ────── */
.fig-tree{max-width:640px;margin:1.75rem auto}
.fig-tree .fig-title{text-align:center;font-weight:700;color:var(--ac);font-size:1rem;margin-bottom:1rem}
.tree-level{border:1px solid var(--bd);border-left:3px solid var(--ac);border-radius:8px;background:var(--bg-sb);padding:.55rem .75rem;margin-bottom:.45rem}
.tree-level .lvl{font-size:.64rem;font-family:var(--fm);color:var(--tx2);text-transform:uppercase;letter-spacing:.05em}
.tree-level .nm{font-weight:600;color:var(--tx);font-size:.88rem}
.tree-level .binding{font-size:.72rem;color:var(--ac);margin-top:.2rem;font-family:var(--fm)}
.fig-tree .d1{margin-left:1.6rem}
.fig-tree .d2{margin-left:3.2rem}
.fig-tree .d3{margin-left:4.8rem}

/* ── Trace waterfall figure ──────────────────────────────── */
.fig-waterfall{max-width:700px;margin:1.75rem auto}
.fig-waterfall .fig-title{text-align:center;font-weight:700;color:var(--ac);font-size:1rem;margin-bottom:1rem}
.wf-row{display:flex;align-items:center;gap:.6rem;margin-bottom:.4rem}
.wf-label{flex:0 0 132px;font-size:.7rem;font-family:var(--fm);color:var(--tx);text-align:right;line-height:1.2}
.wf-track{flex:1;position:relative;height:20px;background:var(--bg);border:1px solid var(--bd);border-radius:4px}
.wf-bar{position:absolute;top:-1px;height:20px;border-radius:4px;background:var(--ac)}
.wf-bar.hot{background:#ea4335}
.wf-axis{display:flex;justify-content:space-between;font-size:.64rem;font-family:var(--fm);color:var(--tx2);margin-top:.35rem;margin-left:144px}
.wf-note{font-size:.7rem;color:#ea4335;margin-left:144px;margin-top:.3rem}
.wf-b1{left:0;width:100%}
.wf-b2{left:6%;width:9%}
.wf-b3{left:16%;width:59%}
.wf-b4{left:8%;width:2%}

/* ── Prerequisites ───────────────────────────────────────── */
.prereq-box{border:1px solid var(--bd);border-radius:10px;padding:1.1rem 1.4rem;background:var(--bg-sb);margin:1rem 0 1.5rem}
.prereq-box li{font-size:calc(16px * var(--reading-scale));color:var(--tx);padding:.3rem 0;border-bottom:1px solid var(--bd2);line-height:1.6}
.prereq-box li:last-child{border-bottom:none}
/* The signpost under the prerequisite box: which catalogued course teaches
   what the box asks for (gen_prereq_links.py). Not narrated. */
.prereq-onramp{margin:-.6rem 0 1.5rem;padding:0 .2rem;font-size:calc(14.5px * var(--reading-scale));color:var(--tx2);line-height:1.6}
.prereq-onramp a{color:var(--primary);font-weight:600;text-decoration:none}
.prereq-onramp a:hover{text-decoration:underline}

/* ── Audio bar ───────────────────────────────────────────── */
/* content-box so the 52px is the control row; safe-area padding extends the
   panel BELOW it (height becomes 52px + safe-area) — otherwise border-box folds
   the safe-area into 52px, squashing controls up and leaving the tab floating. */
.audio-bar{box-sizing:content-box;position:fixed;bottom:0;left:0;right:0;height:52px;background:var(--bg);border-top:1px solid var(--bd);z-index:300;display:flex;align-items:center;transition:transform .25s;padding-bottom:env(safe-area-inset-bottom)}
/* grid 1fr auto 1fr → the play button (middle column) sits dead-centre on the bar */
.audio-bar__inner{width:100%;padding:0 1rem;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:.6rem}
.ab-col-l{display:flex;align-items:center;gap:.5rem;min-width:0}
.ab-center{display:flex;align-items:center;gap:.5rem;position:relative}
.ab-col-r{display:flex;align-items:center;gap:.6rem;min-width:0;justify-content:flex-end;position:relative}
.ab-left{display:flex;flex-direction:column;justify-content:center;gap:1px;min-width:0;flex:1 1 0}
.ab-state{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--tx3);font-family:var(--fm)}
/* Speed · Pause · Lesson N% - the settings a key changes and how far the page
   has been heard; it replaced the lesson title, which the page header shows. */
.ab-readout{font:600 12px/1.3 var(--fm);color:var(--tx2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:.01em}
/* A key changed speed or pause: the new value over Play for a moment. */
.ab-flash{position:absolute;left:50%;bottom:calc(100% + 10px);transform:translateX(-50%);padding:4px 10px;border-radius:8px;background:var(--bg);border:1px solid var(--bd);box-shadow:0 6px 18px -8px rgba(0,0,0,.4);font:600 12px/1.3 var(--fm);color:var(--tx);white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s}
.ab-flash.on{opacity:1}
/* Live player settings live in a "Player settings" popover on EVERY device,
   opened by the #ab-more button pinned to the bar's right edge. */
.ab-more{display:inline-flex;position:absolute;right:.6rem;top:50%;transform:translateY(-50%);z-index:5}
/* No hover/focus tooltips anywhere in the audio bar (belt-and-suspenders: the
   data-tip attrs are already gone from the markup, this also kills any stale one). */
#audio-bar [data-tip]:hover::after,#audio-bar [data-tip]:hover::before,
#audio-bar [data-tip]:focus-visible::after,#audio-bar [data-tip]:focus-visible::before{content:none;display:none}
.ab-settings{display:none;position:absolute;right:.6rem;bottom:calc(100% + 14px);
  flex-direction:column;align-items:stretch;gap:.55rem;min-width:230px;padding:.85rem;
  background:var(--bg);border:1px solid var(--bd);border-radius:14px;z-index:320;
  box-shadow:0 18px 44px -12px rgba(0,0,0,.45),0 4px 12px -6px rgba(0,0,0,.28)}
.audio-bar.ab-open .ab-settings{display:flex}
.ab-set-label{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--tx3);font-family:var(--fm);padding-bottom:.5rem;border-bottom:1px solid var(--bd);margin-bottom:.1rem}
.ab-settings .ab-label{justify-content:space-between;width:100%;font-size:10px}
.ab-share{justify-content:center;width:100%}
.ab-share svg{flex:none}
.ab-settings .ab-label select{font-size:13px;min-height:32px}
.ab-mark-row{display:flex;align-items:center;gap:8px;width:100%}
.ab-settings .ab-mark-row .ab-check{width:auto;flex:1 1 auto;min-width:0}
.ab-mark-row input[type=range]{flex:0 0 40%;min-width:88px;accent-color:var(--accent-cyan);margin:0}
.ab-settings .ab-check{justify-content:flex-start;width:100%;border-color:transparent;font-size:14px;padding:7px 4px;min-height:0}
.ab-settings .ab-check:hover{background:var(--bg-surf)}
/* A sub-heading inside the popover (Skip reading), and a row that opens a
   section of its own (Text size): the same rule as the Keyboard block. */
.ab-group-label,.ab-settings .ab-sep{padding-top:.55rem;margin-top:.15rem;border-top:1px solid var(--bd)}
.ab-group-label{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--tx3);font-family:var(--fm)}
.ab-keys{display:flex;flex-direction:column;gap:.4rem;padding-top:.55rem;margin-top:.15rem;border-top:1px solid var(--bd)}
.ab-keys-label{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--tx3);font-family:var(--fm)}
.ab-key-row{display:flex;align-items:center;justify-content:space-between;gap:1rem;font-size:13px;color:var(--tx2)}
.ab-kbd{flex:none;min-width:22px;padding:2px 7px;font:600 12px/1.4 var(--fm);text-align:center;color:var(--tx);background:var(--bg-sb);border:1px solid var(--bd);border-radius:6px;box-shadow:0 1px 0 var(--bd)}
.ab-kbds{display:inline-flex;gap:4px;flex:none}
/* Text size: the account page's three steps, as a segment in the popover. */
.ab-seg{display:inline-flex;border:1px solid var(--bd);border-radius:7px;overflow:hidden;background:var(--bg-sb)}
.ab-seg button{background:none;border:none;border-left:1px solid var(--bd);padding:0 10px;min-height:32px;font:600 12px var(--fn);color:var(--tx2);cursor:pointer;letter-spacing:0;text-transform:none}
.ab-seg button:first-child{border-left:none}
.ab-seg button:hover{background:var(--bg-surf);color:var(--tx)}
.ab-seg button.on{background:var(--ac);color:#fff}
.ab-btn.ab-play-main{width:40px;height:40px;border-radius:50%;background:var(--primary);color:var(--on-primary);border:none;font-size:15px;display:inline-flex;align-items:center;justify-content:center;padding:0;box-shadow:0 4px 14px -4px color-mix(in srgb,var(--primary) 70%,transparent)}
.ab-btn.ab-play-main:hover{background:var(--primary-hover);color:var(--on-primary)}
.audio-bar--pending{color:var(--tx3);font-size:13px;font-style:italic}
.ab-tab{position:fixed;bottom:calc(52px + env(safe-area-inset-bottom));left:50%;transform:translateX(-50%);z-index:110;width:44px;height:16px;background:var(--bg);border:1px solid var(--bd);border-bottom:none;border-radius:5px 5px 0 0;cursor:pointer;color:var(--tx3);font-size:9px;line-height:1;display:flex;align-items:center;justify-content:center;padding:0;transition:bottom .25s}
/* Sidebar toggle tab */
.sb-toggle{position:fixed;top:calc(var(--hh) + 16px);left:calc(var(--sw) - 1px);z-index:110;width:18px;height:32px;background:var(--bg);border:1px solid var(--bd);border-left:none;border-radius:0 6px 6px 0;cursor:pointer;color:var(--tx3);font-size:14px;display:flex;align-items:center;justify-content:center;padding:0;transition:left .25s}
/* Sidebar hidden state — sidebar slides; toggle follows its right edge to left:0 */
body.sb-hidden .sidebar{transform:translateX(calc(-1 * var(--sw)))}
/* Before course.json has arrived, and when it will not. */
.sb-skeleton{padding:.5rem 1.25rem;display:flex;flex-direction:column;gap:.85rem}
.sb-skeleton i{display:block;height:12px;border-radius:6px;background:var(--bd2);opacity:.7;animation:sb-pulse 1.2s ease-in-out infinite}
.sb-skeleton i:nth-child(odd){width:72%}.sb-skeleton i:nth-child(even){width:52%}.sb-skeleton i:first-child{width:88%;height:16px}
@keyframes sb-pulse{0%,100%{opacity:.45}50%{opacity:.9}}
@media (prefers-reduced-motion:reduce){.sb-skeleton i{animation:none}}
.sb-failed{padding:1rem 1.25rem;color:var(--tx3);font-size:13.5px;line-height:1.5}
.sb-failed p{margin:0 0 .6rem}
.sb-retry{font:600 13px var(--fn);color:var(--ac);background:none;border:1px solid var(--bd);border-radius:7px;padding:.35rem .75rem;cursor:pointer}
body.sb-hidden .sb-toggle{left:0}
/* sidebar collapsed → reclaim its width so the reading column re-centres */
body.sb-hidden .main{margin-left:0}
/* Audio bar hidden state (translateY 100% clears the bar incl. safe-area pad) */
body.bar-hidden .audio-bar{transform:translateY(100%)}
body.bar-hidden .ab-tab{bottom:0}
body.bar-hidden .main{padding-bottom:0}
/* Suppress the slide on the initial restored-hidden state (no flash on load) */
body.bar-anim-off .audio-bar,body.bar-anim-off .ab-tab{transition:none}
.ab-btn{background:none;border:none;border-radius:8px;padding:6px 9px;cursor:pointer;color:var(--tx2);font-size:15px;line-height:1;transition:background .15s,color .15s;font-family:var(--fn);display:inline-flex;align-items:center;justify-content:center}
.ab-btn:hover{background:var(--bg-surf);color:var(--tx)}
.ab-play-main:hover{color:var(--on-primary)}
.ab-btn.active{color:var(--ac);border-color:var(--ac)}
.ab-label{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;font-family:var(--fm);color:var(--tx3);display:flex;align-items:center;gap:6px;white-space:nowrap}
.ab-label select{font-size:12px;font-family:var(--fn);font-weight:600;letter-spacing:0;text-transform:none;background:var(--bg-sb);border:1px solid var(--bd);border-radius:7px;padding:4px 7px;color:var(--tx);cursor:pointer}
/* Highlight / Autoplay check toggles (word + checkbox) */
.ab-check{display:inline-flex;align-items:center;gap:6px;flex:none;background:none;border:1px solid var(--bd);border-radius:6px;padding:4px 10px;font:500 13px/1 var(--fn);color:var(--tx2);cursor:pointer;white-space:nowrap;transition:color .15s,border-color .15s,background .15s}
.ab-check:hover{background:var(--bg-surf)}
.ab-check-box{position:relative;flex:none;width:14px;height:14px;border:1.5px solid var(--bd);border-radius:3px;transition:background .15s,border-color .15s}
.ab-check.on .ab-check-box{background:var(--ac);border-color:var(--ac)}
.ab-check.on .ab-check-box::after{content:"";position:absolute;left:3.5px;top:.5px;width:4px;height:8px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg)}
/* Hover tooltips for audio-bar controls (bar sits at the bottom, so above) */
[data-tip]{position:relative}
[data-tip]:hover::after,[data-tip]:focus-visible::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 11px);left:50%;transform:translateX(-50%);width:max-content;max-width:clamp(180px,60vw,280px);white-space:normal;text-align:left;background:var(--tip-bg);color:var(--tip-tx);border:1px solid var(--tip-bd);font:500 12.5px/1.5 var(--fn);padding:10px 13px;border-radius:11px;pointer-events:none;z-index:310;box-shadow:0 14px 36px -10px rgba(0,0,0,.32),0 3px 10px -4px rgba(0,0,0,.18);animation:tip-pop .15s ease-out}
[data-tip]:hover::before,[data-tip]:focus-visible::before{content:"";position:absolute;bottom:calc(100% + 5px);left:50%;transform:translateX(-50%);border:6px solid transparent;border-top-color:var(--tip-bg);pointer-events:none;z-index:311;animation:tip-pop .15s ease-out}
@keyframes tip-pop{from{opacity:0;transform:translate(-50%,5px)}to{opacity:1;transform:translate(-50%,0)}}
.flow-step,.tree-level,.fig-col{transition:border-color .18s,background .18s,box-shadow .18s}
.flow-step:hover,.tree-level:hover,.fig-col:hover{border-color:var(--ac);background:var(--bg-surf);box-shadow:0 10px 26px -12px rgba(0,0,0,.3)}
.flow-step[data-tip],.tree-level[data-tip]{cursor:help}
/* Figure entrance: staggered fade-in when scrolled into view (JS adds .fig-anim/.fig-in) */
@media (prefers-reduced-motion:no-preference){.fig-anim>.flow-step,.fig-anim>.flow-arrow,.fig-anim>.tree-level,.fig-anim>.fig-col{opacity:0}.fig-in>.flow-step,.fig-in>.flow-arrow,.fig-in>.tree-level,.fig-in>.fig-col{animation:fig-fade .5s ease-out forwards}.fig-in>:nth-child(2){animation-delay:.07s}.fig-in>:nth-child(3){animation-delay:.14s}.fig-in>:nth-child(4){animation-delay:.21s}.fig-in>:nth-child(5){animation-delay:.28s}.fig-in>:nth-child(6){animation-delay:.35s}.fig-in>:nth-child(7){animation-delay:.42s}.fig-in>:nth-child(8){animation-delay:.49s}.fig-in>:nth-child(9){animation-delay:.56s}.fig-in>:nth-child(10){animation-delay:.63s}.fig-in>:nth-child(11){animation-delay:.70s}.fig-in>:nth-child(12){animation-delay:.77s}}
@keyframes fig-fade{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){[data-tip]:hover::after,[data-tip]:hover::before,[data-tip]:focus-visible::after,[data-tip]:focus-visible::before{animation:none}.flow-step,.tree-level,.fig-col{transition:none}}

/* ── Glossary terms — first-occurrence-per-page definition bubbles ──
   shared.js wraps the first match of each glossary term in a .term-def
   span; the bubble (#term-pop, one per page) is a fixed-position floating
   element so it never clips inside the prose's overflow contexts.
   The term is an amber pill (#630): a dotted underline was near-invisible
   on every reader. box-decoration-break:clone keeps a term that wraps
   rounded at both ends of each line. Text colour stays the prose's. */
.term-def{background:color-mix(in srgb,var(--c-warn) 18%,transparent);border-radius:4px;padding:0 .2em;margin:0 -.05em;-webkit-box-decoration-break:clone;box-decoration-break:clone;cursor:help;transition:background-color .12s}
.term-def:hover,.term-def:focus-visible,.term-def.is-open{background:color-mix(in srgb,var(--c-warn) 32%,transparent);outline:none}
/* Dark theme: the amber is brighter there, and a wash the same depth as in
   light reads as a block of colour - a little more, not less, keeps it a
   tint under the text. */
:root:not([data-theme="light"]) .term-def{background:color-mix(in srgb,var(--c-warn) 22%,transparent)}
:root:not([data-theme="light"]) .term-def:hover,
:root:not([data-theme="light"]) .term-def:focus-visible,
:root:not([data-theme="light"]) .term-def.is-open{background:color-mix(in srgb,var(--c-warn) 36%,transparent)}
.term-pop{position:fixed;left:0;top:0;z-index:320;max-width:320px;white-space:normal;text-align:left;background:var(--tip-bg);color:var(--tip-tx);border:1px solid var(--c-warn);font:500 13px/1.55 var(--fn);font-size:calc(13px * var(--reading-scale));padding:11px 14px;border-radius:11px;box-shadow:0 14px 36px -10px rgba(0,0,0,.32),0 3px 10px -4px rgba(0,0,0,.18);pointer-events:none;opacity:0;visibility:hidden;transform:translateY(4px);transition:opacity .15s ease-out,transform .15s ease-out,visibility 0s .15s}
/* A shown bubble takes the tap itself. Without this a tap on the bubble fell
   through to the paragraph under it, which closed the bubble - and moved the
   narration there, because that is what a tap on a paragraph does (#630). */
.term-pop.show{opacity:1;visibility:visible;transform:none;pointer-events:auto;transition:opacity .15s ease-out,transform .15s ease-out}
/* The arrow is two triangles: an amber one a pixel larger behind, and the
   bubble's own colour in front, so the hairline runs round the arrow too
   (#630: the bubble's frame is the term's amber, thin and bright). */
.term-pop::before,.term-pop::after{content:"";position:absolute;top:100%;left:var(--ax,50%);transform:translateX(-50%);border:6px solid transparent;border-top-color:var(--tip-bg)}
.term-pop::before{border-width:7px;border-top-color:var(--c-warn);margin-top:1px}
.term-pop.below::before,.term-pop.below::after{top:auto;bottom:100%;border-top-color:transparent;border-bottom-color:var(--tip-bg)}
.term-pop.below::before{border-bottom-color:var(--c-warn);margin-top:0;margin-bottom:1px}
@media (prefers-reduced-motion:reduce){.term-pop{transition:none}}

/* ── Block highlight — rounded card, soft bg, full-height cyan bar ──
   padding + equal negative margin grows the card around the active
   sentence without shifting surrounding text. */
[data-b]{position:relative;border-radius:10px;transition:background .25s}
/* The sentence mark - the one lens all three readers show, drawn by the page
   for the apps too since #736: ONE overlay element that shared.js positions in document
   coordinates and flows from paragraph to paragraph, not a style on the
   block itself - so lighting a block up never touches its box or margins
   (an earlier margin-based mark collapsed the gap above headings). The
   recipe is the apps' with one edit: a wash faint enough to read straight
   through, and ONE cyan hairline in a glow that bleeds both in and out (as
   Android's blurred stroke does; iOS clips its own to the inside). The apps'
   second, blue hairline read as a thick frame on a screen and was dropped.
   The `hl` class on the block is only state. */
.ab-mark{position:absolute;left:0;top:0;width:0;height:0;box-sizing:border-box;border-radius:15px;pointer-events:none;z-index:3;opacity:0;transition:opacity .2s ease;background:color-mix(in srgb,var(--accent-cyan) 10%,transparent);border:1px solid color-mix(in srgb,var(--accent-cyan) 55%,transparent);box-shadow:inset 0 0 9px color-mix(in srgb,var(--accent-cyan) 40%,transparent),0 0 10px color-mix(in srgb,var(--accent-cyan) 30%,transparent)}
.no-hl .ab-mark{display:none}
/* Word highlight (#640): the block's cyan, no rim, soft edges - the same box
   over the block mark and on its own; darker than the wash is what makes it
   the word. It sits INSIDE the block as a negative-z child, under the text
   (#654): an overlay above the text tinted the letters. `has-word` isolates
   the block so the child paints over the block's ground, not behind the
   page's. The soft edge is a box-shadow, not filter:blur: WebKit left the
   blur's bleed unrepainted where the box had been, a cyan hairline on every
   line already spoken, plain to see once the strength slider (#665) could
   turn the box dense. */
[data-b].has-word{isolation:isolate}
.ab-word{--wl:color-mix(in srgb,var(--accent-cyan) var(--wl-alpha,32%),transparent);position:absolute;left:0;top:0;width:0;height:0;border-radius:6px;pointer-events:none;z-index:-1;opacity:0;background:var(--wl);box-shadow:0 0 2px var(--wl);transition:opacity .15s ease,left .1s ease,top .1s ease,width .1s ease}
@media (prefers-reduced-motion:reduce){.ab-word{transition:opacity .15s ease}}

/* ── Tags ────────────────────────────────────────────────── */
.tag{font-size:11px;font-weight:600;padding:3px 9px;border-radius:20px;letter-spacing:.03em}
.t-compute{background:var(--tag-compute-bg);color:var(--tag-compute-tx)}
.t-storage{background:var(--tag-storage-bg);color:var(--tag-storage-tx)}
.t-db{background:var(--tag-db-bg);color:var(--tag-db-tx)}
.t-serverless{background:var(--tag-serverless-bg);color:var(--tag-serverless-tx)}
.t-managed{background:var(--tag-managed-bg);color:var(--tag-managed-tx)}
.t-infra{background:var(--tag-infra-bg);color:var(--tag-infra-tx)}
.t-analytics{background:var(--tag-analytics-bg);color:var(--tag-analytics-tx)}
.t-nosql{background:var(--tag-nosql-bg);color:var(--tag-nosql-tx)}

/* ── Quiz ─────────────────────────────────────────────────── */
.quiz{margin-top:2.5rem;padding-top:2rem;border-top:1px solid var(--bd)}
.quiz-hd{font-family:var(--fn);font-size:1.5rem;font-weight:700;color:var(--tx);margin:0 0 1.5rem;letter-spacing:-.02em}
.quiz-q{margin-bottom:1rem;padding:1.1rem 1.25rem;background:var(--bg-sb);border:1px solid var(--bd);border-radius:10px}
.quiz-qt{font-weight:600;font-size:calc(15px * var(--reading-scale));line-height:1.55;margin:0 0 .75rem;color:var(--tx)}
.quiz-opts{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.35rem}
.quiz-opts .quiz-opt{padding:.6rem .85rem;border-radius:7px;border:1.5px solid var(--bd);cursor:pointer;font-size:calc(15.5px * var(--reading-scale));color:var(--tx);line-height:1.55;transition:border-color .12s,background .12s,color .12s;user-select:none}
.quiz-opt:hover:not(.qd){border-color:var(--ac);background:var(--ac-dim);color:var(--tx)}
.quiz-opt.qc{border-color:var(--c-ok-bd);background:var(--c-ok-bg);color:var(--c-ok);cursor:default}
.quiz-opt.qw{border-color:var(--c-err-bd);background:var(--c-err-bg);color:var(--c-err);cursor:default}
.quiz-opt.qd{cursor:default}
/* Answer explanations: once a question is answered, each option reveals why it
   is right or wrong. Hidden before the answer so it never spoils the question.
   Green accent = correct, red = not. Desktop reveals on hover; touch devices
   (no hover) get a "Why?" pill and reveal on tap. */
.quiz-q[data-done] .quiz-opt[data-exp]{position:relative}
.quiz-q[data-done] .quiz-opt[data-exp]::after{content:attr(data-exp);content:attr(data-exp) / "";position:absolute;left:0;right:0;bottom:calc(100% + 9px);white-space:normal;text-align:left;background:var(--tip-bg);color:var(--tip-tx);border:1px solid var(--tip-bd);border-left:3px solid var(--c-err);font:500 12.5px/1.55 var(--fn);font-size:calc(12.5px * var(--reading-scale));padding:11px 14px;border-radius:11px;pointer-events:none;z-index:310;box-shadow:0 14px 36px -10px rgba(0,0,0,.32),0 3px 10px -4px rgba(0,0,0,.18);opacity:0;visibility:hidden;transform:translateY(5px);transition:opacity .15s ease-out,transform .15s ease-out,visibility 0s .15s}
.quiz-q[data-done] .quiz-opt.qc[data-exp]::after{border-left-color:var(--c-ok)}
/* Desktop (hover-capable): reveal on hover or keyboard focus, no pill. */
@media (hover:hover){
  .quiz-q[data-done] .quiz-opt[data-exp]{cursor:help}
  .quiz-q[data-done] .quiz-opt[data-exp]:hover::after,.quiz-q[data-done] .quiz-opt[data-exp]:focus-visible::after{opacity:1;visibility:visible;transform:translateY(0);transition:opacity .15s ease-out,transform .15s ease-out}
}
/* Touch (no hover): a "Why?" pill, reveal on tap (focus). */
@media (hover:none){
  .quiz-q[data-done] .quiz-opt[data-exp]{padding-right:3.3rem}
  .quiz-q[data-done] .quiz-opt[data-exp]::before{content:"Why?";position:absolute;right:.6rem;top:50%;transform:translateY(-50%);font-size:10.5px;font-weight:600;letter-spacing:.02em;opacity:.62;border:1px solid currentColor;border-radius:20px;padding:1px 7px;pointer-events:none}
  .quiz-q[data-done] .quiz-opt[data-exp]:focus::after{opacity:1;visibility:visible;transform:translateY(0);transition:opacity .15s ease-out,transform .15s ease-out}
}
@media (prefers-reduced-motion:reduce){.quiz-q[data-done] .quiz-opt[data-exp]::after{transition:none}}
.quiz-summary{display:none;margin-top:1.25rem;padding:1rem 1.25rem;background:var(--bg-surf);border:1px solid var(--bd);border-radius:10px;text-align:center}
.quiz-summary.vis{display:block}
.quiz-score-txt{font-size:calc(15px * var(--reading-scale));font-weight:600;color:var(--tx);margin:0 0 .75rem}
.quiz-retry{padding:.45rem 1.2rem;border-radius:7px;border:1.5px solid var(--ac);background:transparent;color:var(--ac);cursor:pointer;font-size:13px;font-weight:600;font-family:var(--fn);transition:background .12s,color .12s}
.quiz-retry:hover{background:var(--ac);color:#fff}

/* ── Sidebar overlay backdrop ────────────────────────────── */
.sb-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:149;-webkit-tap-highlight-color:transparent}

/* ── Mobile (≤ 767px) ────────────────────────────────────── */
@media (max-width:767px){
  /* Sidebar: overlay, hidden by default via JS */
  .sidebar{z-index:150;box-shadow:4px 0 20px rgba(0,0,0,.2)}
  body:not(.sb-hidden) .sidebar{transform:none}
  body:not(.sb-hidden) .sb-overlay{display:block}

  /* Header (mobile): hamburger on the left (the fixed .sb-toggle); on the right,
     packed to the edge in order theme → user → logo (logo is order:1, last). */
  .site-header{padding-left:3.25rem;padding-right:.85rem;gap:.5rem;justify-content:flex-end}
  body.sb-hidden .site-header{padding-left:3.25rem}
  .header-brand{display:none}
  .academy-home{display:flex}   /* portal logo returns to the top-right on mobile */

  /* Toggle button: full header height, anchored left. The chevron glyph is
     hidden (font-size:0) and replaced by a hamburger icon (theme-aware via a
     CSS mask filled with currentColor), since on mobile this is THE menu button. */
  .sb-toggle{top:0;left:0;width:3rem;height:var(--hh);border-radius:0;border:none;border-right:1px solid var(--bd);font-size:0;color:var(--tx);z-index:201}
  .sb-toggle::before{content:"";width:22px;height:22px;background:currentColor;
    -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cline x1='4' y1='7' x2='20' y2='7'/%3E%3Cline x1='4' y1='12' x2='20' y2='12'/%3E%3Cline x1='4' y1='17' x2='20' y2='17'/%3E%3C/g%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'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cline x1='4' y1='7' x2='20' y2='7'/%3E%3Cline x1='4' y1='12' x2='20' y2='12'/%3E%3Cline x1='4' y1='17' x2='20' y2='17'/%3E%3C/g%3E%3C/svg%3E") center/contain no-repeat}
  /* The lessons hamburger stays pinned at the top-left in BOTH states — it must
     not jump to the drawer's edge when the menu opens. */
  body.sb-hidden .sb-toggle,
  body:not(.sb-hidden) .sb-toggle{left:0;border-right:1px solid var(--bd);border-left:none}

  /* Main: full width */
  .main{margin-left:0}
  body.sb-hidden .main{margin-left:0}

  /* Hide chapter prev/next nav + breadcrumb + trial CTA in the header — the
     bottom nav, the lessons drawer (hamburger) and sidebar locks cover these. */
  .ch-nav{display:none}
  .hc{display:none}
  #trial-cta{display:none}

  /* Content */
  .wrap{padding:1.5rem 1.25rem 5rem}
  .body{font-size:calc(16px * var(--reading-scale))}
  .body h2{font-size:calc(1.5rem * var(--reading-scale));margin:1.75rem 0 .7rem}
  .svc-title{font-size:1.65rem}
  .page-title{font-size:clamp(1.6rem,6vw,2.2rem)}
  .page-sub{font-size:calc(16px * var(--reading-scale))}
  .gloss-grid{grid-template-columns:1fr}
  .pn{margin-top:2rem}
  .pn-btn{padding:.7rem .85rem}

  /* Tables: horizontal scroll */
  .tbl{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch}

  /* Audio bar: keep transport + key controls; ≥44px tap targets */
  .audio-bar__inner{display:grid;grid-template-columns:1fr auto 1fr;gap:.3rem;padding:0 .5rem}
  /* settings live in the #ab-more popover on phones; keep Play + more only */
  .ab-left{display:none}
  .ab-col-l{gap:.25rem;justify-content:flex-end}
  .ab-col-r{gap:.35rem}
  .ab-btn{padding:0 8px;font-size:15px;min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center}
  .ab-btn.ab-play-main{min-width:44px;min-height:44px}
  .ab-check{min-height:44px;padding:0 9px}
  .ab-label{font-size:0;gap:0;min-height:44px}
  .ab-label select{font-size:12px;min-height:34px}
  /* Keyboard shortcuts are irrelevant on touch devices */
  .ab-keys{display:none}

  /* Quiz */
  .quiz-q{padding:.9rem 1rem}
  /* Scoped to match the base rule above, which is .quiz-opts .quiz-opt:
     a bare .quiz-opt here would lose the cascade and quietly do nothing.
     The old 13px is deliberately gone - options are the text a student
     has to read most carefully, and a phone is where that was hardest.
     Only the padding tightens, to buy back the width. */
  .quiz-opts .quiz-opt{padding:.5rem .75rem}
}

/* ── Very small (≤ 479px) ────────────────────────────────── */
@media (max-width:479px){
  /* Hide speed/pause labels entirely — just the selects remain */
  .ab-label span:not(.ab-seg){display:none}
  /* Breadcrumb: show only current page */
  .hc>a,.hc-sep{display:none}
}

/* ── Flashcards (glossary trainer; mounted on #fc-app) ───────
   One whole-course deck, FSRS-scheduled (logic in shared.js). Cards flip in
   3D, fly up on "I know" / down on "Don't know"; swipe up/down on touch.
   The audio bar runs in card mode on this page (body.fc-mode). */
.sb-cards{flex-shrink:0;color:var(--tx3)}
.ch-head.cur .sb-cards{color:var(--ac)}
/* ── Reset progress ───────────────────────────────────────
   Taking the course again. A quiet footer row under the contents, not a button
   competing with the navigation: it is used once in the life of a course, and
   it is destructive. Danger colour only on hover, so it does not shout from the
   rail every time the reader looks at the chapter list. */
.sb-foot{margin-top:.5rem;padding:.7rem 1.25rem 0;border-top:1px solid var(--bd)}
.sb-reset{display:flex;align-items:center;gap:.5rem;width:100%;padding:.45rem .5rem;margin-left:-.5rem;border:0;border-radius:6px;background:none;font:inherit;font-size:12.5px;color:var(--tx3);cursor:pointer;transition:color .15s,background .15s}
.sb-reset:hover{color:var(--c-err);background:color-mix(in srgb,var(--c-err) 10%,transparent)}
.sb-reset svg{flex:none}

/* The confirmation. A native <dialog>, so focus trapping, Escape and the
   backdrop are the browser's job rather than ours. */
/* margin:auto is what centres a modal <dialog>; the sheet's own reset zeroes
   every margin, so it has to be restored here or the dialog pins itself to
   the top-left corner. max-height keeps it scrollable on a short screen. */
.rp-dialog{width:min(420px,calc(100vw - 2rem));margin:auto;max-height:calc(100vh - 3rem);overflow-y:auto;padding:1.4rem;border:1px solid var(--bd);border-radius:14px;background:var(--bg-c,var(--bg-sb));color:var(--tx);box-shadow:0 24px 60px -20px rgba(0,0,0,.5)}
.rp-dialog::backdrop{background:rgba(0,0,0,.5)}
.rp-h{margin:0;font-family:var(--fn);font-size:19px;font-weight:700;color:var(--tx)}
.rp-sub{margin:.35rem 0 1rem;font-size:13.5px;color:var(--tx2)}
.rp-lab{margin:.9rem 0 .3rem;font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--tx3)}
.rp-list{margin:0;padding-left:1.1rem;font-size:13px;line-height:1.6;color:var(--tx2)}
.rp-list li::marker{color:var(--c-err)}
.rp-keep li::marker{color:var(--c-ok)}
.rp-check{display:flex;gap:.6rem;align-items:flex-start;margin:1.1rem 0 0;padding:.7rem .8rem;border:1px solid var(--bd);border-radius:10px;font-size:13px;color:var(--tx);cursor:pointer}
.rp-check input{margin-top:.15rem;flex:none;accent-color:var(--ac)}
.rp-check em{display:block;margin-top:.2rem;font-style:normal;font-size:11.5px;color:var(--tx3)}
.rp-warn{margin:1rem 0 0;padding:.65rem .8rem;border-radius:10px;background:color-mix(in srgb,var(--c-warn) 14%,transparent);font-size:12px;line-height:1.5;color:var(--tx2)}
/* Reassurance, not a warning: an award once earned is permanent, so this one
   is green. .rp-warn stays for the failure message. */
.rp-note{margin:1rem 0 0;padding:.65rem .8rem;border-radius:10px;background:color-mix(in srgb,var(--c-ok) 13%,transparent);font-size:12px;line-height:1.5;color:var(--tx2)}
.rp-btns{display:flex;justify-content:flex-end;gap:.6rem;margin-top:1.3rem}
.rp-btns button{padding:.6rem 1.1rem;border-radius:999px;border:1px solid var(--bd);background:none;font:inherit;font-size:13.5px;font-weight:600;color:var(--tx);cursor:pointer}
.rp-cancel:hover{background:var(--bd2)}
.rp-btns .rp-go{border-color:transparent;background:var(--c-err);color:#fff}
.rp-btns .rp-go:hover{filter:brightness(1.08)}
.rp-btns .rp-go:disabled{opacity:.7;cursor:default}

/* Sidebar: two thin vocabulary bars under the Flashcards entry.
   Green = remembered now, amber = due for review. */
.sb-fc .ch-head{padding-bottom:.35rem}
.sb-fc-bars{padding:0 1.25rem .65rem 2.55rem;cursor:default}
/* One track, segments side by side (known, then to-review); whatever is left
   showing through is the deck not seen yet. */
.sb-fc-bar{display:flex;height:3px;border-radius:2px;background:var(--bd2);overflow:hidden}
.sb-fc-bar i{display:block;height:100%;flex:0 0 auto;transition:width .35s var(--ease-out)}
.sb-fc-know{background:var(--c-ok)}
.sb-fc-rep{background:var(--c-warn)}
.fc-empty{color:var(--tx3);font-style:italic}

/* Vertically centre only the card + its controls (progress, slider, buttons,
   hint) in the space below the page header, so the trainer doesn't cling to
   the top on tall monitors. The .svc-hd header stays put at the top and the
   reading column keeps its normal width — .wrap stays a full-width block
   (only made a flex COLUMN so .body can grow and centre its content between
   the header and the audio bar). */
body.fc-mode{overscroll-behavior-y:contain}
/* Height, not min-height: the trainer is ONE screen, so it takes exactly the
   room between the header and the audio bar and the card gives up height when
   the window is short. With a minimum the card kept its 400px, the reading
   page's 6rem tail was still there, and any window under ~1040px tall grew a
   scrollbar on a page that has nothing to scroll to — the first answer then
   slid the card up under the audio bar.
   The safe-area term is not decoration: .main reserves 60px PLUS the inset, so
   on a notched phone a height that only subtracted 60px would overflow by the
   inset and put the page back on a scrollbar. The vh line above is the
   fallback for anything without svh, and stays env()-free so an engine that
   does not know env() still gets a height. */
body.fc-mode .wrap{display:flex;flex-direction:column;padding-bottom:1.5rem;height:calc(100vh - var(--hh) - 60px);height:calc(100svh - var(--hh) - 60px - env(safe-area-inset-bottom))}
body.fc-mode .svc-hd{flex:none}
body.fc-mode .body{flex:1;min-height:0;display:flex;flex-direction:column;justify-content:center}
/* min-height:0 all the way down, or each flex item floors at its own content
   and the shrink never reaches the card. */
body.fc-mode #fc-app{flex:1;min-height:0;display:flex;flex-direction:column;justify-content:center}
body.fc-mode .fc-study{min-height:0}
body.fc-mode .fc-stage{min-height:0}
/* Under ~660px of window even a floored card cannot fit beside the title and
   the buttons. There the trainer stops pretending to be one screen and goes
   back to a normal scrolling page, so nothing ends up parked under the bar. */
@media (max-height:660px){
  body.fc-mode .wrap{height:auto;min-height:calc(100vh - var(--hh) - 60px);min-height:calc(100svh - var(--hh) - 60px)}
}

/* study view */
.fc-study{display:flex;flex-direction:column;gap:.9rem}
.fc-top{display:flex;align-items:center;gap:.9rem}
.fc-progress{flex:1;display:flex;align-items:center;gap:.7rem;min-width:0}
.fc-count{font:600 12px var(--fm);color:var(--tx3);white-space:nowrap}
.fc-ptrack{position:relative;flex:1;height:5px;border-radius:3px;background:var(--bd2);overflow:hidden}
.fc-ptrack i{position:absolute;left:0;top:0;bottom:0;border-radius:3px;transition:width .3s var(--ease-out)}
.fc-pmiss{background:var(--c-warn)}
.fc-pknow{background:var(--c-ok)}
/* Re-deal what is left of the run. A quiet control beside the progress bar,
   not a third answer button — it decides nothing about the cards. */
.fc-shuffle{flex:none;display:flex;align-items:center;gap:.4rem;padding:.3rem .6rem;border:1px solid var(--bd);border-radius:999px;background:none;font:600 11.5px var(--fn);color:var(--tx3);cursor:pointer;transition:color .15s,border-color .15s,background .15s}
.fc-shuffle:hover{color:var(--tx);border-color:var(--bd2);background:var(--bg-surf)}
.fc-shuffle svg{flex:none}

.fc-stage{display:flex;flex-direction:column;align-items:center;gap:.5rem}
/* auto-flip timeout slider (leftmost = off) */
.fc-timeout{display:flex;align-items:center;gap:.55rem;color:var(--tx3);width:100%;max-width:280px}
.fc-timeout svg{flex:none}
.fc-timeout input[type=range]{flex:1;accent-color:var(--ac);height:14px;cursor:pointer;min-width:0}
/* fixed width fits the longest label ("30 seconds" / "No timeout") so the
   slider track keeps the same length at every value */
.fc-timeout-val{flex:none;font:600 11px var(--fm);width:74px;text-align:left;white-space:nowrap}
/* The box only reserves space. svh, not vh: a mobile toolbar sliding in or out
   changes vh, and that resized the card mid-gesture — a jump, and for the
   frames it lasted a strip of page background showed where the card had been. */
/* In fc-mode the height below is the card's CEILING: the box is a shrinking
   flex item there, so on a short window it gives back whatever the header,
   the buttons and the hint need — down to the floor, and only past that does
   the page scroll. */
.fc-cardbox{width:100%;max-width:560px;height:min(400px,52vh);height:min(400px,52svh);min-height:150px;position:relative;z-index:1}
/* z-index above: the card paints OVER the slider, buttons and hint. The
   faces are 3D-transformed (composited), and the perspective flip reaches
   below the box; painted after the card, the controls overlapped that layer
   and Chrome squashed them into a composited layer of their own for the
   length of every flip and fly-out, then dropped it - their text
   re-rasterised on each frame and flickered. Painted before it, they stay
   on the page's own layer (#616). */
/* The drag lives in custom properties so the gesture and the fly-out keyframes
   below read the SAME numbers. Releasing a dragged card used to clear the
   inline transform first, so the card snapped back to centre for a frame and
   only then flew off from there.
   touch-action keeps the vertical drag ours: without it the browser scrolled
   the first few pixels itself, which on mobile collapses the URL bar and
   relays out the entire page under the card. */
.fc-card{position:relative;width:100%;height:100%;cursor:pointer;outline:none;touch-action:pan-x pinch-zoom;transform:translateY(var(--fc-dy,0px)) rotate(var(--fc-rot,0deg));opacity:var(--fc-op,1);transition:transform .22s var(--ease-out),opacity .22s var(--ease-out)}
/* Finger down: the card must track it exactly, with no easing in between. */
.fc-card.fc-dragging{transition:none}
.fc-card:focus-visible .fc-inner{box-shadow:0 0 0 3px color-mix(in srgb,var(--ac) 45%,transparent),var(--shadow-lg)}
.fc-inner{position:absolute;inset:0;border-radius:var(--r-xl)}
/* Each face carries its own perspective and rotation rather than sharing one
   `transform-style:preserve-3d` parent. A preserve-3d subtree has to be
   rendered as a group and re-rasterised the moment an ancestor takes a
   transform or an opacity of its own — which is precisely what a swipe does —
   and on dark, where the card sits a few RGB steps off the page, that
   re-raster reads as the background changing colour. Two independently
   rotated faces need no group at all, and flip identically. */
.fc-face{position:absolute;inset:0;display:flex;flex-direction:column;backface-visibility:hidden;-webkit-backface-visibility:hidden;border:1px solid var(--bd);border-radius:var(--r-xl);background:var(--bg-raised);box-shadow:var(--shadow-card);padding:1.6rem 1.8rem;overflow:hidden;transition:transform .45s var(--ease-out)}
.fc-front{transform:perspective(1400px) rotateY(0deg);background:linear-gradient(160deg,var(--bg-raised),color-mix(in srgb,var(--accent-blue) 5%,var(--bg-raised)))}
.fc-backside{transform:perspective(1400px) rotateY(180deg);background:linear-gradient(160deg,var(--bg-raised),color-mix(in srgb,var(--accent-violet) 6%,var(--bg-raised)))}
/* Both faces turn the same way, so they stay edge-on together and the swap is
   invisible: front 0 → 180, back 180 → 360. */
.fc-card.fc-flipped .fc-front{transform:perspective(1400px) rotateY(180deg)}
.fc-card.fc-flipped .fc-backside{transform:perspective(1400px) rotateY(360deg)}
/* auto-flip countdown line (fc-timeout setting; width animated from JS) */
.fc-tline{position:absolute;left:0;top:0;height:3px;width:100%;background:var(--grad-audio);opacity:0;border-radius:0 2px 2px 0}
.fc-fit{flex:1;min-height:0;display:flex;align-items:center;justify-content:center;text-align:center;overflow:hidden}
.fc-word{font-weight:700;color:var(--tx);line-height:1.3;letter-spacing:-.015em;overflow-wrap:break-word;max-width:100%}
.fc-defword{font-weight:500;line-height:1.55;letter-spacing:0;text-align:left}
.fc-alias{flex:none;text-align:center;font-size:12.5px;color:var(--tx3);font-style:italic;padding-top:.4rem}

/* fly / enter animations */
@keyframes fc-fly-up{from{transform:translateY(var(--fc-dy,0px)) rotate(var(--fc-rot,0deg));opacity:var(--fc-op,1)}to{transform:translateY(-130%) rotate(5deg);opacity:0}}
@keyframes fc-fly-down{from{transform:translateY(var(--fc-dy,0px)) rotate(var(--fc-rot,0deg));opacity:var(--fc-op,1)}to{transform:translateY(130%) rotate(-5deg);opacity:0}}
@keyframes fc-enter{from{transform:scale(.92);opacity:0}to{transform:scale(1);opacity:1}}
@keyframes fc-pop{from{transform:scale(.2);opacity:0}to{transform:scale(1);opacity:1}}
/* Order matters: `animation` is a shorthand and these selectors have equal
   specificity, so the fly-out rules MUST come after the entrance one — a card
   answered before its entrance animation finished would otherwise keep
   animating fc-enter and never fly. shared.js also drops .fc-enter once it has
   played; either alone fixes it, both together make it hard to break again. */
.fc-card.fc-enter{animation:fc-enter .22s var(--ease-out)}
.fc-card.fc-fly-up{animation:fc-fly-up .32s ease-in forwards;pointer-events:none}
.fc-card.fc-fly-down{animation:fc-fly-down .32s ease-in forwards;pointer-events:none}
@media (prefers-reduced-motion:reduce){
  .fc-card.fc-fly-up,.fc-card.fc-fly-down,.fc-card.fc-enter,.fc-done-badge{animation:none}
  .fc-face,.fc-card{transition:none}
}

/* the two answer buttons — stacked, "I know" on top (least pointer travel) */
.fc-actions{display:flex;flex-direction:column;gap:.55rem;align-items:center}
.fc-btn{display:flex;flex-direction:column;align-items:center;gap:2px;width:100%;max-width:340px;font-family:var(--fn);border-radius:14px;padding:.7rem 1.2rem;cursor:pointer;transition:transform .12s,box-shadow .15s,background .15s,opacity .15s;border:1px solid}
.fc-btn:active{transform:scale(.985)}
/* "I know this" is locked once the recall timeout expires unflipped */
.fc-btn:disabled{cursor:not-allowed;opacity:.4;box-shadow:none;transform:none;filter:grayscale(.4)}
.fc-btn-t{font-size:15px;font-weight:700;display:flex;align-items:center;gap:.5rem}
.fc-btn-s{font-size:11.5px;opacity:.75}
.fc-btn-know{background:var(--c-ok-bg);border-color:var(--c-ok-bd);color:var(--c-ok)}
.fc-btn-know:hover{box-shadow:0 8px 22px -10px color-mix(in srgb,var(--c-ok) 60%,transparent)}
.fc-btn-dont{background:var(--c-warn-bg);border-color:var(--c-warn-bd);color:var(--c-warn)}
.fc-btn-dont:hover{box-shadow:0 8px 22px -10px color-mix(in srgb,var(--c-warn) 60%,transparent)}
.fc-btn-plain{background:var(--bg-sb);border-color:var(--bd);color:var(--tx2)}
.fc-btn-plain:hover{background:var(--bg-surf);color:var(--tx)}
.fc-kbd{min-width:20px;padding:1px 6px;font:600 11px/1.4 var(--fm);text-align:center;color:inherit;background:color-mix(in srgb,currentColor 12%,transparent);border:1px solid color-mix(in srgb,currentColor 35%,transparent);border-radius:5px}

/* bottom hint: flip gesture per device + a pointer to the guide */
.fc-hint{text-align:center;font-size:12px;color:var(--tx3)}
.fc-hint .fc-kbd{font-size:10px}
.fc-hint-sep{margin:0 .35rem;opacity:.6}
.fc-hint-link{color:var(--ac)}
@media (hover:none){.fc-hint-mouse{display:none}}
@media (hover:hover){.fc-hint-touch{display:none}}

/* completion view */
.fc-doneview{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.6rem;padding:2.5rem 0}
.fc-done-badge{width:56px;height:56px;border-radius:50%;background:var(--c-ok);color:#fff;font-size:28px;font-weight:800;display:grid;place-items:center;animation:fc-pop .4s var(--ease-spring)}
.fc-done-hd{font-family:var(--fn);font-size:1.5rem;font-weight:700;color:var(--tx);letter-spacing:-.02em}
.fc-done-sub{font-size:14.5px;color:var(--tx2);max-width:460px;line-height:1.6}
.fc-done-acts{display:flex;flex-direction:column;gap:.55rem;align-items:center;margin-top:.9rem;width:100%}

@media (max-width:767px){
  .fc-cardbox{height:min(340px,48vh);height:min(340px,48svh)}
  .fc-face{padding:1.15rem 1.2rem}
  .fc-btn{max-width:none}
  .fc-kbd{display:none}
}

/* ── Native mode (iOS app) ───────────────────────────────────
   Set by the app on <html> before the page paints. The app draws the
   navigation and owns playback, so the site's own chrome is removed and
   the layout offsets it reserved collapse to zero. Nothing here applies
   in a browser: the class is never added there.
   ─────────────────────────────────────────────────────────── */
html.native{--sw:0px;--hh:0px}
html.native .site-header,
html.native .sidebar,
html.native .sb-toggle,
html.native .sb-overlay,
html.native .onpage,
html.native .audio-bar{display:none}
/* The reader is the whole viewport, but keep room at the foot for the
   app's own player, which floats over the bottom of the web view. */
html.native .main{margin-left:0;padding-top:0}
html.native .wrap{padding:1.5rem 1.25rem 5rem}
/* The trainer's one-screen height subtracts the audio bar, which the app
   hides and replaces with its own floating player. Leave the web view on
   the growing layout rather than cut 60px out of the card for a bar that
   isn't there. */
html.native body.fc-mode .wrap{height:auto;padding-bottom:5rem}

/* Visually hidden, read by assistive tech: the quiz's spoken verdicts and
   explanations live here (deep review 2026-09, RDR-04). */
.sr-only{position:absolute!important;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
/* The options are keyboard-operable now; the ring says which one has focus. */
.quiz-opt:focus-visible{outline:2px solid var(--ac);outline-offset:2px}

/* ── Live figures (#793) ──────────────────────────────────────
   div.fig-live wraps a static <figure> (or a table.tbl); shared.js imports the widget named in
   data-widget from _shared/widgets/ and, once it has mounted, .is-live hides
   the static figure. Everything else (print, no JS, a failed import, the
   contact sheets) keeps showing the static one. Widget chrome is prefixed
   .fig-live-ui so the page's .body rules never reach it. */
.fig-live{margin:1.75rem 0}
.fig-live.is-live>figure,.fig-live.is-live>table{display:none}
.fig-live-ui{border:1px solid var(--bd);border-radius:var(--r-md);background:var(--bg-sb);padding:1rem 1.1rem;display:flex;flex-direction:column;gap:.85rem}
.fig-live-ui .fig-title{text-align:center;font-weight:700;color:var(--ac);font-size:1rem}
.fig-live-ui p{margin:0;line-height:1.55}
.fig-live-ui .wl-row{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap}
.fig-live-ui .wl-label{font-size:.82rem;font-weight:600;color:var(--fg-muted)}
.fig-live-ui .wl-range{flex:1 1 220px;min-width:160px;accent-color:var(--ac)}
.fig-live-ui .wl-value{font-family:'JetBrains Mono',monospace;font-size:.82rem;color:var(--fg);min-width:14ch}
.fig-live-ui .wl-chips{display:flex;flex-wrap:wrap;gap:.4rem}
.fig-live-ui .wl-chip,.fig-live-ui .wl-btn{font:inherit;font-size:.8rem;padding:.3rem .7rem;border-radius:var(--r-pill);border:1px solid var(--bd);background:transparent;color:var(--fg-muted);cursor:pointer}
.fig-live-ui .wl-chip[aria-pressed="true"]{background:var(--ac-dim);border-color:var(--ac);color:var(--fg)}
.fig-live-ui .wl-btn:hover,.fig-live-ui .wl-chip:hover{border-color:var(--ac);color:var(--fg)}
.fig-live-ui button:focus-visible,.fig-live-ui input:focus-visible,.fig-live-ui [tabindex]:focus-visible{outline:2px solid var(--ac);outline-offset:2px}
.fig-live-ui .wl-table{display:flex;flex-direction:column;gap:.45rem;font-size:.8rem}
.fig-live-ui .wl-tr{display:grid;grid-template-columns:6.5rem minmax(0,1fr) 8.5rem 8.5rem;gap:.6rem;align-items:center}
.fig-live-ui .wl-th{color:var(--fg-subtle);font-size:.7rem;text-transform:uppercase;letter-spacing:.04em}
.fig-live-ui .wl-cls{font-family:'JetBrains Mono',monospace;color:var(--fg)}
.fig-live-ui .wl-steps{display:flex;flex-direction:column;gap:.25rem;min-width:0}
.fig-live-ui .wl-bar{display:block;height:6px;border-radius:3px;background:var(--ac)}
.fig-live-ui .wl-bar.is-off{background:var(--c-err)}
.fig-live-ui .wl-num{color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .wl-time{color:var(--fg-muted)}
.fig-live-ui .wl-time.is-off{color:var(--c-err)}
.fig-live-ui .wl-live{font-size:.85rem;color:var(--fg)}
.fig-live-ui .wl-note{font-size:.74rem;color:var(--fg-subtle)}
@media(max-width:640px){.fig-live-ui .wg-tr{grid-template-columns:5.5rem minmax(0,1fr)}.fig-live-ui .wg-tr>.wl-time{grid-column:2}.fig-live-ui .wg-tr.wl-th>span:nth-child(n+3){display:none}}
@media print{.fig-live.is-live>figure{display:block}.fig-live.is-live>table{display:table}.fig-live-ui{display:none}}
.fig-live-ui .wr-board{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:.45rem}
.fig-live-ui .wr-tok{font:inherit;display:flex;flex-direction:column;align-items:center;gap:.15rem;padding:.55rem .3rem;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg);cursor:grab;touch-action:none;user-select:none;-webkit-user-select:none}
.fig-live-ui .wr-tok .wr-th{font-weight:700;font-size:.8rem}
.fig-live-ui .wr-tok .wr-step{font-family:'JetBrains Mono',monospace;font-size:.76rem;color:var(--fg-muted)}
.fig-live-ui .wr-a{border-color:var(--ac)}.fig-live-ui .wr-a .wr-th,.fig-live-ui .wr-at{color:var(--ac)}
.fig-live-ui .wr-b{border-color:var(--c-ok)}.fig-live-ui .wr-b .wr-th,.fig-live-ui .wr-bt{color:var(--c-ok)}
.fig-live-ui .wr-tok.is-drag{cursor:grabbing;box-shadow:0 0 0 2px var(--ac);opacity:.85}
.fig-live-ui .wr-tok.is-refused{animation:wr-shake .3s}
@keyframes wr-shake{25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}
@media(prefers-reduced-motion:reduce){.fig-live-ui .wr-tok.is-refused{animation:none;box-shadow:0 0 0 2px var(--c-err)}}
.fig-live-ui .wr-tr{grid-template-columns:minmax(0,1.3fr) repeat(3,minmax(0,1fr))}
.fig-live-ui .wr-tr.is-write .wl-num{font-weight:700}
.fig-live-ui .wl-live.is-bad{color:var(--c-err)}
@media(max-width:640px){.fig-live-ui .wr-board{grid-template-columns:repeat(3,minmax(0,1fr))}.fig-live-ui .wr-tr{grid-template-columns:minmax(0,1.3fr) repeat(3,minmax(0,1fr))}}
.fig-live-ui .we-in{font-family:'JetBrains Mono',monospace;font-size:.85rem;margin-left:.35rem;padding:.3rem .5rem;width:11rem;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg)}
.fig-live-ui .we-grid{display:grid;gap:2px;font-family:'JetBrains Mono',monospace;font-size:.78rem;overflow-x:auto}
.fig-live-ui .we-h{display:flex;align-items:center;justify-content:center;min-height:1.7rem;color:var(--ac);font-weight:600}
.fig-live-ui .we-c{display:flex;align-items:center;justify-content:center;min-height:1.7rem;border-radius:4px;background:var(--bg-surf);color:var(--fg-muted)}
.fig-live-ui .we-c.is-on{color:var(--fg)}
.fig-live-ui .we-c.is-path{background:var(--ac-dim);color:var(--fg);font-weight:700;box-shadow:inset 0 0 0 1px var(--ac)}
.fig-live-ui .wd-svg{display:block;touch-action:pan-y}
.fig-live-ui .wd-edge{stroke:var(--fg-subtle);stroke-width:2;stroke-opacity:.7}
.fig-live-ui .wd-edge.is-done{stroke:var(--c-ok);stroke-opacity:1}
.fig-live-ui .wd-edge.is-neg,.fig-live-ui .wd-head.is-neg{stroke:var(--c-err);fill:var(--c-err);stroke-opacity:1}
.fig-live-ui .wd-head{fill:var(--fg-subtle)}
.fig-live-ui .wd-wt{fill:var(--fg-muted);font-size:calc(13px * var(--wd-k,1));font-family:'JetBrains Mono',monospace}
.fig-live-ui .wd-wt.is-neg{fill:var(--c-err);font-weight:700}
.fig-live-ui .wd-node{cursor:grab;touch-action:none}
.fig-live-ui .wd-dot{fill:var(--bg-surf);stroke:var(--fg-subtle);stroke-width:2}
.fig-live-ui .wd-hit{fill:transparent;stroke:none;pointer-events:all}
.fig-live-ui .wd-node.is-front .wd-dot{stroke:var(--ac);stroke-dasharray:4 3}
.fig-live-ui .wd-node.is-settled .wd-dot{fill:var(--c-ok-bg);stroke:var(--c-ok)}
.fig-live-ui .wd-node.is-now .wd-dot{stroke-width:3.5}
.fig-live-ui .wd-node:focus-visible{outline:none}
.fig-live-ui .wd-node:focus-visible .wd-dot{stroke:var(--ac);stroke-width:4}
.fig-live-ui .wd-name{fill:var(--fg);font-size:calc(15px * var(--wd-k,1));font-weight:700;pointer-events:none}
.fig-live-ui .wd-dist{fill:var(--ac);font-size:calc(13px * var(--wd-k,1));font-family:'JetBrains Mono',monospace;pointer-events:none}
.fig-live-ui .wd-tr{grid-template-columns:4rem 6rem minmax(0,1fr) 9rem}
.fig-live-ui .wl-num.is-bad{color:var(--c-err);font-weight:700}
.fig-live-ui .wd-weights{display:flex;flex-wrap:wrap;gap:.4rem .9rem;font-size:.8rem;color:var(--fg-muted)}
.fig-live-ui .wd-in{width:4.2rem}
@media(max-width:640px){.fig-live-ui .wd-tr{grid-template-columns:2rem 3.6rem minmax(0,1fr) 4.4rem;gap:.4rem}}
/* Layout widgets for Frontend from Zero (#799): boxmodel, flexbox, gridresize.
   The stages are real CSS the widget sets at run time; these rules only frame
   and colour them. The rule the reader built is shown in .wl-css. */
.fig-live-ui .wl-sr{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.fig-live-ui .wl-slider{flex-wrap:nowrap}
.fig-live-ui .wl-grow{flex:1 1 0;min-width:0;margin:0}
.fig-live-ui .wl-grow .wl-range{flex:1 1 auto;min-width:0}
.fig-live-ui .wl-short{min-width:5.5ch;white-space:nowrap;text-align:right}
.fig-live-ui .wl-css{margin:0;padding:.7rem .85rem;border-radius:var(--r-sm);background:var(--bg-surf);border:1px solid var(--bd);font-family:'JetBrains Mono',monospace;font-size:.78rem;line-height:1.5;color:var(--fg);white-space:pre-wrap;overflow-wrap:anywhere;font-variant-ligatures:none}
.fig-live-ui .wf-prop{min-width:8.5rem;font-family:'JetBrains Mono',monospace;font-weight:500}
.fig-live-ui .wb-stage{padding:.5rem;border:1px dashed var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);overflow:hidden}
.fig-live-ui .wb-fit{transform-origin:left top;width:max-content}
.fig-live-ui .wb-canvas{display:inline-block;vertical-align:top;background:repeating-linear-gradient(45deg,var(--c-warn-bd) 0 6px,transparent 6px 12px)}
.fig-live-ui .wb-box{display:block;border-style:solid;border-color:var(--fg);background:linear-gradient(var(--ac-dim),var(--ac-dim)) content-box,var(--c-ok-bg,var(--bg-sb));color:var(--fg)}
.fig-live-ui .wb-content{display:block;padding:.6rem 0;text-align:center;font-family:'JetBrains Mono',monospace;font-size:.78rem}
.fig-live-ui .wf-stage{display:flex;min-height:13rem;padding:.5rem;border:1px dashed var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);overflow:auto}
.fig-live-ui .wf-item{display:flex;align-items:center;justify-content:center;border-radius:var(--r-xs);border:1px solid var(--ac);background:var(--ac-dim);color:var(--fg);font-size:.82rem;font-weight:600;min-width:3.2rem}
.fig-live-ui .wf-i0{padding:.5rem .9rem}
.fig-live-ui .wf-i1{padding:1.3rem 1.6rem}
.fig-live-ui .wf-i2{padding:.8rem 2.4rem}
@media(prefers-reduced-motion:no-preference){.fig-live-ui .wf-item{transition:transform .2s}}
.fig-live-ui .wg-stage{padding:.5rem 0;overflow:hidden}
.fig-live-ui .wg-frame{position:relative;display:inline-block;vertical-align:top;transform-origin:left top;padding:.75rem 1.6rem .75rem .75rem;border:2px solid var(--ac);border-radius:var(--r-sm);background:var(--bg-surf);min-height:7rem}
.fig-live-ui .wg-area{position:relative}
.fig-live-ui .wg-guides{position:absolute;inset:0;display:grid;overflow:hidden;pointer-events:none}
.fig-live-ui .wg-track{border:1px dashed var(--fg-subtle);border-radius:var(--r-xs)}
.fig-live-ui .wg-grid{position:relative;display:grid}
.fig-live-ui .wg-card{display:flex;flex-direction:column;gap:.5rem;padding:.7rem .8rem .9rem;border-radius:var(--r-xs);background:var(--bg-sb);border:1px solid var(--bd);min-height:5rem}
.fig-live-ui .wg-card-bar{display:block;height:4px;border-radius:2px;background:var(--ac)}
.fig-live-ui .wg-card-title{font-size:1.05rem;font-weight:600;color:var(--fg)}
.fig-live-ui .wg-handle{position:absolute;top:0;right:-2px;bottom:0;width:1.1rem;display:flex;align-items:center;justify-content:center;cursor:ew-resize;touch-action:none;user-select:none;-webkit-user-select:none;background:var(--ac-dim);border-left:1px solid var(--ac);border-radius:0 var(--r-sm) var(--r-sm) 0}
.fig-live-ui .wg-handle::before{content:"";width:3px;height:1.8rem;border-radius:2px;background:var(--ac)}
.fig-live-ui .wg-handle.is-drag,.fig-live-ui .wg-handle:hover{background:var(--ac)}
.fig-live-ui .wg-handle.is-drag::before,.fig-live-ui .wg-handle:hover::before{background:var(--bg-surf)}
/* Kubernetes Deep Dive widgets (#811): hpa, rollout, quorum. They reuse the static
   figures' own .fig-flow, .tree-level and .topo-* markup, so the live figure reads
   like the one it replaces; these rules add only the moving parts. */
.fig-live-ui .fig-flow,.fig-live-ui .wo-tree,.fig-live-ui .topo-frame{width:100%}
.fig-live-ui .wh-pods{display:flex;flex-wrap:wrap;gap:.3rem;justify-content:center;min-height:1rem}
.fig-live-ui .wh-pod{width:1rem;height:1rem;border-radius:3px;background:var(--ac-dim);border:1px solid var(--ac)}
.fig-live-ui .wh-pod.is-new{background:var(--c-ok-bg);border-color:var(--c-ok)}
.fig-live-ui .wh-pod.is-gone{background:transparent;border-style:dashed;border-color:var(--c-err)}
.fig-live-ui .wo-tree .tree-level{margin-bottom:.45rem}
.fig-live-ui .wo-tree .d1{margin-left:1.2rem}
.fig-live-ui .wo-tree .d2{margin-left:2.4rem}
.fig-live-ui .wo-row{display:flex;flex-wrap:wrap;gap:.35rem;margin-top:.3rem}
.fig-live-ui .wo-pod{font-family:'JetBrains Mono',monospace;font-size:.74rem;padding:.15rem .5rem;border-radius:var(--r-sm);border:1px solid var(--c-ok);background:var(--c-ok-bg);color:var(--fg)}
.fig-live-ui .wo-pod.is-starting{border-style:dashed;border-color:var(--fg-subtle);background:transparent;color:var(--fg-muted)}
.fig-live-ui .wl-live.is-bad,.fig-live-ui .wq-band.is-bad{color:var(--c-err)}
.fig-live-ui .wq-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(5rem,1fr))}
.fig-live-ui .wq-cols .topo-zone{padding:.45rem .35rem}
.fig-live-ui .wq-node{font:inherit;font-size:.72rem;font-weight:600;cursor:pointer;color:var(--tx);white-space:nowrap}
.fig-live-ui .wq-node.is-down{border-color:var(--c-err);background:var(--c-err-bg);color:var(--c-err);text-decoration:line-through}
.fig-live-ui .topo-frame.is-bad{border-color:var(--c-err)}
.fig-live-ui button:disabled{opacity:.45;cursor:default}
@media(max-width:640px){.fig-live-ui .wo-tree .d1{margin-left:.6rem}.fig-live-ui .wo-tree .d2{margin-left:1.2rem}}
/* Play buttons (#811): the HPA's traffic chart; a running player's button stays pressed. */
.fig-live-ui .wl-btn[aria-pressed="true"]{background:var(--ac-dim);border-color:var(--ac);color:var(--fg)}
.fig-live-ui .wh-chart{display:flex;flex-direction:column;gap:.35rem}
.fig-live-ui .wh-chart svg{display:block;width:100%;height:9rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf)}
.fig-live-ui .wh-chart polyline{fill:none;vector-effect:non-scaling-stroke;stroke-linejoin:round}
.fig-live-ui .wh-rep{stroke:var(--ac);stroke-width:2.5}
.fig-live-ui .wh-need{stroke:var(--c-warn);stroke-width:1.5;stroke-dasharray:5 4}
.fig-live-ui .wh-max{stroke:var(--c-err);stroke-width:1;stroke-dasharray:2 4}
.fig-live-ui .wh-axis{font-size:.72rem;color:var(--fg-subtle);font-family:'JetBrains Mono',monospace}
.fig-live-ui .wh-legend{display:flex;flex-wrap:wrap;gap:.3rem 1rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .wh-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .wh-key::before{content:"";width:1.4rem;border-top:2.5px solid var(--ac)}
.fig-live-ui .wh-key-need::before{border-top:1.5px dashed var(--c-warn)}
.fig-live-ui .wh-key-max::before{border-top:1px dotted var(--c-err)}
/* Networking Deep Dive widgets (#815). A [hidden] element inside a widget stays hidden even when
   its class sets display (the hpa chart box showed empty before Play). */
.fig-live-ui [hidden]{display:none!important}
/* cidr (Networking Deep Dive 3.x Subnetting and CIDR): the carving tree reuses the
   figure's .tree-level markup; .wc-bits are the 32 address bits, octets 4 across
   (2 x 2 on a phone); .wc-out is the block's numbers. */
.fig-live-ui .wc-tree{width:100%}
.fig-live-ui .wc-d1{margin-left:1.6rem}
.fig-live-ui .wc-d2{margin-left:3.2rem}
.fig-live-ui .wc-bits{display:flex;flex-wrap:wrap;justify-content:center;gap:.6rem 1rem;font-family:'JetBrains Mono',monospace;font-variant-ligatures:none}
.fig-live-ui .wc-oct{display:flex;flex-direction:column;align-items:center;gap:.2rem}
.fig-live-ui .wc-dec{font-size:.82rem;font-weight:600;color:var(--fg)}
.fig-live-ui .wc-row{display:flex;gap:1px}
.fig-live-ui .wc-bit{position:relative;display:inline-flex;align-items:center;justify-content:center;width:1.05rem;height:1.45rem;font-size:.74rem;border-radius:3px;border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg-muted)}
.fig-live-ui .wc-bit.is-net{border-color:var(--ac);background:var(--ac-dim);color:var(--fg);font-weight:600}
.fig-live-ui .wc-bit.is-edge{margin-left:5px}
.fig-live-ui .wc-bit.is-edge::before{content:"";position:absolute;left:-5px;top:-4px;bottom:-4px;width:2px;border-radius:1px;background:var(--c-warn)}
.fig-live-ui .wc-mask{font-size:.68rem;color:var(--fg-subtle)}
.fig-live-ui .wc-legend{display:flex;flex-wrap:wrap;justify-content:center;gap:.3rem 1.1rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .wc-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .wc-key::before{content:"";width:.8rem;height:.8rem;border-radius:3px;border:1px solid var(--bd);background:var(--bg-surf)}
.fig-live-ui .wc-key-net::before{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .wc-out{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:.35rem 1.2rem;margin:0;font-size:.8rem}
.fig-live-ui .wc-kv{display:flex;gap:.6rem;min-width:0}
.fig-live-ui .wc-kv dt{flex:0 0 5.5rem;color:var(--fg-subtle)}
.fig-live-ui .wc-kv dd{margin:0;min-width:0;font-family:'JetBrains Mono',monospace;color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .wc-inbox{display:flex;flex-direction:column;gap:.25rem}
.fig-live-ui .wc-field{gap:.5rem}
.fig-live-ui .wc-in{font-family:'JetBrains Mono',monospace;font-size:.85rem;padding:.3rem .5rem;width:11rem;max-width:100%;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg)}
.fig-live-ui .wc-in[aria-invalid="true"]{border-color:var(--c-err)}
.fig-live-ui .wc-err{font-size:.76rem;color:var(--c-err)}
.fig-live-ui .wc-link{padding-left:.6rem;border-left:3px solid var(--c-ok)}
.fig-live-ui .wc-link.is-off{border-left-color:var(--c-warn)}
@media(max-width:640px){.fig-live-ui .wc-bit{width:.95rem;font-size:.7rem}.fig-live-ui .wc-d1{margin-left:.8rem}.fig-live-ui .wc-d2{margin-left:1.6rem}}

/* lpm (Networking Deep Dive 4, the routing table): the routing table as the
   figure's .tree-level rows, most specific first. */
.fig-live-ui .wp-lpm{width:100%}
.fig-live-ui .wp-d1{margin-left:1.2rem}
.fig-live-ui .wp-d2{margin-left:2.4rem}
.fig-live-ui .wp-d3{margin-left:3.6rem}
.fig-live-ui .wp-d4{margin-left:4.8rem}
.fig-live-ui .wp-route.is-win{border-left-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .wp-route.is-tie{border-left-color:var(--c-warn)}
.fig-live-ui .wp-route.is-miss{border-style:dashed;border-left-style:solid;border-left-color:var(--bd);background:transparent}
.fig-live-ui .wp-route.is-miss .nm{color:var(--fg-subtle);font-weight:500}
.fig-live-ui .wp-route .binding{overflow-wrap:anywhere}
.fig-live-ui .wp-drop{padding:.55rem .75rem;border:1px solid var(--c-err);border-radius:8px;background:var(--c-err-bg);color:var(--c-err);font-weight:600;font-size:.85rem}
.fig-live-ui .wp-inbox{display:flex;flex-direction:column;gap:.25rem}
.fig-live-ui .wp-field{gap:.5rem}
.fig-live-ui .wp-in{font-family:'JetBrains Mono',monospace;font-size:.85rem;padding:.3rem .5rem;width:11rem;max-width:100%;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg)}
.fig-live-ui .wp-in[aria-invalid="true"]{border-color:var(--c-err)}
.fig-live-ui .wp-err{font-size:.76rem;color:var(--c-err)}
@media(max-width:640px){.fig-live-ui .wp-d1{margin-left:.5rem}.fig-live-ui .wp-d2{margin-left:1rem}.fig-live-ui .wp-d3{margin-left:1.5rem}.fig-live-ui .wp-d4{margin-left:2rem}}

/* Networking Deep Dive widget cwnd: the cwnd cycle. The flow row is the static
   figure's own .fig-flow; .is-now marks the phase the sender is in. */
.fig-live-ui .wn-flow .flow-step.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .wn-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.45rem}
.fig-live-ui .wn-stat{display:flex;flex-direction:column;gap:.15rem;padding:.45rem .6rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);min-width:0}
.fig-live-ui .wn-k{font-size:.68rem;color:var(--fg-subtle);text-transform:uppercase;letter-spacing:.04em}
.fig-live-ui .wn-v{font-family:'JetBrains Mono',monospace;font-size:.8rem;color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .wn-v.is-bad{color:var(--c-err);font-weight:700}
.fig-live-ui .wn-chart{display:flex;flex-direction:column;gap:.35rem}
.fig-live-ui .wn-chart svg{display:block;width:100%;height:10rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf)}
.fig-live-ui .wn-chart polyline,.fig-live-ui .wn-chart line{fill:none;vector-effect:non-scaling-stroke;stroke-linejoin:round}
.fig-live-ui .wn-cw{stroke:var(--ac);stroke-width:2.5}
.fig-live-ui .wn-cap{stroke:var(--c-warn);stroke-width:1.5;stroke-dasharray:6 4}
.fig-live-ui .wn-ss{stroke:var(--fg-subtle);stroke-width:1;stroke-dasharray:2 3}
.fig-live-ui .wn-loss{stroke:var(--c-err);stroke-width:3}
.fig-live-ui .wn-axis{font-size:.72rem;color:var(--fg-subtle);font-family:'JetBrains Mono',monospace}
.fig-live-ui .wn-legend{display:flex;flex-wrap:wrap;gap:.3rem 1rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .wn-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .wn-key::before{content:"";width:1.4rem;border-top:2.5px solid var(--ac)}
.fig-live-ui .wn-key-cap::before{border-top:1.5px dashed var(--c-warn)}
.fig-live-ui .wn-key-ss::before{border-top:1px dotted var(--fg-subtle)}
.fig-live-ui .wn-key-loss::before{width:0;height:.9rem;border-top:0;border-left:3px solid var(--c-err)}
@media(max-width:640px){.fig-live-ui .wn-stats{grid-template-columns:repeat(2,minmax(0,1fr))}}

/* Networking Deep Dive widget tcploss: number it, confirm it, resend. The flow row
   is the static figure's own .fig-flow; .is-now marks the step the current event
   belongs to. Segment boxes are buttons (aria-pressed = set to be lost). */
.fig-live-ui .wt-flow .flow-step.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .wt-flow .flow-step.is-now.is-slow{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .wt-segs{display:flex;flex-wrap:wrap;gap:.4rem}
.fig-live-ui .wt-seg{font:inherit;flex:1 1 5.6rem;min-width:0;display:flex;flex-direction:column;align-items:center;gap:.1rem;padding:.45rem .3rem;border-radius:var(--r-sm);border:1px dashed var(--fg-subtle);background:var(--bg-surf);color:var(--fg);cursor:pointer}
.fig-live-ui .wt-n{font-weight:700;font-size:.78rem}
.fig-live-ui .wt-b{font-family:'JetBrains Mono',monospace;font-size:.7rem;color:var(--fg-muted);white-space:nowrap}
.fig-live-ui .wt-s{font-size:.68rem;color:var(--fg-muted)}
.fig-live-ui .wt-seg.is-acked{border-style:solid;border-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .wt-seg.is-held{border-style:solid;border-color:var(--c-warn);background:var(--c-warn-bg)}
.fig-live-ui .wt-seg.is-lost{border-style:solid;border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .wt-seg.is-lost .wt-s{color:var(--c-err);font-weight:700}
.fig-live-ui .wt-seg.is-resent .wt-n{color:var(--ac)}
.fig-live-ui .wt-seg[aria-pressed="true"]{box-shadow:inset 0 -3px 0 var(--c-err)}
.fig-live-ui .wt-seg.is-now{outline:2px solid var(--ac);outline-offset:1px}
.fig-live-ui .wt-ack{font-family:'JetBrains Mono',monospace;font-size:.78rem;color:var(--fg);padding:.45rem .6rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);overflow-wrap:anywhere}
.fig-live-ui .wt-log{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:.15rem;font-family:'JetBrains Mono',monospace;font-size:.74rem;color:var(--fg-subtle)}
.fig-live-ui .wt-ev{padding:.1rem .5rem;border-left:2px solid transparent;overflow-wrap:anywhere}
.fig-live-ui .wt-ev.is-now{color:var(--fg);font-weight:600;border-left-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .wt-ev.wt-lost,.fig-live-ui .wt-ev.wt-rto{color:var(--c-err)}
.fig-live-ui .wt-count{margin-left:auto}
@media(max-width:640px){.fig-live-ui .wt-seg{flex-basis:4.6rem}.fig-live-ui .wt-count{margin-left:0;width:100%}}

/* bdp (Networking Deep Dive, the bandwidth-delay product): the static figure's
   .wf-row waterfall, drawn to scale by the widget; these rules add the axes, the
   note and the throughput colours. */
.fig-live-ui .wz-group{display:flex;flex-direction:column}
.fig-live-ui .wz-group .wf-label{flex-basis:9.5rem}
.fig-live-ui .wz-bar{left:0;min-width:2px}
.fig-live-ui .wz-link{background:var(--fg-subtle)}
.fig-live-ui .wz-got{background:var(--c-ok)}
.fig-live-ui .wz-got.is-short{background:var(--c-err)}
.fig-live-ui .wz-axis{display:flex;justify-content:space-between;margin:.2rem 0 0 10.1rem;font-size:.66rem;font-family:'JetBrains Mono',monospace;color:var(--fg-subtle)}
.fig-live-ui .wz-note{font-size:.76rem;color:var(--fg-muted);margin-left:10.1rem}
.fig-live-ui .wz-note.is-bad{color:var(--c-err)}
@media(prefers-reduced-motion:no-preference){.fig-live-ui .wz-bar{transition:width .2s}}
@media(max-width:640px){.fig-live-ui .wz-group .wf-label{flex-basis:6.5rem}.fig-live-ui .wz-axis{margin-left:7.1rem}.fig-live-ui .wz-note{margin-left:0}}

/* pmtud (Networking Deep Dive, Path MTU Discovery): the static figure's .fig-flow
   steps (turned .ok/.fail per case), a sender - link - receiver line, and the
   DF-bit ping search's probes. */
.fig-live-ui .wm-pathbox{display:flex;flex-direction:column;gap:.35rem}
.fig-live-ui .wm-path{display:flex;align-items:center;gap:.4rem}
.fig-live-ui .wm-node{flex:none;font-size:.76rem;font-weight:600;padding:.25rem .6rem;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg);white-space:nowrap}
.fig-live-ui .wm-node.is-bad{border-color:var(--c-err);color:var(--c-err)}
.fig-live-ui .wm-leg{flex:1 1 1.5rem;min-width:1rem;border-top:3px solid var(--c-ok)}
.fig-live-ui .wm-leg.is-bad{border-top:3px dashed var(--c-err)}
.fig-live-ui .wm-back{font-size:.74rem;color:var(--fg-muted);text-align:center}
.fig-live-ui .wm-back.is-bad{color:var(--c-err)}
.fig-live-ui .wm-probes{display:flex;flex-direction:column;gap:.45rem}
.fig-live-ui .wm-plist{display:flex;flex-wrap:wrap;gap:.35rem}
.fig-live-ui .wm-probe{font-family:'JetBrains Mono',monospace;font-size:.72rem;padding:.15rem .5rem;border-radius:var(--r-sm);border:1px solid var(--c-ok);background:var(--c-ok-bg);color:var(--fg)}
.fig-live-ui .wm-probe.is-bad{border-color:var(--c-err);background:var(--c-err-bg)}
@media(max-width:640px){.fig-live-ui .wm-node{font-size:.7rem;padding:.2rem .4rem}}

/* dnsttl: DNS TTL cutover planner (Networking Deep Dive 6.03) */
.fig-live-ui .wy-scale{width:100%;max-width:700px;margin:0 auto}
.fig-live-ui .wy-scale .wf-bar{min-width:3px}
.fig-live-ui .wy-flow{flex-wrap:nowrap}
.fig-live-ui .wy-flow .flow-step{flex:1 1 0;min-width:0;max-width:none;padding:.6rem .4rem}
.fig-live-ui .wy-flow .flow-arrow{padding:0}
.fig-live-ui .wy-flow .flow-step.ok{border-color:var(--c-ok)}
.fig-live-ui .wy-flow .flow-step.fail{border-color:var(--c-err)}
.fig-live-ui .wy-tl{position:relative;display:grid;grid-template-columns:9.5rem minmax(0,1fr);gap:.3rem .6rem;align-items:center}
.fig-live-ui .wy-lab{font-size:.72rem;font-family:'JetBrains Mono',monospace;color:var(--fg-muted);text-align:right;line-height:1.2}
.fig-live-ui .wy-lab.is-stale{color:var(--c-err)}
.fig-live-ui .wy-track{position:relative;display:block;height:18px;border:1px solid var(--bd);border-radius:4px;background:var(--bg-surf)}
.fig-live-ui .wy-tl.is-random .wy-track{height:12px}
.fig-live-ui .wy-bar{position:absolute;top:-1px;bottom:-1px;min-width:3px;border-radius:3px;background:var(--ac)}
.fig-live-ui .wy-bar.is-before{background:var(--ac)}
.fig-live-ui .wy-bar.is-stale{background:var(--c-err)}
.fig-live-ui .wy-bar.is-done{background:var(--c-err-bg);box-shadow:inset 0 0 0 1px var(--c-err)}
.fig-live-ui .wy-bar.is-gone{background:var(--fg-subtle);opacity:.4}
.fig-live-ui .wy-lab{grid-column:1}
.fig-live-ui .wy-track{grid-column:2}
.fig-live-ui .wy-marks{grid-column:2;position:relative;align-self:stretch;pointer-events:none;margin:-.2rem 0}
.fig-live-ui .wy-mk{position:absolute;top:0;bottom:0;width:0;border-left:2px solid var(--fg);margin-left:-1px}
.fig-live-ui .wy-mk-lower{border-left:2px dashed var(--c-warn)}
.fig-live-ui .wy-mk-clock{border-left:2px solid var(--ac)}
.fig-live-ui .wy-axis{display:flex;justify-content:space-between;gap:.5rem;margin-left:10.1rem;font-size:.68rem;font-family:'JetBrains Mono',monospace;color:var(--fg-subtle)}
.fig-live-ui .wy-legend{display:flex;flex-wrap:wrap;gap:.3rem 1rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .wy-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .wy-key::before{content:"";flex:none;width:1.1rem;height:.6rem;border-radius:2px;background:var(--ac)}
.fig-live-ui .wy-key-stale::before{background:var(--c-err)}
.fig-live-ui .wy-key-gone::before{background:var(--fg-subtle);opacity:.4}
.fig-live-ui .wy-key-lower::before,.fig-live-ui .wy-key-change::before,.fig-live-ui .wy-key-clock::before{width:0;height:.9rem;border-radius:0;background:none;border-left:2px dashed var(--c-warn)}
.fig-live-ui .wy-key-change::before{border-left:2px solid var(--fg)}
.fig-live-ui .wy-key-clock::before{border-left:2px solid var(--ac)}
@media(max-width:640px){.fig-live-ui .wy-tl{grid-template-columns:5.2rem minmax(0,1fr);gap:.3rem .4rem}.fig-live-ui .wy-lab{font-size:.64rem}.fig-live-ui .wy-axis{margin-left:5.6rem}.fig-live-ui .wy-flow{flex-wrap:wrap}.fig-live-ui .wy-flow .flow-step{flex:1 1 100%;flex-direction:row;justify-content:space-between;gap:.6rem;padding:.4rem .7rem;text-align:left}.fig-live-ui .wy-flow .flow-step .ds{text-align:right}.fig-live-ui .wy-flow .flow-arrow{font-size:.9rem;padding:0}.fig-live-ui .wy-scale .wf-label{flex-basis:96px}.fig-live-ui .wy-scale .wf-axis,.fig-live-ui .wy-scale .wf-note{margin-left:104px}.fig-live-ui .wy-scale .wf-axis{gap:.5rem}}
.fig-live-ui .wy-key-done::before{background:var(--c-err-bg);box-shadow:inset 0 0 0 1px var(--c-err)}

/* macswitch: MAC learning switch (Networking Deep Dive 2.02) */
.fig-live-ui .flow-step.wx-on{border-color:var(--ac);background:var(--ac-dim);color:var(--fg)}
.fig-live-ui .flow-step.wx-off{opacity:.5}
.fig-live-ui .wx-sw{display:flex;flex-direction:column;align-items:stretch}
.fig-live-ui .wx-box{border:2px solid var(--fg-subtle);border-radius:var(--r-sm) var(--r-sm) 0 0;border-bottom:none;background:var(--bg-surf);color:var(--fg);font-weight:700;font-size:.85rem;text-align:center;padding:.4rem}
.fig-live-ui .wx-cols{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.4rem}
.fig-live-ui .wx-col{display:flex;flex-direction:column;align-items:center;min-width:0}
.fig-live-ui .wx-port{align-self:stretch;text-align:center;font-family:'JetBrains Mono',monospace;font-size:.72rem;padding:.3rem .2rem;border:2px solid var(--fg-subtle);background:var(--bg-surf);color:var(--fg-muted)}
.fig-live-ui .wx-port.is-in{border-color:var(--c-warn);background:var(--c-warn-bg);color:var(--fg)}
.fig-live-ui .wx-port.is-out{border-color:var(--ac);background:var(--ac-dim);color:var(--fg);font-weight:700}
.fig-live-ui .wx-link{display:block;width:0;height:1.3rem;border-left:2px dotted var(--bd)}
.fig-live-ui .wx-link.is-in{border-left:3px solid var(--c-warn)}
.fig-live-ui .wx-link.is-out{border-left:3px solid var(--ac)}
.fig-live-ui .wx-hosts{display:flex;flex-direction:column;align-items:stretch;gap:.3rem;width:100%}
.fig-live-ui .wx-down{text-align:center;font-size:.66rem;color:var(--fg-subtle);border:1px dashed var(--bd);border-radius:var(--r-xs);padding:.15rem .2rem}
.fig-live-ui .wx-host{display:flex;flex-direction:column;align-items:center;gap:.1rem;padding:.3rem .25rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);min-width:0}
.fig-live-ui .wx-host.is-src{border-color:var(--c-warn);box-shadow:inset 0 0 0 1px var(--c-warn)}
.fig-live-ui .wx-host.is-dst{border-color:var(--ac)}
.fig-live-ui .wx-name{font-weight:700;font-size:.85rem;color:var(--fg)}
.fig-live-ui .wx-mac{font-family:'JetBrains Mono',monospace;font-size:.64rem;color:var(--fg-muted);text-align:center;line-height:1.25}
.fig-live-ui .wx-tblbox{overflow-x:auto;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf)}
.fig-live-ui .wx-table{width:100%;border-collapse:collapse;font-size:.78rem;color:var(--fg)}
.fig-live-ui .wx-table th{text-align:left;font-size:.68rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fg-subtle);padding:.35rem .6rem;border-bottom:1px solid var(--bd)}
.fig-live-ui .wx-table td{padding:.3rem .6rem;white-space:nowrap;font-family:'JetBrains Mono',monospace}
.fig-live-ui .wx-table tr.is-new td{background:var(--c-ok-bg)}
.fig-live-ui .wx-table tr.is-hit td{background:var(--ac-dim)}
.fig-live-ui .wx-table td.is-old{color:var(--c-warn)}
.fig-live-ui .wx-table td.wx-empty{color:var(--fg-subtle);font-family:inherit;font-style:italic}
@media(max-width:640px){.fig-live-ui .wx-cols{gap:.25rem}.fig-live-ui .wx-port{font-size:.64rem;padding:.25rem .1rem}.fig-live-ui .wx-mac{font-size:.58rem}.fig-live-ui .wx-table{font-size:.72rem}.fig-live-ui .wx-table th,.fig-live-ui .wx-table td{padding:.3rem .35rem}}

/* Waterfall bars drawn to scale from the left (#815): the redrawn BDP and DNS TTL figures.
   Width = value / the row axis maximum; .wf-wmin keeps a tiny bar visible. */
.wf-bar.wf-w100{left:0;width:100%}
.wf-bar.wf-w2{left:0;width:2.05%}
.wf-bar.wf-w4{left:0;width:4.17%}
.wf-bar.wf-wmin{left:0;width:.35%;min-width:3px}
/* Computer Science Deep Dive widgets (#820). */
/* intwheel (Computer Science Deep Dive 2, integers): the byte wheel of the
   figure as an SVG ring with HTML labels over it; .ia-centre is the pattern and
   its two readings in the middle of the ring. */
.fig-live-ui .ia-stage{position:relative;width:100%;max-width:30rem;margin:0 auto;aspect-ratio:440/350;border-radius:var(--r-sm)}
.fig-live-ui .ia-svg{position:absolute;inset:0;width:100%;height:100%;display:block}
.fig-live-ui .ia-pos,.fig-live-ui .ia-neg,.fig-live-ui .ia-trail{fill:none;stroke-width:6px;stroke-linecap:round;vector-effect:non-scaling-stroke}
.fig-live-ui .ia-pos{stroke:var(--c-ok);stroke-opacity:.75}
.fig-live-ui .ia-neg{stroke:var(--ac);stroke-opacity:.75}
.fig-live-ui .ia-tick{stroke:var(--fg-subtle);stroke-opacity:.6;stroke-width:1px;vector-effect:non-scaling-stroke}
.fig-live-ui .ia-swrap{stroke:var(--c-err);stroke-width:3px;vector-effect:non-scaling-stroke}
.fig-live-ui .ia-uwrap{stroke:var(--c-warn);stroke-width:3px;stroke-dasharray:4 3;vector-effect:non-scaling-stroke}
.fig-live-ui .ia-trail{stroke:var(--fg);stroke-width:10px;stroke-opacity:.35}
.fig-live-ui .ia-trail.is-wrap{stroke:var(--c-err);stroke-opacity:.6}
.fig-live-ui .ia-dot{fill:var(--fg);stroke:var(--bg-sb);stroke-width:3px;vector-effect:non-scaling-stroke}
.fig-live-ui .ia-labels{position:absolute;inset:0;pointer-events:none}
.fig-live-ui .ia-lab{position:absolute;display:flex;flex-direction:column;line-height:1.2;white-space:nowrap;padding:.05rem .25rem;border-radius:4px}
.fig-live-ui .ia-lab.ia-l{align-items:flex-end;text-align:right}
.fig-live-ui .ia-lab.ia-top{transform:translateY(-100%)}
.fig-live-ui .ia-lab.ia-mid{transform:translateY(-50%)}
.fig-live-ui .ia-lab.is-on{background:var(--ac-dim);box-shadow:inset 0 0 0 1px var(--ac)}
.fig-live-ui .ia-lv{font-size:.8rem;color:var(--fg)}
.fig-live-ui .ia-lu{color:var(--fg-subtle);font-weight:400}
.fig-live-ui .ia-lb{font-family:'JetBrains Mono',monospace;font-size:.68rem;color:var(--fg-muted);font-variant-ligatures:none}
.fig-live-ui .ia-centre{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:flex;flex-direction:column;align-items:center;gap:.15rem;pointer-events:none}
.fig-live-ui .ia-cbits{font-family:'JetBrains Mono',monospace;font-size:1.05rem;font-weight:600;letter-spacing:.04em;color:var(--fg);font-variant-ligatures:none}
.fig-live-ui .ia-cbits .ia-top{color:var(--ac);text-decoration:underline;text-underline-offset:3px}
.fig-live-ui .ia-cread{font-size:.78rem;color:var(--fg-muted)}
.fig-live-ui .ia-legend{display:flex;flex-wrap:wrap;justify-content:center;gap:.3rem 1.1rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .ia-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .ia-key::before{content:"";flex:0 0 auto;width:.9rem;height:.3rem;border-radius:2px;background:var(--fg-subtle)}
.fig-live-ui .ia-key-pos::before{background:var(--c-ok)}
.fig-live-ui .ia-key-neg::before{background:var(--ac)}
.fig-live-ui .ia-key-s::before{width:.2rem;height:.9rem;background:var(--c-err)}
.fig-live-ui .ia-key-u::before{width:.2rem;height:.9rem;background:repeating-linear-gradient(var(--c-warn) 0 3px,transparent 3px 5px)}
.fig-live-ui .ia-reads{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:.3rem 1.2rem;font-size:.8rem}
.fig-live-ui .ia-kv{display:flex;gap:.6rem;min-width:0}
.fig-live-ui .ia-k{flex:0 0 4.6rem;color:var(--fg-subtle)}
.fig-live-ui .ia-v{min-width:0;font-family:'JetBrains Mono',monospace;color:var(--fg);overflow-wrap:anywhere;white-space:pre-wrap}
.fig-live-ui .ia-inbox{display:flex;flex-direction:column;gap:.25rem}
.fig-live-ui .ia-field{gap:.5rem}
.fig-live-ui .ia-in{font-family:'JetBrains Mono',monospace;font-size:.85rem;padding:.3rem .5rem;width:9rem;max-width:100%;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg)}
.fig-live-ui .ia-in[aria-invalid="true"]{border-color:var(--c-err)}
.fig-live-ui .ia-err{font-size:.76rem;color:var(--c-err)}
@media(max-width:640px){.fig-live-ui .ia-lu{display:none}.fig-live-ui .ia-lv{font-size:.72rem}.fig-live-ui .ia-lb{font-size:.6rem}.fig-live-ui .ia-cbits{font-size:.9rem}.fig-live-ui .ia-cread{font-size:.7rem}}

/* floatbits (Computer Science Deep Dive 2, floating point): the three fields
   of the figure as rows of clickable bits (sign red, exponent amber, fraction
   indigo, as in the figure), the decode line and the exact value stored. */
.fig-live-ui .ib-inbox{display:flex;flex-direction:column;gap:.25rem}
.fig-live-ui .ib-field{gap:.5rem}
.fig-live-ui .ib-in{font-family:'JetBrains Mono',monospace;font-size:.85rem;padding:.3rem .5rem;width:14rem;max-width:100%;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg)}
.fig-live-ui .ib-in[aria-invalid="true"]{border-color:var(--c-err)}
.fig-live-ui .ib-err{font-size:.76rem;color:var(--c-err)}
.fig-live-ui .ib-strip{display:flex;flex-wrap:wrap;gap:.5rem .9rem;align-items:flex-start}
.fig-live-ui .ib-group{display:flex;flex-direction:column;gap:.25rem;min-width:0}
.fig-live-ui .ib-group.ib-f{flex:1 1 100%}
.fig-live-ui .ib-glab{font-size:.7rem;color:var(--fg-subtle)}
.fig-live-ui .ib-bits{display:flex;flex-wrap:wrap;gap:4px 7px}
.fig-live-ui .ib-nib,.fig-live-ui .ib-e .ib-bits,.fig-live-ui .ib-s .ib-bits{display:inline-flex;gap:2px}
.fig-live-ui .ib-bit{font:inherit;font-family:'JetBrains Mono',monospace;font-size:.72rem;width:1.1rem;height:1.5rem;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:3px;border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg-muted);cursor:pointer;font-variant-ligatures:none}
.fig-live-ui .ib-s .ib-bit{border-color:var(--c-err);background:var(--c-err-bg);color:var(--fg)}
.fig-live-ui .ib-e .ib-bit{border-color:var(--c-warn);background:var(--c-warn-bg);color:var(--fg)}
.fig-live-ui .ib-f .ib-bit{border-color:var(--ac);background:var(--ac-dim);color:var(--fg)}
.fig-live-ui .ib-bit:hover{box-shadow:inset 0 0 0 1px var(--fg)}
.fig-live-ui .ib-s .ib-glab{color:var(--c-err)}
.fig-live-ui .ib-e .ib-glab{color:var(--c-warn)}
.fig-live-ui .ib-f .ib-glab{color:var(--ac)}
.fig-live-ui .ib-decode{display:flex;flex-direction:column;gap:.2rem;padding:.55rem .75rem;border-radius:var(--r-sm);background:var(--bg-surf);border:1px solid var(--bd)}
.fig-live-ui .ib-formula{font-family:'JetBrains Mono',monospace;font-size:.88rem;color:var(--fg);overflow-wrap:anywhere;font-variant-ligatures:none}
.fig-live-ui .ib-why{font-size:.76rem;color:var(--fg-muted)}
.fig-live-ui .ib-out{display:flex;flex-direction:column;gap:.3rem;margin:0;font-size:.8rem}
.fig-live-ui .ib-kv{display:flex;gap:.6rem;min-width:0}
.fig-live-ui .ib-kv dt{flex:0 0 6.5rem;color:var(--fg-subtle)}
.fig-live-ui .ib-kv dd{margin:0;min-width:0;font-family:'JetBrains Mono',monospace;color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .wl-btn:disabled{opacity:.45;cursor:default}
@media(max-width:640px){.fig-live-ui .ib-bit{width:.98rem;height:1.4rem;font-size:.68rem}.fig-live-ui .ib-kv{flex-direction:column;gap:.05rem}.fig-live-ui .ib-kv dt{flex-basis:auto}}

/* structlayout (Computer Science Deep Dive 2, byte order and serialization):
   two byte maps side by side (the reader's order, then largest first), each a
   stack of 8-byte rows with fields coloured by size (1 red, 2 amber, 4 green,
   8 indigo, the figure's flag red and int64 indigo) and hatched padding; below,
   the field list with a type picker and move buttons. */
.fig-live-ui .ic-maps{display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));gap:.9rem}
.fig-live-ui .ic-panel{display:flex;flex-direction:column;gap:.35rem;min-width:0}
.fig-live-ui .ic-ph{display:flex;flex-wrap:wrap;justify-content:space-between;gap:.2rem .6rem;font-size:.8rem}
.fig-live-ui .ic-pt{font-weight:600;color:var(--fg)}
.fig-live-ui .ic-ps{font-family:'JetBrains Mono',monospace;font-weight:600;color:var(--ac)}
.fig-live-ui .ic-best .ic-pt{color:var(--fg-muted)}
.fig-live-ui .ic-best .ic-ps{color:var(--c-ok)}
.fig-live-ui .ic-best.is-same .ic-ps{color:var(--fg-muted)}
.fig-live-ui .ic-pn{font-size:.74rem;color:var(--fg-subtle)}
.fig-live-ui .ic-map{display:flex;flex-direction:column;gap:3px}
.fig-live-ui .ic-row{display:flex;align-items:stretch;gap:.4rem}
.fig-live-ui .ic-off{flex:0 0 1.4rem;text-align:right;align-self:center;font-family:'JetBrains Mono',monospace;font-size:.68rem;color:var(--fg-subtle)}
.fig-live-ui .ic-cells{flex:1 1 auto;min-width:0;display:grid;grid-template-columns:repeat(8,minmax(0,1fr));gap:2px;background:repeating-linear-gradient(90deg,transparent 0 calc(12.5% - 1px),var(--bd) calc(12.5% - 1px) 12.5%)}
.fig-live-ui .ic-blk{display:flex;align-items:center;justify-content:center;min-width:0;height:2rem;border-radius:4px;border:1px solid var(--bd);font-size:.7rem;color:var(--fg);overflow:hidden;white-space:nowrap}
.fig-live-ui .ic-pad{color:var(--fg-subtle);background:repeating-linear-gradient(45deg,var(--bg-surf) 0 5px,var(--bd) 5px 6px)}
.fig-live-ui .ic-blk.ic-t1{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .ic-blk.ic-t2{border-color:var(--c-warn);background:var(--c-warn-bg)}
.fig-live-ui .ic-blk.ic-t4{border-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .ic-blk.ic-t8{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .ic-axis{font-size:.7rem;color:var(--fg-subtle)}
.fig-live-ui .ic-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.4rem;counter-reset:ic}
.fig-live-ui .ic-item{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem .7rem;padding:.35rem .5rem .35rem .6rem;border-left:3px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);font-size:.8rem;counter-increment:ic}
.fig-live-ui .ic-item::before{content:counter(ic);font-family:'JetBrains Mono',monospace;font-size:.72rem;color:var(--fg-subtle);min-width:.8rem}
.fig-live-ui .ic-item.ic-t1{border-left-color:var(--c-err)}
.fig-live-ui .ic-item.ic-t2{border-left-color:var(--c-warn)}
.fig-live-ui .ic-item.ic-t4{border-left-color:var(--c-ok)}
.fig-live-ui .ic-item.ic-t8{border-left-color:var(--ac)}
.fig-live-ui .ic-sel{font:inherit;font-family:'JetBrains Mono',monospace;font-size:.8rem;padding:.25rem .4rem;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-sb);color:var(--fg)}
.fig-live-ui .ic-where{flex:1 1 10rem;min-width:0;color:var(--fg-muted);font-family:'JetBrains Mono',monospace;font-size:.74rem}
.fig-live-ui .ic-ctl{display:inline-flex;gap:.3rem;margin-left:auto}
.fig-live-ui .ic-mv{min-width:2.1rem;padding:.25rem .5rem}
.fig-live-ui .wl-btn:disabled{opacity:.45;cursor:default}
@media(max-width:640px){.fig-live-ui .ic-blk{font-size:.62rem;height:1.8rem}.fig-live-ui .ic-where{flex-basis:100%;order:3}.fig-live-ui .ic-item{gap:.35rem .45rem}.fig-live-ui .ic-sel{font-size:.74rem;padding:.25rem .2rem}.fig-live-ui .ic-mv{min-width:1.9rem;padding:.25rem .35rem}.fig-live-ui .ic-ctl{gap:.2rem}}

/* crossover (ja): the scan and tree cost curves, the shaded range where the scan
   is cheaper and the crossover line; tick labels are HTML over the SVG. */
.fig-live-ui .ja-plot{position:relative;height:13rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);overflow:hidden}
.fig-live-ui .ja-plot svg{display:block;width:100%;height:100%}
.fig-live-ui .ja-plot line,.fig-live-ui .ja-plot polyline{fill:none;vector-effect:non-scaling-stroke;stroke-linejoin:round}
.fig-live-ui .ja-grid{stroke:var(--bd);stroke-width:1;stroke-dasharray:4 4}
.fig-live-ui .ja-shade{fill:var(--c-ok-bg)}
.fig-live-ui .ja-scan{stroke:var(--c-ok);stroke-width:2.5}
.fig-live-ui .ja-tree{stroke:var(--ac);stroke-width:2.5}
.fig-live-ui .ja-cross{stroke:var(--fg-muted);stroke-width:1.2;stroke-dasharray:3 3}
.fig-live-ui .ja-yt{position:absolute;left:.35rem;transform:translateY(-1px);font-family:'JetBrains Mono',monospace;font-size:.66rem;line-height:1;color:var(--fg-subtle);background:var(--bg-surf);padding:1px 2px;border-radius:2px;pointer-events:none}
.fig-live-ui .ja-xmark{position:absolute;bottom:.35rem;margin-left:.3rem;font-family:'JetBrains Mono',monospace;font-size:.7rem;font-weight:600;color:var(--fg);white-space:nowrap;background:var(--bg-surf);padding:1px 3px;border-radius:2px;pointer-events:none}
.fig-live-ui .ja-xmark.is-right{transform:translateX(-100%);margin-left:-.3rem}
.fig-live-ui .ja-xaxis{display:flex;justify-content:space-between;margin-top:-.55rem;font-family:'JetBrains Mono',monospace;font-size:.66rem;color:var(--fg-subtle)}
.fig-live-ui .ja-xname{margin-top:-.7rem;text-align:center;font-size:.72rem;color:var(--fg-subtle)}
.fig-live-ui .ja-legend{display:flex;flex-wrap:wrap;gap:.3rem 1rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .ja-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .ja-key::before{content:"";width:1.4rem;border-top:2.5px solid var(--c-ok)}
.fig-live-ui .ja-key-tree::before{border-top-color:var(--ac)}
.fig-live-ui .ja-key-shade::before{width:.9rem;height:.8rem;border:1px solid var(--c-ok);border-radius:2px;background:var(--c-ok-bg)}
.fig-live-ui .ja-stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.45rem}
.fig-live-ui .ja-stat{display:flex;flex-direction:column;gap:.15rem;padding:.45rem .6rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);min-width:0}
.fig-live-ui .ja-k{font-size:.68rem;color:var(--fg-subtle);text-transform:uppercase;letter-spacing:.04em}
.fig-live-ui .ja-v{font-family:'JetBrains Mono',monospace;font-size:.8rem;color:var(--fg);overflow-wrap:anywhere}
@media(max-width:640px){.fig-live-ui .ja-plot{height:11rem}.fig-live-ui .ja-stats{grid-template-columns:minmax(0,1fr)}.fig-live-ui .ja-stat{flex-direction:row;justify-content:space-between;align-items:baseline;gap:.6rem}.fig-live-ui .ja-v{text-align:right}}

/* cachewalk (jb): two grids side by side (row walk, column or shuffled walk),
   one cell per 8-byte value, a small gap between 64-byte lines; the cached
   lines tinted, the read of this step green (hit) or red (miss). */
.fig-live-ui .jb-panes{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1.2rem}
.fig-live-ui .jb-pane{display:flex;flex-direction:column;align-items:center;gap:.35rem;min-width:0}
.fig-live-ui .jb-title{font-size:.82rem;font-weight:600;color:var(--fg)}
.fig-live-ui .jb-gridwrap{position:relative;width:100%;max-width:16rem}
.fig-live-ui .jb-grid{display:grid;grid-template-columns:repeat(var(--jb-lines,2),minmax(0,1fr));gap:1px 3px}
.fig-live-ui .jb-line{display:grid;grid-template-columns:repeat(8,minmax(0,1fr));gap:1px;border-radius:2px}
.fig-live-ui .jb-line.is-cached{background:var(--ac-dim);box-shadow:0 0 0 1.5px var(--ac)}
.fig-live-ui .jb-c{aspect-ratio:1;border-radius:1px;background:var(--bg-surf);box-shadow:inset 0 0 0 1px var(--bd)}
.fig-live-ui .jb-line.is-cached .jb-c{background:transparent;box-shadow:inset 0 0 0 1px var(--ac-dim)}
.fig-live-ui .jb-c.is-read,.fig-live-ui .jb-line.is-cached .jb-c.is-read{background:var(--bd)}
.fig-live-ui .jb-line .jb-c.is-hit,.fig-live-ui .jb-line.is-cached .jb-c.is-hit{background:var(--c-ok);box-shadow:none}
.fig-live-ui .jb-line .jb-c.is-miss,.fig-live-ui .jb-line.is-cached .jb-c.is-miss{background:var(--c-err);box-shadow:none}
.fig-live-ui .jb-arrows{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
.fig-live-ui .jb-arrow{stroke:var(--c-ok);stroke-width:2;vector-effect:non-scaling-stroke}
.fig-live-ui .jb-head{fill:var(--c-ok)}
.fig-live-ui .jb-pane:last-child .jb-arrow{stroke:var(--c-warn)}
.fig-live-ui .jb-pane:last-child .jb-head{fill:var(--c-warn)}
.fig-live-ui .jb-count{font-family:'JetBrains Mono',monospace;font-size:.74rem;color:var(--fg);text-align:center}
.fig-live-ui .jb-last{font-family:'JetBrains Mono',monospace;font-size:.7rem;color:var(--fg-subtle);text-align:center}
.fig-live-ui .jb-last.is-miss{color:var(--c-err)}
.fig-live-ui .jb-last.is-hit{color:var(--c-ok)}
.fig-live-ui .jb-legend{display:flex;flex-wrap:wrap;justify-content:center;gap:.3rem 1rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .jb-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .jb-key::before{content:"";width:.8rem;height:.8rem;border-radius:2px;background:var(--ac-dim);box-shadow:0 0 0 1.5px var(--ac)}
.fig-live-ui .jb-key-miss::before{background:var(--c-err);box-shadow:none}
.fig-live-ui .jb-key-hit::before{background:var(--c-ok);box-shadow:none}
.fig-live-ui .jb-key-read::before{background:var(--bd);box-shadow:none}
@media(max-width:640px){.fig-live-ui .jb-panes{gap:.7rem}.fig-live-ui .jb-grid{column-gap:2px}.fig-live-ui .jb-last{font-size:.66rem}}

/* gc (jc): the figure's object graph as SVG shapes with HTML labels over them
   (the stage keeps the viewBox's shape), a count badge per object in reference
   counting, marked objects shaded in tracing, freed ones dashed and faded. */
.fig-live-ui .jc-stage{position:relative;container-type:inline-size}
.fig-live-ui .jc-stage svg{display:block;width:100%;height:auto}
.fig-live-ui .jc-line{stroke:var(--fg-subtle);stroke-width:1.6;vector-effect:non-scaling-stroke}
.fig-live-ui .jc-head{fill:var(--fg-subtle)}
.fig-live-ui .jc-hit{stroke:transparent;stroke-width:16;cursor:pointer;pointer-events:stroke}
.fig-live-ui .jc-edge:hover .jc-line{stroke:var(--fg)}
.fig-live-ui .jc-edge.is-traced .jc-line{stroke:var(--c-ok);stroke-width:2}
.fig-live-ui .jc-edge.is-traced .jc-head{fill:var(--c-ok)}
.fig-live-ui .jc-edge.is-cut .jc-line{stroke:var(--c-err);stroke-dasharray:3 4;stroke-opacity:.6}
.fig-live-ui .jc-edge.is-cut .jc-head{fill:var(--c-err);fill-opacity:.5}
.fig-live-ui .jc-root{fill:var(--ac-dim);stroke:var(--ac);stroke-width:1.5}
.fig-live-ui .jc-obj{fill:var(--bg-surf);stroke:var(--fg-subtle);stroke-width:1.5}
.fig-live-ui .jc-obj.is-marked{fill:var(--c-ok-bg);stroke:var(--c-ok)}
.fig-live-ui .jc-obj.is-leak{fill:var(--c-err-bg);stroke:var(--c-err)}
.fig-live-ui .jc-obj.is-now{stroke-width:3.5}
.fig-live-ui .jc-obj.is-freed{fill:none;stroke:var(--fg-subtle);stroke-dasharray:3 3;stroke-opacity:.6}
.fig-live-ui .jc-obj.is-freed.is-now{stroke:var(--c-err);stroke-opacity:1;stroke-width:2.5}
.fig-live-ui .jc-labels{position:absolute;inset:0;pointer-events:none}
.fig-live-ui .jc-lab{position:absolute;transform:translate(-50%,-50%);font-size:clamp(.62rem,2.2cqw,.9rem);font-weight:700;color:var(--fg);white-space:nowrap;line-height:1}
.fig-live-ui .jc-lab.is-root{font-weight:600;font-size:clamp(.56rem,1.9cqw,.8rem)}
.fig-live-ui .jc-lab.is-freed{color:var(--fg-subtle);font-weight:400;text-decoration:line-through}
.fig-live-ui .jc-badge{position:absolute;transform:translate(-50%,-50%);min-width:1.25em;padding:.1em .3em;border-radius:var(--r-pill);border:1px solid var(--ac);background:var(--bg-sb);color:var(--fg);font-family:'JetBrains Mono',monospace;font-size:clamp(.58rem,1.9cqw,.78rem);line-height:1.1;text-align:center}
.fig-live-ui .jc-badge.is-zero{border-color:var(--c-err);background:var(--c-err-bg);color:var(--c-err);font-weight:700}
.fig-live-ui .jc-legend{display:flex;flex-wrap:wrap;justify-content:center;gap:.3rem 1rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .jc-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .jc-key::before{content:"";width:.8rem;height:.8rem;border-radius:50%;border:1.5px solid var(--fg-subtle);background:var(--bg-surf)}
.fig-live-ui .jc-key-marked::before{border-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .jc-key-leak::before{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .jc-key-count::before{width:auto;height:auto;content:"1";padding:0 .3rem;border-radius:var(--r-pill);border:1px solid var(--ac);font-family:'JetBrains Mono',monospace;font-size:.68rem;background:var(--bg-sb)}
.fig-live-ui .jc-key-freed::before{border-style:dashed;background:transparent}
.fig-live-ui .jc-ref{font-family:'JetBrains Mono',monospace;font-size:.74rem}
.fig-live-ui .jc-ref[aria-pressed="true"]{background:var(--c-err-bg);border-color:var(--c-err);color:var(--fg);text-decoration:line-through}
.fig-live-ui .jc-ref:disabled{opacity:.45;cursor:default;text-decoration:line-through}

/* bstinsert (Computer Science Deep Dive 6.02): two BSTs, HTML key buttons over SVG edges. */
.fig-live-ui .ka-in{font-family:'JetBrains Mono',monospace;font-size:.85rem;padding:.3rem .5rem;width:13rem;max-width:100%;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg)}
.fig-live-ui .ka-typed{gap:.5rem;min-width:0}
.fig-live-ui .ka-panels{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.75rem}
.fig-live-ui .ka-panel{display:flex;flex-direction:column;gap:.5rem;min-width:0;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);padding:.6rem .6rem .5rem}
.fig-live-ui .ka-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:.3rem .45rem;font-size:.8rem;font-weight:600;color:var(--fg)}
.fig-live-ui .ka-seq{display:inline-flex;flex-wrap:wrap;gap:.2rem}
.fig-live-ui .ka-key{font-family:'JetBrains Mono',monospace;font-size:.78rem;min-width:1.3rem;padding:0 .2rem;text-align:center;border-radius:4px;color:var(--fg-subtle);border:1px dashed transparent}
.fig-live-ui .ka-key.is-in{color:var(--fg)}
.fig-live-ui .ka-key.is-next{color:var(--ac);border-color:var(--ac)}
.fig-live-ui .ka-tree{position:relative;min-height:3rem}
.fig-live-ui .ka-edges{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.fig-live-ui .ka-edge{stroke:var(--fg-subtle);stroke-width:1.5;stroke-opacity:.6}
.fig-live-ui .ka-edge.is-path{stroke:var(--ac);stroke-width:2.5;stroke-opacity:1}
.fig-live-ui .ka-node{position:absolute;transform:translate(-50%,-50%);width:1.8rem;height:1.8rem;padding:0;border-radius:50%;font:inherit;font-family:'JetBrains Mono',monospace;font-size:.74rem;font-weight:600;color:var(--fg);border:1.5px solid var(--fg-subtle);background:var(--bg-sb);cursor:pointer;display:flex;align-items:center;justify-content:center}
.fig-live-ui .ka-node.is-ok{border-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .ka-node.is-warn{border-color:var(--c-warn);background:var(--c-warn-bg)}
.fig-live-ui .ka-node.is-err{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .ka-node.is-path{box-shadow:0 0 0 2px var(--ac)}
.fig-live-ui .ka-node.is-new,.fig-live-ui .ka-node.is-found{border-color:var(--ac);background:var(--ac-dim);box-shadow:0 0 0 3px var(--ac)}
.fig-live-ui .ka-empty{font-size:.78rem;color:var(--fg-subtle);text-align:center;padding:.8rem 0}
.fig-live-ui .ka-foot{text-align:center;font-size:.78rem;color:var(--fg-muted)}
.fig-live-ui .ka-foot.is-ok{color:var(--c-ok)}
.fig-live-ui .ka-foot.is-warn{color:var(--c-warn)}
.fig-live-ui .ka-foot.is-err{color:var(--c-err)}
@media(max-width:640px){.fig-live-ui .ka-panels{grid-template-columns:minmax(0,1fr)}.fig-live-ui .ka-node{width:1.45rem;height:1.45rem;font-size:.66rem}}

/* fibcalls (Computer Science Deep Dive 9.03): the naive fib call tree, SVG nodes with HTML labels, and per-argument counts. */
.fig-live-ui .kb-stats{display:flex;flex-wrap:wrap;justify-content:center;gap:.5rem 1.4rem}
.fig-live-ui .kb-stat{display:flex;flex-direction:column;align-items:center;min-width:6rem}
.fig-live-ui .kb-v{font-family:'JetBrains Mono',monospace;font-size:1.15rem;font-weight:700;color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .kb-stat.is-hot .kb-v{color:var(--c-err)}
.fig-live-ui .kb-stat.is-gone .kb-v{color:var(--fg-subtle)}
.fig-live-ui .kb-k{font-size:.72rem;color:var(--fg-muted);text-align:center}
.fig-live-ui .kb-tree{position:relative;width:100%}
.fig-live-ui .kb-svg{position:absolute;inset:0;width:100%;height:100%;display:block;overflow:visible}
.fig-live-ui .kb-edge{stroke:var(--fg-subtle);stroke-width:1;stroke-opacity:.6}
.fig-live-ui .kb-edge.is-never{stroke-dasharray:3 3;stroke-opacity:.3}
.fig-live-ui .kb-edge.is-later,.fig-live-ui .kb-node.is-later{opacity:.12}
.fig-live-ui .kb-node{fill:var(--bg-sb);stroke:var(--fg-subtle);stroke-width:1.5}
.fig-live-ui .kb-node.kb-c0{fill:var(--c-warn-bg);stroke:var(--c-warn)}
.fig-live-ui .kb-node.kb-c1{fill:var(--c-ok-bg);stroke:var(--c-ok)}
.fig-live-ui .kb-node.kb-c2{fill:var(--ac-dim);stroke:var(--ac)}
.fig-live-ui .kb-node.kb-c3{fill:var(--c-err-bg);stroke:var(--c-err)}
.fig-live-ui .kb-node.is-hit{stroke-dasharray:3 2;stroke-width:2}
.fig-live-ui .kb-node.is-never{fill:var(--bg-sb);stroke:var(--fg-subtle);opacity:.3}
.fig-live-ui .kb-node.is-now{stroke:var(--fg);stroke-width:3.5}
.fig-live-ui .kb-labels{position:absolute;inset:0;pointer-events:none}
.fig-live-ui .kb-lab{position:absolute;transform:translate(-50%,-50%);font-family:"JetBrains Mono",monospace;line-height:1;color:var(--fg)}
.fig-live-ui .kb-lab.is-never{color:var(--fg-subtle);opacity:.6}
.fig-live-ui .kb-reps{display:flex;flex-direction:column}
.fig-live-ui .kb-row{margin-bottom:.25rem}
.fig-live-ui .kb-row .wf-label{flex:0 0 4.2rem}
.fig-live-ui .kb-row .wf-track{height:14px;background:var(--bg-surf)}
.fig-live-ui .kb-bar{height:14px;background:var(--fg-subtle)}
.fig-live-ui .kb-bar.kb-c0{background:var(--c-warn)}
.fig-live-ui .kb-bar.kb-c1{background:var(--c-ok)}
.fig-live-ui .kb-bar.kb-c2{background:var(--ac)}
.fig-live-ui .kb-bar.kb-c3{background:var(--c-err)}
.fig-live-ui .kb-count{flex:0 0 14rem;font-size:.74rem;color:var(--fg-muted);font-family:'JetBrains Mono',monospace}
@media(max-width:640px){.fig-live-ui .kb-row{flex-wrap:wrap;gap:.1rem .5rem}.fig-live-ui .kb-row .wf-label{flex-basis:3.4rem;text-align:left}.fig-live-ui .kb-count{flex:1 1 100%;padding-left:3.9rem;font-size:.7rem}}

/* coinchange (Computer Science Deep Dive 9.02): greedy against the best, in the page's two .fig-col columns. */
.fig-live-ui .kc-cols{margin:0}
.fig-live-ui .kc-cols .fig-col{background:var(--bg-surf);gap:.55rem}
.fig-live-ui .kc-cols .fig-col.kc-lost{border-color:var(--c-err)}
.fig-live-ui .kc-cols .fig-col.kc-won{border-color:var(--c-ok)}
.fig-live-ui .kc-edit{gap:.5rem .9rem}
.fig-live-ui .kc-add{gap:.5rem}
.fig-live-ui .kc-in{font-family:'JetBrains Mono',monospace;font-size:.85rem;padding:.3rem .5rem;width:5.5rem;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg)}
.fig-live-ui .kc-chip{font-family:'JetBrains Mono',monospace}
.fig-live-ui .kc-chip:disabled,.fig-live-ui .wl-btn:disabled{opacity:.45;cursor:default}
.fig-live-ui .kc-coins{display:flex;flex-wrap:wrap;gap:.3rem;min-height:2rem;align-items:center}
.fig-live-ui .kc-coin{display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;padding:0 .3rem;border-radius:999px;border:1.5px solid var(--c-ok);background:var(--c-ok-bg);color:var(--fg);font-family:'JetBrains Mono',monospace;font-size:.78rem;font-weight:700}
.fig-live-ui .kc-coin.is-lost{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .kc-more{font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .kc-steps{font-family:'JetBrains Mono',monospace;font-size:.7rem;color:var(--fg-subtle);overflow-wrap:anywhere}
.fig-live-ui .kc-steps:empty{display:none}
.fig-live-ui .kc-sweep{display:flex;flex-direction:column;gap:.4rem}
.fig-live-ui .kc-err:empty{display:none}
.fig-live-ui .kc-err{color:var(--c-err)}
.fig-live-ui .kc-haverow{gap:.5rem}

/* deadlock: two threads, two locks, one cycle (Computer Science Deep Dive 11.04) */
.fig-live-ui .la-stage{position:relative;max-width:560px;width:100%;margin:0 auto;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf)}
.fig-live-ui .la-stage.is-bad{border-color:var(--c-err)}
.fig-live-ui .la-svg{display:block;width:100%;height:auto}
.fig-live-ui .la-thread{fill:var(--ac-dim);stroke:var(--ac);stroke-width:1.5;vector-effect:non-scaling-stroke}
.fig-live-ui .la-thread.is-wait{fill:var(--c-warn-bg);stroke:var(--c-warn)}
.fig-live-ui .la-thread.is-stuck{fill:var(--c-err-bg);stroke:var(--c-err);stroke-width:2.5}
.fig-live-ui .la-thread.is-done{fill:var(--c-ok-bg);stroke:var(--c-ok)}
.fig-live-ui .la-lock{fill:var(--bg-sb);stroke:var(--fg-subtle);stroke-width:1.5;vector-effect:non-scaling-stroke}
.fig-live-ui .la-lock.is-held{fill:var(--c-warn-bg);stroke:var(--c-warn)}
.fig-live-ui .la-line{stroke-width:2;vector-effect:non-scaling-stroke}
.fig-live-ui .la-hold .la-line{stroke:var(--c-ok)}
.fig-live-ui .la-hold .la-head{fill:var(--c-ok)}
.fig-live-ui .la-wait .la-line{stroke:var(--c-err);stroke-dasharray:6 4}
.fig-live-ui .la-wait .la-head{fill:var(--c-err)}
.fig-live-ui .la-wait.is-cycle .la-line{stroke-width:3}
.fig-live-ui .la-lab{position:absolute;transform:translate(-50%,-50%);text-align:center;white-space:nowrap;pointer-events:none;line-height:1.2}
.fig-live-ui .la-nm{font-size:.8rem;font-weight:700;color:var(--fg)}
.fig-live-ui .la-small{display:block;font-size:.68rem;font-weight:500;color:var(--fg-muted)}
.fig-live-ui .la-big{display:block;font-size:1rem}
.fig-live-ui .la-sub{font-size:.7rem;color:var(--fg-muted)}
.fig-live-ui .la-mid{font-size:.72rem;font-weight:600;color:var(--c-err);white-space:normal;width:8rem}
.fig-live-ui .la-legend{display:flex;flex-wrap:wrap;justify-content:center;gap:.3rem 1.2rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .la-key::before{content:"";display:inline-block;width:1.6rem;height:0;margin-right:.4rem;vertical-align:middle;border-top:2px solid var(--c-ok)}
.fig-live-ui .la-key-wait::before{border-top:2px dashed var(--c-err)}
.fig-live-ui .la-steps{margin:0;padding-left:1.4rem;display:flex;flex-direction:column;gap:.2rem;font-size:.8rem;color:var(--fg-muted)}
.fig-live-ui .la-steps li{padding-left:.15rem}
.fig-live-ui .la-ev.is-wait{color:var(--fg)}
.fig-live-ui .la-ev.is-done{color:var(--c-ok)}
.fig-live-ui .la-ev.is-cycle{color:var(--c-err);font-weight:600}
.fig-live-ui .la-empty{list-style:none;margin-left:-1.4rem;font-style:italic;color:var(--fg-subtle)}
.fig-live-ui .la-btns .wl-btn:disabled{opacity:.45;cursor:default;border-color:var(--bd);color:var(--fg-subtle)}
@media(max-width:640px){.fig-live-ui .la-nm{font-size:.72rem}.fig-live-ui .la-small{font-size:.6rem}.fig-live-ui .la-big{font-size:.85rem}.fig-live-ui .la-small{display:block;font-size:.68rem;font-weight:500;color:var(--fg-muted)}
.fig-live-ui .la-big{display:block;font-size:1rem}
.fig-live-ui .la-sub{font-size:.64rem}.fig-live-ui .la-mid{font-size:.64rem;width:5.5rem}}

/* critpath: a 12-job pipeline on N runners, the chain sets the time (Computer Science Deep Dive 8.03) */
.fig-live-ui .lb-crit{font-size:.8rem;font-weight:600;color:var(--c-err)}
.fig-live-ui .lb-gantt{display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .lb-row{display:grid;grid-template-columns:4.2rem minmax(0,1fr);gap:.5rem;align-items:center}
.fig-live-ui .lb-rl{font-size:.7rem;color:var(--fg-subtle);text-align:right;white-space:nowrap}
.fig-live-ui .lb-track{position:relative;height:1.55rem;border-radius:3px;background:var(--bg-surf);border:1px solid var(--bd)}
.fig-live-ui .lb-track.is-idle{border-style:dashed;background:transparent}
.fig-live-ui .lb-bar{position:absolute;top:2px;bottom:2px;display:flex;align-items:center;justify-content:center;overflow:hidden;white-space:nowrap;box-sizing:border-box;padding:0 .15rem;border-radius:3px;border:1px solid var(--ac);background:var(--ac-dim);color:var(--fg);font-size:.68rem}
.fig-live-ui .lb-bar.is-crit{border-color:var(--c-err);background:var(--c-err-bg);font-weight:600}
.fig-live-ui .lb-bar.is-short{border-style:dashed;border-width:2px}
.fig-live-ui .lb-bar.is-future{opacity:.3}
.fig-live-ui .lb-bar.is-now{background:linear-gradient(90deg,var(--ac-dim) var(--lb-done,0%),transparent var(--lb-done,0%))}
.fig-live-ui .lb-bar.is-crit.is-now{background:linear-gradient(90deg,var(--c-err-bg) var(--lb-done,0%),transparent var(--lb-done,0%))}
.fig-live-ui .lb-now{position:absolute;top:-3px;bottom:-3px;width:0;border-left:2px solid var(--fg);pointer-events:none}
.fig-live-ui .lb-abbr,.fig-live-ui .lb-tiny{display:none}
.fig-live-ui .lb-bar.is-tiny .lb-full{display:none}
.fig-live-ui .lb-bar.is-tiny .lb-abbr{display:inline}
.fig-live-ui .lb-axis{margin-top:.1rem}
.fig-live-ui .lb-ticks{position:relative;height:1rem}
.fig-live-ui .lb-tick{position:absolute;top:0;transform:translateX(-50%);font-size:.68rem;color:var(--fg-subtle);font-family:'JetBrains Mono',monospace}
.fig-live-ui .lb-more{text-align:center}
.fig-live-ui .lb-legend{display:flex;flex-wrap:wrap;justify-content:center;gap:.3rem 1.1rem;font-size:.72rem;color:var(--fg-muted)}
.fig-live-ui .lb-key::before{content:"";display:inline-block;width:1.1rem;height:.7rem;margin-right:.35rem;vertical-align:-1px;border-radius:2px;border:1px solid var(--ac);background:var(--ac-dim)}
.fig-live-ui .lb-key-crit::before{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .lb-key-idle::before{border:1px dashed var(--bd);background:transparent}
@media(max-width:640px){.fig-live-ui .lb-row{grid-template-columns:3.4rem minmax(0,1fr);gap:.35rem}.fig-live-ui .lb-rl{font-size:.64rem}.fig-live-ui .lb-full{display:none}.fig-live-ui .lb-abbr{display:inline}.fig-live-ui .lb-bar.is-tiny .lb-abbr{display:none}.fig-live-ui .lb-bar.is-tiny .lb-tiny{display:inline}.fig-live-ui .lb-bar{font-size:.6rem;padding:0}}

/* tmstep: a Turing machine adding 1 to a binary number (Computer Science Deep Dive 14.03) */
.fig-live-ui .lc-in{font-family:'JetBrains Mono',monospace;font-size:.9rem;letter-spacing:.08em;padding:.3rem .5rem;width:9rem;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg)}
.fig-live-ui .lc-in[aria-invalid="true"]{border-color:var(--c-err)}
.fig-live-ui .lc-tapes{display:flex;flex-direction:column;gap:.55rem;overflow-x:auto;padding-bottom:.2rem}
.fig-live-ui .lc-step{display:flex;flex-direction:column;gap:.2rem;opacity:.72}
.fig-live-ui .lc-step.is-now{opacity:1}
.fig-live-ui .lc-lbl{font-size:.72rem;color:var(--fg-subtle)}
.fig-live-ui .lc-line{display:flex;align-items:center;flex-wrap:wrap;gap:.35rem .8rem}
.fig-live-ui .lc-cells{display:grid;grid-template-columns:repeat(var(--lc-n),1.75rem);padding-bottom:.55rem}
.fig-live-ui .lc-cell{position:relative;display:flex;align-items:center;justify-content:center;height:1.75rem;margin-left:-1px;border:1px solid var(--bd);background:var(--bg-surf);font-family:'JetBrains Mono',monospace;font-size:.88rem;color:var(--fg)}
.fig-live-ui .lc-cell:first-child{margin-left:0}
.fig-live-ui .lc-cell.is-blank{color:var(--fg-subtle)}
.fig-live-ui .lc-cell.is-head{z-index:1;border-color:var(--c-warn);background:var(--c-warn-bg);font-weight:700}
.fig-live-ui .lc-cell.is-head::after{content:"";position:absolute;left:50%;bottom:-.6rem;transform:translateX(-50%);border:.28rem solid transparent;border-bottom:.4rem solid var(--c-warn);border-top:0}
.fig-live-ui .lc-cell.is-wrote{box-shadow:inset 0 -3px 0 var(--ac)}
.fig-live-ui .lc-state{font-size:.8rem;color:var(--fg);font-family:'JetBrains Mono',monospace}
.fig-live-ui .lc-state.is-halt{color:var(--c-ok);font-weight:700}
.fig-live-ui .lc-fold{margin:0}
.fig-live-ui .lc-tblbox{overflow-x:auto;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf)}
.fig-live-ui .lc-cap{font-size:.72rem;font-weight:600;color:var(--fg-muted);padding:.4rem .6rem 0}
.fig-live-ui .lc-table{width:100%;border-collapse:collapse;font-size:.78rem;color:var(--fg)}
.fig-live-ui .lc-table th{text-align:left;font-size:.68rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fg-subtle);padding:.35rem .6rem;border-bottom:1px solid var(--bd)}
.fig-live-ui .lc-table td{padding:.3rem .6rem;white-space:nowrap;font-family:'JetBrains Mono',monospace}
.fig-live-ui .lc-table tr.is-fired td{background:var(--c-warn-bg);font-weight:700}
.fig-live-ui .lc-btns .wl-btn:disabled{opacity:.45;cursor:default;border-color:var(--bd);color:var(--fg-subtle)}
@media(max-width:640px){.fig-live-ui .lc-cells{grid-template-columns:repeat(var(--lc-n),1.2rem)}.fig-live-ui .lc-cell{height:1.45rem;font-size:.78rem}.fig-live-ui .lc-table{font-size:.68rem}.fig-live-ui .lc-table th{font-size:.6rem;letter-spacing:0}.fig-live-ui .lc-table th,.fig-live-ui .lc-table td{padding:.28rem .25rem}}

/* aimd: two senders sharing a link (CS Deep Dive ch. 12). A phase plot of (A, B) and a window-over-time chart. */
.fig-live-ui .ma-phase{display:flex;flex-direction:column;align-items:center;gap:.35rem}
.fig-live-ui .ma-phase svg{display:block;width:100%;max-width:20rem;height:auto;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf)}
.fig-live-ui .ma-phase line,.fig-live-ui .ma-phase polyline,.fig-live-ui .ma-chart line,.fig-live-ui .ma-chart polyline{fill:none;vector-effect:non-scaling-stroke;stroke-linejoin:round}
.fig-live-ui .ma-axis{stroke:var(--fg-subtle);stroke-width:1}
.fig-live-ui .ma-full{stroke:var(--c-err);stroke-width:1.5;stroke-dasharray:5 4}
.fig-live-ui .ma-fair{stroke:var(--c-ok);stroke-width:1.5;stroke-dasharray:5 4}
.fig-live-ui .ma-path{stroke:var(--ac);stroke-width:1.6}
.fig-live-ui .ma-start{fill:var(--c-warn);stroke:var(--c-warn)}
.fig-live-ui .ma-now{fill:var(--bg-surf);stroke:var(--ac);stroke-width:2;vector-effect:non-scaling-stroke}
.fig-live-ui .ma-chart{display:flex;flex-direction:column;gap:.35rem}
.fig-live-ui .ma-chart svg{display:block;width:100%;height:10rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf)}
.fig-live-ui .ma-a{stroke:var(--ac);stroke-width:2.5}
.fig-live-ui .ma-b{stroke:var(--c-warn);stroke-width:2}
.fig-live-ui .ma-cap{stroke:var(--c-err);stroke-width:1.5;stroke-dasharray:6 4}
.fig-live-ui .ma-fairline{stroke:var(--c-ok);stroke-width:1.5;stroke-dasharray:6 4}
.fig-live-ui .ma-loss{stroke:var(--c-err);stroke-width:3}
.fig-live-ui .ma-axis-cap{font-size:.72rem;color:var(--fg-subtle);font-family:'JetBrains Mono',monospace;text-align:center}
.fig-live-ui .ma-legend{display:flex;flex-wrap:wrap;justify-content:center;gap:.3rem 1rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .ma-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .ma-key::before{content:"";width:1.4rem;border-top:2.5px solid var(--ac)}
.fig-live-ui .ma-key-path::before{border-top-width:1.6px}
.fig-live-ui .ma-key-b::before{border-top:2px solid var(--c-warn)}
.fig-live-ui .ma-key-full::before,.fig-live-ui .ma-key-cap::before{border-top:1.5px dashed var(--c-err)}
.fig-live-ui .ma-key-fair::before,.fig-live-ui .ma-key-fairline::before{border-top:1.5px dashed var(--c-ok)}
.fig-live-ui .ma-key-dot::before{width:.55rem;height:.55rem;border:0;border-radius:50%;background:var(--c-warn)}
.fig-live-ui .ma-key-loss::before{width:0;height:.9rem;border-top:0;border-left:3px solid var(--c-err)}
.fig-live-ui .ma-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.45rem}
.fig-live-ui .ma-stat{display:flex;flex-direction:column;gap:.15rem;padding:.45rem .6rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);min-width:0}
.fig-live-ui .ma-k{font-size:.68rem;color:var(--fg-subtle);text-transform:uppercase;letter-spacing:.04em}
.fig-live-ui .ma-v{font-family:'JetBrains Mono',monospace;font-size:.8rem;color:var(--fg);overflow-wrap:anywhere}
@media(max-width:640px){.fig-live-ui .ma-stats{grid-template-columns:repeat(2,minmax(0,1fr))}}

/* pktwindow: stop-and-wait vs a window of packets in flight (CS Deep Dive ch. 12). */
.fig-live-ui .mb-draw{display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .mb-heads{display:grid;grid-template-columns:1fr 1fr;gap:.6rem;text-align:center}
.fig-live-ui .mb-head{font-size:.8rem;font-weight:600;color:var(--fg)}
.fig-live-ui .mb-foot{font-size:.75rem;color:var(--fg-muted)}
.fig-live-ui .mb-svg{display:block;width:100%;height:auto;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf)}
.fig-live-ui .mb-svg line{vector-effect:non-scaling-stroke}
.fig-live-ui .mb-lane{stroke:var(--fg-subtle);stroke-width:2}
.fig-live-ui .mb-rtt{stroke:var(--c-warn);stroke-width:2}
.fig-live-ui .mb-pkt{stroke:var(--ac);stroke-width:1.5}
.fig-live-ui .mb-ack{stroke:var(--c-ok);stroke-width:1.2;stroke-dasharray:4 3}
.fig-live-ui .mb-dot{fill:var(--ac);stroke:var(--bg-surf);stroke-width:1}
.fig-live-ui .mb-dot.is-ack{fill:var(--c-ok)}
.fig-live-ui .mb-axis{font-size:.72rem;color:var(--fg-subtle);text-align:center}
.fig-live-ui .mb-busy{display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .mb-busy-lab{font-size:.78rem;color:var(--fg-muted)}
.fig-live-ui .mb-track{height:.7rem;border:1px solid var(--bd);border-radius:var(--r-pill);background:var(--bg-surf);overflow:hidden}
.fig-live-ui .mb-bar{height:100%;min-width:2px;background:var(--ac)}
.fig-live-ui .mb-bar.is-full{background:var(--c-ok)}
.fig-live-ui .mb-table{display:flex;flex-direction:column;gap:.3rem;font-size:.8rem;overflow-x:auto}
.fig-live-ui .mb-tr{display:grid;grid-template-columns:minmax(7rem,1.2fr) minmax(0,1fr) minmax(0,1fr);gap:.6rem;padding:.2rem 0;border-bottom:1px solid var(--bd)}
.fig-live-ui .mb-tr>span{min-width:0;overflow-wrap:anywhere}
.fig-live-ui .mb-tr>span:first-child{color:var(--fg-muted)}
.fig-live-ui .mb-tr>span+span{font-family:'JetBrains Mono',monospace;color:var(--fg)}
.fig-live-ui .mb-th>span,.fig-live-ui .mb-th>span+span{font-family:inherit;color:var(--fg-subtle);font-size:.7rem;text-transform:uppercase;letter-spacing:.04em}
@media(max-width:640px){.fig-live-ui .mb-tr{grid-template-columns:minmax(5.5rem,1fr) minmax(0,1fr) minmax(0,1fr);gap:.4rem;font-size:.74rem}.fig-live-ui .mb-head{font-size:.72rem}.fig-live-ui .mb-foot{font-size:.68rem}}

/* regexblowup: (a+)+$ on a run of a's, backtracking vs the state machine (CS Deep Dive ch. 14). */
.fig-live-ui .mc-text{display:flex;flex-wrap:wrap;align-items:center;gap:.4rem .8rem;justify-content:center}
.fig-live-ui .mc-pat{font-family:'JetBrains Mono',monospace;font-size:.85rem;font-weight:700;color:var(--ac)}
.fig-live-ui .mc-chars{display:flex;flex-wrap:wrap;gap:2px;justify-content:center}
.fig-live-ui .mc-ch{font-family:'JetBrains Mono',monospace;font-size:.8rem;min-width:1.1rem;text-align:center;padding:.1rem .15rem;border:1px solid var(--bd);border-radius:4px;background:var(--bg-surf);color:var(--fg)}
.fig-live-ui .mc-ch.is-bang{border-color:var(--c-err);color:var(--c-err);font-weight:700}
.fig-live-ui .mc-ch.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .mc-view{display:flex;flex-direction:column;gap:.6rem;min-width:0}
.fig-live-ui .mc-tree{display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .mc-tree-top{display:grid;grid-template-columns:3.2rem minmax(0,1fr)}
.fig-live-ui .mc-gaps{display:flex;flex-direction:column}
.fig-live-ui .mc-gaps>span{height:2rem;display:flex;align-items:center;font-size:.7rem;color:var(--fg-subtle)}
.fig-live-ui .mc-tree svg{display:block;width:100%}
.fig-live-ui .mc-edge{stroke:var(--fg-subtle);stroke-width:1.5;vector-effect:non-scaling-stroke}
.fig-live-ui .mc-edge.is-cut{stroke:var(--ac);stroke-dasharray:4 3}
.fig-live-ui .mc-edge.is-on{stroke:var(--c-warn);stroke-width:3}
.fig-live-ui .mc-leaves{display:grid;gap:3px}
.fig-live-ui .mc-leaf{display:flex;flex-direction:column;align-items:center;gap:1px;padding:.25rem .1rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);min-width:0}
.fig-live-ui .mc-grp{font-family:'JetBrains Mono',monospace;font-size:.72rem;color:var(--fg);line-height:1.25}
.fig-live-ui .mc-fail{font-size:.64rem;color:var(--c-err);white-space:nowrap;margin-top:.15rem}
.fig-live-ui .mc-leaf.is-now,.fig-live-ui .mc-try.is-now{border-color:var(--c-warn);background:var(--c-warn-bg)}
.fig-live-ui .mc-leaf.is-later,.fig-live-ui .mc-try.is-later,.fig-live-ui .mc-cell.is-later{opacity:.45}
.fig-live-ui .mc-axis{font-size:.7rem;color:var(--fg-subtle);text-align:center}
.fig-live-ui .mc-list{display:flex;flex-wrap:wrap;gap:.3rem;justify-content:center}
.fig-live-ui .mc-try{font-family:'JetBrains Mono',monospace;font-size:.74rem;padding:.15rem .45rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);color:var(--fg);overflow-wrap:anywhere;max-width:100%}
.fig-live-ui .mc-more{font-size:.74rem;color:var(--fg-subtle);align-self:center}
.fig-live-ui .mc-flow .flow-step.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .mc-flow .mc-accept{border-width:3px;border-style:double}
.fig-live-ui .mc-flow .flow-arrow{font-size:.85rem}
.fig-live-ui .mc-tape{display:flex;flex-wrap:wrap;gap:.3rem;justify-content:center}
.fig-live-ui .mc-cell{display:flex;flex-direction:column;align-items:center;gap:.1rem;padding:.25rem .45rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf)}
.fig-live-ui .mc-cell .mc-k{font-size:.64rem;color:var(--fg-subtle)}
.fig-live-ui .mc-set{font-family:'JetBrains Mono',monospace;font-size:.72rem;color:var(--fg);white-space:nowrap}
.fig-live-ui .mc-cell.is-empty{border-color:var(--c-err)}
.fig-live-ui .mc-cell.is-empty .mc-set{color:var(--c-err)}
.fig-live-ui .mc-cell.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .mc-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.45rem}
.fig-live-ui .mc-stat{display:flex;flex-direction:column;gap:.15rem;padding:.45rem .6rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);min-width:0}
.fig-live-ui .mc-stat .mc-k{font-size:.68rem;color:var(--fg-subtle);text-transform:uppercase;letter-spacing:.04em}
.fig-live-ui .mc-v{font-family:'JetBrains Mono',monospace;font-size:.8rem;color:var(--fg);overflow-wrap:anywhere}
@media(max-width:640px){.fig-live-ui .mc-stats{grid-template-columns:repeat(2,minmax(0,1fr))}.fig-live-ui .mc-tree-top{grid-template-columns:2.6rem minmax(0,1fr)}.fig-live-ui .mc-grp{font-size:.66rem}.fig-live-ui .mc-fail{font-size:.58rem}.fig-live-ui .mc-flow{flex-wrap:nowrap}.fig-live-ui .mc-flow .flow-step{flex:1 1 0;min-width:0;padding:.45rem .3rem}.fig-live-ui .mc-flow .flow-arrow{transform:none;width:auto;font-size:.72rem}}

/* Backend Deep Dive widgets (#824). */
/* oversell: seat 3117, two requests, a guard (Backend Deep Dive 6.03) */
.fig-live-ui .na-cols{margin:0}
.fig-live-ui .na-cols .fig-col{background:var(--bg-surf);gap:.55rem}
.fig-live-ui .na-cols .fig-col.na-wait{border-color:var(--c-warn)}
.fig-live-ui .na-steps{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.4rem}
.fig-live-ui .na-step{display:grid;grid-template-columns:1.4rem minmax(0,1fr);gap:.3rem;align-items:baseline;font-size:.78rem;color:var(--fg-muted)}
.fig-live-ui .na-n{font-weight:700;color:var(--fg-subtle);text-align:right}
.fig-live-ui .na-b{display:flex;flex-direction:column;gap:.1rem;min-width:0}
.fig-live-ui .na-sql{font-family:'JetBrains Mono',monospace;font-size:.74rem;color:var(--fg);overflow-wrap:anywhere;background:none;padding:0}
.fig-live-ui .na-out{font-size:.74rem;overflow-wrap:anywhere}
.fig-live-ui .na-step.is-done .na-n{color:var(--ac)}
.fig-live-ui .na-step.is-bad .na-n,.fig-live-ui .na-step.is-bad .na-out{color:var(--c-err)}
.fig-live-ui .na-step.is-wait .na-n,.fig-live-ui .na-step.is-wait .na-out{color:var(--c-warn);font-weight:600}
.fig-live-ui .na-step.is-skip .na-sql,.fig-live-ui .na-step.is-todo .na-sql{color:var(--fg-subtle)}
.fig-live-ui .na-step.is-skip .na-sql{text-decoration:line-through}
.fig-live-ui .na-end{font-size:.78rem;font-weight:600;color:var(--fg-muted);border-top:1px solid var(--bd);padding-top:.45rem}
.fig-live-ui .na-end.is-ok{color:var(--c-ok)}
.fig-live-ui .na-end.is-bad{color:var(--c-err)}
.fig-live-ui .na-end.is-refused{color:var(--fg)}
.fig-live-ui .na-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.45rem}
.fig-live-ui .na-stat{display:flex;flex-direction:column;gap:.15rem;padding:.45rem .6rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);min-width:0}
.fig-live-ui .na-stat.is-bad{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .na-stat.is-ok{border-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .na-k{font-size:.68rem;color:var(--fg-subtle);text-transform:uppercase;letter-spacing:.04em}
.fig-live-ui .na-v{font-family:'JetBrains Mono',monospace;font-size:.82rem;color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .na-btns .wl-btn:disabled{opacity:.45;cursor:default;border-color:var(--bd);color:var(--fg-subtle)}
.fig-live-ui .na-log{margin:0;padding-left:1.4rem;display:flex;flex-direction:column;gap:.2rem;font-size:.8rem;color:var(--fg-muted)}
.fig-live-ui .na-log li{padding-left:.15rem}
.fig-live-ui .na-ev.is-wait{color:var(--c-warn)}
.fig-live-ui .na-ev.is-done{color:var(--c-ok)}
.fig-live-ui .na-ev.is-refused{color:var(--fg)}
.fig-live-ui .na-empty{list-style:none;margin-left:-1.4rem;font-style:italic;color:var(--fg-subtle)}
@media(max-width:640px){.fig-live-ui .na-stats{grid-template-columns:repeat(2,minmax(0,1fr))}}

/* rings: Stagedoor's middleware rings, reorderable, one request traced (Backend Deep Dive 4.05) */
.fig-live-ui .nb-stack{display:flex;flex-direction:column;gap:.5rem;width:100%;max-width:720px;margin:0 auto}
.fig-live-ui .nb-layer{background:var(--bg-surf);padding:.7rem .85rem}
.fig-live-ui .nb-layer.is-stop{border-color:var(--ac)}
.fig-live-ui .nb-layer.is-skip{border-style:dashed}
.fig-live-ui .nb-layer.is-skip .nb-name,.fig-live-ui .nb-layer.is-skip .stack-layer-sub{color:var(--fg-subtle)}
.fig-live-ui .nb-hd{justify-content:space-between;flex-wrap:wrap;color:var(--fg)}
.fig-live-ui .nb-moves{display:flex;gap:.3rem}
.fig-live-ui .nb-mv{padding:.15rem .6rem;font-size:.85rem;line-height:1.2}
.fig-live-ui .nb-mv:disabled{opacity:.35;cursor:default;border-color:var(--bd);color:var(--fg-subtle)}
.fig-live-ui .nb-layer .stack-layer-sub{color:var(--fg-muted)}
.fig-live-ui .nb-tags{display:flex;flex-wrap:wrap;gap:.3rem .45rem;margin-top:.45rem}
.fig-live-ui .nb-tag{font-size:.72rem;line-height:1.35;padding:.12rem .55rem;border-radius:var(--r-pill);border:1px solid var(--bd);color:var(--fg-muted);background:var(--bg-sb)}
.fig-live-ui .nb-tag.is-stop{border-color:var(--ac);background:var(--ac-dim);color:var(--fg);font-weight:600}
.fig-live-ui .nb-tag.is-ok{border-color:var(--c-ok);background:var(--c-ok-bg);color:var(--fg)}
.fig-live-ui .nb-tag.is-bad{border-color:var(--c-err);background:var(--c-err-bg);color:var(--fg);font-weight:600}
.fig-live-ui .nb-tag.is-skip{border-style:dashed;color:var(--fg-subtle);background:transparent}
.fig-live-ui .nb-result{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,8rem),1fr));gap:.45rem}
.fig-live-ui .nb-cell.nb-wide{grid-column:1/-1}
.fig-live-ui .nb-cell{display:flex;flex-direction:column;gap:.15rem;padding:.45rem .6rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);min-width:0}
.fig-live-ui .nb-cell.is-bad{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .nb-cell.is-ok{border-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .nb-k{font-size:.68rem;color:var(--fg-subtle);text-transform:uppercase;letter-spacing:.04em}
.fig-live-ui .nb-v{font-family:'JetBrains Mono',monospace;font-size:.8rem;color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .nb-probs{margin:0;padding-left:1.2rem;display:flex;flex-direction:column;gap:.3rem;font-size:.8rem}
.fig-live-ui .nb-prob{color:var(--c-err)}
.fig-live-ui .nb-fine{list-style:none;margin-left:-1.2rem;color:var(--c-ok)}

/* pager: offset against cursor paging, rows read and rows repeated or skipped (Backend Deep Dive 3.04) */
.fig-live-ui .nc-cols{margin:0}
.fig-live-ui .nc-cols .fig-col{background:var(--bg-surf);gap:.55rem}
.fig-live-ui .nc-cols .fig-col.is-on{border-color:var(--ac);box-shadow:inset 0 0 0 1px var(--ac)}
.fig-live-ui .nc-read{display:flex;flex-direction:column;gap:.25rem;margin-top:auto}
.fig-live-ui .nc-track{height:8px;border-radius:4px;border:1px solid var(--bd);background:var(--bg-sb);overflow:hidden}
.fig-live-ui .nc-bar{display:block;height:100%;background:var(--ac)}
.fig-live-ui .nc-rv{font-family:'JetBrains Mono',monospace;font-size:.74rem;color:var(--fg)}
.fig-live-ui .nc-req{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,9rem) minmax(0,1fr);gap:.6rem;align-items:start}
.fig-live-ui .nc-write{align-self:center}
.fig-live-ui .nc-block{display:flex;flex-direction:column;gap:.3rem;padding:.6rem .7rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);min-width:0}
.fig-live-ui .nc-bt{font-size:.8rem;font-weight:700;color:var(--fg)}
.fig-live-ui .nc-bs{font-size:.72rem;color:var(--fg-muted);font-family:'JetBrains Mono',monospace;overflow-wrap:anywhere}
.fig-live-ui .nc-rows{display:flex;flex-direction:column;gap:.2rem}
.fig-live-ui .nc-row{display:flex;justify-content:space-between;gap:.6rem;padding:.12rem .45rem;border-radius:4px;border:1px solid transparent;font-family:'JetBrains Mono',monospace;font-size:.76rem;color:var(--fg)}
.fig-live-ui .nc-ts{color:var(--fg-muted)}
.fig-live-ui .nc-row.is-dup{border-color:var(--c-err);background:var(--c-err-bg);font-weight:700}
.fig-live-ui .nc-row.is-skip{border-color:var(--c-warn);background:var(--c-warn-bg);font-weight:700}
.fig-live-ui .nc-more{font-size:.7rem;color:var(--fg-subtle);padding-left:.45rem}
.fig-live-ui .nc-write{font-size:.74rem;color:var(--fg-subtle);text-align:center}
.fig-live-ui .nc-write.is-on{color:var(--c-warn);font-weight:600}
.fig-live-ui .nc-skip{grid-column:1/-1;display:flex;flex-wrap:wrap;align-items:center;gap:.4rem .6rem}
.fig-live-ui .nc-skip .nc-row{min-width:11rem}
.fig-live-ui .nc-tally{display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .nc-tally:empty{display:none}
.fig-live-ui .nc-tnote{font-size:.74rem;color:var(--fg-subtle)}
.fig-live-ui .nc-trow{display:grid;grid-template-columns:5rem minmax(0,1fr) minmax(0,1fr);gap:.5rem;font-size:.8rem;align-items:baseline}
.fig-live-ui .nc-tname{font-weight:700;color:var(--fg)}
.fig-live-ui .nc-tv{font-family:'JetBrains Mono',monospace;color:var(--fg)}
.fig-live-ui .nc-tv.is-bad{color:var(--c-err);font-weight:700}
@media(max-width:640px){.fig-live-ui .nc-req{grid-template-columns:minmax(0,1fr)}.fig-live-ui .nc-trow{grid-template-columns:4rem minmax(0,1fr) minmax(0,1fr)}}

/* Backend Deep Dive widget breaker: the Payrail circuit breaker. The two flow rows
   are the static figure's own .fig-flow; .is-now marks the state the breaker is in
   (.is-bad tripped/open, .is-ok a trial that closed it). .oa-win is the window of
   the last N calls, newest on the right; it greys out while the breaker is open. */
.fig-live-ui .oa-flowbox{display:flex;flex-direction:column;gap:.6rem}
.fig-live-ui .oa-flowbox .fig-flow+.fig-flow{margin-top:0}
.fig-live-ui .oa-flow .flow-step.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .oa-flow .flow-step.is-now.is-bad{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .oa-flow .flow-step.is-now.is-ok{border-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .oa-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.45rem}
.fig-live-ui .oa-stat{display:flex;flex-direction:column;gap:.15rem;padding:.45rem .6rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);min-width:0}
.fig-live-ui .oa-k{font-size:.68rem;color:var(--fg-subtle);text-transform:uppercase;letter-spacing:.04em}
.fig-live-ui .oa-v{font-family:'JetBrains Mono',monospace;font-size:.8rem;color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .oa-v.is-bad{color:var(--c-err);font-weight:700}
.fig-live-ui .oa-winbox{display:flex;flex-direction:column;gap:.35rem}
.fig-live-ui .oa-winhead{font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .oa-win{display:grid;grid-template-columns:repeat(var(--oa-cols,20),minmax(0,1fr));gap:3px}
.fig-live-ui .oa-win.is-frozen{opacity:.5}
.fig-live-ui .oa-cell{display:flex;align-items:center;justify-content:center;min-height:1.6rem;border-radius:3px;border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg-muted);font-family:'JetBrains Mono',monospace;font-size:.64rem;font-variant-ligatures:none}
.fig-live-ui .oa-cell.is-ok{border-color:var(--c-ok);background:var(--c-ok-bg);color:var(--fg)}
.fig-live-ui .oa-cell.is-fail{border-color:var(--c-err);background:var(--c-err-bg);color:var(--c-err);font-weight:700}
.fig-live-ui .oa-cell.is-empty{border-style:dashed;background:transparent}
.fig-live-ui .oa-log{margin:0;padding:0 0 0 1.1rem;font-family:'JetBrains Mono',monospace;font-size:.72rem;color:var(--fg-muted);display:flex;flex-direction:column;gap:.15rem}
.fig-live-ui .oa-log li:first-child{color:var(--fg)}
@media(max-width:640px){.fig-live-ui .oa-stats{grid-template-columns:repeat(2,minmax(0,1fr))}.fig-live-ui .oa-flow{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.4rem}.fig-live-ui .oa-flow .flow-arrow{display:none}.fig-live-ui .oa-flow .flow-step{max-width:none;padding:.55rem .4rem}.fig-live-ui .oa-win{grid-template-columns:repeat(10,minmax(0,1fr))}.fig-live-ui .oa-cell{font-size:.58rem}}

/* Backend Deep Dive widget jitter: the retry storm with and without jitter. Two
   panels like the static figure's two columns (one when a single mode is picked),
   each a histogram of retry arrivals per 5 ms bin; .ob-old is earlier rounds. */
.fig-live-ui .ob-cols{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.75rem}
.fig-live-ui .ob-cols.is-one{grid-template-columns:minmax(0,1fr)}
.fig-live-ui .ob-col{display:flex;flex-direction:column;gap:.45rem;min-width:0;padding:.8rem .85rem;border:1px solid var(--bd);border-radius:10px;background:var(--bg-surf)}
.fig-live-ui .ob-hd .nm{font-weight:600;color:var(--fg);font-size:.95rem;line-height:1.15}
.fig-live-ui .ob-hd .nm small{display:block;font-weight:500;color:var(--fg-muted);font-size:.72rem;margin-top:.1rem}
.fig-live-ui .ob-svg{display:block;width:100%;height:8.5rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-sb)}
.fig-live-ui .ob-bar{fill:var(--c-err);stroke:none}
.fig-live-ui .ob-bar.is-full{fill:var(--ac)}
.fig-live-ui .ob-bar.ob-old{fill-opacity:.35}
.fig-live-ui .ob-axis{font-size:.68rem;color:var(--fg-subtle);font-family:'JetBrains Mono',monospace;overflow-wrap:anywhere}
.fig-live-ui .ob-peak{font-size:.78rem;color:var(--fg);font-weight:600}
.fig-live-ui .ob-cap{font-size:.78rem;color:var(--fg-muted);line-height:1.45}
.fig-live-ui .ob-legend{display:flex;flex-wrap:wrap;gap:.3rem 1rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .ob-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .ob-key::before{content:"";width:1rem;height:.8rem;border-radius:2px;background:linear-gradient(90deg,var(--c-err) 50%,var(--ac) 50%)}
.fig-live-ui .ob-key-old::before{opacity:.35}
@media(max-width:640px){.fig-live-ui .ob-cols{grid-template-columns:minmax(0,1fr)}}

/* Backend Deep Dive widget stampede: one seat-map expiry. The four columns are the
   static figure's own .fig-cols (.is-now marks where Play is, .is-bad a runaway);
   .oc-rows is one bar per wave of misses on a 0 to 1,000 ms axis. */
.fig-live-ui .oc-cols{margin:0}
.fig-live-ui .oc-cols .fig-col{background:var(--bg-surf)}
.fig-live-ui .oc-cols .fig-col.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .oc-cols .fig-col.is-now.is-bad{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .oc-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.45rem}
.fig-live-ui .oc-stat{display:flex;flex-direction:column;gap:.15rem;padding:.45rem .6rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);min-width:0}
.fig-live-ui .oc-k{font-size:.68rem;color:var(--fg-subtle);text-transform:uppercase;letter-spacing:.04em}
.fig-live-ui .oc-v{font-family:'JetBrains Mono',monospace;font-size:.8rem;color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .oc-v.is-bad{color:var(--c-err);font-weight:700}
.fig-live-ui .oc-chart{display:flex;flex-direction:column;gap:.4rem}
.fig-live-ui .oc-axis{font-size:.72rem;color:var(--fg-subtle)}
.fig-live-ui .oc-rows{display:flex;flex-direction:column;gap:.35rem}
.fig-live-ui .oc-row{display:grid;grid-template-columns:5.5rem minmax(0,1fr);grid-template-areas:"lab track" ". note";gap:.1rem .6rem;align-items:center}
.fig-live-ui .oc-label{grid-area:lab;font-family:'JetBrains Mono',monospace;font-size:.72rem;color:var(--fg);text-align:right}
.fig-live-ui .oc-track{grid-area:track;position:relative;height:14px;border:1px solid var(--bd);border-radius:4px;background:var(--bg-surf);overflow:hidden}
.fig-live-ui .oc-bar{position:absolute;top:0;bottom:0;min-width:3px;background:var(--ac)}
.fig-live-ui .oc-bar.is-hot{background:var(--c-err)}
.fig-live-ui .oc-bar.is-ok{background:var(--c-ok)}
.fig-live-ui .oc-bar.is-wait{background:var(--c-warn)}
.fig-live-ui .oc-note{grid-area:note;font-family:'JetBrains Mono',monospace;font-size:.68rem;color:var(--fg-muted);overflow-wrap:anywhere}
@media(max-width:640px){.fig-live-ui .oc-stats{grid-template-columns:repeat(2,minmax(0,1fr))}.fig-live-ui .oc-row{grid-template-columns:3.8rem minmax(0,1fr)}}

/* expandcontract (pa): the rename in three deploys */
.fig-live-ui .pa-flow .flow-step.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .pa-flow .flow-step.is-now.is-bad{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .pa-flow .flow-step.is-done{border-color:var(--c-ok)}
.fig-live-ui .pa-table{display:flex;flex-direction:column;gap:.3rem;padding:.6rem .75rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);font-size:.8rem}
.fig-live-ui .pa-th{font-size:.7rem;color:var(--fg-subtle);text-transform:uppercase;letter-spacing:.04em}
.fig-live-ui .pa-th.pa-pend{text-transform:none;letter-spacing:0;font-size:.72rem}
.fig-live-ui .pa-col{display:grid;grid-template-columns:8rem 7rem minmax(0,1fr);gap:.6rem;align-items:baseline}
.fig-live-ui .pa-name{font-family:'JetBrains Mono',monospace;font-weight:600;color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .pa-type{font-family:'JetBrains Mono',monospace;color:var(--ac)}
.fig-live-ui .pa-fill{color:var(--fg-muted)}
.fig-live-ui .pa-fill.is-warn{color:var(--c-warn)}
.fig-live-ui .pa-codes{display:grid;grid-template-columns:repeat(auto-fit,minmax(13rem,1fr));gap:.6rem}
.fig-live-ui .pa-code{display:flex;flex-direction:column;gap:.2rem;padding:.6rem .75rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);font-size:.8rem;min-width:0}
.fig-live-ui .pa-ct{font-weight:700;color:var(--fg)}
.fig-live-ui .pa-cs{font-size:.7rem;color:var(--fg-subtle);margin-bottom:.15rem}
.fig-live-ui .pa-rw{font-family:'JetBrains Mono',monospace;font-size:.76rem;color:var(--fg-muted)}
.fig-live-ui .pa-verdict{margin-top:.25rem;font-weight:600;color:var(--fg-muted);overflow-wrap:anywhere}
.fig-live-ui .pa-code.is-ok{border-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .pa-code.is-ok .pa-verdict{color:var(--c-ok)}
.fig-live-ui .pa-code.is-bad{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .pa-code.is-bad .pa-verdict{color:var(--c-err)}
.fig-live-ui .pa-code.is-off{opacity:.55;border-style:dashed}
.fig-live-ui .pa-sql{margin:0;padding:.6rem .8rem;border-radius:var(--r-sm);background:var(--bg-surf);border:1px solid var(--bd);font-family:'JetBrains Mono',monospace;font-size:.74rem;line-height:1.5;color:var(--fg);white-space:pre-wrap;overflow-wrap:anywhere;font-variant-ligatures:none}

@media(max-width:640px){.fig-live-ui .pa-flow .flow-step{flex:1 1 40%;max-width:none;padding:.5rem .4rem}.fig-live-ui .pa-flow .flow-arrow{display:none}.fig-live-ui .pa-col{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.fig-live-ui .pa-fill{grid-column:1 / -1;font-size:.74rem}}

/* streamgroup (pb): one Redis stream, one consumer group, two workers */
.fig-live-ui .pb-flow .flow-step.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .pb-flow .flow-step.is-now.is-bad{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .pb-flow .flow-step.is-done{border-color:var(--c-ok)}
.fig-live-ui .pb-flow+.pb-flow{margin-top:.2rem}
.fig-live-ui .pb-clock{font-family:'JetBrains Mono',monospace;font-size:.9rem;font-weight:700;color:var(--ac);text-align:center}
.fig-live-ui .pb-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.6rem}
.fig-live-ui .pb-panel{display:flex;flex-direction:column;gap:.4rem;padding:.6rem .75rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);font-size:.78rem;min-width:0}
.fig-live-ui .pb-ph{font-size:.7rem;font-weight:700;color:var(--fg-subtle);text-transform:uppercase;letter-spacing:.04em}
.fig-live-ui .pb-worker .pb-ph{font-family:'JetBrains Mono',monospace;text-transform:none;letter-spacing:0;font-size:.8rem;color:var(--fg)}
.fig-live-ui .pb-worker.is-dead{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .pb-worker.is-dead .pb-ph{color:var(--c-err)}
.fig-live-ui .pb-body{display:flex;flex-direction:column;gap:.3rem;min-width:0}
.fig-live-ui .pb-scroll{overflow-x:auto}
.fig-live-ui .pb-wide{grid-column:1 / -1}
.fig-live-ui .pb-meta{font-size:.72rem;color:var(--fg-muted);overflow-wrap:anywhere}
.fig-live-ui .pb-empty{font-size:.74rem;color:var(--fg-subtle);font-style:italic}
.fig-live-ui .pb-entry{display:flex;flex-wrap:wrap;gap:.1rem .6rem;padding:.3rem .45rem;border-radius:4px;border-left:3px solid var(--fg-subtle);background:var(--bg-sb)}
.fig-live-ui .pb-entry.is-pending{border-left-color:var(--c-warn)}
.fig-live-ui .pb-entry.is-acked{border-left-color:var(--c-ok)}
.fig-live-ui .pb-id{font-family:'JetBrains Mono',monospace;color:var(--fg);white-space:nowrap}
.fig-live-ui .pb-f{color:var(--fg-muted)}
.fig-live-ui .pb-st{color:var(--fg);font-weight:600}
.fig-live-ui .pb-pel{display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .pb-tr{display:grid;grid-template-columns:10rem minmax(0,1fr) 4rem 5.5rem;gap:.1rem .5rem;align-items:baseline}
.fig-live-ui .pb-c-idle,.fig-live-ui .pb-c-cnt{text-align:right}
.fig-live-ui .pb-tr.pb-th{font-size:.68rem;color:var(--fg-subtle);text-transform:uppercase;letter-spacing:.04em}
.fig-live-ui .pb-tr.is-dead{color:var(--c-err)}
.fig-live-ui .pb-over{color:var(--c-warn);font-weight:700}
.fig-live-ui .pb-job{padding:.25rem .45rem;border-radius:4px;background:var(--bg-sb);color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .pb-job.is-run{box-shadow:inset 3px 0 0 var(--ac)}
.fig-live-ui .pb-job.is-bad{color:var(--c-err);background:transparent;padding-left:0}
.fig-live-ui .pb-btns{gap:.4rem;margin-top:auto}
.fig-live-ui .pb-btns .wl-btn{font-size:.74rem;padding:.25rem .6rem}
.fig-live-ui .pb-crash{border-color:var(--c-err);color:var(--c-err)}
.fig-live-ui .pb-mail{font-weight:600;color:var(--fg)}
.fig-live-ui .pb-mail.is-ok{color:var(--c-ok)}
.fig-live-ui .pb-mail.is-bad{color:var(--c-err)}
.fig-live-ui .pb-log{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:.15rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .pb-ev{display:grid;grid-template-columns:3rem minmax(0,1fr);gap:.4rem;padding:.1rem .4rem;border-left:2px solid var(--bd);overflow-wrap:anywhere}
.fig-live-ui .pb-t{font-family:'JetBrains Mono',monospace;color:var(--fg-subtle);text-align:right}
.fig-live-ui .pb-ev.is-bad{color:var(--c-err);border-left-color:var(--c-err)}
.fig-live-ui .pb-ev.is-ok{color:var(--c-ok);border-left-color:var(--c-ok)}
.fig-live-ui .pb-ev:last-child{color:var(--fg);font-weight:600;border-left-color:var(--ac)}
@media(max-width:640px){.fig-live-ui .pb-grid{grid-template-columns:minmax(0,1fr)}.fig-live-ui .pb-tr{grid-template-columns:minmax(0,1fr) 2.6rem 4.8rem}.fig-live-ui .pb-c-id{grid-column:1;grid-row:1}.fig-live-ui .pb-c-own{grid-column:1;grid-row:2}.fig-live-ui .pb-c-idle{grid-column:2;grid-row:1}.fig-live-ui .pb-c-cnt{grid-column:3;grid-row:1}.fig-live-ui .pb-th .pb-c-own{display:none}.fig-live-ui .pb-flow .flow-step{flex:1 1 40%;max-width:none;padding:.45rem .4rem}.fig-live-ui .pb-flow .flow-arrow{display:none}}

/* eventloop (Backend Deep Dive 14, "Async Where It Pays"): the page's four cards as presets, the loop's timeline and a log-scale lag chart. */
.fig-live-ui .qa-cards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.6rem;margin:0}
.fig-live-ui .qa-card{font:inherit;text-align:left;cursor:pointer;color:inherit;background:var(--bg-sb);padding:.8rem .75rem;gap:.45rem}
.fig-live-ui .qa-card[aria-pressed="true"]{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .qa-card:focus-visible{outline:2px solid var(--ac);outline-offset:2px}
.fig-live-ui .qa-tl,.fig-live-ui .qa-chart{position:relative}
.fig-live-ui .qa-tl svg,.fig-live-ui .qa-chart svg{display:block;width:100%;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf)}
.fig-live-ui .qa-tl svg{height:10rem}
.fig-live-ui .qa-chart svg{height:10rem}
.fig-live-ui .qa-tl path,.fig-live-ui .qa-chart path,.fig-live-ui .qa-chart polyline{fill:none;vector-effect:non-scaling-stroke}
.fig-live-ui .qa-grid{stroke:var(--bd);stroke-width:1}
.fig-live-ui .qa-task{fill:var(--ac-dim);stroke:var(--ac);stroke-width:1;vector-effect:non-scaling-stroke}
.fig-live-ui .qa-task.is-bad{fill:var(--c-err-bg);stroke:var(--c-err)}
.fig-live-ui .qa-wait{fill:var(--c-warn-bg);stroke:var(--c-warn);stroke-width:1;vector-effect:non-scaling-stroke}
.fig-live-ui .qa-wait.is-bad{fill:var(--c-err-bg);stroke:var(--c-err)}
.fig-live-ui .qa-lock{stroke:var(--c-warn);stroke-width:6}
.fig-live-ui .qa-run{stroke:var(--c-ok);stroke-width:1}
.fig-live-ui .qa-arr{stroke:var(--fg-subtle);stroke-width:1}
.fig-live-ui .qa-me{stroke:var(--fg);stroke-width:2}
.fig-live-ui .qa-clock{stroke:var(--ac);stroke-width:1.5;stroke-dasharray:3 3}
.fig-live-ui .qa-alert{stroke:var(--c-err);stroke-width:1;stroke-dasharray:5 4}
.fig-live-ui .qa-curve{stroke:var(--ac);stroke-width:2;stroke-linejoin:round}
.fig-live-ui .qa-dots{stroke:var(--fg-muted);stroke-width:4;stroke-linecap:round}
.fig-live-ui .qa-mydot{stroke:var(--fg);stroke-width:9;stroke-linecap:round}
.fig-live-ui .qa-lane{position:absolute;left:.4rem;margin-top:.15rem;font-size:.66rem;line-height:1;color:var(--fg-subtle);pointer-events:none;white-space:nowrap}
.fig-live-ui .qa-ylab{position:absolute;right:.35rem;transform:translateY(-50%);font-size:.62rem;line-height:1;color:var(--fg-subtle);background:var(--bg-surf);padding:0 .15rem;pointer-events:none;font-family:'JetBrains Mono',monospace}
.fig-live-ui .qa-axis{display:flex;justify-content:space-between;font-size:.66rem;color:var(--fg-subtle);font-family:'JetBrains Mono',monospace;margin-top:-.4rem}
.fig-live-ui .qa-legend{display:flex;flex-wrap:wrap;gap:.3rem 1rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .qa-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .qa-key::before{content:"";width:1.4rem;border-top:2px solid var(--ac)}
.fig-live-ui .qa-key-me::before{width:.6rem;height:.6rem;border:0;border-radius:50%;background:var(--fg)}
.fig-live-ui .qa-key-dots::before{width:.35rem;height:.35rem;border:0;border-radius:50%;background:var(--fg-muted)}
.fig-live-ui .qa-key-alert::before{border-top:1px dashed var(--c-err)}
@media(max-width:640px){.fig-live-ui .qa-cards{grid-template-columns:repeat(2,minmax(0,1fr))}.fig-live-ui .qa-card .fig-col-cap{font-size:.72rem}}

/* errorbudget (Backend Deep Dive 13, "SLOs for One Service"): the page's three SLO cards, the budget arithmetic, a budget bar and a budget-over-the-window chart. */
.fig-live-ui .qb-cards{margin:0}
.fig-live-ui .qb-cards .fig-col.qb-on{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .qb-math{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.5rem}
.fig-live-ui .qb-tile{border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);padding:.55rem .65rem;display:flex;flex-direction:column;gap:.2rem;min-width:0}
.fig-live-ui .qb-tile.is-bad{border-color:var(--c-err)}
.fig-live-ui .qb-lab{font-size:.68rem;text-transform:uppercase;letter-spacing:.04em;color:var(--fg-subtle)}
.fig-live-ui .qb-val{font-family:'JetBrains Mono',monospace;font-size:1rem;font-weight:700;color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .qb-tile.is-bad .qb-val{color:var(--c-err)}
.fig-live-ui .qb-sum{font-size:.72rem;color:var(--fg-muted);line-height:1.35;overflow-wrap:anywhere}
.fig-live-ui .qb-barbox{display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .qb-bar{display:block;height:.8rem;border-radius:.4rem;background:var(--c-ok-bg);border:1px solid var(--c-ok);overflow:hidden}
.fig-live-ui .qb-used{display:block;height:100%;background:var(--c-err)}
.fig-live-ui .qb-bar.is-bad{border-color:var(--c-err)}
.fig-live-ui .qb-bartext{font-size:.76rem;color:var(--fg-muted);font-family:'JetBrains Mono',monospace}
.fig-live-ui .qb-chart{position:relative}
.fig-live-ui .qb-chart svg{display:block;width:100%;height:9rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf)}
.fig-live-ui .qb-chart path,.fig-live-ui .qb-chart polyline{fill:none;vector-effect:non-scaling-stroke;stroke-linejoin:round}
.fig-live-ui .qb-grid{stroke:var(--bd);stroke-width:1}
.fig-live-ui .qb-one{stroke:var(--fg-subtle);stroke-width:1.5;stroke-dasharray:2 4}
.fig-live-ui .qb-fast{stroke:var(--c-warn);stroke-width:1.5;stroke-dasharray:6 4}
.fig-live-ui .qb-kept{stroke:var(--c-err);stroke-width:1.5;stroke-dasharray:3 3}
.fig-live-ui .qb-real{stroke:var(--ac);stroke-width:2.5}
.fig-live-ui .qb-ylab{position:absolute;right:.35rem;transform:translateY(-50%);font-size:.62rem;line-height:1;color:var(--fg-subtle);background:var(--bg-surf);padding:0 .15rem;pointer-events:none;font-family:'JetBrains Mono',monospace}
.fig-live-ui .qb-axis{display:flex;justify-content:space-between;font-size:.66rem;color:var(--fg-subtle);font-family:'JetBrains Mono',monospace;margin-top:-.4rem}
.fig-live-ui .qb-legend{display:flex;flex-wrap:wrap;gap:.3rem 1rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .qb-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .qb-key::before{content:"";width:1.4rem;border-top:2.5px solid var(--ac)}
.fig-live-ui .qb-key-kept::before{border-top:1.5px dashed var(--c-err)}
.fig-live-ui .qb-key-fast::before{border-top:1.5px dashed var(--c-warn)}
.fig-live-ui .qb-key-one::before{border-top:1.5px dotted var(--fg-subtle)}
.fig-live-ui .qb-alerts{display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .qb-alert{margin:0;font-size:.8rem;color:var(--fg-muted);padding:.35rem .6rem;border-left:3px solid var(--bd);border-radius:0 var(--r-sm) var(--r-sm) 0}
.fig-live-ui .qb-alert.is-on{color:var(--fg);border-left-color:var(--c-err);background:var(--c-err-bg)}
@media(max-width:640px){.fig-live-ui .qb-math{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* cardinality (ra): Observability Deep Dive 5 label-discipline (and 1 three-costs). The two
   cards are the static figure's own .fig-cols; .ra-scale sets both counts on one log axis
   with the per-family cap as a line. */
.fig-live-ui .ra-cols{margin:0}
.fig-live-ui .ra-cols .fig-col{background:var(--bg-surf)}
.fig-live-ui .ra-cols .fig-col.is-ok{border-color:var(--c-ok)}
.fig-live-ui .ra-cols .fig-col.is-bad{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .ra-cols .nm small{font-family:'JetBrains Mono',monospace;font-size:.8rem;color:var(--fg)}
.fig-live-ui .ra-cols .fig-col.is-bad .nm small{color:var(--c-err)}
.fig-live-ui .ra-cols .fig-col-cap{overflow-wrap:anywhere}
.fig-live-ui .ra-scale{display:flex;flex-direction:column;gap:.4rem}
.fig-live-ui .ra-row{display:grid;grid-template-columns:8.5rem minmax(0,1fr);gap:.6rem;align-items:center}
.fig-live-ui .ra-lab{display:flex;flex-direction:column;font-size:.74rem;color:var(--fg-muted);text-align:right;min-width:0}
.fig-live-ui .ra-n{font-family:'JetBrains Mono',monospace;font-size:.76rem;color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .ra-track{position:relative;height:16px;border:1px solid var(--bd);border-radius:4px;background:var(--bg-surf)}
.fig-live-ui .ra-fill{position:absolute;left:0;top:0;bottom:0;border-radius:3px 0 0 3px;background:var(--c-ok)}
.fig-live-ui .ra-fill.is-bad{background:var(--c-err)}
.fig-live-ui .ra-cap{position:absolute;top:-4px;bottom:-4px;width:2px;margin-left:-1px;border-radius:1px;background:var(--fg)}
.fig-live-ui .ra-axis{position:relative;height:1.1rem;font-family:'JetBrains Mono',monospace;font-size:.66rem;color:var(--fg-subtle)}
.fig-live-ui .ra-tick{position:absolute;top:0;transform:translateX(-50%);white-space:nowrap}
.fig-live-ui .ra-tick:first-child{transform:none}
.fig-live-ui .ra-tick:last-child{transform:translateX(-100%)}
.fig-live-ui .ra-legend{margin-top:.1rem}
@media(max-width:640px){.fig-live-ui .ra-row{grid-template-columns:6.6rem minmax(0,1fr);gap:.45rem}.fig-live-ui .ra-n{font-size:.72rem}.fig-live-ui .ra-tick:nth-child(even){display:none}}
/* percentiles (rb): Observability Deep Dive 2 percentiles-over-averages. Three panels behind
   chips; .rb-stats are the statistic cards (styled like the figure's .fig-col), .rb-strip the
   requests sorted fastest first on a log latency axis, .rb-meter the fan-out share. */
.fig-live-ui .rb-panel{display:flex;flex-direction:column;gap:.75rem}
.fig-live-ui .rb-stats{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:.5rem}
.fig-live-ui .rb-stats.rb-four{grid-template-columns:repeat(4,minmax(0,1fr))}
.fig-live-ui .rb-stat{display:flex;flex-direction:column;gap:.2rem;padding:.6rem .7rem;border:1px solid var(--bd);border-radius:10px;background:var(--bg-surf);min-width:0}
.fig-live-ui .rb-k{font-size:.72rem;font-weight:600;color:var(--fg-muted)}
.fig-live-ui .rb-v{font-family:'JetBrains Mono',monospace;font-size:1.05rem;font-weight:700;color:var(--fg)}
.fig-live-ui .rb-d{font-size:.7rem;color:var(--fg-subtle);line-height:1.4;overflow-wrap:anywhere}
.fig-live-ui .rb-stat.is-slow{border-color:var(--c-err)}
.fig-live-ui .rb-stat.is-slow .rb-v{color:var(--c-err)}
.fig-live-ui .rb-stat.is-bad{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .rb-stat.is-ok{border-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .rb-strip{position:relative}
.fig-live-ui .rb-strip svg{display:block;width:100%;height:9rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf)}
.fig-live-ui .rb-fast{fill:var(--ac);fill-opacity:.55}
.fig-live-ui .rb-slow{fill:var(--c-err)}
.fig-live-ui .rb-at{fill:var(--fg);fill-opacity:1}
.fig-live-ui .rb-grid{fill:none;stroke:var(--bd);stroke-width:1;vector-effect:non-scaling-stroke}
.fig-live-ui .rb-mean{stroke:var(--c-warn);stroke-width:2;stroke-dasharray:6 4;vector-effect:non-scaling-stroke}
.fig-live-ui .rb-ylab{position:absolute;left:.35rem;transform:translateY(-100%);font-family:'JetBrains Mono',monospace;font-size:.62rem;color:var(--fg-subtle);background:var(--bg-surf);padding:0 .2rem;border-radius:3px;pointer-events:none}
.fig-live-ui .rb-ytop{transform:translateY(2px)}
.fig-live-ui .rb-meanlab{position:absolute;right:.4rem;transform:translateY(-110%);font-family:'JetBrains Mono',monospace;font-size:.68rem;font-weight:600;color:var(--c-warn);background:var(--bg-surf);padding:0 .2rem;border-radius:3px;pointer-events:none}
.fig-live-ui .rb-ranks{position:relative;height:1.1rem;font-family:'JetBrains Mono',monospace;font-size:.66rem;color:var(--fg-muted)}
.fig-live-ui .rb-ranks span{position:absolute;top:0;white-space:nowrap}
.fig-live-ui .rb-r0{left:0}
.fig-live-ui .rb-r{transform:translateX(-50%)}
.fig-live-ui .rb-r1{right:0}
.fig-live-ui .rb-big{font-family:'JetBrains Mono',monospace;font-size:1.3rem;font-weight:700;color:var(--fg)}
.fig-live-ui .rb-meter{position:relative;height:16px;border:1px solid var(--bd);border-radius:4px;background:var(--bg-surf);overflow:hidden}
.fig-live-ui .rb-fill{position:absolute;left:0;top:0;bottom:0;background:var(--c-warn)}
.fig-live-ui .rb-code{font-family:'JetBrains Mono',monospace;font-size:.76rem;color:var(--fg);padding:.45rem .65rem;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);overflow-wrap:anywhere}
@media(max-width:640px){.fig-live-ui .rb-stats{grid-template-columns:repeat(2,minmax(0,1fr))}.fig-live-ui .rb-stats>.rb-stat:first-child:nth-last-child(odd){grid-column:1/-1}.fig-live-ui .rb-stats.rb-four{grid-template-columns:repeat(2,minmax(0,1fr))}.fig-live-ui .rb-r{display:none}}
/* relabel (Observability Deep Dive 3, Service Discovery and Relabeling): the static
   figure's own .fig-flow on top, .is-now on the gate that acts; the six file_sd
   targets as buttons (scraped / never contacted / scraped then dropped); label
   sets before and after, like the Service Discovery page; the blackbox rules. */
.fig-live-ui .rf-flow .flow-step.is-now{border-color:var(--ac);background:var(--ac-dim)}
@media(min-width:641px){.fig-live-ui .rf-flow{flex-wrap:nowrap}.fig-live-ui .rf-flow .flow-step{flex:1 1 0;min-width:0;max-width:none;padding:.7rem .4rem}}
.fig-live-ui .rf-now{font-size:.66rem;font-family:'JetBrains Mono',monospace;color:var(--fg);line-height:1.3;overflow-wrap:anywhere}
.fig-live-ui .rf-now:empty{display:none}
.fig-live-ui .rf-box{display:flex;flex-direction:column;gap:.7rem;min-width:0}
.fig-live-ui .rf-code{margin:0}
.fig-live-ui .rf-targets{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.4rem}
.fig-live-ui .rf-tgt{font:inherit;display:flex;flex-direction:column;align-items:flex-start;gap:.1rem;min-width:0;padding:.4rem .55rem;border-radius:var(--r-sm);border:1px solid var(--c-ok);background:var(--c-ok-bg);color:var(--fg);cursor:pointer;text-align:left}
.fig-live-ui .rf-tgt.is-gone{border-style:dashed;border-color:var(--fg-subtle);background:transparent;color:var(--fg-muted)}
.fig-live-ui .rf-tgt.is-gone .rf-addr{text-decoration:line-through}
.fig-live-ui .rf-tgt.is-paid{border-color:var(--c-warn);background:var(--c-warn-bg)}
.fig-live-ui .rf-tgt.is-pick{box-shadow:0 0 0 2px var(--ac)}
.fig-live-ui .rf-addr{font-family:'JetBrains Mono',monospace;font-size:.78rem;font-weight:600;overflow-wrap:anywhere}
.fig-live-ui .rf-state{font-size:.68rem;color:var(--fg-muted)}
.fig-live-ui .rf-tgt.is-paid .rf-state{color:var(--fg)}
.fig-live-ui .rf-labels{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:.5rem}
.fig-live-ui .rf-col{border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);padding:.5rem .65rem;min-width:0}
.fig-live-ui .rf-colhd{display:block;font-size:.68rem;text-transform:uppercase;letter-spacing:.04em;color:var(--fg-subtle);margin-bottom:.3rem}
.fig-live-ui .rf-kv{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.1rem;font-family:'JetBrains Mono',monospace;font-size:.74rem}
.fig-live-ui .rf-lab{display:flex;flex-wrap:wrap;gap:0 .15rem;padding:.05rem .3rem;border-radius:3px;margin:0}
.fig-live-ui .rf-k{color:var(--fg)}
.fig-live-ui .rf-eq{color:var(--fg-subtle)}
.fig-live-ui .rf-v{color:var(--fg-muted);overflow-wrap:anywhere;min-width:0}
.fig-live-ui .rf-lab.is-meta .rf-k{color:var(--fg-subtle)}
.fig-live-ui .rf-lab.is-new{background:var(--ac-dim)}
.fig-live-ui .rf-lab.is-new .rf-k,.fig-live-ui .rf-lab.is-new .rf-v{color:var(--fg)}
.fig-live-ui .rf-empty{font-size:.78rem;color:var(--fg-muted)}
.fig-live-ui .rf-field{gap:.5rem}
.fig-live-ui .rf-in{font-family:'JetBrains Mono',monospace;font-size:.85rem;padding:.3rem .5rem;width:12rem;max-width:100%;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg)}
.fig-live-ui .rf-in[aria-invalid="true"]{border-color:var(--c-err)}
.fig-live-ui .rf-err{font-size:.76rem;color:var(--c-err);margin-top:-.4rem}
.fig-live-ui .rf-rules{margin:0;padding-left:1.4rem;display:flex;flex-direction:column;gap:.25rem;font-size:.74rem}
.fig-live-ui .rf-rule{padding:.2rem .4rem;border-radius:var(--r-sm);border:1px solid transparent;color:var(--fg-muted);overflow-wrap:anywhere}
.fig-live-ui .rf-rule code{font-family:'JetBrains Mono',monospace;font-size:inherit;background:none;border:0;padding:0;color:inherit}
.fig-live-ui .rf-rule.is-done{color:var(--fg)}
.fig-live-ui .rf-rule.is-now{border-color:var(--ac);background:var(--ac-dim);color:var(--fg)}
.fig-live-ui .rf-rule.is-skip{text-decoration:line-through;color:var(--fg-subtle)}
.fig-live-ui .rf-steptitle{font-size:.8rem;font-weight:600;color:var(--fg)}
.fig-live-ui .rf-out{border:1px solid var(--ac);border-radius:var(--r-sm);background:var(--ac-dim);padding:.5rem .65rem;min-width:0}
.fig-live-ui .rf-url{display:block;font-family:'JetBrains Mono',monospace;font-size:.78rem;color:var(--fg);overflow-wrap:anywhere;background:none;border:0;padding:0}
@media(max-width:640px){.fig-live-ui .rf-targets{grid-template-columns:repeat(2,minmax(0,1fr))}.fig-live-ui .rf-labels{grid-template-columns:minmax(0,1fr)}}
@media(max-width:640px){.fig-live-ui .rf-flow{gap:.1rem}.fig-live-ui .rf-flow .flow-step{padding:.4rem .5rem;gap:.15rem}.fig-live-ui .rf-flow .flow-arrow{padding:0;font-size:.9rem;line-height:1}}
/* alertfor (Observability Deep Dive 9, alerting rules): the figure's three
   .fig-flow boxes, .is-now marking where the alert is at the clock, over a strip
   of rule evaluations: a tall bar is expr returning data, the square's colour the
   alert state, a ring the evaluation that sends the alert to Alertmanager. */
.fig-live-ui .rc-flow .flow-step.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .rc-flow .rc-pend.is-now{border-color:var(--c-warn);background:var(--c-warn-bg)}
.fig-live-ui .rc-flow .flow-step.ok.is-now{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .rc-x{font-family:'JetBrains Mono',monospace;font-size:.66rem;color:var(--fg-muted);line-height:1.3;min-height:.9rem}
.fig-live-ui .rc-box{display:flex;flex-direction:column;gap:.35rem;min-width:0}
.fig-live-ui .rc-strip{display:grid;grid-template-columns:repeat(var(--rc-n,30),minmax(0,1fr));gap:2px;padding-top:4px}
.fig-live-ui .rc-tick{font:inherit;position:relative;display:flex;align-items:flex-end;height:2.6rem;min-width:0;padding:0;border:1px solid var(--bd);border-radius:3px;background:var(--bg-surf);cursor:pointer;overflow:hidden}
.fig-live-ui .rc-tick:disabled{cursor:default;border-style:dashed;background:transparent}
.fig-live-ui .rc-bar{display:block;width:100%;height:16%;background:var(--fg-subtle);opacity:.45}
.fig-live-ui .rc-tick.is-bad .rc-bar{height:68%;background:var(--ac);opacity:1}
.fig-live-ui .rc-tick.is-pending{background:var(--c-warn-bg);border-color:var(--c-warn)}
.fig-live-ui .rc-tick.is-firing{background:var(--c-err-bg);border-color:var(--c-err)}
.fig-live-ui .rc-tick.is-held{border-style:dashed}
.fig-live-ui .rc-tick.is-page{box-shadow:0 0 0 2px var(--c-err)}
.fig-live-ui .rc-tick.is-future{opacity:.5}
.fig-live-ui .rc-tick.is-now{box-shadow:0 0 0 2px var(--ac)}
.fig-live-ui .rc-axis{display:flex;justify-content:space-between;gap:.5rem;font-size:.7rem;color:var(--fg-subtle);font-family:'JetBrains Mono',monospace}
.fig-live-ui .rc-legend{display:flex;flex-wrap:wrap;gap:.3rem .9rem;font-size:.72rem;color:var(--fg-muted)}
.fig-live-ui .rc-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .rc-key::before{content:"";display:inline-block;width:.8rem;height:.8rem;border-radius:2px;border:1px solid var(--bd);background:var(--bg-surf)}
.fig-live-ui .rc-k-data::before{background:linear-gradient(to top,var(--ac) 68%,var(--bg-surf) 68%)}
.fig-live-ui .rc-k-pending::before{background:var(--c-warn-bg);border-color:var(--c-warn)}
.fig-live-ui .rc-k-firing::before{background:var(--c-err-bg);border-color:var(--c-err)}
.fig-live-ui .rc-k-held::before{background:var(--c-err-bg);border:1px dashed var(--c-err)}
.fig-live-ui .rc-k-page::before{box-shadow:0 0 0 2px var(--c-err)}
.fig-live-ui .rc-detect{font-size:.85rem;font-weight:600;color:var(--fg)}
@media(max-width:640px){.fig-live-ui .rc-strip{grid-template-columns:repeat(var(--rc-half,15),minmax(0,1fr));gap:3px}.fig-live-ui .rc-tick{height:2.2rem}}
@media(max-width:640px){.fig-live-ui .rc-flow .flow-step{flex-direction:row;flex-wrap:wrap;justify-content:flex-start;align-items:baseline;gap:.15rem .6rem;padding:.45rem .7rem;text-align:left}.fig-live-ui .rc-flow .rc-x{margin-left:auto}.fig-live-ui .rc-flow .flow-arrow{font-size:.9rem;padding:0}}
/* amroute (Observability Deep Dive 9, Alertmanager): the figure's .fig-tree rows.
   The route that delivers is lit, a route checked without a match is dashed, a
   route never reached is dimmed, and one a broader route above swallowed is red. */
.fig-live-ui .re-tree{width:100%;margin:0 auto}
.fig-live-ui .re-tree .tree-level{min-width:0}
.fig-live-ui .re-node.is-deliver{border-left-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .re-node.is-miss{border-style:dashed;border-left-style:solid;border-left-color:var(--bd);background:transparent}
.fig-live-ui .re-node.is-skip{border-left-color:var(--bd);background:transparent;opacity:.6}
.fig-live-ui .re-node.is-miss .nm,.fig-live-ui .re-node.is-skip .nm{color:var(--fg-muted);font-weight:500}
.fig-live-ui .re-node.is-swallowed{opacity:1;border-color:var(--c-err);border-left-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .re-why{font-size:.72rem;color:var(--fg-muted);margin-top:.25rem}
.fig-live-ui .re-node.is-deliver .re-why{color:var(--c-ok);font-weight:600}
.fig-live-ui .re-node.is-swallowed .re-why{color:var(--c-err);font-weight:600}
.fig-live-ui .re-ctl{display:flex;flex-wrap:wrap;gap:.35rem;margin-top:.4rem}
.fig-live-ui .re-mini{font-size:.74rem;padding:.2rem .6rem;font-family:'JetBrains Mono',monospace}
.fig-live-ui .re-mini[aria-pressed="true"]{background:var(--ac-dim);border-color:var(--ac);color:var(--fg)}
.fig-live-ui .re-mini:disabled{opacity:.4;cursor:default}
.fig-live-ui .re-alert{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem}
.fig-live-ui .re-card-k{font-size:.82rem;font-weight:600;color:var(--fg-muted);margin-right:.2rem}
.fig-live-ui .re-lab{font-family:'JetBrains Mono',monospace;font-size:.74rem;padding:.12rem .5rem;border-radius:var(--r-sm);border:1px solid var(--ac);background:var(--ac-dim);color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .re-cmd{margin:0;padding:.55rem .75rem;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg);font-family:'JetBrains Mono',monospace;font-size:.76rem;line-height:1.5;white-space:pre-wrap;overflow-wrap:anywhere}
.fig-live-ui .re-tally{display:flex;flex-direction:column;gap:.35rem}
.fig-live-ui .re-trow{display:grid;grid-template-columns:8.5rem minmax(0,1fr) 2.5rem;gap:.5rem;align-items:center;font-size:.78rem}
.fig-live-ui .re-rname{font-family:'JetBrains Mono',monospace;color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .re-track{display:block;height:8px;border-radius:4px;background:var(--bg-surf);border:1px solid var(--bd);overflow:hidden}
.fig-live-ui .re-bar{display:block;height:100%;background:var(--ac)}
.fig-live-ui .re-count{font-family:'JetBrains Mono',monospace;color:var(--fg);text-align:right}
.fig-live-ui .re-trow.is-zero .re-rname,.fig-live-ui .re-trow.is-zero .re-count{color:var(--c-err);font-weight:700}
@media(max-width:640px){.fig-live-ui .re-tree .d1{margin-left:.8rem}.fig-live-ui .re-trow{grid-template-columns:7rem minmax(0,1fr) 2rem}}
/* slobudget (Observability Deep Dive 10, Error Budgets and Burn-Rate Alerts): the
   static figures' own .fig-cols cards, then the budget left against the policy's
   50% and 0 marks, the burn rate, and the ladder's rungs lit when they fire. */
.fig-live-ui .rd-cards{margin:0}
.fig-live-ui .rd-cards .fig-col.is-on{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .rd-cards .fig-col.is-bad{border-color:var(--c-err)}
.fig-live-ui .rd-spend,.fig-live-ui .rd-line,.fig-live-ui .rd-verdict{display:block;margin-top:.45rem;color:var(--fg)}
.fig-live-ui .rd-spend{font-weight:600}
.fig-live-ui .rd-line{color:var(--fg-muted)}
.fig-live-ui .rd-ladder .fig-col.is-on .rd-verdict{color:var(--c-err);font-weight:600}
.fig-live-ui .rd-math{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.5rem}
.fig-live-ui .rd-tile{border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);padding:.55rem .65rem;display:flex;flex-direction:column;gap:.2rem;min-width:0}
.fig-live-ui .rd-lab{font-size:.68rem;text-transform:uppercase;letter-spacing:.04em;color:var(--fg-subtle)}
.fig-live-ui .rd-val{font-family:'JetBrains Mono',monospace;font-size:1rem;font-weight:700;color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .rd-sum{font-size:.72rem;color:var(--fg-muted);line-height:1.35;overflow-wrap:anywhere}
.fig-live-ui .rd-barbox{display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .rd-bar{position:relative;display:block;height:.9rem;border-radius:.45rem;background:var(--c-err-bg);border:1px solid var(--bd);overflow:hidden}
.fig-live-ui .rd-left{position:absolute;left:0;top:0;bottom:0;background:var(--c-ok)}
.fig-live-ui .rd-bar.is-review .rd-left{background:var(--c-warn)}
.fig-live-ui .rd-bar.is-freeze{border-color:var(--c-err)}
.fig-live-ui .rd-mark{position:absolute;left:50%;top:0;bottom:0;border-left:2px dashed var(--fg)}
.fig-live-ui .rd-scale{display:grid;grid-template-columns:1fr auto 1fr;gap:.4rem;font-size:.66rem;color:var(--fg-subtle);font-family:'JetBrains Mono',monospace}
.fig-live-ui .rd-scale span:nth-child(2){text-align:center}
.fig-live-ui .rd-scale span:last-child{text-align:right}
.fig-live-ui .rd-bartext{font-size:.76rem;color:var(--fg-muted);font-family:'JetBrains Mono',monospace;overflow-wrap:anywhere}
.fig-live-ui .rd-policy{font-size:.8rem;color:var(--fg-muted);padding:.35rem .6rem;border-left:3px solid var(--c-ok);border-radius:0 var(--r-sm) var(--r-sm) 0;background:var(--c-ok-bg)}
.fig-live-ui .rd-policy.is-review{border-left-color:var(--c-warn);background:var(--c-warn-bg);color:var(--fg)}
.fig-live-ui .rd-policy.is-freeze{border-left-color:var(--c-err);background:var(--c-err-bg);color:var(--fg)}
.fig-live-ui .rd-rungs{display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .rd-rung{margin:0;font-size:.8rem;color:var(--fg-muted);padding:.35rem .6rem;border-left:3px solid var(--bd);border-radius:0 var(--r-sm) var(--r-sm) 0}
.fig-live-ui .rd-rung strong{color:var(--fg);font-weight:600}
.fig-live-ui .rd-rung.is-on{color:var(--fg);border-left-color:var(--c-err);background:var(--c-err-bg)}
@media(max-width:640px){.fig-live-ui .rd-scale{font-size:.6rem}}
/* APIs for Beginners widget verbs: the page's table "Five verbs, two questions" with a
   live last column, the request as typed, the four moments of send / lost answer /
   send again / answer, and the server's state before and after each send.
   .is-lit marks the table row of the picked verb; .is-new / .is-gone mark what a send
   added or removed. */
.fig-live-ui .sc-tblbox{overflow-x:auto;-webkit-overflow-scrolling:touch}
.fig-live-ui .sc-tbl{margin:0;width:100%}
.fig-live-ui .sc-tbl .sc-hshort{display:none}
@media(max-width:640px){.fig-live-ui .sc-tbl th:nth-child(2),.fig-live-ui .sc-tbl td:nth-child(2){display:none}.fig-live-ui .sc-tbl td,.fig-live-ui .sc-tbl th{padding:.4rem .3rem;font-size:.76rem}.fig-live-ui .sc-tbl th{text-transform:none;letter-spacing:0;font-size:.7rem;overflow-wrap:normal}.fig-live-ui .sc-tbl .sc-hfull{display:none}.fig-live-ui .sc-tbl .sc-hshort{display:inline}.fig-live-ui .sc-tbl .sc-after{min-width:0}.fig-live-ui .sc-after-line{font-size:.7rem}.fig-live-ui .sc-tbl code{font-size:.68rem;padding:.05rem .2rem}}
.fig-live-ui .sc-tbl td,.fig-live-ui .sc-tbl th{padding:.45rem .55rem}
.fig-live-ui .sc-tbl .sc-strong{font-weight:700}
.fig-live-ui .sc-tbl tr.is-lit td{background:var(--ac-dim)}
.fig-live-ui .sc-tbl tr.is-lit td:first-child{box-shadow:inset 3px 0 0 var(--ac)}
.fig-live-ui .sc-after{color:var(--fg-subtle);min-width:9rem}
.fig-live-ui .sc-after-line{display:block;font-size:.78rem;line-height:1.4}
.fig-live-ui .sc-after-line.is-ok{color:var(--c-ok)}
.fig-live-ui .sc-after-line.is-bad{color:var(--c-err);font-weight:700}
.fig-live-ui .sc-req{margin:0;padding:.6rem .8rem;border-radius:var(--r-sm);background:var(--bg-surf);border:1px solid var(--bd);font-family:'JetBrains Mono',monospace;font-size:.76rem;line-height:1.5;color:var(--fg);white-space:pre-wrap;overflow-wrap:anywhere;min-height:4.6em;font-variant-ligatures:none}
.fig-live-ui .sc-steps{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.4rem}
.fig-live-ui .sc-step{display:flex;flex-direction:column;gap:.2rem;padding:.45rem .55rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);opacity:.55;min-width:0}
.fig-live-ui .sc-step.is-done{opacity:1}
.fig-live-ui .sc-step.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .sc-step.is-bad{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .sc-step-nm{font-size:.76rem;font-weight:600;color:var(--fg)}
.fig-live-ui .sc-step-ds{font-size:.7rem;color:var(--fg-muted);min-height:2.6em;overflow-wrap:anywhere}
.fig-live-ui .sc-panel{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .7rem;border:1px dashed var(--bd);border-radius:var(--r-sm)}
.fig-live-ui .sc-panel-hd{font-size:.72rem;color:var(--fg-subtle);text-transform:uppercase;letter-spacing:.04em}
.fig-live-ui .sc-cols{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.45rem}
.fig-live-ui .sc-col{display:flex;flex-direction:column;gap:.25rem;min-width:0}
.fig-live-ui .sc-col-hd{font-size:.72rem;font-weight:600;color:var(--fg-muted)}
.fig-live-ui .sc-col-bd{display:flex;flex-direction:column;gap:.2rem;min-height:4.4rem}
.fig-live-ui .sc-line{font-family:'JetBrains Mono',monospace;font-size:.72rem;color:var(--fg);padding:.1rem .35rem;border-radius:3px;border:1px solid var(--bd);background:var(--bg-surf);overflow-wrap:break-word;font-variant-ligatures:none}
.fig-live-ui .sc-line.is-muted{color:var(--fg-subtle);border-style:dashed;background:transparent}
.fig-live-ui .sc-line.is-new{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .sc-line.is-gone{color:var(--fg-subtle);text-decoration:line-through;border-style:dashed;background:transparent}
.fig-live-ui .sc-verdict{font-size:.82rem;font-weight:600;color:var(--fg-muted)}
.fig-live-ui .sc-verdict.is-ok{color:var(--c-ok)}
.fig-live-ui .sc-verdict.is-bad{color:var(--c-err)}
.fig-live-ui .sc-live{min-height:4.4em}
@media(max-width:640px){.fig-live-ui .sc-panel{padding:.5rem .45rem}.fig-live-ui .sc-steps{grid-template-columns:repeat(2,minmax(0,1fr))}.fig-live-ui .sc-cols{gap:.3rem}.fig-live-ui .sc-line{font-size:.6rem;padding:.1rem .15rem}.fig-live-ui .sc-live{min-height:7.2em}}
/* pagewalk (APIs for Beginners, Pagination): the static figure's .fig-flow with
   .is-now on the step the walk is at, a strip of Tandem's stations coloured by the
   page that fetched them (a row of 50 is one page at limit=50; 25 a row on phones),
   the last request and its envelope, a two-dialect tally and the request log. */
.fig-live-ui .sd-flow .flow-step.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .sd-flow .flow-step.ok{border-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .sd-flow .flow-step.fail{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .sd-head{font-size:.78rem;color:var(--fg-muted)}
.fig-live-ui .sd-strip{display:grid;grid-template-columns:repeat(50,minmax(0,1fr));gap:2px;max-width:760px}
.fig-live-ui .sd-c{display:block;aspect-ratio:1;border-radius:2px;background:var(--bg-surf);box-shadow:inset 0 0 0 1px var(--bd)}
.fig-live-ui .sd-c.is-odd{background:var(--ac);box-shadow:none}
.fig-live-ui .sd-c.is-even{background:color-mix(in srgb,var(--ac) 45%,var(--bg-surf));box-shadow:none}
.fig-live-ui .sd-c.is-dup{background:var(--c-err);box-shadow:none}
.fig-live-ui .sd-c.is-miss{background:var(--c-err-bg);box-shadow:inset 0 0 0 2px var(--c-err)}
.fig-live-ui .sd-c.is-new{outline:2px solid var(--c-warn);outline-offset:-2px}
.fig-live-ui .sd-c.is-last{box-shadow:0 0 0 1px var(--fg)}
.fig-live-ui .sd-legend{display:flex;flex-wrap:wrap;gap:.3rem .9rem;font-size:.72rem;color:var(--fg-muted)}
.fig-live-ui .sd-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .sd-key .sd-c{width:11px;height:11px;flex:none}
.fig-live-ui .sd-wire{display:flex;flex-direction:column;gap:.2rem;min-height:3.6rem;padding:.5rem .7rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);font-family:'JetBrains Mono',monospace;font-size:.76rem;line-height:1.45;overflow-wrap:anywhere}
.fig-live-ui .sd-q{color:var(--fg);font-weight:500}
.fig-live-ui .sd-a{color:var(--fg-muted)}
.fig-live-ui .sd-live{min-height:3.2em}
.fig-live-ui .sd-tally{display:flex;flex-direction:column;gap:.2rem;font-size:.78rem;max-width:30rem}
.fig-live-ui .sd-tr{display:grid;grid-template-columns:minmax(0,1.6fr) repeat(4,minmax(0,1fr));gap:.4rem;color:var(--fg-muted);font-family:'JetBrains Mono',monospace}
.fig-live-ui .sd-tr.wl-th{font-family:inherit;font-size:.66rem;letter-spacing:.02em}
.fig-live-ui .sd-tr.is-view{color:var(--fg);font-weight:600}
.fig-live-ui .sd-log{margin:0;padding:.4rem .6rem;list-style:none;max-height:9.5rem;overflow-y:auto;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);font-family:'JetBrains Mono',monospace;font-size:.72rem;line-height:1.5}
.fig-live-ui .sd-log li{padding-left:.5rem;border-left:3px solid transparent;overflow-wrap:anywhere;color:var(--fg)}
.fig-live-ui .sd-log .sd-rq.is-odd{border-left-color:var(--ac)}
.fig-live-ui .sd-log .sd-rq.is-even{border-left-color:color-mix(in srgb,var(--ac) 45%,var(--bg-surf))}
.fig-live-ui .sd-log .sd-ev{color:var(--c-warn)}
@media(max-width:640px){
.fig-live-ui .sd-flow{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.35rem}
.fig-live-ui .sd-flow .flow-arrow{display:none}
.fig-live-ui .sd-flow .flow-step{max-width:none;padding:.5rem .4rem}
.fig-live-ui .sd-strip{grid-template-columns:repeat(25,minmax(0,1fr))}
.fig-live-ui .sd-live{min-height:6.2em}
.fig-live-ui .sd-wire{min-height:5rem}
}
.fig-live-ui .sd-log .sd-idle{color:var(--fg-subtle)}
/* ratelimit (APIs for Beginners, Rate Limits): the static figure's .fig-flow with
   .is-now on the step Vera is at, the clock and the minute it sits in, the
   X-RateLimit-Remaining gauge (one cell a request; a nudge at 12, a warning at 3),
   the last response's headers as the page prints them, and the response log. */
.fig-live-ui .se-flow .flow-step.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .se-flow .flow-step.ok{border-color:var(--c-ok)}
.fig-live-ui .se-flow .flow-step.fail{border-color:var(--c-err)}
.fig-live-ui .se-flow .flow-step.fail.is-now{background:var(--c-err-bg)}
.fig-live-ui .se-flow .flow-step.ok.is-now{background:var(--c-ok-bg)}
.fig-live-ui .se-clock{display:flex;align-items:center;flex-wrap:wrap;gap:.4rem .7rem;font-size:.78rem;color:var(--fg-muted)}
.fig-live-ui .se-time{font-family:'JetBrains Mono',monospace;font-size:.95rem;font-weight:600;color:var(--fg);min-width:8.5ch}
.fig-live-ui .se-win{position:relative;flex:1 1 8rem;min-width:6rem;max-width:16rem;height:8px;border-radius:4px;background:var(--bg-surf);box-shadow:inset 0 0 0 1px var(--bd);overflow:hidden}
.fig-live-ui .se-winfill{position:absolute;left:0;top:0;bottom:0;background:var(--fg-subtle)}
.fig-live-ui .se-wintxt{flex:1 1 14rem;min-width:0}
.fig-live-ui .se-ghead{font-family:'JetBrains Mono',monospace;font-size:.8rem;color:var(--fg)}
.fig-live-ui .se-ghead.is-nudge{color:var(--c-warn)}
.fig-live-ui .se-ghead.is-warn,.fig-live-ui .se-ghead.is-empty{color:var(--c-err)}
.fig-live-ui .se-gauge{display:grid;gap:1px;height:20px}
.fig-live-ui .se-cell{display:block;border-radius:1px;background:var(--bg-surf);box-shadow:inset 0 0 0 1px var(--bd)}
.fig-live-ui .se-cell.is-on{background:var(--c-ok);box-shadow:none}
.fig-live-ui .se-cell.is-on.is-nudge{background:var(--c-warn)}
.fig-live-ui .se-cell.is-on.is-warn{background:var(--c-err)}
.fig-live-ui .se-hdrs{margin:0;min-height:6.4em;padding:.5rem .7rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);font-family:'JetBrains Mono',monospace;font-size:.75rem;line-height:1.3;color:var(--fg);white-space:pre-wrap;overflow-wrap:anywhere}
.fig-live-ui .se-hdrs.is-err{border-color:var(--c-err)}
.fig-live-ui .se-live{min-height:3.2em}
.fig-live-ui .se-counts{font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .se-log{margin:0;padding:.4rem .6rem;list-style:none;height:9.5rem;overflow-y:auto;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);font-family:'JetBrains Mono',monospace;font-size:.72rem;line-height:1.5}
.fig-live-ui .se-log li{padding-left:.5rem;border-left:3px solid transparent;overflow-wrap:anywhere;color:var(--fg-muted)}
.fig-live-ui .se-log .se-rs.is-ok{border-left-color:var(--c-ok);color:var(--fg)}
.fig-live-ui .se-log .se-rs.is-err{border-left-color:var(--c-err);color:var(--fg)}
.fig-live-ui .se-log .se-rs.is-wasted{color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .se-log .se-oth{border-left-color:var(--fg-subtle);color:var(--fg-subtle)}
.fig-live-ui .se-choice button:disabled,.fig-live-ui .se-choice button:disabled:hover{opacity:.5;cursor:default;border-color:var(--bd);color:var(--fg-muted)}
@media(max-width:640px){
.fig-live-ui .se-flow{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.35rem}
.fig-live-ui .se-flow .flow-arrow{display:none}
.fig-live-ui .se-flow .flow-step{max-width:none;padding:.5rem .4rem}
.fig-live-ui .se-live{min-height:5.8em}
}
/* cacheage (APIs for Beginners, caching basics): the figure's four steps with an age bar under each ask, a five-minute timeline */
.fig-live-ui .sf-flow{flex-wrap:nowrap}
.fig-live-ui .sf-flow .flow-step{flex:1 1 0;min-width:0;max-width:none;padding:.6rem .45rem;justify-content:flex-start}
.fig-live-ui .sf-flow .flow-arrow{padding:0}
.fig-live-ui .sf-flow .flow-step.ok{border-color:var(--c-ok)}
.fig-live-ui .sf-flow .flow-step.sf-copy{border-color:var(--ac)}
.fig-live-ui .sf-age{display:flex;flex-direction:column;align-items:stretch;gap:.2rem;width:100%;margin-top:auto}
.fig-live-ui .sf-agetrack{display:block;height:6px;border-radius:3px;background:var(--bg-surf);border:1px solid var(--bd);overflow:hidden}
.fig-live-ui .sf-agefill{display:block;height:100%;background:var(--ac)}
.fig-live-ui .sf-agefill.is-over{background:var(--c-err)}
.fig-live-ui .sf-agelab{display:block;min-height:1.9em;font-family:'JetBrains Mono',monospace;font-size:.62rem;line-height:1.3;color:var(--fg-muted)}
.fig-live-ui .sf-tl{padding:0 7px}
.fig-live-ui .sf-track{position:relative;height:22px;border:1px solid var(--bd);border-radius:4px;background:var(--bg-surf)}
.fig-live-ui .sf-win{position:absolute;top:0;bottom:0;background:var(--ac-dim);border-left:2px solid var(--ac)}
.fig-live-ui .sf-dot{position:absolute;top:50%;width:12px;height:12px;border-radius:50%;border:2px solid var(--bg-surf);transform:translate(-50%,-50%);box-sizing:border-box}
.fig-live-ui .sf-dot.is-copy{background:var(--ac)}
.fig-live-ui .sf-dot.is-fetch{background:var(--c-ok)}
.fig-live-ui .sf-clock{position:absolute;top:-4px;bottom:-4px;width:0;border-left:2px solid var(--fg);margin-left:-1px}
.fig-live-ui .sf-axis{position:relative;height:1rem;margin:0 7px;font-size:.68rem;font-family:'JetBrains Mono',monospace;color:var(--fg-subtle)}
.fig-live-ui .sf-axis span{position:absolute;top:0;transform:translateX(-50%);white-space:nowrap}
.fig-live-ui .sf-axis span.is-first{transform:none}
.fig-live-ui .sf-axis span.is-last{transform:translateX(-100%)}
.fig-live-ui .sf-legend{display:flex;flex-wrap:wrap;gap:.3rem 1rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .sf-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .sf-key::before{content:"";flex:none;width:.7rem;height:.7rem;border-radius:50%;background:var(--ac)}
.fig-live-ui .sf-key-fetch::before{background:var(--c-ok)}
.fig-live-ui .sf-key-win::before{width:1.1rem;height:.6rem;border-radius:2px;background:var(--ac-dim);box-shadow:inset 2px 0 0 var(--ac)}
.fig-live-ui .sf-count{font-size:.8rem;color:var(--fg-muted);min-height:1.55em}
.fig-live-ui .sf-live{min-height:4.1rem}
.fig-live-ui .sf-run .wl-btn:disabled{opacity:.45;cursor:default}
@media(max-width:640px){.fig-live-ui .sf-flow{flex-wrap:wrap}.fig-live-ui .sf-flow .flow-step{flex:1 1 100%;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:baseline;gap:.2rem .6rem;padding:.4rem .7rem;text-align:left}.fig-live-ui .sf-flow .flow-step .ds{text-align:right}.fig-live-ui .sf-flow .flow-arrow{font-size:.9rem;padding:0}.fig-live-ui .sf-age{flex-basis:100%}.fig-live-ui .sf-agelab{min-height:0}.fig-live-ui .sf-live{min-height:6.2rem}}
/* polling (APIs for Beginners, polling and webhooks): the loop or the two columns, four number tiles, the 60-a-minute budget bar, a one-ride timeline */
.fig-live-ui .sg-flow{flex-wrap:nowrap}
.fig-live-ui .sg-flow .flow-step{flex:1 1 0;min-width:0;max-width:none;padding:.6rem .45rem}
.fig-live-ui .sg-flow .flow-arrow{padding:0}
.fig-live-ui .sg-flow .flow-step.ok{border-color:var(--c-ok)}
.fig-live-ui .sg-cols{margin:0}
.fig-live-ui .sg-cols .fig-col-hd .nm{color:var(--fg)}
.fig-live-ui .sg-cols .fig-col-cap{color:var(--fg-muted);min-height:4.4em}
.fig-live-ui .sg-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.5rem}
.fig-live-ui .sg-tile{display:flex;flex-direction:column;gap:.1rem;padding:.5rem .6rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);min-width:0}
.fig-live-ui .sg-v{font-family:'JetBrains Mono',monospace;font-size:1.05rem;font-weight:700;color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .sg-l{font-size:.72rem;color:var(--fg-muted)}
.fig-live-ui .sg-sub{font-size:.66rem;color:var(--fg-subtle)}
.fig-live-ui .sg-budget{display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .sg-blab{font-size:.8rem;color:var(--fg-muted)}
.fig-live-ui .sg-btrack{height:10px;border:1px solid var(--bd);border-radius:5px;background:var(--bg-surf);overflow:hidden}
.fig-live-ui .sg-bfill{display:block;height:100%;min-width:2px;background:var(--ac)}
.fig-live-ui .sg-budget.is-full .sg-bfill{background:var(--c-warn)}
.fig-live-ui .sg-budget.is-over .sg-bfill{background:var(--c-err)}
.fig-live-ui .sg-budget.is-over .sg-blab{color:var(--c-err);font-weight:600}
.fig-live-ui .sg-hook{font-size:.8rem;color:var(--fg-muted);border-left:3px solid var(--c-ok);padding-left:.6rem}
.fig-live-ui .sg-tl{display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .sg-tlrow{display:grid;grid-template-columns:4.6rem minmax(0,1fr);gap:.5rem;align-items:stretch}
.fig-live-ui .sg-labs{display:flex;flex-direction:column;justify-content:space-around;font-size:.7rem;font-family:'JetBrains Mono',monospace;color:var(--fg-muted);text-align:right}
.fig-live-ui .sg-svg{display:block;width:100%;height:44px}
.fig-live-ui .sg-lane{fill:var(--bg-surf);stroke:none}
.fig-live-ui .sg-ride{fill:var(--ac);fill-opacity:.22;stroke:none}
.fig-live-ui .sg-poll{fill:none;stroke:var(--fg-subtle);stroke-width:1.5}
.fig-live-ui .sg-hit{fill:none;stroke:var(--c-ok);stroke-width:3}
.fig-live-ui .sg-hookmk{fill:none;stroke:var(--c-ok);stroke-width:4}
.fig-live-ui .sg-end{fill:none;stroke:var(--fg);stroke-width:1.5;stroke-dasharray:3 3}
.fig-live-ui .sg-clock{fill:none;stroke:var(--ac);stroke-width:2}
.fig-live-ui .sg-axis{display:flex;justify-content:space-between;gap:.5rem;white-space:nowrap;margin-left:5.1rem;font-size:.68rem;font-family:'JetBrains Mono',monospace;color:var(--fg-subtle)}
.fig-live-ui .sg-axis .sg-now{color:var(--fg)}
.fig-live-ui .sg-legend{display:flex;flex-wrap:wrap;gap:.3rem 1rem;font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .sg-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .sg-key::before{content:"";flex:none;width:1.1rem;height:.6rem;border-radius:2px;background:var(--ac);opacity:.3}
.fig-live-ui .sg-key-poll::before,.fig-live-ui .sg-key-hit::before,.fig-live-ui .sg-key-hook::before{opacity:1;width:0;height:.9rem;border-radius:0;background:none;border-left:2px solid var(--fg-subtle)}
.fig-live-ui .sg-key-hit::before{border-left:3px solid var(--c-ok)}
.fig-live-ui .sg-key-hook::before{border-left:4px solid var(--c-ok)}
.fig-live-ui .sg-live{min-height:4.1rem}
@media(max-width:640px){.fig-live-ui .sg-flow{flex-wrap:wrap}.fig-live-ui .sg-flow .flow-step{flex:1 1 100%;flex-direction:row;justify-content:space-between;gap:.6rem;padding:.4rem .7rem;text-align:left}.fig-live-ui .sg-flow .flow-step .ds{text-align:right}.fig-live-ui .sg-flow .flow-arrow{font-size:.9rem;padding:0}.fig-live-ui .sg-cols .fig-col{flex-basis:100%}.fig-live-ui .sg-cols .fig-col-cap{min-height:0}.fig-live-ui .sg-stats{grid-template-columns:repeat(2,minmax(0,1fr))}.fig-live-ui .sg-tlrow{grid-template-columns:3.9rem minmax(0,1fr);gap:.4rem}.fig-live-ui .sg-axis{margin-left:4.3rem}.fig-live-ui .sg-live{min-height:6.2rem}}
/* APIs for Beginners widget webhookdup: the figure's own .fig-flow of four boxes
   (.is-wait not reached yet, .is-now the current step, .is-ok / .is-bad how it
   ended, .is-idle a step that did not happen), the reconcile line, four counters,
   the office's seen ids, and the random day's strip of rides coloured by outcome. */
.fig-live-ui .sh-flow .flow-step{background:var(--bg-surf)}
.fig-live-ui .sh-flow .flow-step.is-ok{border-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .sh-flow .flow-step.is-bad{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .sh-flow .flow-step.is-idle{border-style:dashed;background:transparent}
.fig-live-ui .sh-flow .flow-step.is-now{box-shadow:0 0 0 2px var(--ac)}
.fig-live-ui .sh-flow .flow-step.is-wait{opacity:.4;border-color:var(--bd);background:transparent}
.fig-live-ui .sh-flow .nm{color:var(--fg)}
.fig-live-ui .sh-flow .ds{color:var(--fg-muted)}
.fig-live-ui .sh-time{font-family:'JetBrains Mono',monospace;font-size:.64rem;color:var(--fg-subtle);font-variant-ligatures:none}
.fig-live-ui .sh-rec{font-size:.78rem;color:var(--fg-muted);min-height:2.6em}
.fig-live-ui .sh-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.45rem}
.fig-live-ui .sh-stat{display:flex;flex-direction:column;gap:.15rem;padding:.45rem .6rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);min-width:0}
.fig-live-ui .sh-k{font-size:.66rem;color:var(--fg-subtle);text-transform:uppercase;letter-spacing:.04em}
.fig-live-ui .sh-v{font-family:'JetBrains Mono',monospace;font-size:.9rem;color:var(--fg)}
.fig-live-ui .sh-v.is-bad{color:var(--c-err);font-weight:700}
.fig-live-ui .sh-seen{font-family:'JetBrains Mono',monospace;font-size:.74rem;color:var(--fg-muted);min-height:1.5em;overflow-wrap:anywhere;font-variant-ligatures:none}
.fig-live-ui .sh-day{display:flex;flex-direction:column;gap:.4rem}
.fig-live-ui .sh-dayhead{font-size:.76rem;color:var(--fg-muted)}
.fig-live-ui .sh-strip{display:grid;grid-template-columns:repeat(15,minmax(0,1fr));gap:3px}
.fig-live-ui .sh-cell{min-height:1.3rem;border-radius:3px;border:1px dashed var(--bd);background:transparent}
.fig-live-ui .sh-legend{display:flex;flex-wrap:wrap;gap:.3rem .8rem;font-size:.7rem;color:var(--fg-muted)}
.fig-live-ui .sh-key{display:inline-flex;align-items:center;gap:.3rem}
.fig-live-ui .sh-key::before{content:"";display:inline-block;width:.8rem;height:.8rem;border-radius:3px;border:1px solid var(--bd)}
.fig-live-ui .sh-c-ok,.fig-live-ui .sh-key.sh-c-ok::before{border:1px solid var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .sh-c-caught,.fig-live-ui .sh-key.sh-c-caught::before{border:1px solid var(--c-ok);background:var(--c-ok)}
.fig-live-ui .sh-c-doubled,.fig-live-ui .sh-key.sh-c-doubled::before{border:1px solid var(--c-err);background:var(--c-err)}
.fig-live-ui .sh-c-missed,.fig-live-ui .sh-key.sh-c-missed::before{border:1px dashed var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .sh-c-recovered,.fig-live-ui .sh-key.sh-c-recovered::before{border:1px solid var(--c-warn);background:var(--c-warn-bg)}
.fig-live-ui .sh-key.sh-c-ok,.fig-live-ui .sh-key.sh-c-caught,.fig-live-ui .sh-key.sh-c-doubled,.fig-live-ui .sh-key.sh-c-missed,.fig-live-ui .sh-key.sh-c-recovered{border:0;background:none}
.fig-live-ui .sh-toggles .wl-chip{text-align:left}
.fig-live-ui .sh-live{min-height:4.4em}
.fig-live-ui .sh-live.is-bad{color:var(--c-err)}
@media(max-width:640px){.fig-live-ui .sh-flow{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.4rem}.fig-live-ui .sh-flow .flow-arrow{display:none}.fig-live-ui .sh-flow .flow-step{max-width:none;padding:.55rem .4rem}.fig-live-ui .sh-stats{grid-template-columns:repeat(2,minmax(0,1fr))}.fig-live-ui .sh-strip{grid-template-columns:repeat(10,minmax(0,1fr))}.fig-live-ui .sh-live{min-height:8.8em}.fig-live-ui .sh-rec{min-height:4em}}
.fig-live-ui .sh-dayplay{min-width:8.5rem}
/* shellexp (Linux Deep Dive 3.03 / 3.06): the page's quoting table, then the line through expand, split, glob and quote removal. */
.fig-live-ui .ta-tblbox{overflow-x:auto;-webkit-overflow-scrolling:touch}
.fig-live-ui .ta-tbl{margin:0;width:100%}
.fig-live-ui .ta-tbl td,.fig-live-ui .ta-tbl th{padding:.45rem .55rem}
.fig-live-ui .ta-tbl tr.is-lit td{background:var(--ac-dim)}
.fig-live-ui .ta-tbl tr.is-lit td:first-child{box-shadow:inset 3px 0 0 var(--ac)}
.fig-live-ui .ta-tbl tr.is-lit td.is-col{font-weight:700;color:var(--fg);outline:2px solid var(--ac);outline-offset:-2px}
.fig-live-ui .ta-tbl th.is-col{color:var(--ac)}
.fig-live-ui .ta-forms .wl-chip,.fig-live-ui .ta-dir code{font-family:'JetBrains Mono',monospace;font-variant-ligatures:none}
.fig-live-ui .ta-in{font-family:'JetBrains Mono',monospace;font-size:.85rem;padding:.3rem .5rem;width:11rem;max-width:100%;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg);font-variant-ligatures:none}
.fig-live-ui .ta-in[aria-invalid="true"]{border-color:var(--c-err)}
.fig-live-ui .ta-typed,.fig-live-ui .ta-out{margin:0;padding:.55rem .75rem;border-radius:var(--r-sm);background:var(--bg-surf);border:1px solid var(--bd);font-family:'JetBrains Mono',monospace;font-size:.8rem;line-height:1.5;color:var(--fg);white-space:pre-wrap;overflow-wrap:anywhere;font-variant-ligatures:none}
.fig-live-ui .ta-ps{color:var(--fg-subtle)}
.fig-live-ui .ta-stages{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.4rem}
.fig-live-ui .ta-stage{border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);padding:.45rem .65rem;display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .ta-stage.is-now{border-color:var(--ac);box-shadow:inset 3px 0 0 var(--ac)}
.fig-live-ui .ta-stage.is-later{opacity:.5}
.fig-live-ui .ta-stage-hd{display:flex;justify-content:space-between;gap:.5rem;font-size:.78rem}
.fig-live-ui .ta-stage-nm{font-weight:700;color:var(--fg)}
.fig-live-ui .ta-stage-n{color:var(--fg-muted);font-family:'JetBrains Mono',monospace;font-size:.74rem}
.fig-live-ui .ta-words{display:flex;flex-wrap:wrap;gap:.35rem;min-height:1.7rem;align-items:center}
.fig-live-ui .ta-word{display:inline-block;font-family:'JetBrains Mono',monospace;font-size:.8rem;padding:.12rem .45rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-sb);color:var(--fg);white-space:pre-wrap;max-width:100%;overflow-wrap:anywhere;font-variant-ligatures:none}
.fig-live-ui .ta-word.is-cmd{color:var(--fg-muted);border-style:dashed}
.fig-live-ui .ta-word.is-final:not(.is-cmd){border-color:var(--ac)}
.fig-live-ui .ta-word.is-empty{font-family:inherit;font-style:italic;color:var(--fg-subtle)}
.fig-live-ui .ta-word.is-nomatch{border-color:var(--c-warn)}
.fig-live-ui .ta-syn{color:var(--fg-subtle)}
.fig-live-ui .ta-ref{color:var(--ac);font-weight:600}
.fig-live-ui .ta-x{background:var(--ac-dim)}
.fig-live-ui .ta-g{background:var(--c-ok-bg);color:var(--c-ok)}
.fig-live-ui .ta-none{color:var(--fg-subtle);font-size:.78rem}
.fig-live-ui .ta-why{font-size:.76rem;color:var(--fg-muted);min-height:2.5em}
.fig-live-ui .ta-argv{display:flex;flex-direction:column;gap:.4rem;min-height:4.6rem}
.fig-live-ui .ta-argv.is-later{opacity:.55}
.fig-live-ui .ta-argv-hd{font-size:.82rem;font-weight:600;color:var(--fg);overflow-wrap:anywhere}
.fig-live-ui .ta-effect{font-size:.78rem;color:var(--fg-muted)}
.fig-live-ui .ta-live{min-height:3.1em}
@media(max-width:640px){.fig-live-ui .ta-tbl td,.fig-live-ui .ta-tbl th{padding:.35rem .3rem;font-size:.74rem}.fig-live-ui .ta-tbl th{letter-spacing:0;font-size:.64rem;overflow-wrap:normal}.fig-live-ui .ta-tbl code{font-size:.68rem;padding:.05rem .2rem}}
/* permcheck (Linux Deep Dive 5, "Who gets which access"): the figure's three columns, the kernel's first-match walk. */
.fig-live-ui .tb-file{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem .55rem;padding:.5rem .7rem;border-radius:var(--r-sm);background:var(--bg-surf);border:1px solid var(--bd);font-family:'JetBrains Mono',monospace;font-size:.82rem;color:var(--fg);font-variant-ligatures:none}
.fig-live-ui .tb-mode{font-weight:700;color:var(--ac);letter-spacing:.04em}
.fig-live-ui .tb-f{color:var(--fg-muted)}
.fig-live-ui .tb-own{font-family:'JetBrains Mono',monospace;font-size:.8rem;padding:.12rem .55rem;border-style:dashed;color:var(--fg)}
.fig-live-ui .tb-in{font-family:'JetBrains Mono',monospace;font-size:.9rem;letter-spacing:.08em;padding:.3rem .5rem;width:5.5rem;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg)}
.fig-live-ui .tb-in[aria-invalid="true"]{border-color:var(--c-err)}
.fig-live-ui .tb-cols{margin:0}
.fig-live-ui .tb-cols .fig-col{background:var(--bg-surf);gap:.55rem;padding:.9rem .85rem}
.fig-live-ui .tb-cols .fig-col.is-now{border-color:var(--ac)}
.fig-live-ui .tb-cols .fig-col.is-picked{border-color:var(--ac);box-shadow:inset 0 3px 0 var(--ac);background:var(--ac-dim)}
.fig-live-ui .tb-cols .fig-col.is-off{opacity:.5}
.fig-live-ui .tb-bits{display:flex;gap:.35rem}
.fig-live-ui .tb-bit{font-family:'JetBrains Mono',monospace;font-size:.85rem;min-width:2.3rem;padding:.25rem .5rem;border-radius:var(--r-sm)}
.fig-live-ui .tb-bit[aria-pressed="true"]{color:var(--fg);font-weight:700}
.fig-live-ui .tb-bit[aria-pressed="false"]{color:var(--fg-subtle);text-decoration:line-through}
.fig-live-ui .tb-q{font-size:.76rem;color:var(--fg);min-height:2.4em}
.fig-live-ui .tb-state{font-size:.76rem;font-weight:700;color:var(--fg-muted);min-height:1.3em}
.fig-live-ui .fig-col.is-picked .tb-state{color:var(--ac)}
.fig-live-ui .tb-answer{display:flex;flex-direction:column;gap:.4rem;min-height:3.6rem}
.fig-live-ui .tb-answer.is-later{opacity:.55}
.fig-live-ui .tb-ans-hd{font-size:.82rem;font-weight:600;color:var(--fg)}
.fig-live-ui .tb-ans-bits{display:flex;flex-wrap:wrap;gap:.4rem}
.fig-live-ui .tb-ans{font-size:.8rem;padding:.2rem .65rem;border-radius:var(--r-pill);border:1px solid var(--bd);color:var(--fg-muted)}
.fig-live-ui .tb-ans.is-ok{background:var(--c-ok-bg);color:var(--c-ok);border-color:var(--c-ok)}
.fig-live-ui .tb-ans.is-no{background:var(--c-err-bg);color:var(--c-err);border-color:var(--c-err)}
.fig-live-ui .tb-live{min-height:3.1em}
@media(max-width:640px){.fig-live-ui .tb-cols .fig-col{padding:.7rem .75rem}.fig-live-ui .tb-q{min-height:0}}
/* aclmask (tc-): the ACL mask table, Linux Deep Dive 5 */
.fig-live-ui .tc-tblbox{overflow-x:auto;-webkit-overflow-scrolling:touch}
.fig-live-ui .tc-tbl{margin:0;width:100%}
.fig-live-ui .tc-tbl td,.fig-live-ui .tc-tbl th{padding:.45rem .55rem;vertical-align:middle}
.fig-live-ui .tc-tbl tr.is-lit td{background:var(--c-warn-bg)}
.fig-live-ui .tc-tbl tr.is-lit td:first-child{box-shadow:inset 3px 0 0 var(--c-warn)}
.fig-live-ui .tc-tbl tr.is-lit td:last-child code{color:var(--c-warn);font-weight:700}
.fig-live-ui .tc-bits{display:inline-flex;gap:.2rem;white-space:nowrap}
.fig-live-ui .tc-bit{font-family:'JetBrains Mono',monospace;font-size:.85rem;font-weight:600;width:1.9rem;height:1.9rem;padding:0;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg-subtle);cursor:pointer;font-variant-ligatures:none}
.fig-live-ui .tc-bit[aria-pressed="true"]{border-color:var(--ac);background:var(--ac-dim);color:var(--fg)}
.fig-live-ui .tc-bit.is-clipped{border-color:var(--c-warn);color:var(--c-warn);text-decoration:line-through}
.fig-live-ui .tc-bit:hover{border-color:var(--ac)}
.fig-live-ui .tc-rest{display:flex;flex-direction:column;gap:.4rem;padding:.55rem .7rem;border:1px dashed var(--bd);border-radius:var(--r-sm)}
.fig-live-ui .tc-entry{display:grid;grid-template-columns:6.5rem auto 3.2rem minmax(0,1fr);align-items:center;gap:.3rem .6rem}
.fig-live-ui .tc-tag{font-family:'JetBrains Mono',monospace;font-size:.8rem;color:var(--fg);background:none;border:0;padding:0}
.fig-live-ui .tc-out{font-family:'JetBrains Mono',monospace;font-size:.8rem;color:var(--c-warn);font-weight:700;white-space:nowrap}
.fig-live-ui .tc-hint{font-size:.74rem;color:var(--fg-subtle)}
.fig-live-ui .tc-cmd{font-family:'JetBrains Mono',monospace;font-size:.76rem;font-variant-ligatures:none}
.fig-live-ui .tc-live{min-height:4.7em}
.fig-live-ui .tc-term{margin:0;padding:.65rem .8rem;border-radius:var(--r-sm);background:var(--bg-surf);border:1px solid var(--bd);font-family:'JetBrains Mono',monospace;font-size:.76rem;line-height:1.5;color:var(--fg);white-space:pre;tab-size:8;-moz-tab-size:8;overflow-x:auto;min-height:calc(15 * 1.5em + 1.3rem);font-variant-ligatures:none}
@media(max-width:640px){.fig-live-ui .tc-tbl td,.fig-live-ui .tc-tbl th{padding:.4rem .25rem;font-size:.74rem}.fig-live-ui .tc-tbl th{letter-spacing:0;font-size:.62rem}.fig-live-ui .tc-bits{gap:.12rem}.fig-live-ui .tc-bit{width:1.45rem;height:1.8rem;font-size:.76rem}.fig-live-ui .tc-tbl code{font-size:.68rem;padding:.05rem .15rem}.fig-live-ui .tc-entry{grid-template-columns:4.6rem auto 2.6rem minmax(0,1fr);gap:.3rem .4rem}.fig-live-ui .tc-tag,.fig-live-ui .tc-out{font-size:.72rem}.fig-live-ui .tc-hint{font-size:.66rem}.fig-live-ui .tc-rest{padding:.5rem .5rem}.fig-live-ui .tc-term{margin:0 -.55rem;font-size:.6rem;padding:.5rem .4rem}.fig-live-ui .tc-live{min-height:9.4em}}
/* inodes (td-): names -> inodes -> data blocks, Linux Deep Dive 2 */
.fig-live-ui .td-tblbox{overflow-x:auto;-webkit-overflow-scrolling:touch}
.fig-live-ui .td-tbl{margin:0;width:100%}
.fig-live-ui .td-tbl td,.fig-live-ui .td-tbl th{padding:.45rem .55rem}
.fig-live-ui .td-tbl tr.is-lit td{background:var(--ac-dim)}
.fig-live-ui .td-tbl tr.is-lit td:first-child{box-shadow:inset 3px 0 0 var(--ac)}
.fig-live-ui .td-tbl tr.is-lit td.td-cell-on{font-weight:700;color:var(--fg)}
.fig-live-ui .td-graph{display:flex;flex-direction:column;gap:.4rem;min-height:9.5rem}
.fig-live-ui .td-row{display:grid;grid-template-columns:minmax(0,1fr) 1.2rem minmax(0,1fr) 1.2rem minmax(0,1.1fr);gap:.35rem;align-items:stretch}
.fig-live-ui .td-hd{font-size:.7rem;color:var(--fg-subtle);text-transform:uppercase;letter-spacing:.04em}
.fig-live-ui .td-names{display:flex;flex-direction:column;justify-content:center;gap:.25rem;min-width:0}
.fig-live-ui .td-name{font-family:'JetBrains Mono',monospace;font-size:.74rem;color:var(--fg);padding:.15rem .4rem;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);overflow-wrap:anywhere;font-variant-ligatures:none}
.fig-live-ui .td-name.is-bad{border-color:var(--c-err);color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .td-none{font-size:.72rem;color:var(--fg-subtle);font-style:italic}
.fig-live-ui .td-arrow{display:flex;align-items:center;justify-content:center;color:var(--fg-subtle)}
.fig-live-ui .td-inode,.fig-live-ui .td-data{display:flex;flex-direction:column;justify-content:center;gap:.1rem;min-width:0;padding:.35rem .5rem;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf)}
.fig-live-ui .td-k{font-family:'JetBrains Mono',monospace;font-size:.74rem;color:var(--fg);overflow-wrap:anywhere;font-variant-ligatures:none}
.fig-live-ui .td-v{font-size:.72rem;color:var(--fg-muted);overflow-wrap:anywhere}
.fig-live-ui .td-open{font-size:.72rem;font-weight:600;color:var(--c-warn)}
.fig-live-ui .td-row.is-touched .td-inode{border-color:var(--ac);box-shadow:inset 0 0 0 1px var(--ac)}
.fig-live-ui .td-row.is-held .td-inode,.fig-live-ui .td-row.is-held .td-data{border-color:var(--c-warn);background:var(--c-warn-bg)}
.fig-live-ui .td-row.is-bad .td-data{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .td-row.is-bad .td-data .td-v{color:var(--c-err);font-weight:600}
.fig-live-ui .td-row.is-freed .td-inode,.fig-live-ui .td-row.is-freed .td-data{border-style:dashed;background:transparent;box-shadow:none}
.fig-live-ui .td-row.is-freed .td-k,.fig-live-ui .td-row.is-freed .td-v{color:var(--fg-subtle)}
.fig-live-ui .td-row.is-freed .td-data .td-k{text-decoration:line-through}
.fig-live-ui .td-live{min-height:4.7em}
.fig-live-ui .td-term{margin:0;padding:.6rem .8rem;border-radius:var(--r-sm);background:var(--bg-surf);border:1px solid var(--bd);font-family:'JetBrains Mono',monospace;font-size:.74rem;line-height:1.5;color:var(--fg);white-space:pre;overflow:auto;height:calc(8 * 1.5em + 1.2rem);font-variant-ligatures:none}
.fig-live-ui .td-seq{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:.3rem}
.fig-live-ui .td-seq-step{font-family:'JetBrains Mono',monospace;font-size:.72rem;padding:.15rem .5rem;border-radius:var(--r-pill);border:1px solid var(--bd);color:var(--fg-subtle);font-variant-ligatures:none}
.fig-live-ui .td-seq-step.is-done{color:var(--fg-muted);border-color:var(--fg-subtle)}
.fig-live-ui .td-seq-step.is-now{color:var(--fg);border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .td-seq.is-off .td-seq-step{opacity:.55}
.fig-live-ui .td-cmd{font-family:'JetBrains Mono',monospace;font-size:.74rem;font-variant-ligatures:none}
.fig-live-ui .td-cmds{gap:.4rem}
@media(max-width:640px){.fig-live-ui .td-tbl td,.fig-live-ui .td-tbl th{padding:.4rem .35rem;font-size:.76rem}.fig-live-ui .td-tbl th{letter-spacing:0;font-size:.66rem}.fig-live-ui .td-row{grid-template-columns:minmax(0,1fr) .8rem minmax(0,1fr) .8rem minmax(0,1fr);gap:.2rem}.fig-live-ui .td-inode,.fig-live-ui .td-data{padding:.3rem .35rem}.fig-live-ui .td-k,.fig-live-ui .td-name{font-size:.68rem}.fig-live-ui .td-v,.fig-live-ui .td-open{font-size:.66rem}.fig-live-ui .td-name{padding:.1rem .25rem}.fig-live-ui .td-term{font-size:.66rem;padding:.55rem .5rem;white-space:pre-wrap;overflow-wrap:anywhere}.fig-live-ui .td-graph{min-height:12rem}.fig-live-ui .td-live{min-height:7.8em}}
/* Linux Deep Dive widget procstate: the page's table (process states, or signals) with the row
   of what just happened lit, a ps --forest listing whose rows are the tap targets, a busy-minute
   strip of the zombie count, and the process / signal / run controls.
   .is-lit is the row of the state or signal just shown; .is-also the SIGCHLD the parent got;
   .te-st-X colours a process by its state letter; .is-moved marks a PPID that just became 1. */
.fig-live-ui .te-tblbox{overflow-x:auto;-webkit-overflow-scrolling:touch}
.fig-live-ui .te-tbl{margin:0;width:100%}
.fig-live-ui .te-tbl td,.fig-live-ui .te-tbl th{padding:.45rem .55rem}
.fig-live-ui .te-tbl tr.is-lit td{background:var(--ac-dim)}
.fig-live-ui .te-tbl tr.is-lit td:first-child{box-shadow:inset 3px 0 0 var(--ac)}
.fig-live-ui .te-tbl tr.is-also td:first-child{box-shadow:inset 3px 0 0 var(--c-warn)}
.fig-live-ui .te-lineage{font-family:'JetBrains Mono',monospace;font-size:.72rem;color:var(--fg-muted);overflow-wrap:anywhere;font-variant-ligatures:none}
.fig-live-ui .te-psbox{border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);padding:.5rem .6rem 0;font-family:'JetBrains Mono',monospace;font-size:.74rem;line-height:1.45;font-variant-ligatures:none}
.fig-live-ui .te-psscroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.fig-live-ui .te-ps{display:flex;flex-direction:column;min-width:max-content;padding-bottom:.5rem}
.fig-live-ui .te-pscmd{color:var(--fg-muted);overflow-wrap:anywhere;padding:0 .3rem}
.fig-live-ui .te-psline{white-space:pre;color:var(--fg)}
.fig-live-ui .te-pshead{color:var(--fg-subtle);padding:0 .3rem}
.fig-live-ui .te-psrows{display:flex;flex-direction:column;gap:.1rem;min-height:9.5em;max-height:18em;overflow-y:auto}
.fig-live-ui .te-psrow{font:inherit;display:flex;flex-wrap:wrap;align-items:baseline;column-gap:1rem;text-align:left;padding:.05rem .3rem;border:1px solid transparent;border-radius:4px;background:transparent;color:var(--fg);cursor:pointer}
.fig-live-ui .te-psrow:hover{border-color:var(--bd)}
.fig-live-ui .te-psrow.is-sel{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .te-psrow.te-st-Z .te-psline{color:var(--c-err)}
.fig-live-ui .te-psrow.te-st-D .te-psline,.fig-live-ui .te-psrow.te-st-T .te-psline{color:var(--c-warn)}
.fig-live-ui .te-psrow.is-moved .te-psline{color:var(--c-ok)}
.fig-live-ui .te-why{font-family:system-ui,sans-serif;font-size:.7rem;color:var(--fg-muted)}
.fig-live-ui .te-psrow.te-st-Z .te-why{color:var(--c-err)}
.fig-live-ui .te-empty{color:var(--fg-subtle);padding:0 .3rem}
.fig-live-ui .te-busy{display:flex;flex-direction:column;gap:.35rem}
.fig-live-ui .te-clock{font-size:.76rem;color:var(--fg-muted)}
.fig-live-ui .te-strip{display:flex;align-items:flex-end;gap:1px;height:2.6rem;border-bottom:1px solid var(--bd)}
.fig-live-ui .te-bar{flex:1 1 0;min-width:0;background:var(--c-err);border-radius:1px 1px 0 0}
.fig-live-ui .te-bar.is-empty{background:var(--bd)}
.fig-live-ui .te-live{min-height:4.7em}
.fig-live-ui .te-log{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.1rem;min-height:5.6em;font-family:'JetBrains Mono',monospace;font-size:.7rem;color:var(--fg-subtle);font-variant-ligatures:none}
.fig-live-ui .te-log li{overflow-wrap:anywhere}
.fig-live-ui .te-log li.is-now{color:var(--fg)}
.fig-live-ui .te-ctl{gap:.4rem .5rem}
.fig-live-ui .te-lab{flex:1 0 100%}
.fig-live-ui .te-sig{font-family:'JetBrains Mono',monospace;font-size:.74rem}
@media(max-width:640px){.fig-live-ui .te-why{flex-basis:100%;padding-left:1.5rem}.fig-live-ui .te-psbox{font-size:.66rem;padding:.4rem .4rem 0}.fig-live-ui .te-tbl td,.fig-live-ui .te-tbl th{padding:.4rem .35rem;font-size:.76rem}.fig-live-ui .te-tbl th{text-transform:none;letter-spacing:0;font-size:.7rem}.fig-live-ui .te-tbl td:first-child code{font-size:.66rem}.fig-live-ui .te-live{min-height:7.4em}.fig-live-ui .te-log{min-height:7em}}
/* Linux Deep Dive widget tcpclose: the page's "Connection States" table with the rows of the
   states on screen lit, the two hosts' ss output side by side (stacked on a phone), the steps of
   one connection with a TIME_WAIT clock, and a churn chart of TIME_WAIT against CLOSE_WAIT.
   .is-bad marks the host whose app leaks CLOSE_WAIT. */
.fig-live-ui .tf-tblbox{overflow-x:auto;-webkit-overflow-scrolling:touch}
.fig-live-ui .tf-tbl{margin:0;width:100%}
.fig-live-ui .tf-tbl td,.fig-live-ui .tf-tbl th{padding:.45rem .55rem}
.fig-live-ui .tf-tbl tr.is-lit td{background:var(--ac-dim)}
.fig-live-ui .tf-tbl tr.is-lit td:first-child{box-shadow:inset 3px 0 0 var(--ac)}
.fig-live-ui .tf-hosts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.6rem}
.fig-live-ui .tf-host{display:flex;flex-direction:column;gap:.35rem;min-width:0;padding:.5rem .45rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-sb)}
.fig-live-ui .tf-host.is-bad{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .tf-host-hd{display:flex;flex-wrap:wrap;align-items:baseline;gap:.2rem .5rem}
.fig-live-ui .tf-host-nm{font-weight:700;color:var(--fg);font-size:.85rem;text-transform:capitalize}
.fig-live-ui .tf-host-ip{font-family:'JetBrains Mono',monospace;font-size:.72rem;color:var(--fg-muted);font-variant-ligatures:none}
.fig-live-ui .tf-term{border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);padding:.4rem .45rem;font-family:'JetBrains Mono',monospace;font-size:.64rem;line-height:1.45;font-variant-ligatures:none}
.fig-live-ui .tf-cmd{color:var(--fg-muted);overflow-wrap:anywhere}
.fig-live-ui .tf-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.fig-live-ui .tf-out{margin:0;padding:0;background:transparent;border:0;font:inherit;color:var(--fg);white-space:pre;min-height:4.35em}
.fig-live-ui .tf-host-note{font-size:.74rem;color:var(--fg-muted);min-height:2.6em}
.fig-live-ui .tf-host.is-bad .tf-host-note{color:var(--c-err)}
.fig-live-ui .tf-steps{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:.3rem}
.fig-live-ui .tf-step{font-size:.72rem;padding:.15rem .5rem;border-radius:var(--r-pill);border:1px solid var(--bd);color:var(--fg-subtle)}
.fig-live-ui .tf-step.is-done{color:var(--fg-muted)}
.fig-live-ui .tf-step.is-now{border-color:var(--ac);background:var(--ac-dim);color:var(--fg)}
.fig-live-ui .tf-clock{display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .tf-clock-txt{font-size:.78rem;color:var(--fg)}
.fig-live-ui .tf-clock.is-idle .tf-clock-txt{color:var(--fg-subtle)}
.fig-live-ui .tf-track{display:block;height:6px;border-radius:3px;background:var(--bd);overflow:hidden}
.fig-live-ui .tf-fill{display:block;height:100%;background:var(--c-warn)}
.fig-live-ui .tf-clock.is-bad .tf-fill{background:var(--c-err)}
.fig-live-ui .tf-clock.is-bad .tf-clock-txt{color:var(--c-err)}
.fig-live-ui .tf-chart svg{display:block;width:100%;height:150px;border-left:1px solid var(--bd);border-bottom:1px solid var(--bd)}
.fig-live-ui .tf-chart polyline{fill:none;stroke-width:2;vector-effect:non-scaling-stroke;stroke-linejoin:round}
.fig-live-ui .tf-tw{stroke:var(--c-warn)}
.fig-live-ui .tf-cw{stroke:var(--c-err)}
.fig-live-ui .tf-lim{stroke:var(--fg-subtle);stroke-dasharray:4 4}
.fig-live-ui .tf-axis{font-size:.7rem;color:var(--fg-subtle);margin-top:.25rem}
.fig-live-ui .tf-legend{display:flex;flex-wrap:wrap;gap:.3rem .9rem;font-size:.72rem;color:var(--fg-muted);margin-top:.2rem}
.fig-live-ui .tf-key::before{content:"";display:inline-block;width:14px;height:0;border-top:2px solid;vertical-align:middle;margin-right:.35rem}
.fig-live-ui .tf-key-tw::before{border-color:var(--c-warn)}
.fig-live-ui .tf-key-cw::before{border-color:var(--c-err)}
.fig-live-ui .tf-key-lim::before{border-top-style:dashed;border-color:var(--fg-subtle)}
.fig-live-ui .tf-live{min-height:4.7em}
@media(max-width:640px){.fig-live-ui .tf-hosts{grid-template-columns:minmax(0,1fr)}.fig-live-ui .tf-tbl td,.fig-live-ui .tf-tbl th{padding:.4rem .35rem;font-size:.76rem}.fig-live-ui .tf-tbl th{text-transform:none;letter-spacing:0;font-size:.7rem}.fig-live-ui .tf-term{font-size:.62rem}.fig-live-ui .tf-host-note{min-height:0}.fig-live-ui .tf-live{min-height:7.4em}}
/* oncalendar (Linux Deep Dive, timers.html): OnCalendar table, systemd-analyze output, strips */
.fig-live-ui .tg-cal,.fig-live-ui .tg-mono{display:flex;flex-direction:column;gap:.75rem;min-width:0}
.fig-live-ui .tg-tblbox{overflow-x:auto;max-width:100%}
.fig-live-ui .tg-tbl{margin:0}
.fig-live-ui .tg-tbl tr.tg-on td{background:var(--ac-dim)}
.fig-live-ui .tg-tbl tr.tg-on td:first-child{box-shadow:inset 3px 0 0 var(--ac)}
.fig-live-ui .tg-pick{font:inherit;color:inherit;background:none;border:0;padding:0;margin:0;cursor:pointer;text-align:left}
.fig-live-ui .tg-pick:hover code{border-color:var(--ac)}
.fig-live-ui .tg-inrow{gap:.5rem;flex-wrap:nowrap;margin:0}
.fig-live-ui .tg-key{font-family:'JetBrains Mono',monospace;color:var(--fg)}
.fig-live-ui .tg-in{font-family:'JetBrains Mono',monospace;font-size:.85rem;padding:.3rem .5rem;min-width:0;max-width:100%;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg);font-variant-ligatures:none}
.fig-live-ui .tg-inrow .tg-in{flex:1 1 12rem}
.fig-live-ui .tg-in[aria-invalid="true"]{border-color:var(--c-err)}
.fig-live-ui .tg-field{gap:.5rem;margin:0}
.fig-live-ui .tg-date{width:10.5rem}
.fig-live-ui .tg-time{width:7.5rem}
.fig-live-ui .tg-msg{margin:0;font-size:.8rem;color:var(--c-ok);min-height:1.3em}
.fig-live-ui .tg-msg.is-bad{color:var(--c-err)}
.fig-live-ui .tg-msg.is-warn{color:var(--c-warn)}
.fig-live-ui .tg-out{margin:0;padding:.7rem .85rem;border-radius:var(--r-sm);background:var(--bg-surf);border:1px solid var(--bd);font-family:'JetBrains Mono',monospace;font-size:.76rem;line-height:1.5;color:var(--fg);white-space:pre;overflow-x:auto;max-width:100%;font-variant-ligatures:none}
.fig-live-ui .tg-strip{display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .tg-track{position:relative;height:1.6rem;border-bottom:1px solid var(--fg-subtle);margin:0 .4rem}
.fig-live-ui .tg-mark{position:absolute;top:50%;transform:translate(-50%,-50%)}
.fig-live-ui .tg-mark.tg-tick{top:auto;bottom:0;width:1px;height:.45rem;background:var(--bd);transform:translateX(-50%)}
.fig-live-ui .tg-mark.tg-major{height:.9rem;background:var(--fg-subtle)}
.fig-live-ui .tg-off{position:absolute;top:0;bottom:0;background:var(--c-warn-bg);border-right:1px dashed var(--c-warn)}
.fig-live-ui .tg-hit,.fig-live-ui .tg-miss,.fig-live-ui .tg-due{width:.7rem;height:.7rem;border-radius:50%;box-sizing:border-box}
.fig-live-ui .tg-hit{background:var(--ac)}
.fig-live-ui .tg-due{border:2px solid var(--ac);background:var(--bg-sb)}
.fig-live-ui .tg-miss{border:2px solid var(--c-err);background:var(--bg-sb)}
.fig-live-ui .tg-catch{width:.7rem;height:.7rem;background:var(--c-ok)}
.fig-live-ui .tg-mark.tg-catch{transform:translate(-50%,-50%) rotate(45deg)}
.fig-live-ui .tg-mark.tg-now{top:0;width:2px;height:100%;background:var(--fg);transform:translateX(-50%)}
.fig-live-ui .tg-ends{display:flex;justify-content:space-between;gap:.5rem;font-family:'JetBrains Mono',monospace;font-size:.7rem;color:var(--fg-subtle)}
.fig-live-ui .tg-legend{display:flex;flex-wrap:wrap;gap:.25rem .9rem;font-size:.72rem;color:var(--fg-muted)}
.fig-live-ui .tg-key-item{display:inline-flex;align-items:center;gap:.3rem}
.fig-live-ui .tg-sw{display:inline-block;flex:none}
.fig-live-ui .tg-sw.tg-catch{transform:rotate(45deg) scale(.85)}
.fig-live-ui .tg-cmd{display:block;white-space:pre-wrap;overflow-wrap:anywhere;padding-left:2ch;text-indent:-2ch;color:var(--fg-muted)}
.fig-live-ui .tg-unit{white-space:pre-wrap;overflow-wrap:anywhere}
.fig-live-ui .tg-nowkey{width:2px;height:.8rem;background:var(--fg)}
.fig-live-ui .tg-clock{margin:0;font-family:'JetBrains Mono',monospace;font-size:.8rem;color:var(--fg)}
.fig-live-ui .tg-runs{margin:0;padding-left:1.6rem;font-family:'JetBrains Mono',monospace;font-size:.76rem;line-height:1.6;color:var(--fg-subtle)}
.fig-live-ui .tg-runs li.is-done{color:var(--fg)}
.fig-live-ui .tg-live{min-height:4.2em}
.fig-live-ui .tg-boots{min-height:1.2em}
@media(max-width:640px){
  .fig-live-ui .tg-out{font-size:.62rem;padding:.55rem .45rem}
  .fig-live-ui .tg-runs{font-size:.7rem}
  .fig-live-ui .tg-live{min-height:6.4em}
}
/* gitplaces (Git for Beginners, chapter 2): the figure's own .fig-flow (three places) or
   .fig-cols (three status lists), with each file as a chip in the place its change has
   reached; .is-two marks a file that is in two places at once. The terminal, git status
   and diff panels are real Git output, tab stops at 8. */
.fig-live-ui .ua-draw{display:flex;flex-direction:column;gap:.6rem}
.fig-live-ui .ua-flow .flow-step{flex:1 1 0;min-width:0;max-width:none;justify-content:flex-start;background:var(--bg-surf)}
.fig-live-ui .ua-flow .flow-step.ok{border-color:var(--c-ok)}
.fig-live-ui .ua-cols{margin:0}
.fig-live-ui .ua-cols .fig-col{background:var(--bg-surf);gap:.5rem}
.fig-live-ui .ua-chips{display:flex;flex-wrap:wrap;justify-content:center;gap:.3rem;min-height:1.6rem;margin-top:.15rem}
.fig-live-ui .ua-cols .ua-chips{justify-content:flex-start}
.fig-live-ui .ua-flow .flow-step.ok .ua-chips:empty{display:none}
.fig-live-ui .ua-file{display:inline-flex;align-items:baseline;gap:.3rem;padding:.12rem .5rem;border:1px solid var(--bd);border-radius:var(--r-pill);background:var(--bg-sb);color:var(--fg);font-size:.72rem;line-height:1.35}
.fig-live-ui .ua-file code{font-family:'JetBrains Mono',monospace;font-size:.7rem;background:none;padding:0;color:inherit;font-variant-ligatures:none}
.fig-live-ui .ua-file small{font-size:.62rem;color:var(--fg-muted)}
.fig-live-ui .ua-file.is-sel{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .ua-file.is-two{border-color:var(--c-warn);background:var(--c-warn-bg)}
.fig-live-ui .ua-file.is-two.is-sel{box-shadow:inset 0 0 0 1px var(--c-warn)}
.fig-live-ui .ua-commits{list-style:none;margin:.15rem 0 0;padding:0;width:100%;display:flex;flex-direction:column;gap:.12rem;font-size:.66rem;line-height:1.35;color:var(--fg-muted);text-align:left;overflow-wrap:anywhere}
.fig-live-ui .ua-commits code{font-family:'JetBrains Mono',monospace;font-size:.64rem;color:var(--c-ok);background:none;padding:0}
.fig-live-ui .ua-none{color:var(--fg-subtle);font-style:italic;font-size:.68rem}
.fig-live-ui .ua-hist{font-size:.74rem;color:var(--fg-muted)}
.fig-live-ui .ua-live{min-height:4.7em}
.fig-live-ui .ua-seq{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:.3rem}
.fig-live-ui .ua-seq li{padding:.1rem .5rem;border:1px dashed var(--bd);border-radius:var(--r-pill);font-family:'JetBrains Mono',monospace;font-size:.66rem;color:var(--fg-subtle);font-variant-ligatures:none}
.fig-live-ui .ua-seq li.is-done{border-style:solid;color:var(--fg-muted)}
.fig-live-ui .ua-seq li.is-now{border-style:solid;border-color:var(--ac);background:var(--ac-dim);color:var(--fg)}
.fig-live-ui .ua-seq.is-off li{opacity:.55}
.fig-live-ui .ua-acts{gap:.45rem}
.fig-live-ui .ua-cmd{font-family:'JetBrains Mono',monospace;font-size:.74rem;font-variant-ligatures:none}
.fig-live-ui .ua-term,.fig-live-ui .ua-out{margin:0;padding:.6rem .8rem;border-radius:var(--r-sm);background:var(--bg-surf);border:1px solid var(--bd);font-family:'JetBrains Mono',monospace;font-size:.74rem;line-height:1.5;color:var(--fg);white-space:pre;tab-size:8;-moz-tab-size:8;overflow:auto;max-width:100%;font-variant-ligatures:none}
.fig-live-ui .ua-term{height:calc(7 * 1.5em + 1.2rem)}
.fig-live-ui .ua-out{max-height:calc(20 * 1.5em + 1.2rem)}
.fig-live-ui .ua-prompt{color:var(--fg-muted)}
.fig-live-ui .ua-term .ua-none,.fig-live-ui .ua-out .ua-none{font-size:inherit}
.fig-live-ui .ua-err{color:var(--c-err)}
.fig-live-ui .ua-add{color:var(--c-ok)}
.fig-live-ui .ua-del{color:var(--c-err)}
.fig-live-ui .ua-hunk{color:var(--ac)}
.fig-live-ui .ua-fhd{font-weight:700}
@media(max-width:640px){.fig-live-ui .ua-flow .flow-step{flex:1 1 100%;padding:.5rem .7rem;display:grid;grid-template-columns:minmax(0,7.2rem) minmax(0,1fr);column-gap:.6rem;row-gap:.1rem;align-items:center;justify-items:start;text-align:left}.fig-live-ui .ua-flow .flow-step>.nm,.fig-live-ui .ua-flow .flow-step>.ds{grid-column:1}.fig-live-ui .ua-flow .ua-chips{grid-column:2;grid-row:1 / span 2;justify-content:flex-start;margin:0;min-height:1.6rem}.fig-live-ui .ua-flow .ua-commits{grid-column:1 / -1}.fig-live-ui .ua-flow .flow-arrow{padding:0;font-size:1rem}.fig-live-ui .ua-live{min-height:7.8em}.fig-live-ui .ua-term,.fig-live-ui .ua-out{font-size:.62rem;padding:.5rem .45rem;white-space:pre-wrap;overflow-wrap:anywhere}.fig-live-ui .ua-cmd{font-size:.68rem}}
/* gitbranch (Git for Beginners, chapter 6: branches as labels): the commit graph,
   the folder strip and the terminal. gitmerge.js draws with the same graph and
   folder, so it uses these .ub-* rules too. The commits are the static figure's
   own .flow-step boxes, placed on a grid of --ub-u units (smaller on a phone);
   the arrows are an SVG under them whose ends are percentages of the canvas,
   so they stay on the boxes at any --ub-u. */
.fig-live-ui .ub-graphbox{min-width:0}
.fig-live-ui .ub-graph{--ub-u:1rem;overflow-x:auto;padding:.2rem 0}
.fig-live-ui .ub-canvas{position:relative;margin:0 auto;width:calc((var(--ub-cols) * 8.8 - 1.8) * var(--ub-u));height:calc((var(--ub-rows) * 7.6 - 1.2) * var(--ub-u))}
.fig-live-ui .ub-edges{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.fig-live-ui .ub-edge{stroke:var(--ac);stroke-width:1.6;vector-effect:non-scaling-stroke;fill:none}
.fig-live-ui .ub-arrowhead{fill:var(--ac);stroke:none}
.fig-live-ui .ub-node{position:absolute;box-sizing:border-box;left:calc(var(--ub-x) * 8.8 * var(--ub-u));top:calc(var(--ub-r) * 7.6 * var(--ub-u));width:calc(7 * var(--ub-u));height:calc(6.4 * var(--ub-u));min-width:0;max-width:none;padding:.35rem .3rem;gap:.15rem;overflow-wrap:anywhere}
.fig-live-ui .ub-node .nm{font-family:'JetBrains Mono',monospace}
.fig-live-ui .ub-node .badge{color:var(--c-ok);white-space:nowrap}
.fig-live-ui .ub-node.is-fresh{background:var(--ac-dim)}
.fig-live-ui .ub-folderbox{min-height:1.9rem}
.fig-live-ui .ub-folder{display:flex;flex-wrap:wrap;align-items:center;gap:.4rem .6rem}
.fig-live-ui .ub-files{display:flex;flex-wrap:wrap;gap:.35rem}
.fig-live-ui .ub-file{font-family:'JetBrains Mono',monospace;font-size:.76rem;padding:.15rem .55rem;border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--bg-surf);color:var(--fg)}
.fig-live-ui .ub-file small{font-family:inherit;font-size:.7rem;color:var(--fg-muted)}
.fig-live-ui .ub-file.is-back{border-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .ub-file.is-changed{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .ub-file.is-gone{border-style:dashed;border-color:var(--c-err);background:transparent;color:var(--c-err);text-decoration:line-through}
.fig-live-ui .ub-live{min-height:4.7em}
.fig-live-ui .ub-cmds{gap:.4rem}
.fig-live-ui .ub-cmd{font-family:'JetBrains Mono',monospace;font-size:.74rem}
.fig-live-ui .ub-term{margin:0;padding:.65rem .8rem;border-radius:var(--r-sm);background:var(--bg-surf);border:1px solid var(--bd);font-family:'JetBrains Mono',monospace;font-size:.74rem;line-height:1.5;color:var(--fg);white-space:pre;overflow-x:auto;font-variant-ligatures:none}
@media(max-width:640px){.fig-live-ui .ub-graph{--ub-u:.68rem}.fig-live-ui .ub-node{padding:.25rem .2rem;gap:.1rem}.fig-live-ui .ub-node .nm{font-size:.72rem}.fig-live-ui .ub-node .ds{font-size:.58rem;line-height:1.2}.fig-live-ui .ub-node .badge{font-size:.54rem}.fig-live-ui .ub-folderbox{min-height:3.7rem}.fig-live-ui .ub-live{min-height:9.3em}.fig-live-ui .ub-term{font-size:.64rem;padding:.5rem .55rem}}
/* gitmerge (Git for Beginners, chapter 6: the two outcomes of a merge): the
   figure's own two .fig-col columns, the one this setup produces lit (amber when
   it happens on the wrong branch). The graph, folder strip and terminal are
   gitbranch's .ub-* rules (it draws with gitbranch.js). */
.fig-live-ui .uc-cols{margin:0}
.fig-live-ui .uc-col.is-on{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .uc-col.is-wrong{border-color:var(--c-warn);background:var(--c-warn-bg)}
.fig-live-ui .uc-tag{display:block;min-height:2.4em;font-size:.72rem;font-weight:600;line-height:1.2;color:var(--ac)}
.fig-live-ui .uc-col.is-wrong .uc-tag{color:var(--c-warn)}
.fig-live-ui .uc-setup{display:flex;flex-direction:column;gap:.5rem}
.fig-live-ui .uc-live{min-height:6.2em}
@media(max-width:640px){.fig-live-ui .uc-cols{gap:.5rem}.fig-live-ui .uc-cols .fig-col{padding:.7rem .6rem}.fig-live-ui .uc-live{min-height:10.9em}}
/* gitsync (Git for Beginners, staying-in-sync / chapter 7 index / merging a pull request):
   the static figures' own .topo-frame and .fig-decide; two commit rows, newest right,
   with branch labels above and origin/main below; a terminal of what Git printed. */
.fig-live-ui .ud-copies{display:flex;flex-direction:column;gap:.7rem}
.fig-live-ui .ud-frame{display:flex;flex-direction:column;gap:.5rem;padding:.7rem .8rem}
.fig-live-ui .ud-frame .topo-frame-label{margin-bottom:0}
.fig-live-ui .ud-frame .topo-zone{align-items:stretch}
.fig-live-ui .ud-frame .topo-zone>.topo-zone-label,.fig-live-ui .ud-frame .topo-zone>.topo-node{align-self:center}
.fig-live-ui .ud-graph{position:relative;display:flex;flex-direction:column;gap:.15rem;min-width:0}
.fig-live-ui .ud-graph.is-cut::before{content:"…";position:absolute;left:0;top:50%;transform:translateY(-50%);color:var(--fg-subtle);font-size:.8rem}
.fig-live-ui .ud-refs,.fig-live-ui .ud-hashes{display:grid;align-items:center;min-height:1.15rem}
.fig-live-ui .ud-lanes{position:relative;height:58px}
.fig-live-ui .ud-lanes svg{position:absolute;inset:0;width:100%;height:58px;overflow:visible}
.fig-live-ui .ud-edge{stroke:var(--fg-subtle);stroke-width:2;vector-effect:non-scaling-stroke;fill:none}
.fig-live-ui .ud-edge.is-lost{stroke:var(--c-err);stroke-dasharray:4 3}
.fig-live-ui .ud-dots{position:absolute;inset:0}
.fig-live-ui .ud-dot{position:absolute;display:block;width:14px;height:14px;margin:-7px 0 0 -7px;border-radius:50%;border:2px solid var(--fg-subtle);background:var(--bg-surf);box-sizing:border-box}
.fig-live-ui .ud-base{border-color:var(--fg-subtle);background:var(--bg-surf)}
.fig-live-ui .ud-you{border-color:var(--ac);background:var(--ac)}
.fig-live-ui .ud-other,.fig-live-ui .ud-web{border-color:var(--c-warn);background:var(--c-warn)}
.fig-live-ui .ud-merge{border-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .ud-lost{border-color:var(--c-err);border-style:dashed;background:var(--c-err-bg)}
.fig-live-ui .ud-dot.is-new{box-shadow:0 0 0 3px var(--bg-sb),0 0 0 5px var(--ac)}
.fig-live-ui .ud-hash{font-family:'JetBrains Mono',monospace;font-size:.62rem;color:var(--fg-muted);text-align:center;white-space:nowrap;overflow:hidden;min-width:0}
.fig-live-ui .ud-hash.is-lost{color:var(--c-err);text-decoration:line-through}
.fig-live-ui .ud-chip{font-family:'JetBrains Mono',monospace;font-size:.62rem;line-height:1.3;padding:0 .35rem;border-radius:var(--r-pill);border:1px solid var(--ac);background:var(--ac-dim);color:var(--fg);white-space:nowrap}
.fig-live-ui .ud-chip.is-head{font-weight:700;box-shadow:0 0 0 1px var(--ac)}
.fig-live-ui .ud-chip.is-track{border-style:dashed;border-color:var(--fg-subtle);background:transparent;color:var(--fg-muted)}
.fig-live-ui .ud-sum{font-size:.74rem;color:var(--fg-muted);min-height:1.2em}
.fig-live-ui .ud-legend{display:flex;flex-wrap:wrap;gap:.3rem .9rem;font-size:.72rem;color:var(--fg-muted)}
.fig-live-ui .ud-key{display:inline-flex;align-items:center;gap:.35rem}
.fig-live-ui .ud-key .ud-dot{position:static;margin:0;width:11px;height:11px}
.fig-live-ui .ud-decide{margin:0;max-width:none}
.fig-live-ui .ud-decide .decide-row.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .ud-decide .decide-row.is-now.is-bad{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .ud-term{margin:0;padding:.6rem .75rem;height:11.5rem;overflow:auto;border-radius:var(--r-sm);background:var(--bg-surf);border:1px solid var(--bd);font-family:'JetBrains Mono',monospace;font-size:.7rem;line-height:1.5;color:var(--fg);white-space:pre;font-variant-ligatures:none}
.fig-live-ui .ud-term.is-bad{border-color:var(--c-err)}
.fig-live-ui .ud-live{min-height:4.1em}
.fig-live-ui .ud-cmds .wl-btn{font-family:'JetBrains Mono',monospace;font-size:.74rem}
.fig-live-ui .ud-danger{border-color:var(--c-err);color:var(--c-err)}
@media(max-width:640px){.fig-live-ui .ud-frame{padding:.55rem .5rem}.fig-live-ui .ud-live{min-height:5.6em}.fig-live-ui .ud-term{height:10rem;font-size:.66rem}.fig-live-ui .ud-hash{font-size:.58rem}}
/* gitundo (Git for Beginners, undoing a pushed commit / committed too early): the
   figure's own .fig-flow of commits (.fail the wrong one, .ok the fix, .ue-orphan off
   main); GitHub's and Theo's copies below; the steps of the story; a terminal. */
.fig-live-ui .ue-flow .flow-step{position:relative}
.fig-live-ui .ue-flow .flow-step .nm{font-family:'JetBrains Mono',monospace}
.fig-live-ui .ue-flow .flow-step.ok{border-color:var(--c-ok)}
.fig-live-ui .ue-flow .flow-step.fail{border-color:var(--c-err)}
.fig-live-ui .ue-flow .flow-step.ue-orphan{border-style:dashed;opacity:.72}
.fig-live-ui .ue-main{font-family:'JetBrains Mono',monospace;font-size:.62rem;font-weight:700;color:var(--ac)}
.fig-live-ui .ue-copies{display:flex;flex-direction:column;gap:.35rem}
.fig-live-ui .ue-copy{display:flex;flex-wrap:wrap;align-items:baseline;gap:.2rem .6rem;padding:.4rem .6rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);font-size:.76rem;min-height:2.1rem}
.fig-live-ui .ue-who{font-weight:700;color:var(--fg-muted);min-width:6.5rem}
.fig-live-ui .ue-chain{font-family:'JetBrains Mono',monospace;font-size:.72rem;color:var(--fg)}
.fig-live-ui .ue-tag{color:var(--fg-muted)}
.fig-live-ui .ue-tag.is-ok{color:var(--c-ok)}
.fig-live-ui .ue-tag.is-bad{color:var(--c-err);font-weight:600}
.fig-live-ui .ue-steps{display:flex;flex-wrap:wrap;gap:.3rem;margin:0;padding:0;list-style:none;counter-reset:ue}
.fig-live-ui .ue-step{counter-increment:ue;font-size:.7rem;padding:.12rem .5rem;border-radius:var(--r-pill);border:1px solid var(--bd);color:var(--fg-subtle)}
.fig-live-ui .ue-step::before{content:counter(ue) ". "}
.fig-live-ui .ue-step.is-done{color:var(--fg-muted)}
.fig-live-ui .ue-step.is-now{border-color:var(--ac);background:var(--ac-dim);color:var(--fg);font-weight:600}
.fig-live-ui .ue-term{margin:0;padding:.6rem .75rem;height:10rem;overflow:auto;border-radius:var(--r-sm);background:var(--bg-surf);border:1px solid var(--bd);font-family:'JetBrains Mono',monospace;font-size:.7rem;line-height:1.5;color:var(--fg);white-space:pre;font-variant-ligatures:none}
.fig-live-ui .ue-term.is-bad{border-color:var(--c-err)}
.fig-live-ui .ue-live{min-height:4.1em}
.fig-live-ui .ue-opts{gap:.4rem 1.4rem}
.fig-live-ui .ue-opts>.wl-row{gap:.5rem}
@media(max-width:640px){.fig-live-ui .ue-flow{flex-wrap:wrap;gap:.25rem}.fig-live-ui .ue-flow .flow-step{flex:1 1 100%;max-width:none;flex-direction:row;justify-content:space-between;gap:.6rem;padding:.4rem .7rem;text-align:left}.fig-live-ui .ue-flow .flow-step .ds{flex:1;text-align:right}.fig-live-ui .ue-flow .flow-arrow{font-size:.85rem;padding:0}.fig-live-ui .ue-live{min-height:5.6em}.fig-live-ui .ue-term{font-size:.66rem}.fig-live-ui .ue-who{min-width:0}}
/* pipeline (DevOps for Beginners 2.06 and the CI / scan / promotion flows):
   the figure's own .fig-flow; each stage is a button that can be set to fail,
   and its status line reads pending / running / passed / failed / not run. */
.fig-live-ui .va-box{position:relative}
.fig-live-ui .va-stage{font:inherit;color:inherit;cursor:pointer}
.fig-live-ui .va-flow .flow-arrow{pointer-events:none}
.fig-live-ui .va-st{display:block;min-height:1.1em;font-size:.66rem;font-weight:700;font-family:'JetBrains Mono',monospace;color:var(--fg-subtle);line-height:1.1}
.fig-live-ui .va-box.va-running{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .va-box.va-running .va-st{color:var(--ac)}
.fig-live-ui .va-box.va-passed{border-color:var(--c-ok);background:var(--c-ok-bg)}
.fig-live-ui .va-box.va-passed .va-st{color:var(--c-ok)}
.fig-live-ui .va-box.va-failed{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .va-box.va-failed .va-st,.fig-live-ui .va-box.va-armed .va-st{color:var(--c-err)}
.fig-live-ui .va-box.va-armed{border-color:var(--c-err);border-style:dashed}
.fig-live-ui .va-box.va-notrun{border-style:dashed;opacity:.55}
.fig-live-ui .va-live{min-height:3.1em}
.fig-live-ui .va-week{display:flex;flex-direction:column;gap:.5rem}
.fig-live-ui .va-strip{display:grid;grid-template-columns:repeat(20,minmax(0,1fr));gap:3px}
.fig-live-ui .va-cell{display:flex;align-items:center;justify-content:center;height:1.4rem;border-radius:4px;border:1px solid var(--bd);background:var(--bg-surf);font-family:'JetBrains Mono',monospace;font-size:.66rem;font-weight:700;color:var(--fg-muted)}
.fig-live-ui .va-cell-ok{border-color:var(--c-ok);background:var(--c-ok-bg);color:var(--c-ok)}
.fig-live-ui .va-cell-bad{border-color:var(--c-err);background:var(--c-err-bg);color:var(--c-err)}
.fig-live-ui .va-week.is-on .va-tally{min-height:4.7em}
.fig-live-ui .va-strip:empty{display:none}
@media(max-width:640px){.fig-live-ui .va-flow{flex-wrap:wrap;gap:.25rem}.fig-live-ui .va-flow .flow-step{flex:1 1 100%;max-width:none;display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:.6rem;row-gap:.1rem;align-items:center;padding:.4rem .7rem;text-align:left}.fig-live-ui .va-flow .flow-step .nm{grid-column:1}.fig-live-ui .va-flow .flow-step .ds{grid-column:1}.fig-live-ui .va-flow .va-st{grid-column:2;grid-row:1 / span 2;text-align:right}.fig-live-ui .va-flow .flow-arrow{font-size:.85rem;padding:0;transform:rotate(90deg);width:100%;height:.8rem;line-height:.8rem}.fig-live-ui .va-strip{grid-template-columns:repeat(10,minmax(0,1fr))}.fig-live-ui .va-live{min-height:4.7em}.fig-live-ui .va-week.is-on .va-tally{min-height:6.3em}}
/* rolling (DevOps for Beginners 6.04, Rolling Updates): the figure's own
   .fig-flow of settled states (.is-now: the state the copies are in; .vb-next:
   the one a swap is heading for), the five copies, and a strip of the copies
   serving at each moment (a red column is a moment with none). */
.fig-live-ui .vb-flow .flow-step.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .vb-flow .flow-step.vb-next{border-color:var(--ac);border-style:dashed}
.fig-live-ui .vb-flow .flow-step{flex:1 1 0;min-width:0}
.fig-live-ui .vb-copies{display:grid;grid-template-columns:repeat(var(--vb-n,5),minmax(0,1fr));gap:.4rem}
.fig-live-ui .vb-copy{display:flex;flex-direction:column;align-items:center;gap:.1rem;min-width:0;padding:.45rem .2rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf);text-align:center}
.fig-live-ui .vb-no{font-size:.62rem;color:var(--fg-subtle)}
.fig-live-ui .vb-ver{font-size:.82rem;font-weight:700;color:var(--fg)}
.fig-live-ui .vb-st{font-size:.64rem;font-family:'JetBrains Mono',monospace;color:var(--fg-muted);line-height:1.2}
.fig-live-ui .vb-copy.vb-new.vb-up{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .vb-copy.vb-new.vb-up .vb-st,.fig-live-ui .vb-copy.vb-old.vb-up .vb-st{color:var(--c-ok)}
.fig-live-ui .vb-copy.vb-starting{border-color:var(--c-warn);border-style:dashed;background:var(--c-warn-bg)}
.fig-live-ui .vb-copy.vb-starting .vb-st{color:var(--c-warn)}
.fig-live-ui .vb-copy.vb-stopped{border-color:var(--c-err);border-style:dashed;background:transparent}
.fig-live-ui .vb-copy.vb-stopped .vb-ver{color:var(--fg-subtle);text-decoration:line-through}
.fig-live-ui .vb-copy.vb-stopped .vb-st,.fig-live-ui .vb-copy.vb-sick .vb-st{color:var(--c-err)}
.fig-live-ui .vb-copy.vb-sick{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .vb-count{font-size:.82rem;font-weight:600;color:var(--fg-muted)}
.fig-live-ui .vb-count.is-bad{color:var(--c-err);font-weight:700}
.fig-live-ui .vb-stripbox{display:flex;flex-direction:column;gap:.35rem}
.fig-live-ui .vb-strip{display:grid;grid-template-columns:repeat(24,minmax(0,1fr));gap:3px;align-items:end}
.fig-live-ui .vb-col{display:flex;flex-direction:column-reverse;gap:2px;padding:2px;border-radius:3px;min-height:calc(var(--vb-n,5) * 8px + 4px)}
.fig-live-ui .vb-col.vb-zero{background:var(--c-err-bg);box-shadow:inset 0 0 0 1px var(--c-err)}
.fig-live-ui .vb-cell{display:block;height:6px;border-radius:1px;background:transparent;box-shadow:inset 0 0 0 1px var(--bd)}
.fig-live-ui .vb-cell.vb-on-old{background:var(--fg-subtle);box-shadow:none}
.fig-live-ui .vb-cell.vb-on-new{background:var(--ac);box-shadow:none}
.fig-live-ui .vb-live{min-height:3.1em}
.fig-live-ui .vb-live.is-bad{color:var(--c-err)}
.fig-live-ui .vb-sim{display:flex;flex-direction:column;gap:.5rem}
.fig-live-ui .vb-sim.is-on .vb-tally{min-height:3.1em}
.fig-live-ui .vb-tally:empty{display:none}
@media(max-width:640px){.fig-live-ui .vb-flow{flex-wrap:wrap;gap:.25rem}.fig-live-ui .vb-flow .flow-step{flex:1 1 100%;max-width:none;flex-direction:row;justify-content:space-between;gap:.6rem;padding:.35rem .7rem;text-align:left}.fig-live-ui .vb-flow .flow-step .ds{text-align:right}.fig-live-ui .vb-flow .flow-arrow{font-size:.85rem;padding:0;transform:rotate(90deg);width:100%;height:.8rem;line-height:.8rem}.fig-live-ui .vb-copies{gap:.25rem}.fig-live-ui .vb-copy{padding:.35rem .1rem}.fig-live-ui .vb-st{font-size:.56rem}.fig-live-ui .vb-strip{gap:2px}.fig-live-ui .vb-live{min-height:4.7em}.fig-live-ui .vb-sim.is-on .vb-tally{min-height:6.3em}}
/* fleet (DevOps for Beginners, the orchestrator's loop) */
.fig-live-ui .vc-loopbox{display:flex;flex-direction:column;gap:.35rem}
.fig-live-ui .vc-flow .flow-step.is-now{border-color:var(--ac);background:var(--ac-dim)}
.fig-live-ui .vc-flow .flow-step.is-now.is-bad{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .vc-flow .flow-step .nm{color:var(--fg)}
.fig-live-ui .vc-flow .flow-step .ds{color:var(--fg-muted)}
.fig-live-ui .vc-back{text-align:center;font-size:.72rem;color:var(--fg-subtle)}
.fig-live-ui .vc-frame{width:100%;max-width:720px;box-sizing:border-box}
.fig-live-ui .vc-frame.is-bad{border-color:var(--c-err)}
.fig-live-ui .vc-zone{min-width:0}
.fig-live-ui .vc-zone.is-down{border-color:var(--c-err);background:var(--c-err-bg)}
.fig-live-ui .vc-srv{font:inherit;font-family:'JetBrains Mono',monospace;font-size:.68rem;color:var(--fg-muted);background:transparent;border:1px solid var(--bd);border-radius:var(--r-pill);padding:.15rem .6rem;cursor:pointer}
.fig-live-ui .vc-srv:hover{border-color:var(--ac);color:var(--fg)}
.fig-live-ui .vc-zone.is-down .vc-srv{border-color:var(--c-err);color:var(--c-err)}
.fig-live-ui .vc-node{flex-wrap:wrap;gap:.25rem;min-height:2.1rem;box-sizing:border-box}
.fig-live-ui .vc-dot{color:var(--fg-subtle)}
.fig-live-ui .vc-copy{font:inherit;font-size:.72rem;font-weight:600;color:var(--fg);background:var(--bg-surf);border:1px solid var(--bd);border-radius:5px;padding:.1rem .4rem;cursor:pointer;min-width:4.6em}
.fig-live-ui .vc-copy:hover{border-color:var(--c-err)}
.fig-live-ui .vc-copy.is-starting{border-style:dashed;border-color:var(--ac);color:var(--fg-muted);font-style:italic}
.fig-live-ui .vc-copy.is-dead{border-color:var(--c-err);background:var(--c-err-bg);color:var(--c-err);text-decoration:line-through;cursor:default}
.fig-live-ui .vc-empty{font-size:.72rem;font-style:italic;color:var(--fg-subtle)}
.fig-live-ui .vc-zone.is-down .vc-empty{color:var(--c-err)}
.fig-live-ui .vc-band.is-bad{color:var(--c-err)}
.fig-live-ui .vc-meter{display:flex;flex-wrap:wrap;gap:.5rem}
.fig-live-ui .vc-stat{flex:1 1 6.5rem;display:flex;flex-direction:column;align-items:center;gap:.1rem;padding:.4rem .5rem;border:1px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-surf)}
.fig-live-ui .vc-num{font-family:'JetBrains Mono',monospace;font-size:1.05rem;font-weight:700;color:var(--fg)}
.fig-live-ui .vc-num.is-bad{color:var(--c-err)}
.fig-live-ui .vc-lab{font-size:.68rem;color:var(--fg-subtle);text-align:center}
.fig-live-ui .vc-stripbox{display:flex;flex-direction:column;gap:.3rem}
.fig-live-ui .vc-strip{display:flex;align-items:flex-end;gap:2px;height:2.2rem;padding:2px;border-bottom:1px solid var(--bd)}
.fig-live-ui .vc-bar{flex:1 1 0;min-width:0;height:0;border-radius:2px 2px 0 0}
.fig-live-ui .vc-bar.is-full{background:var(--c-ok)}
.fig-live-ui .vc-bar.is-short{background:var(--c-warn)}
.fig-live-ui .vc-bar.is-off{background:var(--c-err)}
.fig-live-ui .vc-live{min-height:6.3em}
.fig-live-ui .vc-tally{min-height:3.2em}
@media(max-width:640px){.fig-live-ui .vc-flow .flow-step{padding:.45rem .6rem;gap:.15rem}.fig-live-ui .vc-flow .flow-arrow{padding:0;line-height:1}.fig-live-ui .vc-live{min-height:9.5em}.fig-live-ui .vc-tally{min-height:4.8em}.fig-live-ui .vc-stat{flex-basis:5.5rem}}
