/* Slush tokens, tuned for long reading sessions */
:root{
  --carbon:#000;--paper:#fff;--sky:#dceeff;--concrete:#ccc;--mist:#e9e9e9;
  --blue:#4da2ff;--mint:#55db9c;--lav:#e9ccff;--ember:#fb4903;--sun:#ffd731;--violet:#5c4ade;
  --bg:var(--sky);--band:#fff;--band-2:#cccccc;--surface:#fff;--surface-2:#f3f6fa;
  --ink:#000;--text:#1e1f24;--muted:#5b6170;--line:#000;--hair:#d5dbe4;
  --code-bg:#fbfcfe;--kw:#5c4ade;--kc:#cf222e;--str:#1a7f37;--num:#0550ae;--com:#6d7482;--fn:#0e7490;--call:#0e7490;--bi:#9a6700;--self:#8b4bc9;--cls:#a21caf;--attr:#3b5b92;--op:#bc4c00;--b0:#9a6700;--b1:#a21caf;--b2:#0969da;
  --on-accent:#000;--tint:14%;
  --font-display:'Lateral','Druk','Bowlby One','Antonio','Impact','Haettenschweiler','Arial Narrow',sans-serif;
  --font-body:'Aeonik Pro','Inter','Satoshi','General Sans','Segoe UI Variable Text','Segoe UI',system-ui,-apple-system,Roboto,sans-serif;
  --font-mono:'Cascadia Code','JetBrains Mono','Fira Code',Consolas,'SF Mono',Menlo,monospace;
  --r-card:20px;--r-big:40px;--r-pill:1600px;--read:1;
}
:root[data-theme=night]{
  --bg:#0e1014;--band:#12151a;--band-2:#181c23;--surface:#171a20;--surface-2:#1f232b;
  --ink:#f3f4f6;--text:#d6d9e0;--muted:#939aa9;--line:#5a6170;--hair:#2c313b;
  --code-bg:#12151a;--kw:#aea2ff;--kc:#ff7b72;--str:#7ee787;--num:#79c0ff;--com:#7b8393;--fn:#56d4dd;--call:#56d4dd;--bi:#e3b341;--self:#d3a6ff;--cls:#f0a6ff;--attr:#a5c4f3;--op:#ffa657;--b0:#e3b341;--b1:#f0a6ff;--b2:#79c0ff;
  --tint:20%;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth;scroll-padding-top:calc(84px + var(--backh))}
body{margin:0;background:var(--bg);color:var(--text);font:500 calc(15px*var(--read))/1.5 var(--font-body);letter-spacing:-.01em;-webkit-font-smoothing:antialiased;font-feature-settings:"tnum"}
button,input,select,textarea{font:inherit;color:inherit}
button{cursor:pointer}
a{color:inherit}
h1,h2,h3,h4{color:var(--ink);margin:0}
::selection{background:var(--sun);color:#000}
:focus-visible{outline:2px solid var(--violet);outline-offset:2px}
.hidden{display:none!important}
code,kbd,.mono{font-family:var(--font-mono);font-size:.92em}
p code,li code,td code,.co code,summary code{background:var(--surface-2);border:1px solid var(--hair);border-radius:7px;padding:1px 6px;white-space:nowrap;color:var(--ink)}

/* marquee */
.marquee{background:#000;color:#fff;overflow:hidden;white-space:nowrap;font:700 12px/1 var(--font-body);letter-spacing:.032em;text-transform:uppercase;border-bottom:1px solid #000}
.marquee div{display:inline-block;padding:9px 0;animation:mq 46s linear infinite}
.marquee span{margin:0 22px}
@keyframes mq{to{transform:translateX(-50%)}}
body:not([data-view=home]):not([data-view=course]) .marquee,body.focus .marquee{display:none}

/* nav */
.nav{position:sticky;top:0;z-index:50;display:flex;align-items:center;gap:12px;padding:10px 20px;background:var(--bg);border-bottom:1px solid var(--line)}
.logo{width:42px;height:42px;border-radius:50%;border:1px solid var(--line);background:var(--surface);display:grid;place-items:center;font:800 15px/1 var(--font-display);color:var(--ink);text-decoration:none;flex:none;letter-spacing:.02em}
.nav nav{display:flex;gap:4px;margin:0 auto;flex-wrap:wrap;justify-content:center}
.pill{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line);background:var(--surface);color:var(--ink);border-radius:var(--r-pill);padding:10px 14px;font:700 13px/1 var(--font-body);letter-spacing:.032em;text-decoration:none;white-space:nowrap;transition:transform .12s,background .12s}
@media(hover:hover){.pill:hover{transform:translateY(-1px);background:var(--surface-2)}}
.pill:active{transform:translateY(1px) scale(.97)}
.pill.fill,.pill[aria-current=page],.pill.on{background:var(--ink);color:var(--surface)}
.pill.sm{padding:7px 11px;font-size:12px}
.pill.icon{width:38px;height:38px;padding:0;justify-content:center;font-size:15px}
.pill[disabled]{opacity:.45;cursor:not-allowed;transform:none}
.pill.c-blue{background:var(--blue);color:#000}.pill.c-mint{background:var(--mint);color:#000}.pill.c-sun{background:var(--sun);color:#000}.pill.c-lav{background:var(--lav);color:#000}.pill.c-ember{background:var(--ember);color:#000}.pill.c-violet{background:var(--violet);color:#fff}
.tools{display:flex;gap:4px;flex:none}
.up{text-transform:uppercase;letter-spacing:.032em;font-weight:700;font-size:12px}
.muted{color:var(--muted)}

/* views */
.view{display:none}
.view.on{display:block;animation:viewIn .28s ease both}
@keyframes viewIn{from{opacity:0;transform:translateY(8px)}}
.wrap{max-width:1440px;margin:0 auto;padding:28px 24px 80px}
.display,.ch-head h2,.ch-head .blob,.stat b,.gamehead h2,.overlay h3,.bins div,.logo{font-synthesis:none}
.display{font-family:var(--font-display);font-weight:800;text-transform:uppercase;line-height:.88;color:var(--ink);letter-spacing:0;margin:0}
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-card);padding:24px}
.card.big{border-radius:var(--r-big)}
.tag{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--line);border-radius:var(--r-pill);padding:4px 10px;font:700 11px/1.2 var(--font-body);letter-spacing:.032em;text-transform:uppercase;background:var(--surface);color:var(--ink)}
.tag.blue{background:var(--blue);color:#000}.tag.mint{background:var(--mint);color:#000}.tag.sun{background:var(--sun);color:#000}.tag.lav{background:var(--lav);color:#000}.tag.ember{background:var(--ember);color:#000}.tag.violet{background:var(--violet);color:#fff}

/* home */
.hero{position:relative;background:var(--sky);overflow:hidden;border-bottom:1px solid var(--line)}
:root[data-theme=night] .hero{background:var(--bg)}
.hero-in{position:relative;max-width:1440px;margin:0 auto;padding:56px 24px 64px;min-height:560px}
.hero h1{font-size:clamp(84px,17.5vw,270px);position:relative;z-index:2;pointer-events:none}
.hero h1 span{display:block}
.hero h1 span+span{margin-left:.5em}
.ribbon{position:absolute;inset:0;width:100%;height:100%;z-index:1;pointer-events:none}
.hero .lead{position:relative;z-index:3;font:500 clamp(18px,2vw,26px)/1.25 var(--font-body);color:var(--ink);max-width:640px;margin:26px 0 22px}
.hero .cta{position:relative;z-index:3;display:flex;gap:8px;flex-wrap:wrap}
.sticker{position:absolute;z-index:4;border:1px solid #000;border-radius:20px;padding:10px 14px;font:700 14px/1 var(--font-mono);color:#000;cursor:grab;user-select:none;touch-action:none;transition:transform .15s}
.sticker:active{cursor:grabbing}
.sticker.round{border-radius:50%;width:84px;height:84px;display:grid;place-items:center;padding:0;font-size:16px}
.band{border-bottom:1px solid var(--line)}
.band.white{background:var(--band)}.band.gray{background:var(--band-2)}.band.sky{background:var(--bg)}
.band h2{font-size:clamp(54px,8vw,120px);margin-bottom:26px}
.grid{display:grid;gap:12px}
.g4{grid-template-columns:repeat(4,1fr)}.g3{grid-template-columns:repeat(3,1fr)}.g2{grid-template-columns:repeat(2,1fr)}
@media(max-width:1000px){.g4{grid-template-columns:repeat(2,1fr)}.g3{grid-template-columns:1fr 1fr}}
@media(max-width:640px){.g4,.g3,.g2{grid-template-columns:1fr}}
.stat b{display:block;font:800 54px/.9 var(--font-display);color:var(--ink)}
.stat span{font:700 12px/1.3 var(--font-body);letter-spacing:.032em;text-transform:uppercase;color:var(--muted)}
.tile{display:flex;flex-direction:column;gap:10px;text-decoration:none;min-height:190px;transition:transform .15s}
@media(hover:hover){.tile:hover{transform:translateY(-3px) rotate(-.4deg)}}
.tile .tag{align-self:flex-start}
.tile h3{font:700 calc(24px*var(--read))/1.15 var(--font-body)}
.tile p{margin:0;color:#111}
.tile.blue{background:var(--blue)}.tile.mint{background:var(--mint)}.tile.lav{background:var(--lav)}.tile.sun{background:var(--sun)}.tile.violet{background:var(--violet)}.tile.ember{background:var(--ember)}
.tile.blue *,.tile.mint *,.tile.lav *,.tile.sun *,.tile.ember *{color:#000}.tile.violet *{color:#fff}
.tile .go{margin-top:auto;align-self:flex-start;background:#fff;color:#000!important;border-color:#000}
.bar{height:10px;border:1px solid var(--line);border-radius:99px;background:var(--surface);overflow:hidden}
.bar i{display:block;height:100%;background:var(--mint);border-right:1px solid var(--line);width:0;transition:width .5s}
.partlist a{display:flex;justify-content:space-between;gap:10px;padding:12px 0;border-top:1px solid var(--hair);text-decoration:none;font-weight:700;color:var(--ink)}
.partlist a:first-child{border-top:0}
.partlist small{color:var(--muted);font-weight:500}

/* notes */
.notes{display:grid;grid-template-columns:320px minmax(0,1fr);gap:20px;max-width:1440px;margin:0 auto;padding:20px 24px 80px;align-items:start}
body.focus .notes{grid-template-columns:minmax(0,1fr)}
body.focus .toc{display:none}
.toc{position:sticky;top:78px;max-height:calc(100vh - 96px);overflow:auto;padding:16px;border-radius:var(--r-card);scrollbar-width:thin}
.toc input{width:100%;border:1px solid var(--line);border-radius:var(--r-pill);padding:9px 14px;background:var(--surface);margin-bottom:10px}
.toc .part{font:700 11px/1.2 var(--font-body);letter-spacing:.032em;text-transform:uppercase;color:var(--muted);margin:16px 4px 6px}
.toc .ch{display:flex;align-items:center;gap:8px;width:100%;text-align:left;border:1px solid transparent;background:none;border-radius:12px;padding:7px 8px;font-weight:700;font-size:calc(13.5px*var(--read));color:var(--ink);line-height:1.25}
.toc .ch:hover{background:var(--surface-2)}
.toc .ch.cur{border-color:var(--line);background:var(--sky)}
:root[data-theme=night] .toc .ch.cur{background:var(--surface-2)}
.toc .ch .n{flex:none;width:24px;height:24px;border-radius:50%;border:1px solid var(--line);display:grid;place-items:center;font-size:11px;background:var(--surface);color:var(--ink)}
.toc .ch.done .n{background:var(--mint);color:#000}
.toc .subs{margin:2px 0 6px 20px;border-left:1px solid var(--hair);display:none}
.toc .ch.cur+.subs,.toc.filtering .subs{display:block}
.toc .subs a{display:block;padding:4px 10px;font-size:calc(12.5px*var(--read));text-decoration:none;color:var(--muted);border-radius:8px;line-height:1.3}
.toc .subs a:hover,.toc .subs a.cur{color:var(--ink);background:var(--surface-2)}
.toc .subs a b{font-weight:700;color:var(--ink);margin-right:5px;font-family:var(--font-mono);font-size:11px}
.reader{min-width:0}
.chapter{display:none}
.chapter.on{display:block;animation:viewIn .25s ease both}
.ch-head{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-big);padding:30px 34px;margin-bottom:14px;position:relative;overflow:hidden}
.ch-head .crumb{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:16px}
.ch-head h2{font:800 clamp(40px,5.4vw,78px)/.92 var(--font-display);text-transform:uppercase;max-width:14ch;position:relative;z-index:1}
.ch-head .blob{position:absolute;right:-30px;top:-30px;width:210px;height:210px;border-radius:50%;border:1px solid var(--line);display:grid;place-items:center;font:800 110px/1 var(--font-display);color:#000;padding:26px 30px 0 0}
.ch-head .jump{display:flex;flex-wrap:wrap;gap:4px;margin-top:20px;position:relative;z-index:1}
.sub{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-card);padding:26px 34px;margin-bottom:12px}
.sub>*{max-width:76ch}
.sub>.wide,.sub>.tbl,.sub>pre.code,.sub>.codebox,.sub>.ll{max-width:none}
.sub h3{display:flex;align-items:center;gap:12px;font:700 calc(23px*var(--read))/1.2 var(--font-body);margin-bottom:14px}
.sub h3 .no{flex:none;border:1px solid var(--line);border-radius:var(--r-pill);padding:4px 10px;font:700 12px/1.2 var(--font-mono);color:#000}
.sub p,.sub li{font-size:calc(16.5px*var(--read));line-height:1.72}
.sub p{margin:0 0 14px}
.sub ul,.sub ol{margin:0 0 14px;padding-left:24px}
.sub li{margin-bottom:5px}
.sub li::marker{font-weight:700;color:var(--ink)}
.sub strong,.sub b{color:var(--ink);font-weight:700}
.sub h4{font:700 calc(15px*var(--read))/1.3 var(--font-body);text-transform:uppercase;letter-spacing:.032em;margin:20px 0 8px}
.sub .acts{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px}
.co{border:1px solid var(--line);border-radius:var(--r-card);padding:16px 20px 14px;margin:16px 0}
.co::before{content:attr(data-t);display:inline-block;border:1px solid #000;border-radius:var(--r-pill);padding:4px 10px;font:700 11px/1.2 var(--font-body);letter-spacing:.032em;text-transform:uppercase;color:#000;margin-bottom:10px}
.co>:last-child{margin-bottom:0}
.co.key{background:color-mix(in srgb,var(--blue) var(--tint),var(--surface))}.co.key::before{background:var(--blue)}
.co.check{background:color-mix(in srgb,var(--violet) var(--tint),var(--surface))}.co.check::before{background:var(--lav)}
.co.warn{background:color-mix(in srgb,var(--sun) calc(var(--tint) + 8%),var(--surface))}.co.warn::before{background:var(--ember)}
.co.ex{background:color-mix(in srgb,var(--mint) var(--tint),var(--surface))}.co.ex::before{background:var(--mint)}
.co.practice{background:var(--surface-2)}.co.practice::before{background:var(--sun)}
details.ans{margin-top:8px}
details.ans summary{cursor:pointer;display:inline-flex;list-style:none;border:1px solid var(--line);border-radius:var(--r-pill);padding:6px 12px;font:700 12px/1 var(--font-body);letter-spacing:.032em;text-transform:uppercase;background:var(--surface);color:var(--ink)}
details.ans summary::-webkit-details-marker{display:none}
details.ans[open] summary{background:var(--ink);color:var(--surface)}
details.ans>div{margin-top:10px;animation:viewIn .2s ease both}
.tbl{overflow:auto;border:1px solid var(--line);border-radius:16px;margin:14px 0}
table{border-collapse:collapse;width:100%;font-size:calc(14.5px*var(--read))}
td{padding:10px 14px;text-align:left;border-bottom:1px solid var(--hair);vertical-align:top;line-height:1.45}
th{padding:10px 14px;text-align:left;vertical-align:top;font:700 calc(11.5px*var(--read))/1.3 var(--font-body);letter-spacing:.032em;text-transform:uppercase;background:var(--surface-2);color:var(--ink);border-bottom:1px solid var(--line)}
tr:last-child td{border-bottom:0}
td:first-child{font-weight:700;color:var(--ink)}
td.c1{background:color-mix(in srgb,var(--mint) 22%,var(--surface))}td.cn{background:color-mix(in srgb,var(--sun) 26%,var(--surface))}
.ch-foot{display:flex;gap:8px;justify-content:space-between;align-items:center;flex-wrap:wrap;margin-top:16px}
.ll{margin:14px 0;border:1px dashed var(--hair);border-radius:16px;padding:10px;background:var(--surface-2);overflow:auto}
.ll svg{display:block;margin:0 auto;max-width:100%;height:auto}
.qlist{counter-reset:q;list-style:none;padding:0!important}
.qlist>li{counter-increment:q;border-top:1px solid var(--hair);padding:14px 0 10px 44px;position:relative;margin:0}
.qlist>li::before{content:counter(q);position:absolute;left:0;top:13px;width:30px;height:30px;border-radius:50%;border:1px solid var(--line);display:grid;place-items:center;font:700 12px/1 var(--font-mono);background:var(--sun);color:#000}

/* code blocks + editor */
.codebox{border:1px solid var(--line);border-radius:16px;background:var(--code-bg);margin:14px 0;overflow:hidden}
.codebox .bar2{display:flex;align-items:center;gap:6px;padding:7px 10px 7px 14px;border-bottom:1px solid var(--hair);font:700 11px/1 var(--font-body);letter-spacing:.032em;text-transform:uppercase;color:var(--muted)}
.codebox .bar2 span{margin-right:auto}
.codebox pre{margin:0;padding:14px 0;overflow:auto;font:400 calc(13.5px*var(--read))/1.62 var(--font-mono);color:var(--ink);tab-size:4;counter-reset:ln}
.codebox pre .l{display:block;padding:0 18px 0 0;white-space:pre}
.codebox pre .l::before{counter-increment:ln;content:counter(ln);display:inline-block;width:44px;padding-right:14px;text-align:right;color:var(--muted);opacity:.6;user-select:none}
.codebox pre .l{transition:background-color .22s,box-shadow .22s}
.codebox pre .l.hot{background:color-mix(in srgb,var(--sun) 40%,transparent);box-shadow:inset 3px 0 0 var(--ember)}
.t-kw{color:var(--kw);font-weight:600}.t-kc{color:var(--kc);font-weight:600}.t-str{color:var(--str)}.t-num{color:var(--num)}.t-const{color:var(--num);font-weight:600}.t-com{color:var(--com);font-style:italic}.t-fn{color:var(--fn);font-weight:600}.t-call{color:var(--call)}.t-bi{color:var(--bi)}.t-self{color:var(--self);font-style:italic}.t-cls{color:var(--cls);font-weight:600}.t-attr{color:var(--attr)}.t-op{color:var(--op)}.t-dec{color:var(--bi)}.t-b0{color:var(--b0)}.t-b1{color:var(--b1)}.t-b2{color:var(--b2)}
.editor{position:relative;display:grid;grid-template-columns:48px 1fr;background:var(--code-bg);font:400 calc(14px*var(--read))/1.6 var(--font-mono);min-height:0;overflow:hidden;height:100%}
.editor .gut{padding:14px 10px 14px 0;text-align:right;color:var(--muted);opacity:.7;user-select:none;overflow:hidden;white-space:pre;border-right:1px solid var(--hair)}
.editor .gut .err{color:#000;background:var(--ember);border-radius:6px;padding:0 4px;margin-right:-4px;opacity:1}
.editor .area{position:relative;overflow:hidden}
.editor pre,.editor textarea{position:absolute;inset:0;margin:0;padding:14px 16px;border:0;font:inherit;white-space:pre;overflow:auto;tab-size:4;letter-spacing:0}
.editor pre{color:var(--ink);pointer-events:none;overflow:hidden}
.editor textarea{background:transparent;color:transparent;caret-color:var(--ink);resize:none;outline:none}
.editor textarea::selection{background:color-mix(in srgb,var(--blue) 40%,transparent);color:transparent}

/* code view */
.codeview{max-width:1600px;margin:0 auto;padding:16px 20px 30px}
.subnav{display:flex;gap:4px;margin-bottom:14px;flex-wrap:wrap;align-items:center}
.ptable td,.ptable th{padding:12px 16px}
.ptable tr.row{cursor:pointer;transition:background .12s}
.ptable tr.row:hover td{background:var(--surface-2)}
.dot{display:inline-grid;place-items:center;width:22px;height:22px;border-radius:50%;border:1px solid var(--line);font-size:12px;background:var(--surface);color:#000}
.dot.ok{background:var(--mint)}
.diff{font:700 11px/1 var(--font-body);letter-spacing:.032em;text-transform:uppercase;border:1px solid #000;border-radius:99px;padding:4px 9px;color:#000}
.diff.Easy{background:var(--mint)}.diff.Medium{background:var(--sun)}.diff.Hard{background:var(--ember)}
.ws{display:grid;grid-template-columns:minmax(320px,42%) minmax(0,1fr);gap:12px;height:calc(100vh - 150px - var(--backh));min-height:560px}
@media(max-width:1000px){.notes{grid-template-columns:1fr}.toc{position:static;max-height:300px}}
.pane{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-card);display:flex;flex-direction:column;min-height:0;overflow:hidden}
.pane-h{display:flex;align-items:center;gap:6px;padding:9px 12px;border-bottom:1px solid var(--line);flex-wrap:wrap}
.pane-h .sp{margin-left:auto}
.pane-b{padding:18px 22px;overflow:auto;flex:1;min-height:0}
.pane-b h2{font:700 calc(24px*var(--read))/1.2 var(--font-body);margin-bottom:10px}
.pane-b p,.pane-b li{font-size:calc(15px*var(--read));line-height:1.65}
.pane-b pre.io{background:var(--surface-2);border:1px solid var(--hair);border-radius:12px;padding:10px 14px;font:400 calc(13px*var(--read))/1.55 var(--font-mono);white-space:pre-wrap;color:var(--ink);margin:8px 0 14px}
.right{display:grid;grid-template-rows:minmax(0,1.5fr) minmax(0,1fr);gap:12px;min-height:0}
.console{font:400 calc(13px*var(--read))/1.55 var(--font-mono)}
.case-tabs{display:flex;gap:4px;flex-wrap:wrap;margin-bottom:10px}
.kv{display:grid;grid-template-columns:96px 1fr;gap:6px 12px;align-items:start;margin-bottom:8px}
.kv label{font:700 11px/1.9 var(--font-body);letter-spacing:.032em;text-transform:uppercase;color:var(--muted)}
.kv pre,.kv input{margin:0;background:var(--surface-2);border:1px solid var(--hair);border-radius:10px;padding:6px 10px;font:400 calc(13px*var(--read))/1.5 var(--font-mono);white-space:pre-wrap;word-break:break-word;color:var(--ink);width:100%}
.kv pre.bad{border-color:var(--ember);background:color-mix(in srgb,var(--ember) 12%,var(--surface))}
.verdict{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:12px}
.verdict b{font:800 calc(34px*var(--read))/.9 var(--font-display);font-synthesis:none;text-transform:uppercase;color:var(--ink)}
.verdict .st{width:38px;height:38px;border-radius:14px;border:1px solid #000;display:grid;place-items:center;font-size:18px;color:#000;transform:rotate(-8deg)}
.verdict.ok .st{background:var(--mint)}.verdict.no .st{background:var(--ember)}
.errbox{border:1px solid var(--ember);background:color-mix(in srgb,var(--ember) 10%,var(--surface));border-radius:12px;padding:10px 14px;white-space:pre-wrap;color:var(--ink);font:400 calc(13px*var(--read))/1.55 var(--font-mono);margin:0 0 10px}
.out{white-space:pre-wrap;word-break:break-word;color:var(--ink);margin:0}
.pg{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr);gap:12px;height:calc(100vh - 150px - var(--backh));min-height:520px}
@media(max-width:1000px){.pg{grid-template-columns:1fr;height:auto}.pg .pane{min-height:420px}}
.pg-in{display:inline-block;vertical-align:baseline;width:min(28ch,100%);max-width:100%;box-sizing:border-box;margin:0;padding:0 6px;border:1px solid var(--ink);border-radius:6px;background:var(--surface-2);color:var(--ink);font:400 calc(13px*var(--read))/1.4 var(--font-mono)}
.pg textarea.stdin{width:100%;border:1px solid var(--hair);border-radius:10px;background:var(--surface-2);padding:8px 10px;font:400 calc(13px*var(--read))/1.5 var(--font-mono);resize:vertical;min-height:54px}
select.pill{appearance:none;padding-right:26px;background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,transparent 50%);background-position:calc(100% - 15px) 55%,calc(100% - 10px) 55%;background-size:5px 5px;background-repeat:no-repeat}

/* lab */
.lab{display:grid;grid-template-columns:minmax(0,1fr) 400px;gap:12px}
@media(max-width:1100px){.lab{grid-template-columns:1fr}}
.stage{position:relative;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-big);overflow:hidden}
.stage svg{display:block;width:100%;height:400px}
.narr{border-top:1px solid var(--line);padding:14px 20px;min-height:58px;font-size:calc(15.5px*var(--read));color:var(--ink);display:flex;gap:10px;align-items:center}
.transport{display:flex;gap:6px;align-items:center;padding:10px 14px;border-top:1px solid var(--hair);flex-wrap:wrap}
.transport input[type=range]{accent-color:var(--violet);width:110px}
.ops{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.field{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--line);border-radius:var(--r-pill);padding:4px 6px 4px 12px;background:var(--surface);font:700 12px/1 var(--font-body);letter-spacing:.032em;text-transform:uppercase;color:var(--ink)}
.field input{width:58px;border:0;background:var(--surface-2);border-radius:99px;padding:6px 8px;font:500 13px/1 var(--font-mono);text-align:center;outline:none}
.vars{display:flex;gap:6px;flex-wrap:wrap;padding:10px 14px;border-top:1px solid var(--hair);min-height:46px}
.vars span{font:500 calc(12px*var(--read))/1 var(--font-mono);border:1px solid var(--hair);border-radius:99px;padding:6px 10px;background:var(--surface-2);color:var(--ink)}
svg .nd rect{fill:var(--surface);stroke:var(--line);stroke-width:1.2}
svg .nd .cell{fill:var(--surface-2)}
svg .nd text{font:600 14px var(--font-mono);fill:var(--ink);text-anchor:middle;dominant-baseline:central}
svg .nd .addr{font:400 9px var(--font-mono);fill:var(--muted)}
svg .lk{fill:none;stroke:var(--ink);stroke-width:1.6}
svg .lk.prev{stroke:var(--violet)}
svg .lk.hot{stroke:var(--ember);stroke-width:2.8}
svg .ah{fill:var(--ink)}svg .ah.prev{fill:var(--violet)}svg .ah.hot{fill:var(--ember)}
svg .nd text.nul{font:500 8.5px var(--font-mono);fill:var(--muted);dominant-baseline:central}
svg .lab-t{font:700 10.5px var(--font-mono);dominant-baseline:central;text-anchor:middle}
svg .port{fill:var(--ink)}

/* quiz */
.quiz{max-width:860px;margin:0 auto}
.qcard h3{font:700 calc(22px*var(--read))/1.35 var(--font-body);margin:12px 0 18px}
.opt{display:flex;gap:12px;align-items:center;width:100%;text-align:left;border:1px solid var(--line);background:var(--surface);border-radius:16px;padding:13px 16px;margin-bottom:8px;font-size:calc(15.5px*var(--read));color:var(--ink);transition:transform .12s,background .12s}
@media(hover:hover){.opt:hover:not([disabled]){transform:translateX(4px);background:var(--surface-2)}}
.opt .k{flex:none;width:28px;height:28px;border-radius:50%;border:1px solid var(--line);display:grid;place-items:center;font:700 12px/1 var(--font-mono);background:var(--surface);color:#000}
.opt.right{background:color-mix(in srgb,var(--mint) 35%,var(--surface))}.opt.right .k{background:var(--mint)}
.opt.wrong{background:color-mix(in srgb,var(--ember) 22%,var(--surface));animation:shake .3s}.opt.wrong .k{background:var(--ember)}
@keyframes shake{25%{transform:translateX(-6px)}75%{transform:translateX(6px)}}
.pips{display:flex;gap:3px;flex-wrap:wrap}
.pips i{width:14px;height:14px;border-radius:50%;border:1px solid var(--line);background:var(--surface)}
.pips i.ok{background:var(--mint)}.pips i.no{background:var(--ember)}.pips i.cur{background:var(--ink)}.pips i.ans{background:var(--lav)}.pips i.cur.ans{background:var(--ink);box-shadow:inset 0 0 0 3px var(--lav)}
.opt.sel{background:color-mix(in srgb,var(--lav) 30%,var(--surface))}.opt.sel .k{background:var(--lav)}
.hub{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(240px,100%),1fr));gap:12px}
.hubcard{display:flex;flex-direction:column;align-items:flex-start;gap:8px}
.hubcard h3{font:700 calc(22px*var(--read))/1.2 var(--font-body);margin:6px 0 0}
.hubcard p{font-size:calc(15.5px*var(--read));line-height:1.55;margin:0}
.hubcard .pill{margin-top:auto;white-space:normal;line-height:1.3}
.chrows{display:grid;gap:8px;margin-top:12px}
.chrow{display:flex;flex-wrap:wrap;gap:6px 12px;align-items:center;width:100%;text-align:left;border:1px solid var(--line);background:var(--surface);border-radius:16px;padding:11px 14px;color:var(--ink);font-size:calc(15px*var(--read))}
@media(hover:hover){.chrow:hover{background:var(--surface-2)}}
.chrow .no{flex:none;min-width:28px;height:28px;border-radius:50%;border:1px solid var(--line);background:var(--lav);color:#000;display:grid;place-items:center;font:700 12px/1 var(--font-mono)}
.chrow .t{flex:1 1 12ch;min-width:0}
.chrow .c{margin-left:auto;font-size:calc(13px*var(--read));color:var(--muted)}
.qnav{display:flex;gap:8px;flex-wrap:wrap;justify-content:space-between;align-items:center;margin-top:12px}
.qrev{margin:12px 0 0;padding-left:24px}
.qrev li{font-size:calc(15.5px*var(--read));line-height:1.6;margin-bottom:18px}
.qrev .qq{font-weight:700}.qrev .qa{margin-top:4px}

/* arcade */
.gamehead{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:12px}
.gamehead h2{font:800 clamp(40px,5vw,70px)/.9 var(--font-display);text-transform:uppercase;margin-right:auto}
.hud{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.gbox{position:relative;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-big);overflow:hidden}
.gbox canvas{display:block;width:100%;height:auto;touch-action:none}
.overlay{position:absolute;inset:0;display:grid;place-items:center;background:color-mix(in srgb,var(--bg) 82%,transparent);text-align:center;padding:20px;z-index:5}
.overlay h3{font:800 clamp(44px,7vw,96px)/.9 var(--font-display);text-transform:uppercase;margin-bottom:14px}
.overlay p{max-width:520px;margin:0 auto 16px;color:var(--ink);font-size:calc(15.5px*var(--read));line-height:1.55}
.listline{font:500 13px/1.6 var(--font-mono);color:var(--ink);padding:12px 18px;border-top:1px solid var(--line);overflow:auto;white-space:nowrap}
.surgeon{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);gap:12px}
@media(max-width:1000px){.surgeon{grid-template-columns:1fr}}
.zone{min-height:74px;border:1px dashed var(--line);border-radius:16px;padding:8px;display:flex;flex-direction:column;gap:6px;background:var(--surface-2)}
.zone.tray{flex-direction:row;flex-wrap:wrap;align-content:flex-start}
.zone.over{background:color-mix(in srgb,var(--blue) 22%,var(--surface))}
.stmt{border:1px solid var(--line);border-radius:12px;background:var(--surface);padding:10px 14px;font:500 14px/1.3 var(--font-mono);color:var(--ink);cursor:grab;user-select:none;touch-action:none;display:flex;gap:10px;align-items:center}
.stmt::before{content:'⠿';color:var(--muted)}
.stmt.fixed{cursor:default;border-style:dashed;color:var(--muted);background:transparent}
.stmt.fixed::before{content:''}
.stmt.drag{position:fixed;z-index:99;pointer-events:none;transform:rotate(-2deg) scale(1.03);background:var(--sun);color:#000}
.stmt.ghost{opacity:.25}
.stmt.run{background:var(--sun);color:#000}
.drop-wrap{position:relative;height:540px}
.faller{position:absolute;width:260px;border:1px solid #000;border-radius:20px;padding:14px 16px;background:var(--lav);color:#000;font-weight:700;font-size:15px;line-height:1.3;cursor:grab;touch-action:none;user-select:none;text-align:center}
.faller small{display:block;font:700 10.5px/1.4 var(--font-body);letter-spacing:.032em;text-transform:uppercase;margin-bottom:5px;opacity:.7}
.bins{position:absolute;left:0;right:0;bottom:0;height:96px;display:grid;grid-template-columns:1fr 1fr;border-top:1px solid var(--line)}
.bins div{display:grid;place-items:center;font:800 54px/1 var(--font-display);color:#000}
.bins div:first-child{background:var(--mint);border-right:1px solid var(--line)}.bins div:last-child{background:var(--sun)}
.bins div.flash{animation:flash .35s}
@keyframes flash{50%{filter:brightness(1.25);transform:scale(1.03)}}
.linkit svg{display:block;width:100%;height:520px;touch-action:none;user-select:none}
.linkit .gn{cursor:grab}
.linkit .gport{cursor:crosshair}
.toast.act{pointer-events:auto;display:flex;align-items:center;gap:12px;padding:8px 8px 8px 20px}
.toast{position:fixed;left:50%;bottom:calc(26px + var(--tabbar) + var(--safe-b));transform:translate(-50%,30px);background:var(--ink);color:var(--surface);border-radius:99px;padding:12px 20px;font:700 13px/1.3 var(--font-body);letter-spacing:.032em;opacity:0;transition:opacity .25s,transform .38s cubic-bezier(.2,1.5,.4,1);z-index:200;pointer-events:none}
.toast.on{opacity:1;transform:translate(-50%,0)}
.confetti{position:fixed;z-index:300;width:16px;height:16px;border:1px solid #000;border-radius:5px;pointer-events:none}
@media(max-width:820px){.hero-in{padding:32px 16px 40px;min-height:0}.hero .sticker{display:none}.wrap{padding:20px 14px 60px}.notes{padding:12px 12px 60px}.sub{padding:18px 16px}.ch-head{padding:22px 18px;border-radius:26px}.ch-head .crumb{padding-right:84px}.ch-head .blob{width:120px;height:120px;font-size:60px;padding:14px 16px 0 0;right:-20px;top:-20px}.codeview{padding:12px}.pane-b{padding:14px}.stage svg{height:300px}.linkit svg{height:380px}.drop-wrap{height:460px}.faller{width:210px}}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms!important;animation-delay:0s!important;animation-iteration-count:1!important;transition:none!important;scroll-behavior:auto!important}.marquee div{animation:none}}
@media print{.nav,.toc,.marquee,.ch-foot,.acts{display:none!important}.chapter{display:block!important}.notes{display:block}body{background:#fff}}

/* shell additions: module switcher, course home, load error */
body[data-view=course] #mainnav,body[data-view=err] #mainnav,body[data-view=play] #mainnav{visibility:hidden}
.modsw{position:relative;flex:none}
.modsw-menu{position:absolute;top:calc(100% + 8px);left:0;z-index:60;display:flex;flex-direction:column;gap:4px;padding:10px;min-width:230px}
.modsw-menu .pill{justify-content:flex-start}
.pill[aria-disabled=true]{opacity:.5;cursor:default;border-style:dashed}
.pill[aria-disabled=true]:hover{transform:none;background:var(--surface)}
.packerr{max-width:720px;margin:40px auto}
.packerr h2{font:700 30px/1.15 var(--font-body);margin:14px 0 8px}
.packerr p{font-size:calc(16px*var(--read));line-height:1.6;margin:0 0 18px}
.modcard{display:flex;flex-direction:column;gap:10px;min-height:230px;text-decoration:none;transition:transform .15s}
@media(hover:hover){a.modcard:hover{transform:translateY(-3px) rotate(-.4deg)}}
.modcard .num{font:800 84px/.8 var(--font-display);color:#000;font-synthesis:none}
.modcard h3{font:700 calc(24px*var(--read))/1.15 var(--font-body);color:#000}
.modcard p{margin:0;color:#111}
.modcard.soon{background:var(--surface);border-style:dashed}
.modcard.soon .num,.modcard.soon h3{color:var(--muted)}
.modcard .meter{margin-top:auto;display:grid;gap:6px}
.modcard .meter span{font:700 11px/1.3 var(--font-body);letter-spacing:.032em;text-transform:uppercase;color:#000}
.toc-toggle{display:none}
.stage-scroll{overflow-x:auto}

/* array, ring, grid and stack drawings (modules/m2/draw.js) */
.dg{margin:14px 0;border:1px dashed var(--hair);border-radius:16px;padding:12px;background:var(--surface-2);overflow:auto}
.dg svg{display:block;margin:0 auto;max-width:none}
.dg-cap{text-align:center;font-size:calc(13px*var(--read));color:var(--muted);margin-top:6px}
.dgs .c{fill:var(--surface);stroke:var(--line);stroke-width:1.2}
.dgs .c.dim{fill:var(--surface-2)}
.dgs .c.hot{fill:var(--sun)}.dgs .c.ok{fill:var(--mint)}.dgs .c.bad{fill:var(--ember)}.dgs .c.ghost{opacity:.35}
.dgs .v{font:600 14px var(--font-mono);fill:var(--ink);text-anchor:middle;dominant-baseline:central}
.dgs .v.sm{font-size:10.5px}.dgs .v.on{fill:#000}
.dgs .ix{font:500 10.5px var(--font-mono);fill:var(--muted);text-anchor:middle}
.dgs .mk{font:700 10.5px var(--font-mono);text-anchor:middle;dominant-baseline:central}
.dgs .lbl{font:700 14px var(--font-mono);fill:var(--ink);text-anchor:end;dominant-baseline:central}
.dgs .ctr{font:700 13px var(--font-mono);fill:var(--muted);text-anchor:middle;dominant-baseline:central}
.dgs .track{fill:none;stroke:var(--hair);stroke-width:1.5;stroke-dasharray:4 5}
.dgs .ptr{stroke:var(--ink);stroke-width:1.4;fill:none}
/* trees and B+ trees (modules/m4/tree.js) */
.dgs .tn .ns{fill:var(--surface);stroke:var(--line);stroke-width:1.2}
.dgs .tn.hot .ns{fill:var(--sun)}.dgs .tn.ok .ns{fill:var(--mint)}.dgs .tn.bad .ns{fill:var(--ember)}
.dgs .tn.dim{opacity:.38}
.dgs .tn.ghost{opacity:.55}.dgs .tn.ghost .ns{stroke-dasharray:4 3;fill:var(--surface-2)}
.dgs .te{stroke:var(--ink);stroke-width:1.4;fill:none}
.dgs .te.on{stroke:var(--ember);stroke-width:3.2}
.dgs .sl{stroke:var(--muted);stroke-width:1;fill:none;stroke-dasharray:2 3}
.dgs .stub{fill:var(--surface-2);stroke:var(--muted);stroke-width:1;stroke-dasharray:2 2}
.dgs .thread{stroke:var(--blue);stroke-width:1.8;fill:none;stroke-dasharray:5 4}
.dgs .ah{fill:var(--blue);stroke:none}
.dgs .nul{font:700 12px var(--font-mono);fill:var(--muted);text-anchor:middle;dominant-baseline:central}
.dgs .bdg{font:700 10.5px var(--font-mono);fill:var(--ink);text-anchor:middle;dominant-baseline:central;paint-order:stroke;stroke:var(--surface-2);stroke-width:3px;stroke-linejoin:round}
.dgs .bn.over .c{stroke:var(--ember);stroke-width:2}
.dgs .bl{stroke:var(--muted);stroke-width:1.4;fill:none;stroke-dasharray:4 4}
.dgs .bl+.ah{fill:var(--muted)}
.dgs .cut{stroke:var(--ember);stroke-width:2.5;fill:none}
/* Module IV games: a tree whose nodes are buttons (paintBoard in modules/m4/tree.js) */
.gplay{user-select:none;-webkit-user-select:none}
.gscroll{overflow-x:auto;padding:8px 0 4px}
.gtree{position:relative;margin:0 auto}
.gedges{position:absolute;inset:0;transition:opacity .2s;pointer-events:none}
.gedges line{stroke:var(--ink);stroke-width:1.6}
.gedges line.on{stroke:var(--ember);stroke-width:3.4}
.gedges line.faint{stroke:var(--muted);stroke-dasharray:3 4}
.gedges path{fill:none;stroke:var(--blue);stroke-width:2;stroke-dasharray:5 4}
.gnode{position:absolute;width:42px;height:42px;border-radius:50%;border:1px solid var(--line);background:var(--surface);color:var(--ink);display:grid;place-items:center;padding:0;font:700 14px/1 var(--font-mono);transition:left .35s,top .35s,background-color .15s;touch-action:none;z-index:1;cursor:pointer}
.gnode b{font-weight:700}.gnode b.sm{font-size:11px}
.gnode small{position:absolute;top:-12px;right:-12px;font:700 10.5px/1 var(--font-mono);color:var(--ink);background:var(--surface-2);border:1px solid var(--hair);border-radius:8px;padding:2px 4px;pointer-events:none}
.gnode.hot{background:var(--sun);color:#000}.gnode.ok{background:var(--mint);color:#000}.gnode.bad{background:var(--ember);color:#000}
.gnode.dim{opacity:.4}
.gnode.sel{outline:3px solid var(--violet);outline-offset:2px}
.gnode.over{outline:3px solid var(--blue);outline-offset:2px}
.gnode.dragging{z-index:4;transition:none}
.gnode.gslot{border-style:dashed;background:var(--surface-2);color:var(--muted)}
.gnode:focus-visible{outline:3px solid var(--ink);outline-offset:2px}
.gstrip{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.gchip{min-width:40px;height:40px;padding:0 10px;border:1px solid var(--line);border-radius:12px;background:var(--surface);color:var(--ink);display:inline-grid;place-items:center;font:700 14px/1 var(--font-mono);touch-action:none;cursor:pointer}
.gchip.hot{background:var(--sun);color:#000}.gchip.ok{background:var(--mint);color:#000}.gchip.dim{opacity:.35}.gchip.sel{outline:3px solid var(--violet);outline-offset:2px}
.gchip.dragging{position:relative;z-index:4}
.gtree .gfall{position:absolute;z-index:3;width:46px;min-width:0;padding:0;height:34px;border-width:2px;box-shadow:0 3px 0 var(--line);cursor:grab;transition:left .35s,top .35s}
.gtree .gfall.dragging{position:absolute;transition:none;cursor:grabbing}
.gtree .gcol{position:absolute;min-width:0;width:32px;height:32px;padding:0;border-radius:9px;font-size:13px;cursor:default;transition:opacity .25s,background-color .25s}
.gtree .gpeg{position:absolute;min-width:0;width:54px;height:32px;padding:0;border-style:dashed;border-radius:9px;font-size:12px;letter-spacing:.04em}
.gtree .gpeg.over{outline:3px solid var(--blue);outline-offset:2px}
.gedges.gwire path{stroke-width:3.2;stroke-dasharray:7 5}
.gtree .gcap{position:absolute;left:0;font:700 10.5px/1 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);white-space:nowrap}
.sub>.dg,.sub>.q,.sub>.two{max-width:none}

/* formulae, question blocks and answer boxes in the notes */
.eq{font:500 calc(15.5px*var(--read))/1.7 var(--font-mono);text-align:center;margin:12px 0;color:var(--ink);overflow-x:auto;white-space:nowrap}
.eq.box{border:1px solid var(--line);border-radius:12px;padding:8px 16px;width:fit-content;max-width:100%;margin:14px auto;background:var(--surface-2)}
.co .eq.box,.q .eq.box{background:var(--surface)}
.q{border:1px solid var(--line);border-radius:var(--r-card);padding:16px 20px 14px;margin:16px 0;background:var(--surface-2)}
.q>:last-child{margin-bottom:0}
.q-head{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:10px}
.q-head b{font-size:calc(15.5px*var(--read));color:var(--ink)}
.ask{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:10px 0}
.ask label{display:inline-flex;align-items:center;gap:10px;border:1px solid var(--line);border-radius:var(--r-pill);padding:4px 5px 4px 14px;background:var(--surface);font:700 calc(12px*var(--read))/1.2 var(--font-body);letter-spacing:.032em;text-transform:uppercase;color:var(--ink);flex:1 1 280px;max-width:560px}
.ask input{flex:1;min-width:90px;border:0;background:var(--surface-2);border-radius:99px;padding:9px 12px;font:500 calc(14px*var(--read))/1 var(--font-mono);outline:none;text-transform:none;letter-spacing:0}
.ask.ok label{background:color-mix(in srgb,var(--mint) 45%,var(--surface))}
.ask.no label{background:color-mix(in srgb,var(--ember) 22%,var(--surface));animation:shake .3s}
.ask-msg{font:700 calc(12.5px*var(--read))/1.3 var(--font-body);color:var(--ink)}
.two{display:grid;grid-template-columns:1fr 1fr;gap:12px}
@media(max-width:820px){.two{grid-template-columns:1fr}.q{padding:14px 14px 12px}}

/* lab player additions */
.dgs .rt{font:700 10.5px var(--font-body);fill:var(--muted);text-anchor:middle;letter-spacing:.04em;text-transform:uppercase}
.field.wide input{width:230px;text-align:left}
.field select{border:0;background:var(--surface-2);border-radius:99px;padding:6px 8px;font:500 13px/1 var(--font-mono);outline:none;text-transform:none;letter-spacing:0}
.player-help ul{padding-left:18px;margin:12px 0 0;line-height:1.6;font-size:calc(14px*var(--read))}
.player-code{max-height:520px}
.narr{flex-wrap:wrap}

/* Module II games: shared board pieces */
.yard{padding:18px 20px 16px;display:grid;gap:12px}
.yard-in{display:flex;flex-direction:column;gap:6px;align-items:flex-start}
.yard-expr{font:800 clamp(30px,5vw,56px)/1 var(--font-display);color:var(--ink);letter-spacing:.02em;font-synthesis:none}
.rail{display:flex;gap:12px;align-items:center;border:1px solid var(--line);border-radius:var(--r-pill);padding:8px 16px;background:var(--surface-2);min-height:62px;overflow-x:auto}
.rail>.up{flex:none}
.pieces{display:flex;gap:6px;align-items:center;flex-wrap:wrap;min-height:44px}
.rail .pieces{flex-wrap:nowrap}
.piece{flex:none;display:inline-grid;place-items:center;min-width:44px;height:44px;padding:0 10px;border:1px solid #000;border-radius:14px;background:var(--lav);color:#000;font:700 18px/1 var(--font-mono);user-select:none;-webkit-user-select:none;transition:transform .18s;cursor:default}
.piece.and{background:var(--sun)}.piece.op{background:var(--lav)}.piece.par{background:var(--blue)}.piece.car{background:var(--blue);border-radius:12px 12px 6px 6px}
.piece.wait{opacity:.55}.piece.done{background:var(--mint)}.piece.ghost{background:var(--surface);border-style:dashed;color:var(--muted)}.piece.want{background:var(--sun);outline:2px solid var(--ink);outline-offset:2px}
#sy-head,#sy-top,#st-head,#st-top{cursor:grab;position:relative;z-index:3}
.piece.dragging{transition:none;cursor:grabbing;z-index:9}
.slot{flex:none;width:44px;height:44px;border:1px dashed var(--line);border-radius:12px;opacity:.5}
.yard-cols{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.zone2{border:1px dashed var(--line);border-radius:20px;padding:12px 14px;background:var(--surface-2);display:flex;flex-direction:column;gap:8px;min-height:104px;transition:background .12s}
.zone2.over{background:color-mix(in srgb,var(--blue) 26%,var(--surface))}
.yard-msg{border:1px solid var(--line);border-radius:16px;padding:12px 16px;font-size:calc(15px*var(--read));line-height:1.5;color:var(--ink);background:var(--surface);min-height:48px}
.yard-msg.no{background:color-mix(in srgb,var(--ember) 16%,var(--surface))}.yard-msg.ok{background:color-mix(in srgb,var(--mint) 22%,var(--surface))}
.yard-msg.shake,.ask.no label{animation:shake .3s}
.yard-btns{gap:6px}
.pill.c-ember{color:#000}
@media(max-width:820px){.yard{padding:14px 12px}.yard-cols{grid-template-columns:1fr}.piece{min-width:38px;height:38px;font-size:16px}.slot{width:38px;height:38px}}

/* Tower of Hanoi */
.hn-rule{font-size:calc(15px*var(--read));line-height:1.5;color:var(--ink);max-width:70ch}
.hn-board{--dh:26px;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;align-items:end;padding-top:34px}
.hn-peg{position:relative;border:1px dashed var(--line);border-radius:20px;background:var(--surface-2);padding:10px 8px 0;cursor:pointer;transition:background .15s,border-color .15s,transform .15s;-webkit-tap-highlight-color:transparent}
.hn-peg.over,.hn-peg.held{background:color-mix(in srgb,var(--blue) 24%,var(--surface))}
.hn-peg.aim{background:color-mix(in srgb,var(--sun) 34%,var(--surface));border-style:solid}
.hn-stack{position:relative;display:flex;flex-direction:column-reverse;align-items:center;gap:3px;height:calc((var(--n) + 1)*(var(--dh) + 3px))}
.hn-stack::before{content:'';position:absolute;left:50%;top:0;bottom:0;width:8px;transform:translateX(-50%);border:1px solid var(--line);border-bottom:0;border-radius:8px 8px 0 0;background:var(--surface)}
.hn-disc{position:relative;z-index:1;flex:none;width:var(--w);height:var(--dh);border:1px solid #000;border-radius:99px;background:var(--c);color:#000;font:700 13px/1 var(--font-mono);display:grid;place-items:center;user-select:none;-webkit-user-select:none;transition:transform .18s,box-shadow .18s}
.hn-disc.top{cursor:grab}
.hn-peg.held .hn-disc.top{transform:translateY(-16px);box-shadow:0 10px 0 -6px color-mix(in srgb,var(--ink) 25%,transparent)}
.hn-disc.aim{outline:2px solid var(--ink);outline-offset:2px;animation:hnAim .9s ease-in-out infinite}
@keyframes hnAim{50%{transform:translateY(-7px)}}
.hn-disc.dragging{transition:none;cursor:grabbing;z-index:9;box-shadow:0 8px 18px -8px rgba(0,0,0,.5)}
.hn-base{border-top:1px solid var(--line);margin:0 -8px;padding:7px 4px 9px;text-align:center;display:grid;gap:2px;font:500 11.5px/1.3 var(--font-mono);color:var(--muted)}
.hn-base b{font:800 22px/1 var(--font-display);color:var(--ink);font-synthesis:none}
@media(max-width:820px){.hn-board{--dh:22px;gap:6px;padding-top:26px}.hn-peg{padding:8px 4px 0;border-radius:16px}.hn-base{margin:0 -4px;font-size:10px}.hn-disc{font-size:11.5px}}

/* Ring Rush */
.ringbox{padding:18px 20px;display:grid;gap:14px}
.rr-call{display:grid;gap:8px;max-width:520px}
.rr-op{font:800 clamp(34px,6vw,64px)/1 var(--font-display);color:var(--ink);font-synthesis:none}
.rr-stage{display:grid;grid-template-columns:minmax(0,420px) minmax(0,1fr);gap:20px;align-items:center}
.rr-ring{position:relative;width:100%;max-width:420px;aspect-ratio:1;margin:0 auto}
.rcell{position:absolute;transform:translate(-50%,-50%);width:17%;aspect-ratio:1;border:1px solid var(--line);border-radius:18px;background:var(--sun);color:#000;font:700 clamp(14px,2.4vw,20px)/1 var(--font-mono);display:grid;place-items:center;touch-action:manipulation;transition:transform .12s}
.rcell.free{background:var(--surface-2);border-style:dashed}
@media(hover:hover){.rcell:hover{transform:translate(-50%,-50%) scale(1.06)}}
.rcell.ok{background:var(--mint)}.rcell.bad{background:var(--ember)}
.ridx{position:absolute;transform:translate(-50%,-50%);font:700 12px/1.2 var(--font-mono);color:var(--muted);display:grid;justify-items:center;gap:2px;pointer-events:none;text-align:center}
.ridx b{font:700 10px/1 var(--font-mono);border:1px solid #000;border-radius:99px;padding:3px 6px;color:#000}
.ridx .t-front{background:var(--mint)}.ridx .t-rear{background:var(--ember)}
.rmid{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);text-align:center;font:700 13px/1.5 var(--font-mono);color:var(--muted)}
.rr-side{display:flex;flex-direction:column;gap:10px;align-items:flex-start}
.rr-side .pill{font-size:15px;padding:13px 22px}
.rr-note{margin:6px 0 0;font-size:calc(15.5px*var(--read));line-height:1.5;color:var(--ink);min-height:70px;border-radius:14px;padding:2px 0}
.rr-note.no{background:color-mix(in srgb,var(--ember) 16%,transparent);padding:10px 12px}
.rr-vars{margin:0;font:500 13px/1.4 var(--font-mono)}
/* Address Hunt */
.hunt{padding:18px 20px;display:grid;gap:14px}
.hunt-q{display:grid;gap:8px}
.hunt-ask{font:800 clamp(30px,5vw,56px)/1 var(--font-display);color:var(--ink);font-synthesis:none}
.hunt-cols{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.25fr);gap:18px;align-items:start}
.hgrid{display:inline-grid;gap:3px;margin-top:8px;max-width:100%;overflow:auto}
.hrow{display:flex;gap:3px}
.hlab{flex:none;width:34px;height:20px;display:grid;place-items:center;font:500 11px/1 var(--font-mono);color:var(--muted)}
.hrow .hlab:first-child{height:34px}
.hcell{flex:none;width:34px;height:34px;border:1px solid var(--line);border-radius:8px;background:var(--surface)}
.hcell.hot{background:var(--sun);outline:2px solid var(--ink);outline-offset:1px}
.hmem{display:flex;flex-wrap:wrap;gap:4px;margin-top:8px}
.mcell{flex:none;min-width:54px;height:36px;padding:0 6px;border:1px solid var(--line);border-radius:10px;background:var(--surface);color:var(--ink);font:600 12.5px/1 var(--font-mono);touch-action:manipulation;transition:transform .1s}
@media(hover:hover){.mcell:hover{transform:translateY(-2px);background:var(--surface-2)}}
.mcell.ok{background:var(--mint);color:#000}.mcell.bad{background:var(--ember);color:#000}
@media(max-width:820px){.rr-stage,.hunt-cols{grid-template-columns:1fr}.ringbox,.hunt{padding:14px 12px}.mcell{min-width:48px;height:34px;font-size:11.5px}.hcell,.hlab{width:28px}.hcell{height:28px}.hrow .hlab:first-child{height:28px}}

/* ---------- phone and tablet layout ---------- */
.pane>.editor{flex:1;min-height:0}
@media(max-width:1000px){
  .notes{grid-template-columns:minmax(0,1fr)}
  .toc-toggle{display:inline-flex;position:fixed;left:12px;bottom:calc(14px + var(--tabbar) + var(--safe-b));z-index:80;background:var(--ink);color:var(--surface)}
  .toc{display:none;position:fixed;inset:0;top:0;z-index:70;max-height:none;border-radius:0;border:0;padding:70px 16px 40px;overflow:auto}
  .toc.open{display:block}
  .toc.open~.reader{visibility:hidden}
  body.focus .toc-toggle{display:none}
  .lab{grid-template-columns:minmax(0,1fr)}
  .lab>div{min-width:0}
}
@media(max-width:820px){
  .modsw .pill{padding:9px 11px;font-size:12px}
  .tools .pill.icon{width:34px;height:34px;font-size:13px}
  .logo{width:36px;height:36px;font-size:12px}
  .stage svg{height:auto;aspect-ratio:16/9}
  .gamehead h2{font-size:clamp(34px,10vw,56px)}
  .band h2{font-size:clamp(44px,13vw,80px)}
  .card{padding:18px}
  .card.big{border-radius:26px}
  .kv{grid-template-columns:76px minmax(0,1fr)}
  .field.wide input{width:150px}
  .eq{font-size:calc(13.5px*var(--read))}
  .ask label{flex-basis:100%}
  .ptable td:nth-child(4),.ptable th:nth-child(4),.ptable td:nth-child(6),.ptable th:nth-child(6){display:none}
  .toast{max-width:calc(100vw - 24px);white-space:normal;text-align:center;border-radius:20px}
}
@media(max-width:480px){
  .hero h1{font-size:19vw}
  .hero .lead{font-size:17px}
  .ch-head h2{font-size:clamp(30px,10vw,44px)}
  .sub h3{font-size:calc(20px*var(--read))}
  .rr-op,.hunt-ask,.yard-expr{font-size:30px}
}

/* night theme: labels that sit on a coloured sticker surface keep their paper look */
.tile .tag,.modcard:not(.soon) .tag{background:#fff;color:#000;border-color:#000}
.modcard.soon p{color:var(--muted)}

/* ---------- app shell: safe areas everywhere; on phones a slim top bar and a tab bar at the thumb ---------- */
:root{--safe-t:env(safe-area-inset-top,0px);--safe-b:env(safe-area-inset-bottom,0px);--safe-l:env(safe-area-inset-left,0px);--safe-r:env(safe-area-inset-right,0px);--tabbar:0px;--backh:0px;--movedh:0px}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
a,button,summary,.pill,.opt,.tile,.modcard,.hn-peg{-webkit-tap-highlight-color:transparent}
button,.pill,.opt,summary{touch-action:manipulation}
.nav{padding-top:calc(10px + var(--safe-t));padding-left:calc(20px + var(--safe-l));padding-right:calc(20px + var(--safe-r));user-select:none;-webkit-user-select:none}
.nav nav .ic{display:none}
.nav nav .pill{transition:transform .12s,background-color .2s,color .2s}
.sizer{display:flex;gap:4px;align-items:center;position:relative}
.sizer-pop{display:flex;gap:4px;align-items:center}
#t-size,#t-pct{display:none}
.nav .readbar{display:none;position:absolute;left:0;right:0;bottom:-4px;height:3px;pointer-events:none}
body[data-view=notes] .nav .readbar{display:block}
/* the way back to the notes: its own row in the sticky header; with no return point nothing here is in the layout */
body.has-back .nav{flex-wrap:wrap}
.backbar{flex:0 0 100%;display:flex;align-items:center;gap:6px}
.backbar .pill.icon{width:32px;height:32px;font-size:12px}
html.has-back{--backh:44px}   /* the strip's row (32px) and the header's row gap (12px): .ws, .pg and scroll-padding-top were sized for the header without it */
.readbar i{display:block;height:100%;background:var(--violet);transform-origin:0 50%;transform:scaleX(0);transition:transform .12s linear}
.install{position:relative;z-index:3;display:flex;gap:10px 14px;align-items:center;flex-wrap:wrap;margin-top:14px;max-width:640px;font-size:calc(14px*var(--read));line-height:1.45;color:var(--ink)}
.standalone body{overscroll-behavior-y:none}
.player-svg{min-width:0}
@media(max-width:1100px){
  .lab>div:first-child{display:flex;flex-direction:column}
  .lab>div:first-child>.card{order:-1;margin:0 0 12px!important}
}
@media(max-width:900px){
  :root{--tabbar:60px}
  html{scroll-padding-top:calc(66px + var(--safe-t) + var(--backh));scroll-padding-bottom:calc(var(--tabbar) + var(--safe-b) + 8px)}
  body{padding-bottom:calc(var(--tabbar) + var(--safe-b))}
  body[data-view=course],body[data-view=err]{padding-bottom:var(--safe-b)}
  .marquee{display:none}
  .nav{gap:8px;padding:8px calc(12px + var(--safe-r)) 8px calc(12px + var(--safe-l));padding-top:calc(8px + var(--safe-t))}
  .tools{margin-left:auto}
  .nav{row-gap:6px}
  .backbar{min-width:0}
  html.has-back{--backh:42px}
  #back-go{min-width:0;overflow:hidden;text-overflow:ellipsis}
  .nav nav{position:fixed;left:0;right:0;bottom:0;z-index:60;margin:0;display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:2px;padding:5px calc(6px + var(--safe-r)) calc(5px + var(--safe-b)) calc(6px + var(--safe-l));background:var(--bg);border-top:1px solid var(--line)}
  .nav nav .pill{flex-direction:column;gap:3px;justify-content:center;min-height:50px;padding:5px 0 4px;border-color:transparent;background:none;border-radius:16px;font-size:9.5px;letter-spacing:.05em;color:var(--muted)}
  .nav nav .ic{display:block;width:22px;height:22px}
  .nav nav .pill[aria-current=page]{background:var(--ink);color:var(--surface)}
  .nav nav .pill[aria-current=page] .ic{animation:tick .32s ease-out}
  body[data-view=course] #mainnav,body[data-view=err] #mainnav,body[data-view=play] #mainnav{display:none}
  body[data-view=play]{--tabbar:0px}
  #t-focus{display:none}
  #t-size{display:inline-flex}
  .sizer-pop{display:none;position:absolute;top:calc(100% + 10px);right:-42px;z-index:70;background:var(--surface);border:1px solid var(--line);border-radius:99px;padding:5px;box-shadow:0 12px 30px -14px rgba(0,0,0,.5)}
  .sizer.open .sizer-pop{display:flex;animation:popIn .16s ease backwards}
  #t-pct{display:inline-block;min-width:46px;text-align:center;color:var(--ink)}
  .sizer-pop .pill.icon{width:40px;height:40px;font-size:15px}
  .toc{padding-bottom:calc(70px + var(--tabbar) + var(--safe-b))}
  .ch-head .jump .pill{white-space:normal;text-align:left;line-height:1.3;border-radius:16px;padding:8px 12px}
  .wrap{padding-left:calc(14px + var(--safe-l));padding-right:calc(14px + var(--safe-r))}
}
@media(max-width:820px){.player[data-mod=m3] .player-svg{min-width:760px}}
/* iOS zooms the whole page when a field with text under 16px takes focus */
@media(max-width:900px),(pointer:coarse){
  .field input,.field select,.toc input,select.pill,.timer-pop input{font-size:16px}
  .ask input{font-size:max(16px,calc(14px*var(--read)))}.kv input,.pg textarea.stdin,.pg-in{font-size:max(16px,calc(13px*var(--read)))}
  .editor{font-size:max(16px,calc(14px*var(--read)));grid-template-columns:40px 1fr}
}

/* ---------- code workspace on a narrow screen: one of PROBLEM / CODE / TESTS at a time ---------- */
.mtabs{display:none}
@media(max-width:1000px){
  .mtabs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px;margin-bottom:8px}
  .mtabs .pill{justify-content:center;padding:10px 6px}
  .ws{display:block;height:auto;min-height:0}
  .ws .right{display:block}
  .ws .pane{min-height:0}
  .ws[data-m=desc] .right,.ws[data-m=code]>.pane,.ws[data-m=result]>.pane,.ws[data-m=code] .right>.pane:last-child,.ws[data-m=result] .right>.pane:first-child{display:none}
  .ws .pane-b{overflow:visible}
  .ws .pane .editor{height:420px;height:clamp(260px,calc(100dvh - 340px),720px);min-height:0;flex:none}
  .ws .right>.pane:last-child{min-height:300px}
}
.editor .curline{position:absolute;left:0;right:0;top:0;pointer-events:none;background:color-mix(in srgb,var(--sun) 22%,transparent);opacity:0;transition:transform .09s ease-out,opacity .15s}
.keybar{display:none;gap:4px;padding:6px 8px;overflow-x:auto;border-bottom:1px solid var(--hair);background:var(--surface-2);scrollbar-width:none;flex:none}
.keybar::-webkit-scrollbar{display:none}
.keybar button{flex:none;min-width:38px;height:36px;border:1px solid var(--line);border-radius:10px;background:var(--surface);color:var(--ink);font:600 16px/1 var(--font-mono);padding:0 8px;touch-action:manipulation}
.keybar button:active{background:var(--sun);color:#000;transform:scale(.93)}
@media(pointer:coarse){.keybar{display:flex}}

/* ---------- study timer ---------- */
#t-timer.run{width:auto;min-width:66px;padding:0 12px;font:700 13px/1 var(--font-mono);letter-spacing:0}
.timer-pop{position:fixed;top:calc(68px + var(--safe-t) + var(--movedh));right:calc(16px + var(--safe-r));z-index:90;width:340px;max-width:calc(100vw - 24px);padding:14px;display:grid;gap:12px;box-shadow:0 20px 50px -22px rgba(0,0,0,.55);animation:popIn .18s ease backwards}
.tm-tabs{display:flex;gap:4px;align-items:center;flex-wrap:wrap}
.tm-tabs [data-tm=close]{margin-left:auto;width:32px;height:32px}
.tm-face{display:grid;gap:10px;justify-items:start}
.tm-time{font:800 72px/.9 var(--font-display);color:var(--ink);font-synthesis:none;letter-spacing:.01em}
.tm-face .bar{width:100%}
.tm-face .bar i{transition:width .25s linear;background:var(--sun)}
.tm-row{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.tm-row .field input{width:64px}
.tm-log{margin:0;font-size:13px;line-height:1.5}
.tm-log b{color:var(--ink)}
.pill.clock{font-family:var(--font-mono);letter-spacing:0;min-width:66px;justify-content:center}
@media(max-width:900px){.timer-pop{top:auto;left:calc(12px + var(--safe-l));right:calc(12px + var(--safe-r));width:auto;max-width:none;bottom:calc(var(--tabbar) + var(--safe-b) + 10px);max-height:calc(100vh - 76px - var(--tabbar) - var(--safe-b) - var(--safe-t) - var(--backh) - var(--movedh));max-height:calc(100dvh - 76px - var(--tabbar) - var(--safe-b) - var(--safe-t) - var(--backh) - var(--movedh));overflow-y:auto;overscroll-behavior:contain;animation-name:rise}.tm-time{font-size:64px}}

/* ---------- small motions: each one is short, and all of them stop under "reduce motion" ---------- */
@keyframes popIn{from{opacity:0;transform:translateY(-6px) scale(.97)}}
@keyframes rise{from{opacity:0;transform:translateY(12px)}}
@keyframes stamp{0%{opacity:0;transform:scale(1.7) rotate(-24deg)}60%{opacity:1;transform:scale(.9) rotate(-8deg)}100%{transform:scale(1) rotate(-8deg)}}
@keyframes ring{from{box-shadow:0 0 0 0 color-mix(in srgb,var(--mint) 75%,transparent)}to{box-shadow:0 0 0 14px transparent}}
@keyframes tick{0%{transform:scale(.4);opacity:0}70%{transform:scale(1.18);opacity:1}100%{transform:scale(1)}}
@keyframes glow{from{background:var(--sun);color:#000;border-color:#000}}
@keyframes blobIn{from{transform:scale(.55) rotate(-24deg);opacity:0}}
body,.nav,.card,.sub,.ch-head,.codebox,.pane,.stage,.co,.q,.toc,.band,.hero{transition:background-color .25s ease,border-color .25s ease,color .25s ease}
.grid>*{animation:rise .42s cubic-bezier(.2,.7,.3,1) backwards}
.grid>:nth-child(2){animation-delay:.04s}.grid>:nth-child(3){animation-delay:.08s}.grid>:nth-child(4){animation-delay:.12s}.grid>:nth-child(5){animation-delay:.16s}.grid>:nth-child(6){animation-delay:.2s}.grid>:nth-child(n+7){animation-delay:.24s}
.chapter.on .ch-head .blob{animation:blobIn .5s cubic-bezier(.2,1.3,.4,1) backwards}
.modsw-menu{animation:popIn .16s ease backwards}
.qcard .opt:not([disabled]){animation:rise .3s ease backwards}
.qcard .opt:not([disabled]):nth-of-type(2){animation-delay:.04s}.qcard .opt:not([disabled]):nth-of-type(3){animation-delay:.08s}.qcard .opt:not([disabled]):nth-of-type(4){animation-delay:.12s}
.opt.right{animation:ring .6s ease-out}
.opt.right .k,.q-done:not(.hidden),.editor .gut .err,.toc .ch.done .n{animation:tick .34s ease-out}
.ask.ok label{animation:ring .6s ease-out}
.verdict .st{animation:stamp .42s cubic-bezier(.2,.8,.3,1) backwards}
.verdict b{animation:rise .3s ease .08s backwards}
.vars span.chg{animation:glow .9s ease-out}
.player-narr>span{animation:rise .22s ease backwards}
.pips i{transition:background-color .2s,transform .2s}
.pips i.cur{transform:scale(1.25)}
.bar i{transition-timing-function:cubic-bezier(.2,.8,.3,1)}
details.ans summary{transition:background-color .15s,color .15s,transform .1s}
details.ans summary:active{transform:scale(.97)}
.toc .ch{transition:background-color .15s,border-color .15s}
.stat b{animation:rise .5s cubic-bezier(.2,.7,.3,1) backwards}

/* ---------- touch screens: every control is big enough for a thumb ---------- */
@media(pointer:coarse){
  .pill{min-height:40px}
  .pill.sm{min-height:36px;padding:8px 13px}
  .pill.icon,.nav nav .pill{min-height:0}
  .nav nav .pill{min-height:50px}
  .toc .ch{padding:10px 8px}
  .toc .subs a{padding:8px 10px}
  .opt{padding:15px 16px}
  details.ans summary{padding:10px 14px}
  .transport input[type=range]{height:32px;width:130px}
  .field{padding:5px 7px 5px 13px}
  .field input,.field select{padding:8px 9px}
}
@media(max-width:900px){.tools .pill.icon{width:36px;height:36px}}
@media(max-width:480px){.logo{display:none}.hn-base span{white-space:nowrap}}

/* lab on a narrow screen: the statement being run is repeated under the note, because the code panel is further down */
.player-code{position:relative}
.narr-code{display:none}
@media(max-width:1100px){.player-narr{flex:1 1 100%;display:flex;flex-wrap:wrap;gap:6px 8px;align-items:center}.narr-code{display:block;flex:1 1 100%;font:500 calc(12.5px*var(--read))/1.5 var(--font-mono);background:var(--code-bg);border:1px solid var(--hair);border-left:3px solid var(--ember);border-radius:8px;padding:5px 10px;overflow-x:auto;white-space:pre}}
#lab-kinds{position:relative}

/* the Lab's way to the playground (ALL STRUCTURES) stands by the heading, apart from the row of scene tabs */
#v-lab .gamehead h2{margin-right:0}#v-lab .gamehead>a{margin-right:auto}
/* DS playground: the Lab's player, with the History card as the third part of its grid: at the top of the second column, above the code; on a narrow screen
   under the stage and above the code. Its list scrolls inside the card, so fifty entries move nothing else. */
#play-groups,#play-items{position:relative}
.play-bar{display:flex;gap:8px 10px;align-items:center;flex-wrap:wrap;margin-bottom:12px}
.play-bar .hud{margin-right:auto}
@media(min-width:1101px){#play-player{grid-template-rows:auto 1fr}#play-player>div:first-child{grid-column:1;grid-row:1/3}#play-player>.play-hist{grid-column:2;grid-row:1}#play-player>div:nth-child(2){grid-column:2;grid-row:2}}
@media(max-width:1100px){#play-player>.play-hist{order:1}#play-player>div:nth-child(2){order:2}}
.play-hist{padding:16px;min-width:0}
.play-hh{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-bottom:10px}
.play-hh .tag{margin-right:auto}
.play-list{list-style:none;margin:0;padding:0;display:grid;gap:2px;position:relative;max-height:calc(204px*var(--read));overflow-y:auto;overscroll-behavior:contain}
.play-hist li{font:500 calc(13px*var(--read))/1.35 var(--font-mono)}
.play-hist li button{display:block;width:100%;text-align:left;background:none;border:1px solid transparent;border-radius:10px;padding:6px 10px;color:var(--ink);overflow-wrap:anywhere}
@media(hover:hover){.play-hist li button:hover{background:var(--surface-2)}}
.play-hist li button[aria-current]{background:var(--surface-2);border-color:var(--line);font-weight:700}
.play-hist li span,.play-hist li small{color:var(--muted);font-size:inherit;font-weight:500}
.play-note{margin:8px 0 0;font-size:calc(13.5px*var(--read));line-height:1.45;color:var(--ink)}
.play-note:empty{display:none}
#play-player [data-p=cost]:empty{display:none}      /* the cost tag at Start, after an undo: no empty pill beside the narration */
@media(pointer:coarse){.play-hist li button{min-height:36px}}
/* on a phone the helper's round button floats over the right edge of whatever scrolls past it: UNDO and REDO stand at the left, and the entries stop short of it */
@media(max-width:900px){.play-hh .tag{order:1;margin:0 0 0 auto}body.has-sc .play-list{padding-right:58px}}
@media(max-width:820px){#play-groups,#play-items{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;padding:2px 14px 4px;margin:0 -14px;width:calc(100% + 28px)}#play-groups::-webkit-scrollbar,#play-items::-webkit-scrollbar{display:none}#v-play .gamehead{margin-bottom:8px}#v-play .gamehead h2{font-size:clamp(30px,9.4vw,40px)}.play-bar .hud{margin-right:0}}
@media(max-width:820px){#lab-kinds{flex-wrap:nowrap;overflow-x:auto;width:100%;scrollbar-width:none;padding:2px 0 4px;margin:0 -14px;padding-left:14px;padding-right:14px;width:calc(100% + 28px)}#lab-kinds::-webkit-scrollbar{display:none}#v-lab .gamehead{margin-bottom:8px}#v-lab .gamehead h2{font-size:40px}}

/* ---------- Module I games ---------- */
.ld-row{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.ld-card{position:relative;display:grid;place-items:center;min-width:104px;min-height:74px;padding:14px 14px 10px;border:1px solid #000;border-radius:18px;background:var(--lav);color:#000;font:700 19px/1.1 var(--font-mono);transition:transform .15s,background-color .15s,box-shadow .15s}
.ld-card small{position:absolute;left:9px;top:6px;font:700 10px/1 var(--font-body);opacity:.6}
.ld-card.pick{background:var(--sun);transform:translateY(-6px) rotate(-2deg);box-shadow:0 8px 0 -4px rgba(0,0,0,.3)}
.ld-card.ok{background:var(--mint)}.ld-card.bad{background:var(--ember)}
.ld-lt{font:700 15px/1 var(--font-mono);color:var(--muted);font-style:normal}
.bh-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(46px,1fr));gap:5px}
.bh-cell{display:grid;gap:2px;justify-items:center;padding:8px 2px 5px;border:1px solid var(--line);border-radius:12px;background:var(--surface);color:var(--ink);transition:transform .12s,background-color .15s,opacity .2s}
.bh-cell b{font:700 15px/1 var(--font-mono)}
.bh-cell small{font:500 10px/1 var(--font-mono);color:var(--muted)}
.bh-cell.out{opacity:.32;border-style:dashed;background:var(--surface-2)}
.bh-cell.seen{background:var(--sun);color:#000}.bh-cell.seen small{color:#000}
.bh-cell.hit{background:var(--mint);animation:ring .6s ease-out}
.bh-cell.aim{outline:2px solid var(--ink);outline-offset:2px}
.bh-cell:active{transform:scale(.94)}
.spot{gap:12px}
.spot .codebox pre{font-size:calc(14.5px*var(--read))}
.sp-opts{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:6px}
.sp-opts .pill{justify-content:center;font-family:var(--font-mono);letter-spacing:0;font-size:14px;padding:13px 10px}
.sp-opts .pill[disabled]{opacity:1}
.sp-opts .pill[disabled]:not(.c-mint):not(.c-ember){opacity:.45}
@media(max-width:820px){.ld-card{min-width:86px;min-height:64px;font-size:16px;flex:1 1 86px}.ld-lt{display:none}.sp-opts{grid-template-columns:1fr 1fr}}

/* ---------- analysis problems: a program to read, answer chips, and a table of measurements ---------- */
#ws-prog{flex:1;min-height:0;overflow:auto;margin:0;border:0;border-radius:0}
#ws-prog pre{font-size:calc(14px*var(--read));min-height:100%;overflow:visible}
#ws-prog .l.star{background:color-mix(in srgb,var(--sun) 45%,transparent);box-shadow:inset 3px 0 0 var(--ember)}
.ws.an #ws-editor,.ws.an .keybar,.ws.an #ws-reset,.ws.an #ws-run,.ws.an #ws-submit,.ws.an #ws-saved{display:none!important}
.ws:not(.an) #ws-prog{display:none}
.an{display:grid;gap:14px;font-family:var(--font-body)}
.an-q{display:flex;gap:10px;align-items:flex-start}
.an-q>div{flex:1;min-width:0;display:grid;gap:7px}
.an-q>.dot{margin-top:20px;flex:none}
.dot.no{background:var(--ember)}
.an-chips{display:flex;flex-wrap:wrap;gap:5px}
.an-chips .pill{font-family:var(--font-mono);letter-spacing:0;font-size:calc(13px*var(--read))}
.verdict .up,.an .ops .up{font-size:calc(12px*var(--read))}
.an-ask{text-transform:uppercase;letter-spacing:.032em;font-weight:700;font-size:calc(12px*var(--read));color:var(--muted)}
.an-q input{border:1px solid var(--line);border-radius:12px;background:var(--surface-2);padding:9px 12px;font:500 calc(15px*var(--read))/1 var(--font-mono);width:180px;color:var(--ink)}
.an-t td{white-space:nowrap}
.an-bar{display:block;height:5px;border-radius:9px;background:var(--blue);margin-top:5px;min-width:3px;transition:width .5s cubic-bezier(.2,.8,.3,1)}
.an-bar.s{background:var(--violet)}
@media(max-width:900px),(pointer:coarse){.an-q input{font-size:max(16px,calc(15px*var(--read)))}}

/* ---------- Black Box ---------- */
.bbox{gap:14px}
.bb-top{display:flex;gap:16px;align-items:center;flex-wrap:wrap}
.bb-machine{flex:none;width:118px;height:118px;border:1px solid #000;border-radius:26px;background:#000;color:#fff;display:grid;place-items:center;align-content:center;gap:4px;text-align:center;padding:8px;transform:rotate(-3deg)}
.bb-machine b{font:800 54px/.8 var(--font-display);color:var(--sun);font-synthesis:none}
.bb-machine span{font:700 11px/1.2 var(--font-body);letter-spacing:.04em;text-transform:uppercase}
.bb-machine.go{animation:bbHum .5s ease-in-out}
@keyframes bbHum{25%{transform:rotate(-6deg) scale(1.04)}60%{transform:rotate(1deg) scale(.98)}}
.bb-top .yard-in{flex:1 1 260px}
.bb-charts{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.bb-chart{border:1px solid var(--line);border-radius:20px;background:var(--surface-2);padding:12px 12px 10px;display:grid;gap:8px;min-width:0}
.bb-bars{display:grid;gap:6px;align-items:end}
.bb-col{display:grid;gap:4px;justify-items:center;min-width:0}
.bb-v{font:700 12px/1 var(--font-mono);color:var(--ink);min-height:12px}
.bb-n{font:500 10.5px/1 var(--font-mono);color:var(--muted);white-space:nowrap}
.bb-track{position:relative;width:100%;height:150px;display:flex;align-items:flex-end;justify-content:center;border-bottom:1px solid var(--line)}
.bb-bar{display:block;width:72%;background:var(--blue);border:1px solid #000;border-bottom:0;border-radius:8px 8px 0 0;transition:height .45s cubic-bezier(.2,.8,.3,1);transform-origin:50% 100%}
.bb-chart.space .bb-bar{background:var(--violet)}
.bb-bar.new{animation:bbGrow .55s cubic-bezier(.2,.9,.3,1) backwards}
@keyframes bbGrow{from{transform:scaleY(0)}}
.bb-slot{display:block;width:72%;height:100%;border:1px dashed var(--hair);border-bottom:0;border-radius:8px 8px 0 0}
.bb-ghost{position:absolute;left:4%;right:4%;height:0;border-top:2px dashed var(--ember)}
.bb-x{font:500 11.5px/1.5 var(--font-mono)}
.bb-ask{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.bb-ask>div{display:grid;gap:7px;align-content:start}
.bbox .overlay{overflow:auto;place-items:start center}
.bbox .overlay h3{font-size:clamp(40px,6vw,72px)}
@media(max-width:820px){.bb-charts,.bb-ask{grid-template-columns:1fr}.bb-track{height:120px}.bb-machine{width:92px;height:92px}.bb-machine b{font-size:40px}}
/* Split Decision: a B+ tree as rows of key chips */
.bpt{position:relative;display:flex;flex-direction:column;align-items:center;gap:36px;width:max-content;padding:8px 10px 12px;margin:0 auto}
.bpr{display:flex;gap:18px;justify-content:center}
.bpn{position:relative;display:flex;align-items:center;padding:4px;min-height:40px;border:1px solid var(--line);border-radius:12px;background:var(--surface);color:var(--ink);font:inherit}
button.bpn{cursor:pointer}
.bpn.first{margin-left:12px}
.bpn.leaf{background:var(--surface-2)}
.bpn.leaf:not(:last-child)::after{content:'→';position:absolute;right:-16px;top:50%;transform:translateY(-50%);color:var(--muted);font:700 12px/1 var(--font-mono);pointer-events:none}
.bpn.full{border-color:var(--ember);box-shadow:inset 0 0 0 2px var(--ember)}
.bpn.low{border-style:dashed;border-color:var(--ember)}
.bpn.sel{outline:3px solid var(--violet);outline-offset:2px}
.bpn.over,button.bpn:focus-visible{outline:3px solid var(--blue);outline-offset:2px}
.bpk{min-width:28px;height:30px;padding:0 5px;display:grid;place-items:center;border-radius:8px;font:700 13px/1 var(--font-mono)}
.bpk.hot{background:var(--sun);color:#000}.bpk.ok{background:var(--mint);color:#000}
.bpgap{position:relative;width:22px;height:36px;padding:0;border:0;background:none;cursor:pointer}
.bpgap::before{content:'';position:absolute;left:10px;top:3px;bottom:3px;width:2px;border-radius:2px;background:var(--muted);opacity:.45}
.bpgap:hover::before,.bpgap.on::before,.bpgap:focus-visible::before{left:8px;width:6px;background:var(--blue);opacity:1}
.bpgap:focus-visible{outline:none}
.bpcut{width:4px;height:36px;margin:0 5px;border-radius:2px;background:var(--ember)}
.bpdiv{position:absolute;left:-14px;top:-7px;bottom:-7px;width:12px;border-radius:6px;background:var(--blue);border:1px solid var(--line);cursor:ew-resize;touch-action:none;z-index:3}
/* Nothing in the notes may be wider than a phone screen. A long chapter or problem title wraps inside its button; an
   answer box may shrink below the 20 characters a text input asks for; a long run of inline code may break. */
.ch-foot .pill,.sub .acts .pill{white-space:normal;max-width:100%;line-height:1.25;text-align:left}
.ask label{min-width:0}
.ask input{width:0}
@media(max-width:820px){p code,li code,td code,.co code,summary code{white-space:normal;overflow-wrap:anywhere}}

/* ---------- the written questions in the Quiz hub: a list per section, a page per question ---------- */
.wr-sum{font-size:calc(15.5px*var(--read));line-height:1.55;margin:0 0 12px}
.wr-list{display:grid;gap:8px}
.wr-list .row{display:flex;flex-wrap:wrap;gap:6px 12px;align-items:center;min-width:0;border:1px solid var(--line);background:var(--surface);border-radius:16px;padding:11px 14px;color:var(--ink);text-decoration:none;font-size:calc(15px*var(--read));line-height:1.45}
@media(hover:hover){.wr-list .row:hover{background:var(--surface-2)}}
.wr-list .no{flex:none;min-width:28px;height:28px;border-radius:50%;border:1px solid var(--line);background:var(--lav);color:#000;display:grid;place-items:center;font:700 12px/1 var(--font-mono)}
.wr-list .t{flex:1 1 16ch;min-width:0;overflow-wrap:anywhere}
.wr-list .lead{display:block;color:var(--muted);font-size:calc(13.5px*var(--read))}
.wr-q .q{margin:0 0 12px;font-size:calc(16.5px*var(--read));line-height:1.72;min-width:0}
.wr-q p,.wr-q li,.wr-model p,.wr-model li{font-size:calc(16.5px*var(--read));line-height:1.72}
.wr-q p,.wr-model p{margin:0 0 14px}
.wr-q ul,.wr-q ol,.wr-model ul,.wr-model ol{margin:0 0 14px;padding-left:24px}
.wr-q .q>*,.wr-model>*{max-width:76ch}
.wr-q .q>.dg,.wr-q .q>.tbl,.wr-q .q>.codebox,.wr-q .q>.ll,.wr-q .q>.q-head,.wr-model>.dg,.wr-model>.tbl,.wr-model>.codebox,.wr-model>.ll,.wr-model>.two{max-width:none}
.wr-q .acts,.wr-model .acts{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px}
.wr-q .acts .pill,.wr-model .acts .pill{white-space:normal;max-width:100%;line-height:1.25;text-align:left}
.wr-ans label{display:block;margin-bottom:8px}
#wr-text{display:block;width:100%;box-sizing:border-box;min-height:220px;margin:0;padding:12px 14px;border:1px solid var(--line);border-radius:16px;background:var(--surface-2);color:var(--ink);font:500 calc(16px*var(--read))/1.6 var(--font-body);resize:vertical}
@media(max-width:900px),(pointer:coarse){#wr-text{font-size:max(16px,calc(16px*var(--read)))}}
.wr-meta{display:flex;gap:6px 14px;flex-wrap:wrap;justify-content:space-between;margin-top:8px;font-size:calc(13px*var(--read));color:var(--muted)}
.wr-meta .ok{color:var(--ink);font-weight:700}
.wr-act{margin-top:12px;display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.wr-act .pill{white-space:normal;max-width:100%;line-height:1.25}
.wr-note{font-size:calc(14px*var(--read));line-height:1.5;color:var(--muted);margin:10px 0 0}
.wr-ans #wr-read{margin:0 0 8px}
/* what the check said: the first-stage reason, the rejection, or why the answer could not be checked; then the marks, the worked answer and the attempts */
/* the line is a live region, so it is always in the tree: empty, it takes no room, but it is never display:none (a region that appears with its text is not announced) */
.wr-msg{font:700 calc(14.5px*var(--read))/1.5 var(--font-body);color:var(--ink);margin:0;padding:0;min-height:0;overflow-wrap:anywhere}
.wr-msg:not(:empty){margin-top:10px}
.wr-note:empty{display:none}
.wr-res{margin-top:12px;min-width:0}
.wr-res>.guarded:first-child>.wr-h:first-child{margin-top:0}
.wr-res .wr-h:focus{outline:none}
.wr-res .wr-h:focus-visible{outline:2px solid var(--ink);outline-offset:4px;border-radius:6px}
.wr-top{display:flex;gap:6px 10px;flex-wrap:wrap;align-items:center}
.wr-when{font-size:calc(13.5px*var(--read));line-height:1.4;color:var(--muted)}
.wr-score{font:500 calc(20px*var(--read))/1.1 var(--font-body);margin:14px 0 6px;color:var(--ink)}
.wr-score b{font-size:2em;font-weight:700}
.wr-one{font-size:calc(14px*var(--read));line-height:1.5;color:var(--muted);margin:0 0 6px;max-width:76ch}
.wr-pts{list-style:none;margin:12px 0;padding:0;display:grid;gap:8px}
.wr-pt{display:flex;gap:10px 12px;align-items:flex-start;min-width:0;border:1px solid var(--line);border-radius:16px;padding:10px 12px;background:var(--surface);font-size:calc(15px*var(--read));line-height:1.5}
.wr-pt .mk{flex:none;min-width:54px;text-align:center;border:1px solid var(--line);border-radius:var(--r-pill);padding:4px 8px;background:var(--surface-2);color:var(--ink);font:700 calc(12.5px*var(--read))/1.3 var(--font-mono)}
.wr-pt.full .mk{background:var(--mint);color:#000}.wr-pt.part .mk{background:var(--sun);color:#000}
.wr-pt .b{flex:1 1 0;min-width:0;overflow-wrap:anywhere}
.wr-pt q{display:block;margin:5px 0;padding-left:10px;border-left:3px solid var(--line);font-style:italic}
.wr-pt .c{display:block;color:var(--muted)}
.wr-fb{font-size:calc(16px*var(--read));line-height:1.6;margin:0 0 4px;max-width:76ch;overflow-wrap:anywhere}
.wr-h{font:700 calc(15px*var(--read))/1.3 var(--font-body);text-transform:uppercase;letter-spacing:.032em;margin:22px 0 10px}
.wr-model{min-width:0;font-size:calc(16.5px*var(--read));line-height:1.72}
.wr-model li{margin-bottom:5px}
.wr-try{border:1px solid var(--line);border-radius:16px;padding:10px 12px;margin-top:8px;min-width:0}
.wr-try summary{cursor:pointer;font:700 calc(14.5px*var(--read))/1.4 var(--font-body);color:var(--ink)}
.wr-try .wr-score{margin-top:10px}
/* the words an attempt was checked on: the student's own, so they are outside the guarded blocks and can be selected and copied */
.wr-own{margin:10px 0 0;min-width:0}
.wr-own summary{cursor:pointer;font:700 calc(14px*var(--read))/1.4 var(--font-body);color:var(--muted)}
.wr-own p{margin:8px 0 0;padding:10px 12px;border:1px solid var(--line);border-radius:16px;background:var(--surface-2);color:var(--ink);font-size:calc(15px*var(--read));line-height:1.6;white-space:pre-wrap;overflow-wrap:anywhere;max-width:76ch}
/* the notice before the first send */
.wr-dlg{border:1px solid var(--line);border-radius:var(--r-big);background:var(--surface);color:var(--ink);padding:22px;width:min(520px,calc(100vw - 32px));max-width:none;box-sizing:border-box}
.wr-dlg::backdrop{background:rgba(0,0,0,.5)}
.wr-dlg p{font-size:calc(16px*var(--read));line-height:1.6;margin:0 0 6px}
/* light protection: a written question, its feedback and its worked answer cannot be selected; fields inside them still can */
.guarded{user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
.guarded input,.guarded textarea,.guarded select{user-select:text;-webkit-user-select:text;-webkit-touch-callout:default}
/* a code listing inside a guarded block has no COPY button (its RUN IN PLAYGROUND button, where it has one, stays) */
.guarded [data-copy]{display:none}

/* ---------- StudyCompanion: a round button at the corner, above the tab bar on a phone, and the small panel of turns it opens ---------- */
.sc-btn{position:fixed;right:calc(20px + var(--safe-r));bottom:calc(20px + var(--tabbar) + var(--safe-b));z-index:65;width:52px;height:52px;padding:0;border:1px solid var(--line);border-radius:50%;background:var(--violet);color:#fff;display:grid;place-items:center;box-shadow:0 12px 26px -14px rgba(0,0,0,.6);transition:transform .12s}
.sc-btn svg{width:24px;height:24px}
.sc-btn:active{transform:scale(.94)}
.sc-btn:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
/* muted while a quiz set runs: still a button, which says why when it is pressed */
.sc-btn[aria-disabled=true]{background:var(--surface-2);color:var(--muted);border-style:dashed;box-shadow:none;cursor:default}
.sc-btn[aria-disabled=true]:active{transform:none}
/* the button floats over the page's corner: while it is there the page ends with room for it, so the last control of a page (NEXT, MARK COMPLETE, the test panel) is never left under it */
body.has-sc .wrap,body.has-sc .notes,body.has-sc .codeview{padding-bottom:88px}
.sc-panel{position:fixed;right:calc(20px + var(--safe-r));bottom:calc(84px + var(--tabbar) + var(--safe-b));z-index:66;width:380px;max-width:calc(100vw - 24px);max-height:min(560px,calc(100vh - 190px - var(--tabbar)));max-height:min(560px,calc(100dvh - 190px - var(--tabbar)));display:flex;flex-direction:column;gap:10px;padding:14px;box-shadow:0 20px 50px -22px rgba(0,0,0,.55)}
.sc-head{display:flex;align-items:center;justify-content:space-between;gap:8px;flex:none}
.sc-head b{font:700 14px/1.2 var(--font-body);color:var(--ink)}
.sc-head .pill.icon{width:32px;height:32px;font-size:12px}
.sc-log{flex:1 1 auto;min-height:72px;overflow:auto;display:flex;flex-direction:column;gap:8px;padding:2px;overscroll-behavior:contain;scrollbar-width:thin}
.sc-turn{max-width:90%;margin:0;padding:9px 12px;border:1px solid var(--line);border-radius:16px;font-size:calc(14.5px*var(--read));line-height:1.5;white-space:pre-wrap;overflow-wrap:anywhere}
.sc-turn.me{align-self:flex-end;background:var(--ink);color:var(--surface)}
.sc-turn.it{align-self:flex-start;background:var(--surface-2);color:var(--ink)}
.sc-note{margin:0;font-size:calc(13.5px*var(--read));line-height:1.5;color:var(--muted)}
.sc-wait{margin:0;font-size:calc(13.5px*var(--read));line-height:1.5;color:var(--muted)}
.sc-src{display:grid;gap:3px;justify-items:start;max-width:90%;padding-left:4px;font-size:calc(13px*var(--read));line-height:1.45;color:var(--muted);overflow-wrap:anywhere}
.sc-src a{color:var(--ink);font-weight:700}
/* the line under the turns is a live region, so it is always in the tree, empty or not (a region that appears with its text is not announced) */
.sc-say{flex:none;margin:0;font:700 calc(13.5px*var(--read))/1.5 var(--font-body);color:var(--ink);overflow-wrap:anywhere}
.sc-form{display:flex;gap:8px;align-items:flex-end;flex:none}
#sc-text{flex:1 1 0;min-width:0;max-height:140px;margin:0;padding:9px 12px;border:1px solid var(--line);border-radius:16px;background:var(--surface-2);color:var(--ink);font:500 calc(14.5px*var(--read))/1.45 var(--font-body);resize:none}
@media(max-width:900px),(pointer:coarse){#sc-text{font-size:max(16px,calc(14.5px*var(--read)))}}
@media(max-width:900px){
  .sc-btn{right:calc(12px + var(--safe-r));bottom:calc(14px + var(--tabbar) + var(--safe-b))}
  .sc-panel{left:calc(8px + var(--safe-l));right:calc(8px + var(--safe-r));bottom:calc(74px + var(--tabbar) + var(--safe-b));width:auto;max-width:none;max-height:calc(100vh - 150px - var(--tabbar) - var(--backh) - var(--safe-t) - var(--safe-b));max-height:calc(100dvh - 150px - var(--tabbar) - var(--backh) - var(--safe-t) - var(--safe-b))}
}
@media print{.sc-btn,.sc-panel{display:none!important}}
/* the bar that announces a move: an ordinary block above the header, so no layout arithmetic depends on it */
.movedbar{display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px;padding:10px 20px;padding-top:calc(10px + var(--safe-t));padding-left:calc(20px + var(--safe-l));padding-right:calc(20px + var(--safe-r));background:var(--sun);color:#000;border-bottom:1px solid #000}
.movedbar .mv-t{flex:1 1 260px;min-width:0;font-size:calc(14px*var(--read));line-height:1.5;overflow-wrap:anywhere}
.movedbar a{color:#000;font-weight:700;text-decoration:underline}
.movedbar .pill{background:#000;color:#fff}
/* the course page's own card for moving progress */
.keep{margin-top:26px}
.keep h3{font:700 24px/1.2 var(--font-body);margin:0 0 8px}
.keep p{font-size:calc(16px*var(--read));line-height:1.6;margin:0 0 14px;max-width:70ch}
.keep .cta{display:flex;gap:8px;flex-wrap:wrap}

/* ---------- notes upgrade ---------- */
/* the growth plot (notes.js, PlotCore): the curves take the theme's own colours, which hold their contrast in the night theme, and each also has its own dash pattern and an end label */
.dg-plot{--p0:var(--ink);--p1:var(--num);--p2:var(--kc);--p3:var(--str);--p4:var(--cls);--p5:var(--bi)}
.dg-plot text{font-family:var(--font-body);font-weight:700;font-size:calc(12px*var(--read));dominant-baseline:central;fill:var(--ink)}
.dg-plot .tk{font-size:calc(11px*var(--read));font-weight:500;fill:var(--muted)}
.dg-plot .n0t{paint-order:stroke;stroke:var(--surface-2);stroke-width:4px;stroke-linejoin:round}
.dg-plot .ax{stroke:var(--muted);stroke-width:1.3;fill:none}
.dg-plot .n0{stroke:var(--ink);stroke-width:1.3;stroke-dasharray:6 4;fill:none}
.dg-plot .ld{stroke:var(--muted);stroke-width:1;fill:none}
.dg-plot .pl{fill:none;stroke-width:2.2;stroke-linejoin:round}
.dg-plot .pl.hi{stroke-width:3.6}
.dg-plot .p0{stroke:var(--p0)}.dg-plot .p1{stroke:var(--p1)}.dg-plot .p2{stroke:var(--p2)}.dg-plot .p3{stroke:var(--p3)}.dg-plot .p4{stroke:var(--p4)}.dg-plot .p5{stroke:var(--p5)}
.dg-plot .te.p0{fill:var(--p0);stroke:none}.dg-plot .te.p1{fill:var(--p1);stroke:none}.dg-plot .te.p2{fill:var(--p2);stroke:none}.dg-plot .te.p3{fill:var(--p3);stroke:none}.dg-plot .te.p4{fill:var(--p4);stroke:none}.dg-plot .te.p5{fill:var(--p5);stroke:none}
.dg.dg-bad{border-style:solid;border-color:var(--ember)}
.dg[data-kind=plot]:empty::before{content:attr(data-cap);display:block;text-align:center;font-size:calc(13px*var(--read));color:var(--muted)}
@media print{:root[data-theme=night] .dg[data-kind=plot]{--ink:#000;--muted:#333;--surface-2:#fff;--num:#000;--kc:#000;--str:#000;--cls:#000;--bi:#000;border-color:#000}}
/* a figure in the notes (notes.js, FigCore): a Lab scene at rest inside the paragraph, which becomes a small player when one of its buttons is pressed. The still frame is
   written with the player's own parts (.stage, .narr, .vars, .card, .ops), so one set of rules lays out both. The note keeps room for one line and the statement under it,
   and the hint under a still frame is as tall as the transport that replaces it: on a wide screen the buttons stay where they were when one is pressed */
.fig{margin:18px 0}
.sub>.fig{max-width:none}
.fig-cap{font-size:calc(15.5px*var(--read));line-height:1.5;font-weight:700;margin:0 0 8px}
.fig-body>div{min-width:0}
.fig .stage{border-radius:18px}
.fig .stage svg{height:320px}
.fig .narr{padding:10px 14px;min-height:calc(38px + 42px*var(--read));align-items:flex-start;align-content:flex-start}
.fig .card{padding:12px;border-radius:18px;margin-top:8px!important}
.fig-idle{font-size:calc(13px*var(--read));line-height:1.4;color:var(--muted);min-height:49px}
.fig .player-buttons,.fig .player-transport [data-p=speed],.fig .player-transport span:not([data-p]){display:none}
.fig-foot{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}
.fig.fig-bad{border:1px solid var(--ember);border-radius:16px;padding:12px}
.fig:empty::before{content:attr(data-t);display:block;font-size:calc(15.5px*var(--read));line-height:1.5;font-weight:700}
/* a compact player has no code panel beside it at any width, so the statement being run is shown under the note at every width */
.player-compact .player-narr{flex:1 1 240px;min-width:0;display:flex;flex-wrap:wrap;gap:6px 8px;align-items:center}
.player-compact .narr-code{display:block;flex:1 1 100%;font:500 calc(12.5px*var(--read))/1.5 var(--font-mono);background:var(--code-bg);border:1px solid var(--hair);border-left:3px solid var(--ember);border-radius:8px;padding:5px 10px;overflow-x:auto;white-space:pre}
@media(max-width:820px){.fig .stage svg{height:auto;aspect-ratio:auto}}
@media(pointer:coarse){.fig-idle{min-height:57px}}
@media print{.fig .card,.fig .transport,.fig-foot button{display:none!important}}
/* the figure's box takes the focus (tabindex -1) so that its keys survive a STEP button that disables itself at the end of a trace; a pointer leaves no ring on it */
.fig-body:focus:not(:focus-visible){outline:none}
/* on a phone the note and the variables grow by a line or two at each step: the transport row goes above the drawing, so that the second tap hits the control the first did */
@media(max-width:820px){.fig .stage{display:flex;flex-direction:column}.fig .stage>.transport{order:-1}}
