/* learn.css - Brainlag Learn (maths and science). Built on brainlag.css tokens; light and dark follow the OS
   (or the site's theme switch). Mobile first: the player is one question per screen with a sticky bottom bar.
   No gradients, no pills, no cards inside cards: hierarchy comes from type, spacing and rules. */
:root{
  --ln-right:#13804f; --ln-right-bg:#edfbf0; --ln-wrong:#c0362c; --ln-wrong-bg:#ffe6e2; --ln-self:#1f6fb5; --ln-self-bg:#eff8ff;
  --ln-lip:#006b73; --ln-ease:cubic-bezier(.22,1,.36,1); --ln-spring:cubic-bezier(.34,1.56,.64,1);
}
:root[data-theme="dark"]{
  --ln-right:#3fd59a; --ln-right-bg:#10301f; --ln-wrong:#ff8a80; --ln-wrong-bg:#3a1a19; --ln-self:#7cc0f5; --ln-self-bg:#13304f; --ln-lip:#075a62;
}
body.ln{background:var(--paper)}

/* ---------------------------------------------------------------- hub and unit pages */
main.wrap.ln-main{max-width:var(--wrap);padding-top:28px;padding-bottom:8px}
.ln-main h1{margin:6px 0 10px}
.ln-lead{font-size:18px;color:var(--ink-2);max-width:62ch;line-height:1.55;margin:0 0 20px}
.ln-sub{color:var(--ink-3);margin:-6px 0 12px;font-size:15px}
.ln-crumb{font-size:14.5px;color:var(--ink-3);margin:0}
.ln-crumb a{color:var(--study-ink);font-weight:700}
.ln-subj{margin:34px 0 0}
.ln-units,.ln-qlist{list-style:none;margin:0;padding:0;border-top:2px solid var(--rule)}
.ln-units > li,.ln-qlist > li{border-bottom:2px solid var(--rule)}
.ln-units a,.ln-qlist a{display:grid;gap:3px;padding:16px 4px;color:var(--ink)}
.ln-qlist > li > span{display:block;padding:12px 4px 0}.ln-qlist > li > span.m{padding:2px 4px 12px}
.ln-units a:hover .t,.ln-qlist a:hover .t{color:var(--study-ink)}
.ln-units .t,.ln-qlist .t{font:600 19px/1.25 var(--f-display)}
.ln-units .d{color:var(--ink-2);font-size:16px;max-width:70ch}
.ln-units .m,.ln-qlist .m{color:var(--ink-3);font-size:14.5px}
.ln-more{margin:22px 0 0}.ln-more a{color:var(--study-ink);font-weight:700}
.ln-legal{margin:44px 0 0;color:var(--ink-3);font-size:13.5px;max-width:80ch;line-height:1.5}
.ln-cols{display:grid;grid-template-columns:minmax(0,1fr);gap:8px 56px}
@media (min-width:980px){.ln-cols{grid-template-columns:minmax(0,1fr) 340px}}
.ln-cols h2{font-size:21px;margin:26px 0 10px}
.ln-lessons{list-style:none;margin:0;padding:0}
.ln-lessons li a{display:grid;grid-template-columns:44px minmax(0,1fr) 28px;gap:14px;align-items:start;padding:14px 4px;border-bottom:2px solid var(--rule);color:var(--ink)}
.ln-lessons li:first-child a{border-top:2px solid var(--rule)}
.ln-lessons .n{width:44px;height:44px;border-radius:14px;display:grid;place-items:center;font:700 18px var(--f-display);background:var(--study-tint);color:var(--study-ink);box-shadow:none}
.ln-lessons .body{display:grid;gap:3px}
.ln-lessons .t{font:600 19px/1.25 var(--f-display)}
.ln-lessons .d{color:var(--ink-2);font-size:15.5px}
.ln-lessons .m{color:var(--ink-3);font-size:14px}
.ln-lessons a:hover .t{color:var(--study-ink)}
.ln-lessons li.done .n{background:var(--study);color:#fff}
:root[data-theme="dark"] .ln-lessons li.done .n{color:#04161c}
.ln-lessons li.done .st::after{content:'';display:block;width:12px;height:22px;margin:8px 0 0 8px;border:solid var(--study-ink);border-width:0 4px 4px 0;transform:rotate(45deg)}
.ln-aside{padding-top:2px}
.ln-can{margin:0;padding-inline-start:20px;color:var(--ink-2)}.ln-can li{margin:0 0 6px}
.ln-spec{list-style:none;margin:0;padding:0;color:var(--ink-2);font-size:15px}
.ln-spec li{padding:8px 0;border-bottom:1px solid var(--rule)}.ln-spec span{color:var(--ink-3)}
.ln-due{margin:26px 0 0}.ln-due a{color:var(--study-ink);font-weight:700}

/* ---------------------------------------------------------------- the player */
body.ln-play{min-height:100dvh}
.lp{min-height:100dvh;display:flex;flex-direction:column}
.lp-top{position:sticky;top:0;z-index:20;display:flex;align-items:center;gap:14px;padding:12px max(16px,env(safe-area-inset-left)) 10px;background:var(--paper)}
.lp-x,.lp-snd{flex:none;width:44px;height:44px;display:grid;place-items:center;border-radius:12px;color:var(--ink-3);background:none;border:0;cursor:pointer}
.lp-x:hover,.lp-snd:hover{color:var(--ink);background:var(--sunk)}
.lp-snd .off{display:none}.lp-snd.off .off{display:inline}.lp-snd.off .on{display:none}
.lp-bar{flex:1;height:16px;border-radius:8px;background:var(--sunk);overflow:hidden;position:relative}
.lp-bar > span{position:absolute;inset:0;background:var(--study);transform:translateX(-100%);border-radius:8px;
  transition:transform .7s var(--ln-spring);box-shadow:inset 0 4px 0 rgba(255,255,255,.28)/* lint-ok: strip, the progress fill's own highlight, not a card edge */}
.lp-bar.sheen::after{content:'';position:absolute;top:0;bottom:0;width:40%;inset-inline-start:-40%;background:rgba(255,255,255,.35);transform:skewX(-20deg);animation:lnSheen .45s .55s var(--ln-ease) both}
@keyframes lnSheen{to{inset-inline-start:110%}}
.lp-meta{flex:none;display:flex;gap:12px;align-items:center;font-weight:700;color:var(--ink-2);font-size:15px}
.lp-meta:empty{display:none}
.lp-combo{color:var(--gold-ink)}.lp-combo.pop{animation:lnPop .26s var(--ln-spring)}
.lp-clock{font-variant-numeric:tabular-nums}.lp-clock.low{color:var(--ln-wrong)}

.lp-stage{flex:1;width:100%;max-width:900px;margin:0 auto;padding:10px 16px 200px}
.lp-screen > h1,.lp-screen > h2.lp-h,.lq-title{font-size:clamp(23px,4.6vw,30px);margin:10px 0 14px;outline:none}
.lq-title .of{color:var(--ink-3);font-weight:500}
.lp-screen.enter{animation:lnIn .32s var(--ln-ease) both}
@keyframes lnIn{from{opacity:0;transform:translateX(18px)}to{opacity:1;transform:none}}
.lp-prose{font-size:17.5px;line-height:1.65;color:var(--ink)}
.lp-prose p,.lp-prose ul,.lp-prose ol{max-width:66ch}
.lp-prose h3{margin:22px 0 6px}
.lp-prose code{font-family:var(--f-mono);background:var(--sunk);padding:1px 6px;border-radius:6px}
.lp-prose .fml{font:600 21px/1.6 var(--f-display);text-align:center;margin:18px 0;padding:14px 8px;border-top:2px solid var(--rule);border-bottom:2px solid var(--rule);max-width:none}
.lp-prose .ln-note{padding:10px 14px;background:var(--gold-tint);border-radius:var(--r1);color:var(--ink-2)}   /* a soft panel, never a left bar (owner, 8 Oct) */
.wk{counter-reset:wk;list-style:none;padding:0;margin:14px 0 18px;max-width:62ch}
.wk li{counter-increment:wk;display:grid;grid-template-columns:30px 1fr;gap:10px;padding:7px 0;border-bottom:1px solid var(--rule)}
.wk li::before{content:counter(wk);font-weight:700;color:var(--study-ink)}
figure.lgraph{margin:14px 0 18px;max-width:560px}   /* 560: drawGraph's widest drawing, so a graph sits 1:1 (figures audit, 15 Oct) */
.la .lp-prose > figure.lgraph{max-width:min(100%,560px)}   /* in a lesson too: the column's own max-width:100% had stretched it to 742, the drawing scaled 1.33x */
figure.lgraph[data-graph]:empty{min-height:380px}   /* a lesson's graph keeps its height while the script draws it: nothing below it moves */
.lgr{width:100%;height:auto;display:block;font:500 12.5px var(--f-body);touch-action:manipulation}
/* a phone draws the graph 400 wide and shows it a little narrower, so its numbers grow to stay at 12 px or more on
   screen (efficacy, 11 Oct: a science graph's ticks at 11.2 px) */
@media (max-width:519px){.lgr{font-size:13.8px}}
.lgr .mn{stroke:rgba(var(--ink-rgb),.08);stroke-width:1}.lgr .mj{stroke:rgba(var(--ink-rgb),.2);stroke-width:1.5}   /* drawn 1:1: the minor grid a quiet true 1 px, the major 1.5 */
.lgr .axes line{stroke:var(--ink);stroke-width:2}
.lgr text{fill:var(--ink-2)}.lgr .lab{fill:var(--ink);font-weight:700;font-size:13.5px}
.lgr .ln{fill:none;stroke:var(--study-ink);stroke-width:3;stroke-linejoin:round;stroke-linecap:round}
.lgr .tan{stroke:var(--pink-ink);stroke-width:2.5;stroke-dasharray:7 5}
.lgr .pt{fill:var(--ink)}.lgr .pl{fill:var(--ink);font-weight:700;font-size:14px}
.lgr .hit{fill:transparent;cursor:crosshair}
.lgr .cross{stroke:var(--blue-ink);stroke-width:2.6;stroke-linecap:round;pointer-events:none}
/* drawn answers (learn-draw.js): the chosen point stands out; the right points after marking are study-ink rings; the
   keyboard rows are 44 px targets */
.lgr .cross.is-on{stroke-width:3.4}
.lgr .ld-ans .ring{fill:none;stroke:var(--study-ink);stroke-width:2.6;pointer-events:none}.lgr .pl.ans{fill:var(--study-ink)}
.ld-rows{display:grid;gap:8px;margin:10px 0 0}
.ld-row{display:grid;grid-template-columns:auto minmax(0,1fr) minmax(0,1fr);align-items:center;gap:8px 12px;max-width:460px}
.ld-name{min-width:44px;min-height:44px;padding:0 12px;display:inline-flex;align-items:center;font-weight:700;color:var(--ink)}
button.ld-name{border:2px solid var(--rule-2);border-radius:12px;background:var(--surface);cursor:pointer;font:inherit;font-weight:700}
button.ld-name[aria-pressed="true"]{border-color:var(--study);background:var(--study-tint)}
.ld-c{display:flex;align-items:center;gap:6px;min-width:0}.ld-c .lq-cell{width:100%;min-width:0;min-height:44px}.ld-c span{white-space:nowrap}
.lgr .ld-line{stroke:var(--blue-ink);stroke-width:2.6;stroke-linecap:round;pointer-events:none}
.lgr .ld-line.ans{stroke:var(--study-ink);stroke-dasharray:9 6}
.lgr .ld-handle{fill:var(--surface);stroke:var(--blue-ink);stroke-width:2.6;pointer-events:none}
.ldraw.is-drag .lgr{touch-action:none}   /* dragging a handle on the grid does not scroll the page */
.lgr .ld-bar{fill:color-mix(in srgb,var(--blue-ink) 22%,transparent);stroke:var(--blue-ink);stroke-width:2.6;pointer-events:none}
.lgr .ld-bar.is-given{fill:color-mix(in srgb,var(--ink-2) 16%,transparent);stroke:var(--ink-2)}
.lgr .ld-bar.ans{fill:none;stroke:var(--study-ink);stroke-dasharray:9 6}
.lgr .ld-cat{fill:var(--ink-2);font-size:13px}
.lgr .ld-cell{fill:color-mix(in srgb,var(--blue-ink) 30%,transparent);stroke:none;pointer-events:none}
.lgr .ld-cell.ans{fill:none;stroke:var(--study-ink);stroke-width:2.6;stroke-dasharray:7 5}
.lgr .ld-focus{fill:none;stroke:var(--ink);stroke-width:3;pointer-events:none}
.ldraw .lgr:focus{outline:none}.ldraw .lgr:focus-visible{outline:3px solid var(--study);outline-offset:3px;border-radius:6px}
/* the keyboard rows line up in one grid, the names in one column */
.ld-rows:not(.is-one){grid-template-columns:auto minmax(0,1fr) minmax(0,1fr);max-width:520px;align-items:center;column-gap:12px}.ld-rows:not(.is-one) > .ld-row{display:contents}
.ld-shapes{display:flex;flex-wrap:wrap;gap:10px;margin:16px 0 0}.ld-shapes .msh{flex:1 0 100%;margin:0}
.ld-shape{display:inline-flex;align-items:center;gap:10px;min-height:48px;padding:6px 14px 6px 8px;border:2px solid var(--rule-2);border-radius:14px;background:var(--surface);color:var(--ink);font:inherit;font-weight:600;cursor:pointer}
.ld-shape svg{flex:none}.ld-shape path{fill:none;stroke:currentColor;stroke-width:2.6;stroke-linecap:round}
.ld-shape[aria-checked="true"]{border-color:var(--study);background:var(--study-tint)}
.ld-shape.is-right{box-shadow:0 0 0 3px var(--study-ink)}
.lgr .ld-arc{fill:none;stroke:var(--ink-2);stroke-width:2;pointer-events:none}
.ld-tools{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0 0}
.ld-tool{min-height:44px;padding:0 16px;border:2px solid var(--rule-2);border-radius:12px;background:var(--surface);color:var(--ink);font:inherit;font-weight:700;cursor:pointer}
.ld-tool[aria-pressed="true"]{border-color:var(--study);background:var(--study-tint)}
.ld-kb{margin:10px 0 0}.ld-kbb{min-height:44px;padding:0;border:0;background:none;display:flex;align-items:center;cursor:pointer;color:var(--study-ink);font:inherit;font-weight:700;text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:3px}
.ld-kbp[hidden]{display:none}.ld-kbp .lq-hint{margin:4px 0 8px}
.ldraw .lgr .ticks text,.ldraw .lgr .pl{paint-order:stroke;stroke:var(--paper);stroke-width:4px;stroke-linejoin:round}   /* numbers and names readable where an arc or line crosses them */
.ld-kbrow{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 12px;max-width:520px}.ld-kbrow .ld-tool{grid-column:1/-1;justify-self:start}
.ld-row.is-one{grid-template-columns:minmax(0,1fr)}.ld-row.is-one .ld-c{justify-content:space-between}.ld-row.is-one .ld-name{min-height:0;padding:0}.ld-row.is-one .lq-cell{max-width:8em}
.lq-stem .qt,.lp-prose table{border-collapse:collapse;margin:10px 0 14px;font-variant-numeric:tabular-nums}
.lq-stem .qt th,.lq-stem .qt td{border:2px solid var(--rule-2);padding:6px 10px;text-align:center}
.lq-stem .qt th{text-align:start;font-weight:600;color:var(--ink-2)}
.lq-stem{font-size:17.5px;line-height:1.6}

/* tools inside a lesson: the real tool page in a frame, its chrome hidden */
.lp-try .lp-tool,.lp-tool{margin:16px -4px 0;position:relative}
.lp-tool iframe{display:block;width:100%;border:0;background:transparent;opacity:0;transition:opacity .25s var(--ln-ease)}
.lp-tool.ready iframe{opacity:1}
.lp-toolnote{font-size:14px;margin:8px 4px 0}.lp-toolnote a{color:var(--study-ink);font-weight:700}
@media (min-width:1000px){.lp-stage:has(.lp-try.is-on){max-width:1100px}}

/* a question */
.lq-part{padding:16px 0 18px;border-top:2px solid var(--rule)}
.lq-part:first-of-type{border-top:0}
.lq-prompt{display:flex;gap:4px 10px;align-items:baseline;font-size:17.5px;line-height:1.55}.lq-prompt .pt{flex:1;min-width:0}
.lq-prompt .pl{font-weight:700;color:var(--ink-2)}
.lq-prompt .pt p{margin:0}
.lq-prompt .lq-mk{color:var(--ink-3);font-size:14px;white-space:nowrap}
.lq-in{margin:12px 0 0}
.lq-in.shake{animation:lnShake .32s var(--ln-ease)}
@keyframes lnShake{0%,100%{transform:none}20%{transform:translateX(-7px)}40%{transform:translateX(6px)}60%{transform:translateX(-4px)}80%{transform:translateX(2px)}}
.lq-line{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.lq-line .lab{font-weight:700;color:var(--ink-2);min-width:4ch}
.lq-line .u{font-weight:700;color:var(--ink-2);font-size:18px}
.lq-field,.lq-cell,.lq-write{font:500 20px var(--f-body);color:var(--ink);background:var(--surface);border:2px solid var(--rule-2);border-radius:14px;padding:10px 14px;min-height:52px;
  transition:border-color .15s var(--ln-ease),box-shadow .15s var(--ln-ease)}
.lq-field{width:min(240px,100%)}.lq-field.wide{width:min(440px,100%)}.lq-field.unit{width:120px}
.lq-cell{width:84px;min-height:46px;text-align:center;padding:8px 6px;font-size:18px}
.lq-write{width:100%;font-size:17px;line-height:1.5;min-height:140px;resize:vertical}
.lq-field:focus,.lq-cell:focus,.lq-write:focus{outline:none;border-color:var(--study);box-shadow:0 0 0 4px color-mix(in srgb,var(--study) 22%,transparent)}
.lq-field[readonly],.lq-cell[readonly]{background:var(--sunk)}
.lq-syms{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0 0}
.lq-sym{min-width:48px;height:44px;border-radius:12px;border:2px solid var(--rule-2);background:var(--surface);color:var(--ink);font:600 18px var(--f-body);cursor:pointer;box-shadow:none}
.lq-sym:active{transform:scale(.98);box-shadow:none}
.lq-read{margin:8px 0 0;font-size:14.5px;color:var(--ink-3);min-height:1.4em}.lq-read.bad{color:var(--ln-wrong)}
.lq-hint{color:var(--ink-3);font-size:14.5px;margin:8px 0}
.lq-hinted{margin:8px 0 0;padding:8px 12px;background:var(--study-tint);border-radius:var(--r1);color:var(--ink-2);font-size:15.5px}
.lq-scroll{overflow-x:auto;padding-bottom:4px}
.lq-table{border-collapse:collapse;font-variant-numeric:tabular-nums}
.lq-table th,.lq-table td{border:2px solid var(--rule-2);padding:6px;text-align:center;min-width:64px;font-size:16px}
.lq-table th{font-weight:600;color:var(--ink-2)}
.lq-plotin{display:flex;flex-wrap:wrap;gap:8px 14px}
.lq-plotin .pi{display:flex;align-items:center;gap:6px;font-size:15px;color:var(--ink-2)}
.lq-plotin .lq-cell{width:70px}

/* answer tiles */
.t-mcq{display:grid;gap:12px}
@media (min-width:640px){.t-mcq:has(.mini){grid-template-columns:repeat(2,minmax(0,1fr))}}
.lq-tile{display:flex;align-items:center;gap:14px;width:100%;min-height:60px;padding:12px 16px;text-align:start;font:500 18px/1.35 var(--f-body);color:var(--ink);
  background:var(--surface);border:2px solid var(--rule-2);border-radius:16px;box-shadow:none;cursor:pointer;
  transition:border-color .12s var(--ln-ease),background-color .12s var(--ln-ease),box-shadow .09s var(--ln-ease),transform .09s var(--ln-spring)}
.lq-tile .k{flex:none;width:30px;height:30px;border-radius:9px;border:2px solid var(--rule-2);display:grid;place-items:center;font-size:14px;font-weight:700;color:var(--ink-3)}
.lq-tile:hover{border-color:color-mix(in srgb,var(--study) 55%,var(--rule-2))}
.lq-tile:active{transform:scale(.98);box-shadow:0 0 0 var(--rule-2)}
.lq-tile[aria-pressed="true"]{border-color:var(--study);background:var(--study-tint);box-shadow:none}
.lq-tile[aria-pressed="true"] .k{border-color:var(--study);color:var(--study-ink)}
.lq-tile.pop{animation:lnTile .22s var(--ln-spring)}
@keyframes lnTile{0%{transform:scale(.96)}40%{transform:scale(1.04)}100%{transform:none}}
.lq-tile.right{border-color:var(--ln-right);background:var(--ln-right-bg);box-shadow:none}
.lq-tile.wrong{border-color:var(--ln-wrong);background:var(--ln-wrong-bg);box-shadow:none}
.lq-tile:disabled{cursor:default}
.lq-tile .mini{display:block;width:132px;height:auto}
.mini .ax{stroke:var(--ink-3);stroke-width:1.5}.mini .cv{fill:none;stroke:var(--study-ink);stroke-width:3}.mini text{font:600 11px var(--f-body);fill:var(--ink-2)}

/* results inside a part */
.lq-res:empty{display:none}
.lq-res{margin:12px 0 0}
.lq-res .sc{margin:0;font-size:15.5px}
.lq-part.is-right .sc b{color:var(--ln-right)}.lq-part.is-wrong .sc b{color:var(--ln-wrong)}.lq-part.is-part .sc b{color:var(--gold-ink)}
.lq-res .say{margin:4px 0 0;color:var(--ink-2)}
.lq-res .ans{margin:8px 0 0;font-weight:700}
.ms{margin:12px 0 0;padding:12px 0 0;border-top:1px dashed var(--rule-2)}
.msh{margin:0 0 6px;font-weight:700;color:var(--ink-2);font-size:15px}
.ms ul{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.ms li{font-size:15.5px;line-height:1.45}
.ms label{display:flex;gap:10px;align-items:flex-start;cursor:pointer}
.ms input{width:22px;height:22px;margin:1px 0 0;accent-color:var(--study);flex:none}
.ms .sch b{display:inline-block;min-width:2.4em;color:var(--study-ink)}
.lv{display:grid;gap:8px}
.lvl{display:flex;gap:10px;align-items:flex-start;padding:10px 12px;border:2px solid var(--rule);border-radius:14px;cursor:pointer}
.lvl:has(input:checked){border-color:var(--study);background:var(--study-tint)}
.lv.is-auto .lvl{cursor:default}.lv.is-auto .lvl.is-on{border-color:var(--study);background:var(--study-tint)}   /* the level the ticked points reach */
.lv.is-pick .lvl{flex-wrap:wrap;cursor:default}.lv.is-pick .lvl>span:first-child{flex:1 1 220px}   /* a level picked by the learner (18 Oct): its descriptor, then its marks */
.lvm{display:flex;flex-wrap:wrap;gap:6px;margin-left:auto}
.lvm label{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:4px;min-width:48px;min-height:44px;padding:0 12px;border:2px solid var(--rule-2);border-radius:6px;background:var(--surface);color:var(--ink);font-weight:700;font-variant-numeric:tabular-nums;cursor:pointer}   /* a mark to pick: the site's choice box, square-cornered, its radio hidden (no pills) */
.lvm input{position:absolute;inset:0;opacity:0;margin:0;cursor:pointer}
.lvm label:has(input:checked){border-color:var(--study);background:var(--study-tint);box-shadow:inset 0 0 0 1px var(--study)}
.lvm label:has(input:checked)::before{content:"";width:6px;height:11px;margin:-3px 2px 0 0;border:solid currentColor;border-width:0 2.5px 2.5px 0;transform:rotate(45deg)}   /* (picked: a tick as well as the colour) */
.lvm label:has(input:focus-visible){outline:3px solid var(--study-ink);outline-offset:2px}
.lq-ws{margin:22px 0 0;padding:16px 0 0;border-top:2px solid var(--rule)}
.lq-ws h2{font-size:19px;margin:0 0 8px}
.lq-ws ol{margin:0;padding-inline-start:22px;display:grid;gap:6px;font-size:16.5px}
.lq-ws ol{grid-template-columns:minmax(0,1fr)}.lq-ws ol > li{min-width:0}.lq-ws pre{max-width:100%;overflow-x:auto}   /* a worked solution's code scrolls in its own box on a phone (audit, 11 Oct: up to 198 px past the edge) */
.lq-ws .own{margin:10px 0 0;color:var(--ink-3);font-size:13.5px}
.lp-loading,.lp-err{color:var(--ink-3);padding:30px 0}

/* bottom bar and feedback sheet */
.lp-foot{position:fixed;inset-inline-start:0;inset-inline-end:0;bottom:0;z-index:30;background:var(--paper);border-top:2px solid var(--rule)}
.lp-sheet{max-width:900px;margin:0 auto;padding:0 16px}
.lp-sheet:empty{display:none}
.lp-sheet.is-right,.lp-sheet.is-wrong,.lp-sheet.is-neutral{padding-top:16px}
.lp-foot:has(.lp-sheet.is-right){background:var(--ln-right-bg);border-top-color:transparent}
.lp-foot:has(.lp-sheet.is-wrong){background:var(--ln-wrong-bg);border-top-color:transparent}
.lp-foot:has(.lp-sheet.is-neutral){background:var(--ln-self-bg);border-top-color:transparent}
.lp-sheet.rise{animation:lnRise .3s var(--ln-ease)}
@keyframes lnRise{0%{transform:translateY(100%)}62%{transform:translateY(-6px)}100%{transform:none}}
.lp-sh .t{margin:0;font:700 22px var(--f-display)}
.is-right .lp-sh .t{color:var(--ln-right)}.is-wrong .lp-sh .t{color:var(--ln-wrong)}.is-neutral .lp-sh .t{color:var(--ln-self)}
.lp-sh .l{margin:4px 0 0;color:var(--ink);max-width:62ch}
/* a right answer: "Correct +2" and "2 of 2 marks. First try." on one line, the rest below (owner, 11 Oct: less text, no scrolling at 320) */
.is-right .lp-shx{display:flex;flex-wrap:wrap;align-items:baseline;column-gap:12px}.is-right .lp-shx>*{flex:1 0 100%;min-width:0}
.is-right .lp-shx>.t{flex:0 0 auto}.is-right .lp-shx>.t+.l{flex:1 1 0;min-width:6em;margin:0}
.lp-link{background:none;border:0;padding:6px 0;margin:4px 0 0;color:var(--study-ink);font:700 15.5px var(--f-body);text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.lp-actions{max-width:900px;margin:0 auto;display:flex;gap:12px;padding:14px 16px calc(14px + env(safe-area-inset-bottom))}
.lp-btn{flex:1;display:inline-flex;align-items:center;justify-content:center;min-height:54px;padding:0 18px;border-radius:16px;border:0;cursor:pointer;
  font:700 17px var(--f-body);letter-spacing:.01em;text-align:center;background:var(--study-btn);color:var(--on-study-btn);box-shadow:none;
  transition:transform .09s var(--ln-spring),box-shadow .09s var(--ln-ease),background-color .15s var(--ln-ease)}
.lp-btn:not(:disabled):hover{background:var(--study-btn-hover)}
.lp-btn:active{transform:scale(.98);background:var(--study-btn-press);box-shadow:0 0 0 var(--study-btn-lip);transition-duration:0s}
.lp-btn:disabled{background:var(--sunk);color:var(--ink-3);box-shadow:inset 0 0 0 2px var(--btn-off-edge);cursor:default;transform:none}
.lp-btn.quiet,:root[data-theme="dark"] .lp-btn.quiet{background:var(--btn-2);color:var(--ink);border:2px solid var(--btn-2-edge);box-shadow:none}
.lp-foot:has(.is-right) .lp-btn:not(.quiet){background:var(--ln-right);box-shadow:none}
/* after a miss the bar's next step ("Another one", Try again) is the ordinary primary button: an action, not a warning */
:root[data-theme="dark"] .lp-foot:has(.is-right) .lp-btn:not(.quiet){color:#0b1626}
@media (min-width:700px){.lp-actions{justify-content:flex-end}.lp-btn{flex:0 0 auto;min-width:180px}}

/* number keypad (touch screens) */
.lp-pad{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;max-width:520px;margin:0 auto;padding:12px 16px 0}
.lp-key{min-height:50px;border-radius:12px;border:2px solid var(--rule-2);background:var(--surface);color:var(--ink);font:600 21px var(--f-body);box-shadow:none}
.lp-key:active{transform:scale(.98);box-shadow:none}
.lp-key.wide{background:var(--sunk)}
body.pad-on .lp-stage{padding-bottom:492px}   /* (the keys and the keyboard row under them) */
/* short screens (mobile sweep, 19 Oct): keys never wider than their column (at 200% zoom "x10^" pushed the last column
   off the screen); on a short phone the keys are 44 px; on a phone on its side the pad is two rows of eight, the digits
   first in order, so the question and the box keep the room above it */
.lp-pad{grid-template-columns:repeat(4,minmax(0,1fr))}
.lp-key{min-width:0;overflow:hidden;text-overflow:clip}
/* "Use phone keyboard" (LRN-26): a quiet full-width row under the keys, last in every layout, 44 px */
.lp-padkb{grid-column:1/-1;order:99;min-height:44px;border:0;background:none;color:var(--study-ink);font:700 15px var(--f-body);text-decoration:underline;text-underline-offset:3px;cursor:pointer}
@media (max-height:260px),(max-width:259px){.lp-padkb{display:none}}   /* (200% zoom: no room for a fifth row; Done still closes the pad) */
@media (max-width:259px){.lp-pad{gap:6px;padding-inline:10px}.lp-pad .lp-key{font-size:13px;padding-inline:2px}}   /* 200% zoom on a phone: "Done" and "×10^" whole in their keys */
@media (max-height:600px){
  .lp-pad{gap:6px;padding-top:8px}
  .lp-key{min-height:44px;font-size:19px}
  body.pad-on .lp-stage{padding-bottom:352px}
}
@media (min-height:501px) and (max-height:600px) and (min-width:560px){
  .lp-pad{grid-template-columns:repeat(8,minmax(0,1fr));max-width:760px}
  .lp-key:nth-child(1){order:7}.lp-key:nth-child(2){order:8}.lp-key:nth-child(3){order:9}.lp-key:nth-child(4){order:15}.lp-key:nth-child(5){order:4}.lp-key:nth-child(6){order:5}.lp-key:nth-child(7){order:6}.lp-key:nth-child(8){order:12}.lp-key:nth-child(9){order:1}.lp-key:nth-child(10){order:2}.lp-key:nth-child(11){order:3}.lp-key:nth-child(12){order:14}.lp-key:nth-child(13){order:10}.lp-key:nth-child(14){order:11}.lp-key:nth-child(15){order:13}.lp-key:nth-child(16){order:16}
  body.pad-on .lp-stage{padding-bottom:252px}
}
/* the keypad stands on the bar, outside its box (15 Oct, course_cls: added inside the fixed bar it lifted the bar's top
   236 px, a layout shift of 0.11 on a phone); the bar's own top rule and paper drawn round the keypad instead */
.lp-foot > .lp-pad{position:absolute;inset-inline:0;bottom:100%;padding-bottom:10px;isolation:isolate}
.lp-foot > .lp-pad::before{content:'';position:absolute;inset:0 -100vmax;z-index:-1;background:var(--paper);border-top:2px solid var(--rule)}
/* a phone on its side, or a short screen at 200% zoom, under 500 px tall (coordinator, 19 Oct): the pad docks beside
   the question, full height at the right, four keys wide; the question, the top bar and the bar under it keep the rest
   of the width, so nothing is under the pad (learn.js padFit measures to the bar, not to the pad, when it is docked) */
@media (max-height:500px) and (min-aspect-ratio:1/1){
  .lp-foot > .lp-pad{position:fixed;inset-inline:auto 0;top:0;bottom:0;width:clamp(208px,36vw,300px);max-width:none;margin:0;box-sizing:border-box;
    grid-template-columns:repeat(4,minmax(0,1fr));grid-auto-rows:minmax(44px,1fr);align-content:stretch;gap:4px;padding:4px max(6px,env(safe-area-inset-right)) 4px 6px;z-index:40}
  .lp-foot > .lp-pad::before{inset:0;border-top:0;border-inline-start:2px solid var(--rule)}
  .lp-foot > .lp-pad .lp-key{min-height:44px;font-size:clamp(15px,2.2vw,18px);padding-inline:2px}
  body.pad-on .lp-stage{padding-bottom:0;padding-inline-end:calc(clamp(208px,36vw,300px) + 8px)}
  body.pad-on .lp-foot,body.pad-on .lp-top{padding-inline-end:calc(clamp(208px,36vw,300px) + 8px)}
}
body.pad-on .lp-foot{border-top-color:transparent}

/* the end of a lesson or test */
.lp-done{text-align:center;position:relative;padding-top:10px}
.lp-done > h1{font-size:clamp(28px,6vw,38px);animation:lnRiseT .3s .3s var(--ln-spring) both}
@keyframes lnRiseT{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.ln-noodle{display:block;width:88px;height:91px;margin:8px auto 0}
.ln-noodle.hop{animation:lnHop .6s var(--ln-ease)}
/* the animated celebration (noodle/celebrate-anim.svg): its viewBox is padded so the jump and the confetti never clip; the
   larger box and negative margins keep Noodle the size and place of the 88 px drawing */
.ln-noodle.ln-cel{width:117px;height:121px;margin:-9px auto -13px}
@keyframes lnHop{0%{transform:translateY(3px)}20%{transform:translateY(-16px)}50%{transform:translateY(0)}65%{transform:translateY(-4px)}100%{transform:none}}
.lp-sub{color:var(--ink-2);margin:4px auto 0;max-width:56ch}
.lp-stats{display:flex;justify-content:center;flex-wrap:wrap;gap:12px 40px;margin:24px 0 8px}
.lp-stats > div{display:grid;justify-items:center;gap:2px;animation:lnRiseT .3s var(--ln-ease) both}
.lp-stats > div:nth-child(1){animation-delay:.65s}.lp-stats > div:nth-child(2){animation-delay:.8s}.lp-stats > div:nth-child(3){animation-delay:.95s}
.lp-stats dt{color:var(--ink-3);font-size:14px;font-weight:600}
.lp-stats dd{margin:0;font:700 34px var(--f-display);color:var(--study-ink);font-variant-numeric:tabular-nums}
.lp-stats span{color:var(--ink-3);font-size:14px}
.lp-intro .lp-stats{justify-content:flex-start}.lp-intro{text-align:start}
.lp-confetti{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
.lp-result{text-align:start}.lp-result > h1,.lp-result > .ln-noodle{text-align:center}
.lp-result .lp-stats{justify-content:center}
.lp-result h2{font-size:20px;margin:28px 0 10px}
.lp-bars{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.lp-bars li{display:grid;grid-template-columns:minmax(0,1fr) minmax(80px,1fr) 56px;gap:12px;align-items:center;font-size:15.5px}
.lp-bars .bar{display:block;align-self:center;height:12px;border-radius:6px;background:var(--sunk);overflow:hidden}
.lp-bars .bar i{display:block;width:100%;height:100%;background:var(--study);transform-origin:left}
.lp-bars .v{text-align:end;font-variant-numeric:tabular-nums;color:var(--ink-2)}
.lp-rq{border-top:2px solid var(--rule)}
.lp-rq summary{display:flex;justify-content:space-between;gap:12px;padding:14px 2px;cursor:pointer;font-weight:600}
.lp-rq .lq{padding:0 0 16px}
.lp-jump{padding-inline-start:22px}
.lp-list h2{font-size:20px;margin:26px 0 8px}
.lp-lock{text-align:start}.lp-lock .ln-noodle{margin:6px 0 0}
.lp-facts{color:var(--ink-3)}
.lp-plusline{margin:22px 0 0;font-weight:600}.lp-plusline a{color:var(--study-ink)}
.lp-lock-in{display:flex;gap:16px;align-items:flex-start}.lp-lock-in .ln-noodle{margin:0;flex:none}.lp-lock-in a{color:var(--study-ink);font-weight:700}

@media (prefers-reduced-motion:reduce){
  .lp-screen.enter,.lp-sheet.rise,.lq-tile.pop,.lq-in.shake,.ln-noodle.hop,.lp-done > h1,.lp-stats > div,.lp-combo.pop{animation:none}
  .lp-bar > span{transition:none}.lp-bar.sheen::after{display:none}
}
@keyframes lnPop{0%{transform:scale(1)}40%{transform:scale(1.18)}100%{transform:scale(1)}}
.lq-intro{margin:6px 0 4px;padding:0 0 12px;border-bottom:2px solid var(--rule);color:var(--ink-2);font-size:16.5px}
.lq-intro p{margin:0 0 6px}.lq-introt{font-weight:700;color:var(--study-ink)}
.lp-stats dd span{font:inherit;color:inherit}

/* ================================================================ October 2026: motion and the streak (learn-fx.js)
   Timings and reasons: handoff-2026-10-06/LEARN_MOTION_SPEC.md. Transform and opacity only; Noodle never scales. */
/* a wide table in a lesson scrolls inside itself instead of widening the page on a phone */
.lp-prose table{display:block;max-width:100%;overflow-x:auto}
/* the player never scrolls sideways: a screen slides in from 18 px right, inside the stage */
.lp-stage{overflow-x:clip}

/* the feedback sheet: a mark that pops, the title lands a frame after the bar rises */
.lp-sh{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:start}
.lp-shx{min-width:0}
.lp-mk{width:38px;height:38px;border-radius:50%;display:grid;place-items:center;color:#fff;margin-top:-3px}
.lp-mk svg{width:22px;height:22px}
.is-right .lp-mk{background:var(--ln-right)}.is-wrong .lp-mk{background:var(--ln-wrong)}.is-neutral .lp-mk{background:var(--ln-self)}
:root[data-theme="dark"] .lp-mk{color:#0b1626}
.lp-sheet:not(.again) .lp-mk{animation:lnMark .36s .06s var(--ln-spring) both}
.lp-sheet:not(.again) .lp-sh .t{animation:lnLand .26s .04s var(--ln-ease) both}
@keyframes lnMark{from{transform:scale(.4) rotate(-20deg);opacity:0}to{transform:none;opacity:1}}
@keyframes lnLand{from{transform:translateY(8px);opacity:0}to{transform:none;opacity:1}}

/* buttons: the face drops onto its lip at once, springs back in 90 ms */
.lp-btn:not(:disabled):active{filter:brightness(.96)}

/* Noodle stands on the action bar, right-hand end, feet on its top edge; one fixed box, so he never changes size */
.lp-coach{position:absolute;inset-inline-end:max(10px,calc(50% - 440px));bottom:calc(100% - 5px);width:90px;height:93px;pointer-events:none;z-index:1;transition:opacity .18s var(--ln-ease),visibility .18s var(--ln-ease)}
.ln-coach{display:block}
.ln-layer{position:absolute;inset:0}
.ln-layer svg{display:block;width:100%;height:100%;overflow:visible}
body.pad-on .lp-coach{opacity:0;visibility:hidden}
body.coach-off .lp-coach{display:none}
@media (max-height:600px){.lp-coach{display:none}}

/* top bar: room for the bar on a phone; the vibration switch (Android only) */
@media (max-width:440px){.lp-top{gap:4px;padding-inline-start:max(8px,env(safe-area-inset-left));padding-inline-end:max(8px,env(safe-area-inset-right))}.lp-combo .w{display:none}}
.lp-combo{display:inline-flex;align-items:center;gap:4px}
.lp-combo svg{flex:none}

/* combo: from three first tries in a row the bar warms to gold, glows, and a light runs along the fill */
.lp-bar{transition:box-shadow .3s var(--ln-ease)}
.lp-bar > span{overflow:hidden;transition:transform .7s var(--ln-spring),background-color .3s var(--ln-ease)}
.lp-bar.is-combo{box-shadow:0 0 0 3px color-mix(in srgb,var(--gold) 32%,transparent),0 0 16px color-mix(in srgb,var(--gold) 50%,transparent)}
.lp-bar.is-combo > span{background:var(--gold)}
.lp-bar.is-combo > span::after{content:'';position:absolute;top:0;bottom:0;inset-inline-start:0;width:30%;background:rgba(255,255,255,.45);transform:translateX(-120%) skewX(-20deg);animation:lnComboRun 1.6s .2s var(--ease-io,cubic-bezier(.45,0,.55,1)) infinite}
@keyframes lnComboRun{0%{transform:translateX(-120%) skewX(-20deg)}60%,100%{transform:translateX(380%) skewX(-20deg)}}

/* lesson complete: Noodle, then three figures that count up */
.lp-coach-big{position:relative;display:block;width:124px;height:128px;margin:0 auto}
.lp-done-fx > h1{animation:none}
.lp-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:10px;max-width:480px;margin:22px auto 10px}
.lp-tiles > div{display:grid;justify-items:center;gap:2px;padding:10px 4px 12px;border:2px solid var(--rule-2);border-radius:16px;box-shadow:none;background:var(--surface)}
.lp-tiles dt{font-size:13.5px;font-weight:700;color:var(--ink-3)}
.lp-tiles dd{margin:0;font:700 30px/1.15 var(--f-display);font-variant-numeric:tabular-nums}
.lp-tiles .st-xp{border-color:color-mix(in srgb,var(--gold) 70%,var(--rule-2));box-shadow:none}
.lp-tiles .st-xp dd{color:var(--gold-ink)}
.lp-tiles .st-acc{border-color:color-mix(in srgb,var(--ln-right) 55%,var(--rule-2));box-shadow:none}
.lp-tiles .st-acc dd{color:var(--ln-right)}
.lp-tiles .st-time dd{color:var(--study-ink)}
.lp-facts2{font-size:15px;color:var(--ink-3)}

/* the streak screen */
.lp-streak{text-align:center;padding-top:4px}
.sk-stage{display:flex;justify-content:center;align-items:flex-end;height:178px;margin:6px auto 0}
.sk-coach{position:relative;display:block;width:104px;height:108px;margin:0 -6px 0 0}
.sk-flame{display:block;font-size:128px;line-height:0;margin-bottom:6px}
.sk-flame .blk-flame{vertical-align:bottom}
.sk-num{margin:6px 0 0;font:800 64px/1 var(--f-display);color:#e8641e;font-variant-numeric:tabular-nums}
:root[data-theme="dark"] .sk-num{color:#ff9a5c}
.sk-roll{display:inline-grid;overflow:hidden;padding:0 4px}
.sk-roll > span{grid-area:1/1;display:block}
.lp-streak > h1{font-size:22px;margin:4px 0 16px}
.sk-week{display:flex;justify-content:center;gap:6px;list-style:none;padding:0;margin:0 auto 14px;max-width:340px}
.sk-week li{flex:1;display:grid;justify-items:center;gap:6px;max-width:42px}
.sk-week .wd{font-size:13px;font-weight:700;color:var(--ink-3)}
.sk-week .is-now .wd{color:var(--ink)}
.sk-week .dot{width:34px;height:34px;border-radius:50%;display:grid;place-items:center;border:2px solid var(--rule-2);background:var(--surface);color:#fff}
.sk-week .dot svg{width:18px;height:18px}
.sk-week .is-done .dot{background:#ff7a3d;border-color:#e55e00}
.sk-week .is-rest .dot{background:#dcf0ff;border-color:#8eaed4;color:#0561a1}
.sk-week .is-today .dot{border-style:dashed;border-color:#ff7a3d}
.sk-line{max-width:34ch}

/* the course path: keycap nodes joined by a line; done (gold, a tick), current (teal, a soft ring), open, Plus */
.ln-lessons.is-path li a{grid-template-columns:56px minmax(0,1fr);gap:16px;padding:12px 4px 20px;border:0;position:relative}
.ln-lessons.is-path li:first-child a{border-top:0}
.ln-lessons.is-path .st{display:none}
.ln-lessons.is-path .n{position:relative;z-index:1;width:56px;height:56px;border-radius:50%;font-size:19px;background:var(--sunk);color:var(--ink-3);box-shadow:none;transition:transform .09s var(--ln-spring),box-shadow .09s var(--ln-spring)}
.ln-lessons.is-path a:active .n{transform:scale(.98);box-shadow:none;transition-duration:0s}
.ln-lessons.is-path .n svg{width:26px;height:26px}
.ln-lessons.is-path li.is-done .n{background:var(--gold);color:#472d00;box-shadow:none}
.ln-lessons.is-path li.is-current .n{background:var(--study);color:#fff;box-shadow:none}
:root[data-theme="dark"] .ln-lessons.is-path li.is-current .n{color:#04161c}
.ln-lessons.is-path li.is-current .n::before{content:'';position:absolute;inset:-9px -11.5px -14px;border-radius:50%;border:3px solid var(--study);opacity:.45;animation:lnRing 2s var(--ease-io,cubic-bezier(.45,0,.55,1)) infinite}
@keyframes lnRing{0%,100%{transform:scale(.94);opacity:.5}50%{transform:scale(1.04);opacity:.18}}
.ln-lessons.is-path li.is-current .t{color:var(--study-ink)}
.ln-lessons.is-path li.is-lock .n{color:var(--ink-3)}
.ln-seg{position:absolute;inset-inline-start:32px;top:76px;bottom:-12px;width:5px;margin-inline-start:-2.5px;border-radius:3px;background:var(--rule-2);overflow:hidden}
.ln-seg i{display:block;height:100%;background:var(--gold);transform-origin:50% 0;transform:scaleY(0)}
.ln-lessons.is-path li.is-done .ln-seg i{transform:none}
.ln-ring{position:absolute;inset:-6px;border-radius:50%;border:4px solid var(--study);pointer-events:none;opacity:0}

/* the streak on the hub and unit pages */
.ln-streak{float:inline-end;display:inline-flex;align-items:center;gap:6px;margin:2px 0 0 12px;font:800 20px/1 var(--f-display);color:#e8641e;font-variant-numeric:tabular-nums}
:root[data-theme="dark"] .ln-streak{color:#ff9a5c}
.ln-streak .blk-flame{width:22px;vertical-align:middle}
.ln-streak.is-out,.ln-streak.is-frozen{color:var(--ink-3)}

@media (prefers-reduced-motion:reduce){
  .lp-sheet .lp-mk,.lp-sh .t,.lp-bar.is-combo > span::after,.ln-lessons.is-path li.is-current .n::before{animation:none!important}
  .lp-bar,.lp-bar > span,.lp-coach,.ln-lessons.is-path .n{transition:none}
}

/* ================================================================ October 2026: how a question reads
   Measured across every template (docs/status/QUESTION_VISUAL_AUDIT.md); learn.js polish() does the text side. */
/* superscripts and subscripts drawn in the body face (Onest has no ⁴ to ⁹, ⁻ or ₀ to ₉), without opening the line */
/* (owner, 12 Oct: "the 4^8 question, you can barely see the 8"): 72% of the text, never under 12 px (feedback and
   working at 15.5 px had drawn them at 11 px), raised about a third of the text's em (.48 of its own), line-height 0
   so a line never jumps; a bank's own <sup>/<sub> (rich()) follows the same rule. In a maths prompt the numbers are
   semibold (numWeight), so the power is too: a thin small 8 beside a heavy 4 was the part that vanished.
   dev/market/sup-size.cjs measures it. */
.lx-s,sup,sub{font-size:max(.72em,12px);line-height:0;position:relative;vertical-align:baseline}
sup,sup.lx-s{top:-.48em}
sub,sub.lx-s{top:.26em}
.lq-stem:has(.lx-n) sup,.lq-prompt .pt:has(.lx-n) sup,.lp-prose:has(.lx-n) sup{font-weight:600}
.lx-nw{white-space:nowrap;word-spacing:-.07em}   /* a no-break space, narrowed to about a fifth of an em */
.lq-tile .c{text-wrap:balance}
.lq-stem p,.lq-prompt .pt,.lq-res .say,.lq-ws li,.lp-sh .l,.ms li{text-wrap:pretty}
/* tables: proportional figures. Onest's tabular figures centre a narrow 1 in a wide slot and leave a gap after the
   minus, which read as "1 3" and "- 6"; static numbers here do not change, so they do not need to line up digit by digit */
.lq-stem .qt,.lq-table,.lp-prose table,.lq-res table,.lq-ws table{font-variant-numeric:normal}
.lq-stem .qt th,.lp-prose th,.lq-table th{overflow-wrap:normal;hyphens:manual}
.lq td.n{white-space:nowrap}
/* a table scrolls inside its own box, with a soft shadow on the side that has more */
.lq-tscroll{max-width:100%;overflow-x:auto;margin:10px 0 14px;overscroll-behavior-x:contain;
  background:linear-gradient(90deg,var(--paper) 40%,rgba(var(--ink-rgb),0)) left center/28px 100% no-repeat local,
    linear-gradient(270deg,var(--paper) 40%,rgba(var(--ink-rgb),0)) right center/28px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%,rgba(var(--ink-rgb),.2),rgba(var(--ink-rgb),0)) left center/12px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%,rgba(var(--ink-rgb),.2),rgba(var(--ink-rgb),0)) right center/12px 100% no-repeat scroll}
.lq-tscroll > table,.lp-prose .lq-tscroll > table{display:table;margin:0;max-width:none;overflow:visible}
.lq-stem .lq-tscroll > .qt,.lq-tscroll > .lq-table{margin:0}
/* turned to run down a phone: headings on top, labels on the left, numbers on the right */
table.is-tall{min-width:min(100%,240px)}
table.is-tall th,table.is-tall td,.lq-stem .qt.is-tall th,.lq-stem .qt.is-tall td{text-align:start}
table.is-tall .n,.lq-stem .qt.is-tall .n{text-align:end}
table.is-tall tr:first-child > *{vertical-align:bottom}
.lq-table.is-tall td{padding:4px 6px}
/* a wide reading table on a phone: a card a row (learn.js cardFit; owner rule: row cards on mobile, never squashed) */
.lq-tscroll:has(> table.is-cards){overflow:visible;background:none;display:block;width:100%}
table.is-cards,table.is-cards > :is(thead,tbody,tfoot),table.is-cards tr,table.is-cards :is(td,th){display:block;width:auto;min-width:0;max-width:none}
table.is-cards{width:100% !important}
table.is-cards :is(thead,tr.lt-head){display:none}
table.is-cards tr{border:2px solid var(--rule-2);border-radius:14px;padding:10px 14px 8px;margin:0 0 10px;background:var(--surface)}   /* the lesson's other cards' edge (.cs-viz), never a faint line (19 Oct) */
table.is-cards tr:last-child{margin-bottom:0}
table.is-cards tr > :is(td,th){border:0 !important;padding:2px 0 !important;background:none !important;text-align:start !important;white-space:normal}
table.is-cards tr > :first-child{font-weight:700;padding-bottom:4px !important}
table.is-cards td.lt-eq{white-space:nowrap !important}   /* one equation a cell: whole on its line in the card (LRN-05) */
table.is-cards tr > [data-h]::before{content:attr(data-h) ": ";font-weight:600;color:var(--ink-3)}   /* the column's name, then the value: one line where it fits */
/* an answer box and its unit stay on one line; the box gives way first */
.lq-fu{display:flex;align-items:center;gap:8px;flex:1 1 0;min-width:min(100%,210px);max-width:100%}   /* a unit after the box: 8 px from it */
.lq-fu .lq-field{flex:0 1 auto;min-width:120px}
.lq-fu .lq-field.unit{flex:0 1 120px;min-width:84px}
.lq-fu .u{flex:none;white-space:nowrap}
.lq-line .lab{flex:none;max-width:100%}
.lq-line.lq-pre{gap:8px;flex-wrap:nowrap}.lq-line.lq-pre .lab{min-width:0}   /* a unit before the box (£): against it, 8 px, never on a line of its own (learn.js) */
.lq-field,.lq-cell{max-width:100%}
/* touch targets: 44 px */
.lp-link{min-height:44px}
.lp-keep{margin:18px 0 0;text-align:center}.lp-keep .lp-link{display:inline-flex;align-items:center}
.ms label:has(input){min-height:44px;align-items:center}
.ms label:has(input) input{margin:0}
/* long typed answers (lists, sentences) fit a phone's line */
.lq-field.wide{font-size:18px}
@media (max-width:440px){.lq-field.wide{font-size:17px;padding-inline-start:12px;padding-inline-end:12px}}
/* computer science tables scroll in the shared wrapper (with its edge shadow); its tabs and grid cells keep 44 px */
.lq-tscroll > table.cs-t{display:table;max-width:none;overflow:visible;font-variant-numeric:normal}
.cs-langs .cs-lang{min-height:44px}
.cs-code .cs-pre{background:linear-gradient(90deg,var(--surface) 40%,rgba(var(--ink-rgb),0)) left center/28px 100% no-repeat local,
    linear-gradient(270deg,var(--surface) 40%,rgba(var(--ink-rgb),0)) right center/28px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%,rgba(var(--ink-rgb),.2),rgba(var(--ink-rgb),0)) left center/12px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%,rgba(var(--ink-rgb),.2),rgba(var(--ink-rgb),0)) right center/12px 100% no-repeat scroll,var(--surface)}
@media (max-width:520px){.lq .lq-grid .lq-cell{min-height:44px}}
/* a nuclide's mass and atomic numbers, stacked and right-aligned before its symbol */
.lx-nuc{display:inline-flex;flex-direction:column;align-items:flex-end;vertical-align:.5em;font-size:.66em;line-height:1.02;margin-inline-end:.06em;top:0}
.lx-nuc > sup,.lx-nuc > sub{font-size:1em;vertical-align:baseline;line-height:inherit;top:0}
/* a fraction of two numbers, built up; the slash is kept in the text but not drawn */
.lx-fr{display:inline-flex;flex-direction:column;align-items:center;vertical-align:.46em;font-size:.84em;line-height:1.12;margin:0 .08em;font-variant-numeric:lining-nums}
.lx-fr > span:first-child{/* lint-ok: strip, a fraction's bar */border-bottom:.09em solid currentColor;padding:0 .14em}
.lx-fr > span:last-child{padding:0 .14em}
.lx-sl{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
/* a square root's bar over what it covers */
/* a root (learn.js roots, rootDraw): the sign and the bar are one SVG path drawn to the root's size in currentColor at
   Onest's stem weight, with a mitred corner where the rising stroke meets the bar; the bar spans the whole radicand */
.lx-sqrt{position:relative;display:inline-block;white-space:nowrap;padding-inline-start:.6em;margin:0 .06em 0 .04em;line-height:1.15;vertical-align:baseline}
/* a radicand longer than its line wraps inside its root (A-level physics at 320 and 390: "√(2 × 6.67 × 10⁻¹¹ × ...)" ran off the
   screen): the root is at most its line's width, the sign runs the whole height and the bar spans every line under
   it (learn.js rootDraw draws from the root's box); a root that fits keeps to one line, as before */
.lx-sqrt{white-space:normal;max-width:100%}.lx-sqrt > .lx-rad{max-width:100%;white-space:normal}
.lx-sqrt.has-i{margin-inline-start:.36em}
.lx-rs,.lx-rs path{fill:none;stroke:currentColor;stroke-linejoin:miter;stroke-miterlimit:3;stroke-linecap:butt}   /* mitred at the bar; the sharp foot bevels instead of spiking */
.lx-rs{position:absolute;inset-inline-start:0;top:0;overflow:visible;pointer-events:none}
.lx-rad{display:inline-block;padding:.17em .1em 0 .02em}   /* the clearance under the bar; the right padding is the bar's overhang */
.lx-ri{position:absolute;inset-inline-start:-.42em;bottom:52%;font-size:.62em;line-height:1}
.lq-tile .lx-fr{font-size:.9em}

/* ================================================================ 7 Oct (owner): chosen, not yet, disabled, flashcards, breathers */
/* "not yet" (and "That did not go through") comes with a retry curl, never alarm red: a miss is part of learning. Its
   own soft raspberry (coordinator, 19 Oct, LRN-24): not the teal of right and of the brand, not the amber and brown of
   before, not the wine ground in dark mode. --miss-ink for words and marks, --miss-tint for grounds, --miss-btn for a
   filled miss button (white text). Light: ink on tint 4.95:1, white on the button 5.83:1; dark: ink on tint 7.78:1,
   white on the button 4.93:1. Thought catcher (tools) uses the same values. */
:root{--miss-ink:#b03a5b;--miss-tint:#fde7ee;--miss-btn:#b03a5b;--ln-wrong:var(--miss-ink);--ln-wrong-bg:var(--miss-tint)}
:root[data-theme="dark"]{--miss-ink:#ff8fab;--miss-tint:#2a1630;--miss-btn:#c2416a;--ln-wrong:var(--miss-ink);--ln-wrong-bg:var(--miss-tint)}
/* a chosen answer keeps its box: violet edge and a small lift, no tint that could read as marked right */
.lq-tile[aria-pressed="true"]{border-color:var(--play);background:var(--surface);box-shadow:none;transform:translateY(-2px)}
.lq-tile[aria-pressed="true"] .k{border-color:var(--play);background:var(--play);color:#fff}
:root[data-theme="dark"] .lq-tile[aria-pressed="true"] .k{color:#0b1626}
.lq-tile.right[aria-pressed="true"],.lq-tile.wrong[aria-pressed="true"]{transform:none}
.lq-tile.right[aria-pressed="true"]{box-shadow:none;border-color:var(--ln-right);background:var(--ln-right-bg)}
.lq-tile.wrong[aria-pressed="true"]{box-shadow:none;border-color:var(--ln-wrong);background:var(--ln-wrong-bg)}
.lq-tile.pop{animation:none}
/* a disabled button reads as waiting, with a label you can still read (no green on near-black) */
.lp-btn:disabled,:root[data-theme="dark"] .lp-btn:disabled{background:var(--sunk);color:var(--ink-2);box-shadow:inset 0 0 0 2px var(--btn-off-edge);opacity:1}
:root[data-theme="dark"] .lp-btn:disabled{background:#1b2f4b;color:#c8d7e8;box-shadow:inset 0 0 0 2px var(--btn-off-edge)}
/* numbers in a maths question carry a little more weight */
.lx-n,.lq-stem .lx-fr,.lq-prompt .lx-fr{font-weight:600}
/* Added to Flashcards: a card drops onto the stack and a tick draws in */
.lp-decked{display:inline-flex;align-items:center;gap:8px;text-decoration:none;color:var(--ink-2);cursor:default}
.lp-deckic{flex:none;overflow:visible}
.lp-deckic rect{fill:var(--surface);stroke:currentColor;stroke-width:1.6}
.lp-deckic .s2{opacity:.45}.lp-deckic .s1{opacity:.7}
.lp-deckic .fly{fill:var(--study-tint);stroke:var(--study-ink)}
.lp-deckic .tk{fill:none;stroke:var(--study-ink);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1;stroke-dashoffset:0}
.lp-decked.go .fly{animation:lnCardIn .42s cubic-bezier(.22,1,.36,1) both}
.lp-decked.go .tk{animation:lnTick .3s .34s var(--ln-ease) both}
.lp-decked.go span{animation:lnLand .26s .3s var(--ln-ease) both}
@keyframes lnCardIn{from{transform:translate(-14px,-16px) rotate(-14deg);opacity:0}70%{transform:translate(1px,1px) rotate(2deg);opacity:1}to{transform:none}}
@keyframes lnTick{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}
/* a breather between questions */
.lp-break{display:grid;justify-items:center;text-align:center;padding-top:6vh;cursor:pointer}
.lp-break-coach{position:relative;display:block;width:124px;height:128px}
.lp-break > h1{font-size:clamp(26px,5vw,34px);margin:14px 0 6px}
.lp-break .lp-sub{font-size:17px}
.lp-break:not(.reduce) > h1{animation:lnRiseT .3s .12s var(--ln-spring) both}
@media (prefers-reduced-motion:reduce){.lp-decked.go .fly,.lp-decked.go .tk,.lp-decked.go span,.lp-break > h1{animation:none}.lq-tile[aria-pressed="true"]{transform:none}}

/* ================================================================ 7 Oct, later (owner): quieter choice, results, gaps, Enter, space */
/* chosen: a quiet edge and the faintest tint, same box; the result colours take over after Check */
.lq-tile[aria-pressed="true"]{border-color:color-mix(in srgb,var(--ink) 50%,var(--rule-2));background:color-mix(in srgb,var(--ink) 4%,var(--surface));box-shadow:none;transform:none}
.lq-tile[aria-pressed="true"] .k,:root[data-theme="dark"] .lq-tile[aria-pressed="true"] .k{border-color:currentColor;background:none;color:var(--ink)}
.lq-tile.right .c,.lq-tile.right .k,.lq-tile.right[aria-pressed="true"] .k{color:var(--ln-right);border-color:var(--ln-right);font-weight:600}
.lq-tile.wrong .c,.lq-tile.wrong .k,.lq-tile.wrong[aria-pressed="true"] .k{color:var(--ln-wrong);border-color:var(--ln-wrong);font-weight:600}
.lq-tile.right[aria-pressed="true"]{border-color:var(--ln-right);background:var(--ln-right-bg);box-shadow:none}
.lq-tile.wrong[aria-pressed="true"]{border-color:var(--ln-wrong);background:var(--ln-wrong-bg);box-shadow:none}
/* the box to fill in a prompt ("−2 □ −7"): a digit's size or more, outlined; it shows the chosen symbol */
.lx-gap{display:inline-block;box-sizing:border-box;min-width:1.9em;height:1.6em;line-height:calc(1.6em - 4px);overflow:hidden;text-align:center;padding:0 .15em;margin:0 .12em;border:2px solid var(--ink-3);border-radius:.3em;font-weight:700;color:var(--ink);
  vertical-align:-.4425em}   /* overflow:hidden puts its baseline at the bottom edge, empty or filled: the box's middle then sits at the middle of the figures (Onest figures are .715em tall) */
.lx-gap.is-filled{border-color:var(--ink);background:color-mix(in srgb,var(--ink) 5%,transparent)}
.lx-gap.right{border-color:var(--ln-right);color:var(--ln-right);background:var(--ln-right-bg)}
.lx-gap.wrong{border-color:var(--ln-wrong);color:var(--ln-wrong);background:var(--ln-wrong-bg)}
/* the hint, offered once after a long think */
.lq-offer{margin:14px 0 0;color:var(--ink-2);font-size:15.5px}
.lq-hintbtn.is-offer{font-size:16.5px}
/* space: the question sits a little above the middle of the room it has, in a column of about 820 px, and its type
   grows on big screens; the action bar lines up with that column */
.lp-stage{max-width:820px;display:flex;flex-direction:column;padding-bottom:180px}
.lp-stage::before,.lp-stage::after{content:'';flex:2 1 0;min-height:0}
.lp-stage::after{flex-grow:3}
.lp-stage::before,.lp-stage::after{visibility:hidden}   /* the centring spacers are never content that moves (a test's first screen: 0.14 at 390) */
/* a wide screen: the in-page bar waits unseen until the first real screen is drawn (learn.js: body.lq-first), so its
   moves as the loading shape gives way to the question are not layout shifts (the question page at 1440: 0.087) */
@media (min-width:700px){body.ln-fhold:not(.lq-first) .lp-foot{visibility:hidden}}
/* a lesson's article reads from the top: no room above it (at the first paint, the article parsed so far is short and
   these spacers pushed it 82 px down, then gave the room back: CLS 0.08 at 390, 14 Oct) */
.lp-stage:has(> .la.is-on)::before,.lp-stage:has(> .la.is-on)::after{content:none}
.lp-stage > *{flex:none}
.lp-stage > [hidden]{display:none}
.lq-stem,.lq-prompt{font-size:clamp(17.5px,1.05vw + 6px,25px)}
.lq-field,.lq-cell{font-size:clamp(20px,.6vw + 12px,24px)}
.lq-field{min-height:clamp(52px,2vw + 30px,64px)}
.lq-tile{font-size:clamp(18px,.6vw + 10px,22px);min-height:clamp(60px,2vw + 36px,72px)}
.lp-sheet,.lp-actions{max-width:820px}
@media (min-width:1100px){
  .lp-foot{border-top-width:1px}
  /* Noodle stands beside the question, at its height, in a fixed box (larger on a wide screen, never scaled in motion) */
  .lp-coach{width:120px;height:124px;right:calc(50% - 410px - 150px);bottom:calc(50dvh - 40px)}
}
@media (min-width:1700px){.lp-stage{max-width:900px}.lp-sheet,.lp-actions{max-width:900px}.lp-coach{right:calc(50% - 450px - 160px)}}
/* working: a box above the answer for 2+ mark questions */
.lq-work{margin:14px 0 4px;border:2px solid var(--rule-2);border-radius:16px;background:var(--surface)}
.lq-workh{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:2px 6px 2px 4px}
.lq-worktog,.lq-workmono{min-height:44px;background:none;border:0;cursor:pointer;color:var(--ink-2);font:700 15.5px var(--f-body);display:inline-flex;align-items:center;gap:6px;padding:0 10px;border-radius:12px}
.lq-workmono{font-weight:600;font-size:14px;color:var(--ink-3)}
.lq-workmono[aria-pressed="true"]{color:var(--study-ink)}
.lq-worktog svg{transition:transform .18s var(--ln-ease)}
.lq-work.is-shut .lq-worktog svg{transform:rotate(-90deg)}
.lq-work.is-shut .lq-workb,.lq-work.is-shut .lq-workmono{display:none}
.lq-workb{padding:0 12px 12px}
.lq-workta{display:block;width:100%;min-height:96px;resize:none;overflow:hidden;border:0;border-top:1px dashed var(--rule-2);background:transparent;color:var(--ink);font:500 18px/1.6 var(--f-body);padding:10px 4px 6px}
.lq-workta:focus{outline:none}
.lq-work:focus-within{border-color:var(--study);box-shadow:0 0 0 4px color-mix(in srgb,var(--study) 18%,transparent)}
.lq-work.is-mono .lq-workta{font-family:var(--f-mono);font-size:16.5px}
.lq-workta[readonly]{color:var(--ink-2)}
.lq-worksyms{margin-top:6px}
.lq-worksyms .lq-sym{min-width:44px;height:44px;font-size:17px}
/* after Check: your working beside the worked solution */
.lq-compare{display:grid;gap:4px 28px;margin:22px 0 0;padding:16px 0 0;border-top:2px solid var(--rule)}
.lq-compare .lq-ws{margin:0;padding:0;border:0}
.lq-yours h2{font-size:19px;margin:0 0 8px}
.lq-yours pre{margin:0 0 8px;white-space:pre-wrap;font:500 16.5px/1.55 var(--f-body);color:var(--ink-2)}
.lq-yours .pl{margin:0;font-weight:700;color:var(--ink-3)}
@media (min-width:860px){.lq-compare{grid-template-columns:minmax(0,1fr) minmax(0,1.2fr)}}
/* lesson complete: Noodle and the result side by side on a wide screen, stacked on a phone; a plain row of figures */
.lp-done2{text-align:start;display:grid;gap:8px 48px;align-items:center;justify-items:center}
.lp-done-hero{position:relative;width:150px;height:155px}
.lp-done2 .lp-coach-big{width:150px;height:155px;margin:0}
.lp-done2 .lp-friend{position:absolute;inset-inline-start:118px;top:48px;width:96px;height:auto}
.lp-done-body{width:100%;max-width:560px}
.lp-done2 h1{font-size:clamp(34px,3.2vw + 14px,52px);margin:0;text-align:center;line-height:1.05}
.lp-done-name{margin:8px 0 0;text-align:center;font:600 clamp(19px,1vw + 12px,24px)/1.3 var(--f-display);color:var(--study-ink)}
.lp-row{display:flex;justify-content:center;gap:0;margin:26px 0 8px;padding:14px 0;border-top:2px solid var(--rule);border-bottom:2px solid var(--rule)}
.lp-row > div{flex:1;display:grid;justify-items:center;gap:2px;padding:0 10px}
.lp-row > div + div{border-inline-start:2px solid var(--rule)}
.lp-row dt{font-size:14px;font-weight:700;color:var(--ink-3)}
.lp-row dd{margin:0;font:700 clamp(32px,2vw + 18px,44px)/1.1 var(--f-display);font-variant-numeric:tabular-nums}
.lp-row dd.sm{font-size:clamp(32px,2vw + 18px,44px);white-space:nowrap}
.lp-row .st-xp dd{color:var(--gold-ink)}.lp-row .st-acc dd{color:var(--ln-right)}.lp-row .st-time dd{color:var(--study-ink)}
.lp-dh{font-size:18px;margin:20px 0 6px}
.lp-dl{list-style:none;margin:0;padding:0}
.lp-dl li{display:flex;align-items:center;gap:10px;min-height:44px;padding:4px 0;border-bottom:1px solid var(--rule);font-size:16.5px}
.lp-dl li.ok svg{flex:none;color:var(--ln-right)}
.lp-dl li span{flex:1}
.lp-dlink{flex:none;min-height:44px;display:inline-flex;align-items:center;color:var(--study-ink);font-weight:700}
@media (min-width:900px){.lp-done2{grid-template-columns:auto minmax(0,560px);justify-content:center}.lp-done-hero,.lp-done2 .lp-coach-big{width:190px;height:196px}.lp-done2 .lp-friend{inset-inline-start:150px;top:70px}.lp-done2 h1,.lp-done-name{text-align:start}.lp-row{justify-content:flex-start}}
/* the spark of a right answer (learn.js zap) */
.lp-zap{position:fixed;z-index:40;pointer-events:none;overflow:visible}
.lp-zap .z{fill:none;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}
.lp-plus{position:fixed;z-index:41;pointer-events:none;font:800 30px/1 var(--f-display);color:var(--ln-right);text-shadow:0 2px 0 var(--paper)}
.lp-plus.is-part{color:var(--gold-ink);font-size:24px}
.lp-bar.is-zap > span{animation:lnZapBar .7s var(--ln-ease)}
@keyframes lnZapBar{0%{background:var(--study)}30%{background:var(--ln-right)}100%{background:var(--study)}}
.lq-glow{box-shadow:0 0 0 4px color-mix(in srgb,var(--ln-right) 35%,transparent);border-radius:16px}
@media (prefers-reduced-motion:reduce){.lp-bar.is-zap > span{animation:none}}
/* buttons never wrap their label: they size to it, and when a bar cannot hold them side by side they stack full width */
body.ln .lp-btn,body.ln-play .lp-btn,body.ln button,body.ln .btn,.lp-link,.lq-tile .k{white-space:nowrap}
.lp-actions{flex-wrap:wrap}
.lp-btn{flex:1 1 auto;min-width:min(100%,max-content)}
@media (min-width:700px){.lp-btn{flex:0 0 auto;min-width:180px}}
/* lesson screens: a reading measure, larger type, room between paragraphs, the key idea first */
.lp-learn .lp-prose,.lp-try .lp-prose{font-size:clamp(18px,.4vw + 15px,19.5px);line-height:1.6}
.lp-prose p,.lp-prose ul,.lp-prose ol{max-width:65ch}
.lp-prose p{margin:0 0 1em}
/* no word left alone on a last line (owner): paragraphs wrap 'pretty', short captions balance their lines */
.lp-prose p,.lp-prose li{text-wrap:pretty}
.lp-prose figcaption,.lp-video figcaption,.lq-viscap{text-wrap:balance}
.lp-prose .ln-key{font:600 clamp(20px,.8vw + 15px,24px)/1.4 var(--f-body);color:var(--ink);margin:2px 0 18px;padding:14px 18px;background:var(--study-tint);border-radius:var(--r2);max-width:52ch}
.lp-prose .lx-n{font-weight:600}
.lp-prose .qt{border-collapse:collapse}
.lp-prose .qt th,.lp-prose .qt td{border:2px solid var(--rule-2);padding:7px 12px;text-align:center}
.lp-prose .qt th{font-weight:600;color:var(--ink-2)}
.lp-prose .qt tr:nth-child(even) td{background:color-mix(in srgb,var(--ink) 3%,transparent)}
/* the place-value chart */
/* the columns told apart by space and a soft fill per digit, not ruled lines (no-hairlines rule, coordinator 14 Oct) */
table.lx-pv{border-collapse:separate;border-spacing:6px 6px;margin:0 -6px 12px;font-variant-numeric:normal}
.lx-pv th{font:600 13.5px/1.2 var(--f-body);color:var(--ink-3);padding:4px 8px 0;text-align:center;vertical-align:bottom;white-space:normal;min-width:64px}
.lx-pv td{font:700 clamp(28px,2vw + 16px,38px)/1.3 var(--f-display);text-align:center;padding:8px 8px 6px;color:var(--ink);background:var(--sunk);border-radius:12px}
.lx-pv .pt{min-width:0;width:18px;padding:0;background:none;color:var(--ink-3)}
.lx-pv th.hit{color:var(--study-ink)}
.lx-pv td.hit{background:var(--study-btn);color:#fff;border-radius:12px}   /* the digit the text talks about: brand teal, white digit (4.9:1) */
.lx-pv[style*="--pvw"] th:not(.pt),.lx-pv[style*="--pvw"] td:not(.pt){box-sizing:border-box;width:var(--pvw);min-width:0;max-width:var(--pvw)}
.lx-pv th{hyphens:auto}   /* (a heading in a cell shrunk to fit a phone breaks at a syllable, never sticks out) */
/* worked steps, one tap at a time; lined-up decimals with the added zeros lighter */
.wk-step li[hidden]{display:none}
.wk-next{margin:0 0 14px;padding:0 4px}
.wk-aligned .wk-n{display:inline-grid;grid-template-columns:var(--wk-i,3ch) auto auto;justify-self:start;white-space:nowrap;font:600 20px/1.4 var(--f-mono)}   /* a number never breaks: whole part, point, decimals on one line */
.wk-aligned .wk-n > *{white-space:nowrap}
.wk-aligned .wk-n .i{text-align:end}
.wk-aligned .wk-n .z{color:var(--ink-3);text-decoration:underline dotted;text-underline-offset:4px}
/* wide screens: the explanation on the left, its picture (chart, table, worked steps, formula) on the right */
@media (min-width:1100px){
  .lp-stage:has(> .lp-learn.is-on){max-width:1160px}
  .lp-learn .lp-prose{display:grid;grid-template-columns:minmax(0,62ch) minmax(280px,1fr);column-gap:56px;grid-auto-flow:row dense;align-items:start}
  .lp-learn .lp-prose > *{grid-column:1}
  .lp-learn .lp-prose > :is(.lq-tscroll,figure,.fml,ol.wk,.wk-next,.lp-tool,table,blockquote,.ln-note){grid-column:2;grid-row:span 3}
  .lp-learn .lp-prose > .wk-next{grid-row:auto}
  .lp-learn .lp-prose > .ln-key{grid-column:1 / -1;max-width:60ch}
}
/* a screen that opens on a question: think first, then Show me */
.ln-think{margin:4px 0 20px;padding:16px 18px;border:2px solid var(--rule-2);border-radius:18px;background:var(--surface);max-width:60ch}
.ln-think .t{margin:0;font:600 clamp(20px,.8vw + 15px,24px)/1.35 var(--f-body)}
.ln-think .h{margin:6px 0 12px;color:var(--ink-3);font-size:16px}
.lp-learn .lp-prose > .ln-think{grid-column:1 / -1}
.lp-prose [hidden]{display:none!important}
.lp-zap .zb{fill:#fff2cc;stroke:#15365a;stroke-width:1.3;stroke-linejoin:round}
.lp-zap .z{stroke-width:3}
@media (min-width:1100px){
  .lp-learn .lp-prose > .lq-tscroll:has(> .lx-pv){grid-column:1 / -1;grid-row:auto}
  body:has(.lp-learn.is-on) .lp-coach{inset-inline-end:max(10px,calc(50% - 580px));bottom:calc(100% - 5px)}
}
@media (max-width:440px){table.lx-pv{border-spacing:3px 4px;margin-inline:-3px}.lx-pv th{font-size:11px;padding:4px 3px;min-width:0}.lx-pv td{font-size:26px;padding:6px 4px 4px}.lx-pv .pt{width:10px}}
/* the narrowest phones (320): the place-value table uses the page's side gutters and slimmer cells, so "hundredths" is
   on screen without a sideways scroll (la_layout cut at 320) */
@media (max-width:359px){.lp-prose .lq-tscroll:has(> .lx-pv){margin-inline:-12px;max-width:calc(100% + 24px)}.lx-pv th{padding:4px 2px}.lx-pv td{padding:6px 3px 4px}.lx-pv .pt{width:6px}table.lx-pv{border-spacing:2px 3px;margin-inline:0}}
/* lesson complete, refined (owner): one character, stats on one line, the spark line under them, WWW and EBI folds */
.lp-done2 .lp-friend{display:none}
.lp-done2 .lp-earn{display:none}
.lp-done2 .lh-earned{margin:10px 0 0;display:flex;align-items:center;gap:8px;color:var(--ink-2);font-weight:600}
.lp-row dd{white-space:nowrap}
.lp-row > div{align-content:start}
.lp-fold{border-bottom:2px solid var(--rule)}
.lp-fold summary{display:flex;align-items:center;gap:10px;min-height:52px;cursor:pointer;list-style:none;font-weight:700}
.lp-fold summary::-webkit-details-marker{display:none}
.lp-fold summary .ic{display:grid;place-items:center;width:28px;height:28px;border-radius:50%;flex:none}
.lp-fold.www summary .ic{color:var(--ln-right);background:var(--ln-right-bg)}
.lp-fold.ebi summary .ic{color:var(--play-ink);background:var(--play-tint)}
.lp-fold summary .lb{font:700 18px var(--f-display)}
.lp-fold summary .ct{margin-inline-start:auto;color:var(--ink-3);font-weight:600;font-size:15px}
.lp-fold summary .chev{flex:none;color:var(--ink-3);transition:transform .2s var(--ln-ease)}
.lp-fold[open] summary .chev{transform:rotate(180deg)}
.lp-fold .lead{margin:0 0 6px;color:var(--ink-2)}
.lp-fold .lp-dl{margin-bottom:10px}
.lp-fold .lp-dl li{align-items:flex-start;padding:8px 0}
.lp-fold .lp-dl li > span{display:grid;gap:2px}
.lp-fold .say{color:var(--ink-2);font-size:15.5px;font-weight:400}
.lp-fold-none{display:flex;align-items:center;gap:10px;min-height:52px;margin:0;border-bottom:2px solid var(--rule);color:var(--ln-right);font-weight:700}
.lp-done2{margin-top:auto;margin-bottom:auto}
@media (prefers-reduced-motion:reduce){.lp-fold summary .chev{transition:none}}
/* leave this lesson? (an in-page sheet) */
.lp-modal{position:fixed;inset:0;z-index:60;display:grid;place-items:end center;background:rgba(var(--ink-rgb),.35)}
:root[data-theme="dark"] .lp-modal{background:rgba(0,0,0,.55)}
.lp-dlg{width:min(100%,520px);background:var(--paper);border-radius:22px 22px 0 0;padding:22px 20px calc(18px + env(safe-area-inset-bottom));display:grid;justify-items:center;text-align:center;gap:4px;animation:lnRise .3s var(--ln-ease)}
.lp-dlg h2{margin:6px 0 0;font-size:24px}
.lp-dlg p{margin:0 0 12px;color:var(--ink-2)}
.lp-dlgb{display:flex;gap:12px;width:100%}
.lp-dlgb .lp-btn{flex:1 1 0;min-width:0}
@media (min-width:700px){.lp-modal{place-items:center}.lp-dlg{border-radius:22px}}
@media (prefers-reduced-motion:reduce){.lp-dlg{animation:none}}
/* the coach steps aside when he would stand on content: the gutter by the action bar, else out of view */
body.coach-tuck .lp-coach{inset-inline-end:auto;inset-inline-start:max(12px,calc(50% - 410px));bottom:0;width:84px;height:87px}   /* in the action bar, left of its buttons (a fixed size for this place; he is never scaled in motion) */
body.coach-away .lp-coach{opacity:0;visibility:hidden}
body:has(.lp-modal) .lp-coach{visibility:hidden}   /* the sheet brings its own Noodle: still one character */
/* no hairlines that only repeat what spacing already says (owner, 7 Oct): stats grouped by space and type, one
   divider at most between the two folds, none under a fold's own header, none between worked steps or parts */
.lp-row{border:0;padding:0;gap:clamp(20px,4vw,48px);margin:22px 0 6px}
.lp-row > div{flex:0 1 auto;padding:0;justify-items:start}
.lp-row > div + div{border:0}
.lp-row dd{order:-1;line-height:1}
.lp-row dt{font-size:14px;margin-top:6px}
@media (max-width:899px){.lp-row{justify-content:center}.lp-row > div{justify-items:center}}
.lp-fold{border:0}
.lp-fold + .lp-fold,.lp-fold + .lp-fold-none,.lp-fold-none + .lp-fold{border-top:2px solid var(--rule)}
.lp-fold-none{border:0}
.lp-dl li,.lp-fold .lp-dl li{border:0}
.lp-dl li + li{border-top:1px solid var(--rule)}
.lp-done2 .lh-earned{margin-top:14px}
.lp-done2 .lp-fold:first-of-type,.lp-done2 .lp-fold-none:first-of-type{margin-top:18px}
.lq-part{border-top:0;padding-top:12px}
.lq-part + .lq-part{margin-top:12px}
.lq-ws,.lq-compare{border-top:0;margin-top:30px;padding-top:0}
.ms{border-top:0;padding-top:4px}
.wk li{border-bottom:0;padding:5px 0}
.lp-prose .fml{border:0;margin:24px 0;padding:6px 8px}
.lq-intro{border-bottom:0;padding-bottom:4px}
.lp-done2 .lh-earned{justify-content:flex-start;text-align:start;margin-inline-start:0;margin-inline-end:0}
/* diagrams drawn without a fill came out black, which vanished on the dark theme (13,320 findings in the audit):
   they take the text colour. In a layer, so any class or inline rule in a diagram still wins, and only shapes with no
   fill of their own (or from a group) are touched */
@layer lx-defaults{
  :where(.lq-stem,.lq-prompt,.lq-tile,.lq-ws,.lq-res,.lp-prose) svg :where(path,polygon,polyline,circle,rect,ellipse,text,tspan):not([fill]):not([fill] *):not([style*="fill"]){fill:currentColor}
}
/* a right answer's text on its pale green: a darker green for type (4.41:1 was just under AA) */
:root{--ln-right-ink:#0d6a40}
:root[data-theme="dark"]{--ln-right-ink:var(--ln-right)}
.lq-tile.right .c,.lq-tile.right .k,.lq-tile.right[aria-pressed="true"] .k,.lx-gap.right{color:var(--ln-right-ink)}
.lq-tile.right .k{border-color:var(--ln-right-ink)}
/* the leave sheet stands clearly off the lesson, like every site modal (header.php dialog.blm) */
.lp-modal{background:rgba(15,30,50,.45);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);animation:lnFade .18s var(--ln-ease)}
:root[data-theme="dark"] .lp-modal{background:rgba(5,12,24,.62)}
.lp-dlg{background:#fff;border:1px solid rgba(21,54,90,.10);box-shadow:0 2px 6px rgba(15,30,50,.10),0 28px 70px rgba(15,30,50,.32)}
:root[data-theme="dark"] .lp-dlg{background:#1b2f4b;border-color:rgba(200,215,232,.16);box-shadow:0 2px 8px rgba(0,0,0,.4),0 30px 80px rgba(0,0,0,.6)}
@keyframes lnFade{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){.lp-modal{animation:none}}
/* lesson complete: Save to flashcards, the cards shown as they will be studied */
.lp-save{margin:22px 0 0}
.lp-save .lead{margin:0 0 8px;color:var(--ink-2)}
.lp-cards{list-style:none;margin:0 0 10px;padding:0;display:grid;gap:12px}
.lp-cards li{display:flex;align-items:center;gap:14px}
.lp-cards .fcp{flex:1;min-width:0;padding:12px 16px;border:2px solid var(--rule-2);border-radius:16px;background:var(--surface)}
.lp-cards .cf{margin:0;font-weight:700}
.lp-cards .cb{margin:6px 0 0;color:var(--ink-2);font-size:15.5px;font-weight:400}
@media (max-width:520px){.lp-cards li{flex-direction:column;align-items:stretch;gap:4px}}
/* lesson complete, celebrated (owner, 8 Oct): Noodle the hero (larger box, never scaled in motion), a burst behind
   him, the real time, What went well and Even better if as two tinted panels (the owner asked for boxes here) */
.lp-done-hero{position:relative}
.lp-burst{position:absolute;left:50%;top:50%;width:300px;height:300px;margin:-150px 0 0 -150px;pointer-events:none;overflow:visible;z-index:0}
.lp-done-hero .lp-coach-big{position:relative;z-index:1}
@media (min-width:900px){.lp-done-hero,.lp-done2 .lp-coach-big{width:230px;height:238px}}
.lp-flyspark{position:fixed;z-index:70;pointer-events:none}
.lp-fold,.lp-fold + .lp-fold,.lp-fold + .lp-fold-none,.lp-fold-none + .lp-fold{border:0}
.lp-fold{margin:14px 0 0;padding:4px 16px 6px;border-radius:var(--r2,18px)}
.lp-fold.www{background:color-mix(in srgb,var(--ln-right) 9%,var(--paper));box-shadow:inset 0 0 0 1.5px color-mix(in srgb,var(--ln-right) 22%,transparent)}
.lp-fold.ebi{background:color-mix(in srgb,#f0a52a 12%,var(--paper));box-shadow:inset 0 0 0 1.5px color-mix(in srgb,#f0a52a 30%,transparent)}
.lp-fold.ebi summary .ic{color:#8a5d00;background:color-mix(in srgb,#f0a52a 28%,var(--paper))}
:root[data-theme="dark"] .lp-fold.ebi summary .ic{color:#ffd48a}
.lp-fold summary .ct{color:var(--ink-2)}
.lp-fold .lp-dl li + li{border-top:0}
.lp-fold .lp-dl li{padding:10px 0}
.lp-fold .lp-dlink.lp-btn{flex:0 0 auto;min-width:0;min-height:44px;padding:0 16px;font-size:15px}
.lp-fold-none{margin:14px 0 0;padding:10px 16px;border-radius:var(--r2,18px);background:color-mix(in srgb,var(--ln-right) 9%,var(--paper))}
.lp-done2 .lp-fold:first-of-type,.lp-done2 .lp-fold-none:first-of-type{margin-top:16px}
/* palette on this screen: semantic tokens only (owner, 8 Oct): the figures in one accent, success green and warm gold
   from their tokens, the primary button in the primary token */
.lp-row .st-xp dd,.lp-row .st-acc dd,.lp-row .st-time dd,.lp-row .st-streak dd{color:var(--study-ink)}
.lp-row .st-streak dd{display:flex;align-items:flex-end;gap:4px}
.lp-row .st-streak .blk-flame{width:.8em;height:1em;display:inline-block}
.lp-fold.ebi{background:color-mix(in srgb,var(--gold) 14%,var(--paper));box-shadow:inset 0 0 0 1.5px color-mix(in srgb,var(--gold) 38%,transparent)}
.lp-fold.ebi summary .ic,:root[data-theme="dark"] .lp-fold.ebi summary .ic{color:var(--gold-ink);background:color-mix(in srgb,var(--gold) 30%,var(--paper))}
:root[data-theme="dark"] .lp-fold.ebi summary .ic{color:var(--gold)}
.lp-done-name{color:var(--ink-2)}
/* a practice item: its button under the text on a phone, so the title never leaves a word stranded */
@media (max-width:560px){.lp-fold.ebi .lp-dl li{flex-direction:column;align-items:stretch;gap:8px}.lp-fold .lp-dlink.lp-btn{align-self:flex-start}.lp-row{gap:10px 18px;flex-wrap:wrap}}
/* leftovers from the audit: long units wrap under their box instead of running off a phone; code blocks show the
   edge shadow wherever they sit */
.lq-fu{flex-wrap:nowrap}   /* the unit stays beside its box; a long unit wraps inside its own column */
.lq-fu .u{flex:0 1 auto;white-space:normal;max-width:9em;min-width:min-content;line-height:1.2;overflow-wrap:normal}   /* never narrower than its longest unit word (mol/dm³ ran 10 px past the column at 390 px): the box gives way instead */
.lq-fu .lq-field{min-width:110px}
body.ln-play .lq-line > .lq-fu > .lq-field:not(.unit){width:134px}body.ln-play .lq-line > .lq-fu > .lq-field.unit{flex:1 1 142px;min-width:84px}   /* on a phone the answer box starts at 134 px (grows as typed) and the unit box at 142 px: room for a standard-form answer and for light-years */
pre.cs-pre,.lq pre{background:linear-gradient(90deg,var(--surface) 40%,rgba(var(--ink-rgb),0)) left center/28px 100% no-repeat local,
  linear-gradient(270deg,var(--surface) 40%,rgba(var(--ink-rgb),0)) right center/28px 100% no-repeat local,
  radial-gradient(farthest-side at 0 50%,rgba(var(--ink-rgb),.2),rgba(var(--ink-rgb),0)) left center/12px 100% no-repeat scroll,
  radial-gradient(farthest-side at 100% 50%,rgba(var(--ink-rgb),.2),rgba(var(--ink-rgb),0)) right center/12px 100% no-repeat scroll,var(--surface)}
/* a drawing in a question or a choice never runs past its box: it scales to fit (labels keep the 12 px floor) */
.lq-stem svg,.lq-prompt svg,.lq-tile .c svg,.lq-ws svg,.lq-res svg{max-width:100%;height:auto}
.lq-tile .c{min-width:0}

/* ---- the palette agent's patch, brand/identity/palette/patches/learn-lesson-complete.css (8 Oct) ---- */
/* Lesson complete in the palette 2.0 (brand/identity/COLOUR.md; owner, 8 Oct: "it feels a bit mismatched"): one action
   colour (teal: Finish!), one reward colour (gold: the XP figure, the Spark, the flame), green only on the tick that
   means right; the heading, the lesson name and the other figures in ink; both panels on the same quiet surface, told
   apart by their icon and heading, not by a second and third tint. Append to brainlag.space/public/assets/learn/learn.css. */
.lp-done2 h1{color:var(--ink)}
.lp-done-name{color:var(--ink-2)}
.lp-row .st-xp dd{color:var(--gold-ink)}
.lp-row .st-acc dd,.lp-row .st-time dd,.lp-row .st-streak dd{color:var(--ink)}
.lp-fold.www,.lp-fold.ebi,.lp-fold-none{background:var(--sunk);box-shadow:none}
:root[data-theme="dark"] .lp-fold.www,:root[data-theme="dark"] .lp-fold.ebi,:root[data-theme="dark"] .lp-fold-none{background:var(--surface)}
.lp-fold.www summary .ic,:root[data-theme="dark"] .lp-fold.www summary .ic{color:var(--ln-right-ink);background:var(--ln-right-bg)}
.lp-fold.ebi summary .ic,:root[data-theme="dark"] .lp-fold.ebi summary .ic{color:var(--study-ink);background:var(--study-tint)}
.lp-fold-none{color:var(--ink)}.lp-fold-none svg{color:var(--ln-right-ink)}
.lp-btn,:root[data-theme="dark"] .lp-btn{color:var(--on-study-btn)}   /* white on --study-btn, 4.76:1 (owner, 9 Oct) */
.lp-btn.quiet,:root[data-theme="dark"] .lp-btn.quiet{color:var(--ink)}
/* the feedback bar's own button keeps white type on green (the dark on-primary is for teal only) */
:root:not([data-theme="dark"]) .lp-foot:has(.is-right) .lp-btn:not(.quiet){color:#fff}
/* stats in equal columns, every label on one line; the flame and its number never squeeze */
.lp-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(88px,1fr));gap:12px 20px;justify-items:stretch}
.lp-row > div{min-width:0;justify-items:start}
.lp-row dt{white-space:nowrap}
.lp-row .st-streak dd{white-space:nowrap}
.lp-row .st-streak .blk-flame{flex:none}
@media (max-width:899px){.lp-row > div{justify-items:center}}
/* the result always scrolls clear of the fixed action bar */
.lp-stage:has(> .lp-done2.is-on){padding-bottom:calc(150px + env(safe-area-inset-bottom))}

/* ---- question pages, the owner's notes of 8 Oct (bubble sort, two's complement) ----
   Marks in one place; the tip as a tinted block, never a rule; no line between blocks anywhere on a question page
   (the audit's hairline and double-rule checks, tests/learn/visual/audit-page.js, fail on one); grids square and structured, marked cell by cell. */
.lq-mkh{margin:-6px 0 14px;color:var(--ink-3);font-size:14.5px;font-weight:600}
.lq-line.lq-typed-line{display:flex;flex-direction:column;align-items:stretch;gap:8px;margin-top:24px}.lq-line.lq-typed-line .lab{min-width:0;max-width:none}
.lq .lq-line.lq-typed-line .lq-field.lq-typed-field,.lq-line.lq-typed-line .lq-field.lq-typed-field{width:100% !important;max-width:none;min-height:54px;height:54px;font-size:17.5px;padding:0 16px}
.lq-hint.lq-typed-hint,.lq-part .lq-hint.lq-typed-hint{margin:6px 0 0}   /* typed recall: question, label, box and hint one tight group */
.lq-title.has-chip .lq-typechip{float:right;margin:4px 0 4px 12px;font-family:inherit;letter-spacing:0;line-height:1.4}[dir="rtl"] .lq-title.has-chip .lq-typechip{float:left;margin:4px 12px 4px 0}   /* floated, so a title in two runs ("Question 6 of 9") keeps its spacing */
.lq-typechip{display:inline-flex;align-items:center;gap:5px;padding:2px 10px 2px 8px;border-radius:999px;background:var(--study-tint);color:var(--ink-2);font-size:13.5px;font-weight:700;vertical-align:middle}.lq-typechip svg{fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}   /* typed recall: at the end of the title line */
.lq-tip{display:flex;gap:12px;align-items:flex-start;margin:2px 0 18px;padding:12px 16px;border:0;border-radius:14px;background:var(--study-tint);color:var(--ink);font-size:16.5px;line-height:1.5}
.lq-tipi{flex:none;margin-top:1px;fill:none;stroke:var(--study-ink);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.lq-tipb{min-width:0}.lq-tipb p{margin:0}.lq-tipb p + p{margin-top:6px}
.lq-intro,.lq-hinted,.lq-part,.lq-part + .lq-part,.lq-ws,.lq-compare,.ms{border-top:0;border-bottom:0}
.lq-hinted{border-inline-start:0;border-radius:12px;background:var(--study-tint)}
.lq .lq-grid{border-collapse:collapse;border:2px solid var(--rule-2);width:auto}
.lq .lq-grid th,.lq .lq-grid td{border:2px solid var(--rule-2);border-radius:0;padding:0;min-width:62px;height:50px;position:relative;vertical-align:middle}
.lq .lq-grid thead th{background:var(--sunk);color:var(--ink-2);font-weight:700;padding:8px 10px;height:auto}
.lq .lq-grid td:not(:has(.lq-cell)){padding:8px 12px}
.lq .lq-grid tbody td:first-child:not(:has(.lq-cell)){background:var(--sunk);font-weight:700;color:var(--ink-2);text-align:start}
.lq .lq-grid .lq-cell{display:block;width:76px;max-width:none;min-height:50px;margin:0;border:0;border-radius:0;background:var(--surface);padding:6px 10px;box-shadow:none}
.lq .lq-grid .lq-cell:focus{box-shadow:inset 0 0 0 3px var(--study)}
.lq .lq-grid .lq-cell[readonly]{background:transparent}
.lq .lq-grid td.c-ok{background:var(--ln-right-bg)}.lq .lq-grid td.c-no{background:var(--ln-wrong-bg)}
.lq .lq-grid .ci{position:absolute;top:4px;inset-inline-end:4px;width:16px;height:16px;border-radius:50%;display:grid;place-items:center;color:var(--paper);pointer-events:none}
.lq .lq-grid .c-ok .ci{background:var(--ln-right)}.lq .lq-grid .c-no .ci{background:var(--ln-wrong)}
.lq .lq-grid .ci svg{width:11px;height:11px;fill:none;stroke:currentColor;stroke-width:3.6;stroke-linecap:round;stroke-linejoin:round}
.lq-part.is-right .lq-field{border-color:var(--ln-right);background:var(--ln-right-bg)}
.lq-part.is-wrong .lq-field{border-color:var(--ln-wrong)}
.lq-glow{box-shadow:none}
.lp-sh .t .lp-plus{position:static;display:inline-block;margin-inline-start:10px;font-size:22px;line-height:1;text-shadow:none}
.lq-part.is-part .lq-field{border-color:var(--gold-ink)}
.lq-part:is(.is-right,.is-wrong,.is-part) .lq-field:not(.unit){padding-inline-end:44px}
.lq-fi{flex:none;position:relative;z-index:1;width:24px;height:24px;margin:0 12px 0 -46px;border-radius:50%;display:grid;place-items:center;color:var(--paper);pointer-events:none}
.lq-fi.is-right{background:var(--ln-right)}.lq-fi.is-wrong{background:var(--ln-wrong)}.lq-fi.is-part{background:var(--gold-ink)}
.lq-fi svg{fill:none;stroke:currentColor;stroke-width:3.6;stroke-linecap:round;stroke-linejoin:round}
.lq-workta{border-top:0;padding-top:12px}
.ms{border-top:0}

/* ---- lesson complete, the owner's notes of 8 Oct: the earlier palette read better (more of a celebration). The
   figures and panels take their colours back, in palette 2.0 tokens only (colour-lint 0): gold for XP, green for right
   first time, teal for time and the lesson name, a green panel for what went well and a gold one for even better if,
   no edges. The on-primary button text (#062529, AA) stays. No day-streak figure (it has its own screen). */
.lp-done-name{color:var(--study-ink)}
.lp-row .st-xp dd{color:var(--gold-ink)}
.lp-row .st-acc dd{color:var(--ln-right-ink)}
.lp-row .st-time dd{color:var(--study-ink)}
.lp-fold.www,.lp-fold-none,:root[data-theme="dark"] .lp-fold.www,:root[data-theme="dark"] .lp-fold-none{background:var(--ln-right-bg);box-shadow:none}
.lp-fold.ebi,:root[data-theme="dark"] .lp-fold.ebi{background:var(--gold-tint);box-shadow:none}
.lp-fold.ebi summary .ic,:root[data-theme="dark"] .lp-fold.ebi summary .ic{color:var(--gold-ink);background:var(--paper)}
.lp-fold.www summary .ic,:root[data-theme="dark"] .lp-fold.www summary .ic{background:var(--paper)}
/* the figures never clip: they keep their size where there is room and wrap to a second row where there is not */
.lp-row{display:flex;flex-wrap:wrap;gap:12px clamp(20px,4vw,40px)}
.lp-row > div{flex:0 0 auto;min-width:0}
.lp-row dd,.lp-row dd.sm{font-size:clamp(28px,1.6vw + 20px,44px)}
@media (max-width:899px){.lp-row{justify-content:center}}
/* the feedback panel and its buttons always fit the screen: on a short or landscape screen the panel's text scrolls
   inside it and the buttons stay in view; no rule above it, a soft shadow instead */
.lp-foot,.lp-foot:has(.lp-sheet.is-right){border-top:0;box-shadow:0 -10px 28px rgba(var(--ink-rgb),.07);max-height:100dvh;display:flex;flex-direction:column}
.lp-sheet{flex:0 1 auto;min-height:0;max-height:calc(100dvh - 120px);overflow-y:auto;overscroll-behavior:contain}
.lp-actions{flex:none}
.lp-foot > .lp-sheet,.lp-foot > .lp-actions{width:100%;box-sizing:border-box}
/* The feedback panel sits on the pinned bar, out of its flow (as the keypad, .lp-pad): the bar's own box never
   changes size, so nothing moves when the panel comes (it grew the bar 84-462 px at Check: a layout shift of 0.22 at
   390, the mark arriving after the tap's input window). learn.js footH counts its height into --lp-foot-h, so the
   page keeps room under the question; keepAnswerInView scrolls the chosen answer above it. It rises with the bar
   (FALLBACK.feedback: a transform); its box is held at the bar's top and lifted by its own height (a transform), so
   a panel that grows (Show the answer) does not move its own start either. Phones only (under 700 px): from 700 the
   panel and its buttons share a row, in flow as before. */
@media (max-width:699px){
  .lp-foot > .lp-sheet{position:absolute;inset-inline:0;top:0;bottom:auto;transform:translateY(-100%);max-width:none;margin:0;max-height:calc(100dvh - var(--lp-act-h,96px) - 24px);background:var(--paper);box-shadow:0 -10px 28px rgba(var(--ink-rgb),.07)}
  .lp-foot > .lp-sheet.is-right{background:var(--ln-right-bg)}
  .lp-foot > .lp-sheet.is-wrong{background:var(--ln-wrong-bg)}
  .lp-foot > .lp-sheet.is-neutral{background:var(--ln-self-bg)}
  .lp-foot:has(> .lp-sheet:not(:empty)){box-shadow:none}
  body.pad-on .lp-foot > .lp-sheet{transform:translateY(calc(-100% - var(--lp-pad-h,0px)))}
  /* a new mark on the same panel (Try again, Show the answer) rises into its place over the bar, not from under it */
  .lp-foot > .lp-sheet.rise{animation-name:lnSheetIn}
  body.pad-on .lp-foot > .lp-sheet.rise{animation:none}
}
@keyframes lnSheetIn{0%{transform:translateY(calc(-100% + 18px));opacity:.4}62%{transform:translateY(calc(-100% - 4px));opacity:1}100%{transform:translateY(-100%)}}
/* the panels' headings: the count keeps to one line and drops under 360 px (the list says it anyway); the heading itself
   is never cut off ("What went w…" at 375: coordinator, 19 Oct), it wraps */
.lp-fold summary .ct{white-space:nowrap}
.lp-fold summary .lb{min-width:0;line-height:1.15;overflow-wrap:break-word}
@media (max-width:420px){.lp-fold summary .ct{font-size:14px}}
@media (max-width:359px){.lp-fold summary .ct{display:none}}
.lp-fold summary .chev{margin-inline-start:auto}.lp-fold summary .ct + .chev{margin-inline-start:0}
/* the top bar fits 320 px: under 360 the "in a row" count steps out (it was pushing the page 15 px wide) */
@media (max-width:359px){.lp-top .lp-combo{display:none}.lp-top{gap:4px}}

/* ---- concept visuals (learn-visual.js) and the friend in the feedback panel, 8 Oct ---- */
.lq-vis{margin:14px 0 6px;padding:14px 16px 12px;border-radius:16px;background:var(--sunk);max-width:420px}
.lq-vish{margin:0 0 6px;font:700 14.5px var(--f-body);color:var(--ink-2)}
.lq-visart{display:block;width:100%;height:auto;overflow:visible}
.lq-visart text{font:600 14px var(--f-body);fill:var(--ink)}
.lq-visart .bar rect{fill:var(--study);transition:y .3s var(--ln-ease),height .3s var(--ln-ease)}
.lq-visart .bar.is-empty rect{fill:var(--paper)}
.lq-visart .bar.is-cmp rect{fill:var(--gold)}
.lq-visart .bar.is-swap rect{fill:var(--ln-right)}
.lq-visart .fr .on{fill:var(--study)}.lq-visart .fr .off{fill:var(--paper)}
.lq-visart .fr.is-common .on{fill:var(--ln-right)}
.lq-visart .fr .lab{font-weight:700}
.lq-visart .track{fill:var(--rule-2)}
.lq-visart .trolley .body{fill:var(--study-tint);stroke:var(--study-ink);stroke-width:3}
.lq-visart .trolley .wheel{fill:var(--ink-2)}
.lq-visart .arrow path{fill:none;stroke:var(--gold-ink);stroke-width:4;stroke-linecap:round;stroke-linejoin:round}
.lq-visart .v{fill:var(--gold-ink);font-weight:700}
.lq-viscap{margin:6px 0 0;font-size:14.5px;color:var(--ink-2);min-height:1.4em}
.lq-visplay{margin-top:6px}
@media (prefers-reduced-motion:reduce){.lq-visart .bar rect{transition:none}}
@media (min-width:1000px){
  .lp-stage:has(.lq.has-vis){max-width:1180px}
  .lq.has-vis{display:grid;grid-template-columns:minmax(0,1fr) minmax(300px,380px);column-gap:44px;align-items:start}
  .lq.has-vis > *{grid-column:1}
  .lq.has-vis > .lq-viscol{grid-column:2;grid-row:1 / span 40;position:sticky;top:84px;margin-top:6px;display:grid}
  .lq-viscol .lq-vis{margin:0;max-width:none}
  .lq-vis-floor{display:flex;justify-content:flex-end;min-height:0}
  .lq-vis-floor .lp-coach{position:relative;inset-inline-end:auto;inset-inline-start:auto;bottom:auto;margin:-4px 14px 0 0;width:120px;height:124px}
  .lq.has-vis > .ls-read{grid-column:1;grid-row:1;justify-self:end;align-self:start;float:none;margin:6px 0 0}
  .lq.has-vis > .lq-title{grid-column:1;grid-row:1;padding-inline-end:52px}
}
.lp-sh.has-friend{grid-template-columns:auto minmax(0,1fr) auto}
.lp-shf{width:64px;height:66px;align-self:center}
body.sheet-friend .lp-coach{display:none}
html[data-chars="off"] .lp-shf{display:none}
html[data-chars="off"] .lp-done-hero{display:none}
@media (min-width:900px){html[data-chars="off"] .lp-done2{grid-template-columns:minmax(0,560px)}}

/* the progress bar never blinks (owner, 8 Oct): only its fill moves, by transform; no colour change, sheen or glow
   swaps on Next or on an answer. The combo's warmth is in the "in a row" chip, not the bar. */
.lp-bar,.lp-bar.is-combo{box-shadow:none;transition:none}
.lp-bar > span,.lp-bar.is-combo > span{background:var(--study);transition:transform .5s cubic-bezier(.22,1,.36,1);animation:none}
.lp-bar.sheen::after,.lp-bar.is-combo > span::after{content:none;display:none;animation:none}
.lp-bar.is-zap > span{animation:none}
@media (prefers-reduced-motion:reduce){.lp-bar > span{transition:none}}
html[data-motion="off"] .lp-bar > span{transition:none}
/* nothing in the bar changes its width while a lesson runs: the "in a row" chip floats under the bar instead of
   taking room beside it (it used to squeeze the bar each time it came and went), and the Sparks count keeps a fixed slot */
.lp-top{position:sticky}
.lp-meta{position:relative}
.lp-top .lp-combo{position:absolute;inset-inline-end:0;top:calc(100% + 6px);white-space:nowrap;font-size:14px;pointer-events:none}
.lp-top .lp-combo[hidden]{display:none}
.lh-topcount{min-width:56px;justify-content:center;font-variant-numeric:tabular-nums}

/* ---- teach first, then practise; the pace guide (owner, 8 Oct) ---- */
.lq-mkh.has-pace{display:flex;flex-wrap:wrap;align-items:center;gap:4px 18px}
.lq-pace{display:inline-flex;align-items:center;gap:7px;margin:-6px 0 14px;color:var(--ink-3);font-size:14.5px;font-weight:600;font-variant-numeric:tabular-nums}
.lq-mkh .lq-pace{margin:0}
.lq-paceg{flex:none;transform:rotate(-90deg)}
.lq-paceg circle{fill:none;stroke-width:3.2;stroke-linecap:round}
.lq-paceg .tr{stroke:var(--sunk)}
.lq-paceg .fl{stroke:var(--study);stroke-dasharray:100;stroke-dashoffset:100;animation:lnPace linear forwards /* motion-lint: ok the guide time empties at a constant speed, like a clock */}
@keyframes lnPace{to{stroke-dashoffset:0}}
.lq-pace.is-done .fl,.lq-pace.is-paused .fl{animation-play-state:paused}
.lq-pace[hidden]{display:none}
@media (prefers-reduced-motion:reduce){.lq-paceg{display:none}}
html[data-motion="off"] .lq-paceg{display:none}
.lq-revisit{display:block;margin:14px 0 0}
.lq-learnfirst{margin:-4px 0 16px;color:var(--ink-2);font-size:15.5px}
.lq-learnfirst a{color:var(--study-ink);font-weight:700}
.lp-bridge .lp-sub{max-width:52ch}
.lp-taught{margin:18px 0 0;padding:0;list-style:none;counter-reset:tg;display:grid;gap:10px;max-width:520px}
.lp-taught li{counter-increment:tg;display:grid;grid-template-columns:32px 1fr;align-items:center;gap:12px;padding:12px 14px;border-radius:14px;background:var(--sunk);font-weight:600}
.lp-taught li::before{content:counter(tg);display:grid;place-items:center;width:32px;height:32px;border-radius:50%;background:var(--study-tint);color:var(--study-ink);font-weight:800}
dialog.lp-revisit{width:min(760px,calc(100vw - 24px));max-height:min(86dvh,900px);padding:0;border:0;border-radius:22px;background:var(--paper);color:var(--ink);box-shadow:0 24px 70px rgba(0,0,0,.28);overflow:hidden;display:flex;flex-direction:column}
dialog.lp-revisit:not([open]){display:none}
dialog.lp-revisit::backdrop{background:rgba(8,17,32,.5)}
.lp-rvh{display:flex;align-items:center;gap:12px;padding:16px 16px 10px 22px;background:var(--paper)}
.lp-rvh h2{margin:0;flex:1;font-size:22px}
.lp-rvx{flex:none;width:44px;height:44px;display:grid;place-items:center;border:0;border-radius:12px;background:var(--sunk);color:var(--ink);cursor:pointer}
.lp-rvb{overflow-y:auto;padding:4px 22px 24px;overscroll-behavior:contain}
.lp-rvs + .lp-rvs{margin-top:26px}
.lp-rvs h3{margin:0 0 8px;font-size:18px;color:var(--study-ink)}
@media (max-width:560px){dialog.lp-revisit{width:100vw;max-width:100vw;max-height:92dvh;margin:auto 0 0;border-radius:22px 22px 0 0}}
/* a lesson's video (the text below it is the same lesson, so it works with no video at all) */
.lp-video{margin:4px 0 22px;max-width:720px}
.lp-video video{display:block;width:100%;aspect-ratio:16/9;border-radius:16px;background:var(--sunk);object-fit:cover}
.lp-video figcaption{margin:8px 0 0;color:var(--ink-3);font-size:14.5px}
.lp-rvx:focus{outline:none}.lp-rvx:focus-visible{outline:3px solid var(--study);outline-offset:2px}

/* ---- Learn: the lesson as an article, then Practice (owner, 9 Oct) ---- */
.lp-stage:has(> .la.is-on){max-width:760px;padding-bottom:140px}
.la{display:block}
.la-head{margin:18px 0 22px}
.la-head h1{margin:0 0 8px;font-size:clamp(28px,4.4vw,40px);line-height:1.12}
.la-meta{margin:0;color:var(--ink-3);font-size:15.5px;font-weight:600}
.la-sec{margin:0 0 34px}
.la-sec > h2,.la-body h2{margin:0 0 10px;font-size:clamp(21px,2.6vw,26px);line-height:1.25}
.la .lp-prose p,.la .lp-prose li{font-size:18px;line-height:1.65}
.la .lp-tool{margin:16px 0 0}
.la-script{margin:24px 0;padding:14px 18px;border-radius:16px;background:var(--sunk);color:var(--ink-2)}
.la-script summary{cursor:pointer;font-weight:700;min-height:44px;padding:10px 0;box-sizing:border-box}
.la-next{display:grid;grid-template-columns:auto minmax(0,1fr);gap:8px 22px;align-items:center;margin:44px 0 0;padding:26px 26px 28px;border-radius:24px;background:var(--study-tint);scroll-margin-bottom:120px}
.la-next-art{width:120px;height:124px;align-self:end}
.la-next-art img{display:block;width:120px;height:124px}
.la-next h2{margin:0 0 8px;font-size:clamp(22px,2.6vw,28px);line-height:1.2;color:var(--ink)}
.la-why{margin:0 0 14px;color:var(--ink-2);font-size:16.5px;line-height:1.5;max-width:46ch}
.la-gets{list-style:none;margin:0 0 20px;padding:0;display:grid;gap:8px}
.la-gets li{display:grid;grid-template-columns:22px 1fr;gap:10px;align-items:center;font-weight:600;color:var(--ink)}
.la-gets li::before{content:'';width:22px;height:22px;border-radius:50%;background:var(--study) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 12.5l4 4 8-9' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/16px no-repeat}
.la-keep{margin:-8px 0 18px;color:var(--ink-3);font-size:15.5px;line-height:1.5}
.la-keep a{display:inline-flex;align-items:center;min-height:44px;margin-block:-11px;color:var(--study-ink);font-weight:700;text-decoration:underline;text-underline-offset:3px}
.la-go.lp-btn{display:inline-flex;min-width:220px;text-decoration:none}
@media (max-width:560px){.la-next{grid-template-columns:1fr;padding:22px 18px 24px}.la-next-art{width:96px;height:99px;justify-self:start}.la-next-art img{width:96px;height:99px}.la-go.lp-btn{width:100%}}
html[data-minimal="on"] .la-gets,html[data-minimal="on"] .la-next-art,html[data-chars="off"] .la-next-art{display:none}
html[data-minimal="on"] .la-next,html[data-chars="off"] .la-next{grid-template-columns:1fr}
/* on the article the action bar stays out of the way until near the end, then rises with the next step */
body.is-article .lp-foot{transform:translateY(110%);transition:transform .3s cubic-bezier(.22,1,.36,1)}
body.is-article.la-bar-on .lp-foot{transform:none}
@media (prefers-reduced-motion:reduce){body.is-article .lp-foot{transition:none}}

/* the pace countdown: a ring that empties around mm:ss, beside the marks; overtime calm and warm (owner, 9 Oct) */
.lq-pace{gap:10px}
.lq-paceg{flex:none;width:40px;height:40px;transform:rotate(-90deg)}
.lq-paceg circle{fill:none;stroke-width:4.5;stroke-linecap:round}
.lq-paceg .tr{stroke:color-mix(in srgb,var(--ink) 14%,transparent)}
.lq-paceg .fl{stroke:var(--study);animation:none;transition:stroke .4s var(--ln-ease)}
.lq-pace .t{font:700 17px/1 var(--f-body);color:var(--ink);font-variant-numeric:tabular-nums;min-width:4.2ch}
.lq-pace.is-low .t{color:var(--study-ink)}
.lq-pace.is-over .fl{stroke:color-mix(in srgb,var(--gold) 55%,var(--sunk))}
.lq-pace.is-over .t{color:var(--ink-3);font-weight:600}
.lq-pace.is-done{opacity:.55}
.lq-pace.is-still .t{color:var(--ink-3);font-weight:600}
.lq-mkh.has-pace{align-items:center}

/* Noodle in the practice player (owner, 9 Oct): wide screens give him a fixed place beside the question column, from
   the start, standing on a soft floor, never at the window's edge and never scroll-triggered; narrower screens leave
   him out of the question (no room beside it), so he never covers an option */
@media (min-width:1100px){
  body.ln-play .lp-coach,body.ln-play.coach-tuck .lp-coach{position:fixed;inset-inline-start:min(calc(50% + 410px + 36px),calc(100% - 156px));inset-inline-end:auto;top:132px;bottom:auto;width:120px;height:124px;opacity:1;visibility:visible}
  body.ln-play .lp-coach::after{content:'';position:absolute;inset-inline-start:18px;inset-inline-end:18px;bottom:-4px;height:10px;border-radius:50%;background:color-mix(in srgb,var(--ink) 12%,transparent);z-index:-1}
  body.ln-play.coach-floor .lp-coach{position:relative;inset-inline-start:auto;top:auto}
}
@media (max-width:1099px){body.ln-play:not(.coach-floor):not(.coach-say) .lp-coach{display:none}}
/* onward from lesson complete: the next lesson is the big button; Finish! the quiet one */
.lp-btn.textlink,:root[data-theme="dark"] .lp-btn.textlink{background:none;box-shadow:none;border:0;color:var(--study-ink);text-decoration:underline;text-underline-offset:4px;min-width:0;flex:0 0 auto;padding:0 12px}
.lp-onward{margin:18px 0 0;color:var(--ink-2);font-weight:600}

/* the why under the result: body size, full ink, the panel grows to fit (and the answer is scrolled above it) */
.lp-sh .why{margin:6px 0 4px;color:var(--ink);font-size:16.5px;line-height:1.5;max-width:62ch}

.lq-worksyms .lq-sym.is-more{display:none}.lq-worksyms.is-open .lq-sym.is-more{display:inline-flex;align-items:center;justify-content:center}
.lq-worksyms .lq-symmore{font-size:15px;padding:0 14px;color:var(--study-ink)}

/* one size and weight for every choice: "no figure" (a word) reads like the figures beside it (owner, 9 Oct) */
.lq-tile .fb.fb-none{font-size:1em;font-weight:600;color:inherit}
@media (min-width:1100px){body.ln-play.coach-away .lp-coach{visibility:hidden}}

/* the top bar (owner pick A): close, where you are in words, the progress bar, then settings, Sparks and sound */
.lp-loc{flex:none;color:var(--ink-3);font:600 15px/1.2 var(--f-body);white-space:nowrap;text-decoration:none;padding:6px 4px;border-radius:8px}
.lp-loc:hover{color:var(--ink-2)}
@media (max-width:560px){.lp-top{flex-wrap:wrap;row-gap:0}.lp-loc{order:9;flex-basis:100%;padding:0 0 4px 52px;font-size:14px}}

/* Noodle saying the question (owner pick D) */
.lq-say{display:grid;grid-template-columns:120px minmax(0,1fr);gap:26px;align-items:end;margin:4px 0 6px}
.lq-sayc{position:relative;width:120px;height:124px}
body.ln-play.coach-say .lq-sayc .lp-coach{position:absolute;inset:0;inset-inline-start:0;top:0;inset-inline-end:auto;bottom:auto;width:120px;height:124px;display:block;visibility:visible;opacity:1}
body.ln-play.coach-say .lq-sayc .lp-coach::after{display:none}
/* Noodle's speech bubble (owner, 10 Oct: "Broken bubble anyway - bad connector placement"): the outline and the tail are
   one SVG path drawn by learn.js sayDraw, filled with the surface and stroked 2 px in --say-edge, behind the words; the
   tail's base sits on the side facing Noodle at his head, its tip 6 px short of him. No border, no pseudo-element tail. */
.lq-sayb{position:relative;isolation:isolate;align-self:center;margin-bottom:22px;padding:18px 22px;border:0;border-radius:20px;background:none;min-width:0;overflow-wrap:anywhere;overflow:visible}
.lq-saybg{position:absolute;inset-inline-start:0;top:0;z-index:-1;overflow:visible;pointer-events:none}
.lq-saybg path{fill:var(--surface);stroke:var(--say-edge);stroke-width:2;stroke-linejoin:round}
[dir="rtl"] .lq-sayc{transform:scaleX(-1)}   /* RTL: Noodle faces the bubble on his left, so his arm points at it (the bubble measures his mirrored mouth) */
.lq-sayb .lq-prompt{margin:0}

/* the "in a row" chip: on a phone it sits at the right end of the location line, clear of the words; on the lesson end
   and streak screens it steps out (the run is over, and the screen has its own figures) */
@media (max-width:560px){.lp-meta{position:static}.lp-top .lp-combo{top:auto;inset-inline-end:max(16px,env(safe-area-inset-right));bottom:6px}}
body:has(.lp-done.is-on) .lp-top .lp-combo,body:has(.lp-streak.is-on) .lp-top .lp-combo{display:none}

.lp-video .lp-vcredit{display:block;margin-top:4px;font-size:13px;color:var(--ink-3)}   /* a licence credit under a lesson video */

/* leaving a lesson (owner, 9 Oct: "more sad and red"): a warm red edge on the sheet, Noodle droops once, and Leave is
   the red destructive button (white on red-600 in light, red-950 on red-300 in dark: AA both); Keep going stays teal */
:root{--ln-leave:#c0362c;--ln-leave-on:#fff;--ln-leave-tint:#ffe6e2}
:root[data-theme="dark"]{--ln-leave:#ff8a80;--ln-leave-on:#381310;--ln-leave-tint:#3a1a19}   /* red-950 on red-300 */
.lp-modal.is-leave .lp-dlg{background:var(--ln-leave-tint)}   /* the whole sheet a soft warm red, rounded like the rest (no one-sided edge, no gradient) */
.lp-modal.is-leave .ln-noodle{transform-origin:50% 90%;animation:lnDroop .6s var(--ln-ease) .12s both}
@keyframes lnDroop{0%{transform:none}55%{transform:translateY(9px) rotate(-5deg)}100%{transform:translateY(8px) rotate(-4deg)}}
.lp-btn.danger,:root[data-theme="dark"] .lp-btn.danger{background:var(--ln-leave);color:var(--ln-leave-on);box-shadow:none}
.lp-btn.danger:focus-visible{outline:3px solid var(--ln-leave);outline-offset:3px}
@media (prefers-reduced-motion:reduce){.lp-modal.is-leave .ln-noodle{animation:none;transform:translateY(8px) rotate(-4deg)}}
html[data-motion="off"] .lp-modal.is-leave .ln-noodle{animation:none;transform:translateY(8px) rotate(-4deg)}

/* Noodle presents the question (owner, 9 Oct): he stands left, pointing right at the music or graph and the bubble
   beside him; the group is centred in the column, so no half-empty row beside a narrow stave */
.lq-say{grid-template-columns:120px minmax(0,1fr);align-items:center}
.lq-sayr{display:grid;gap:12px;min-width:0}
.lq-say.has-fig{justify-content:center;grid-template-columns:120px minmax(0,auto)}
.lq-say.has-fig .lq-sayr > .mn-fig,.lq-say.has-fig .lq-sayr > figure.lgraph{margin:0}
.lq-sayr .lq-sayb{margin-bottom:0;align-self:start}

/* the guide time (owner, 9 Oct): no ring; an icon, "Guide time 0:43" on the marks' baseline, a slim rounded track under
   the row that empties left to right; past it, "+0:12 over the guide" calm and muted */
.lq-mkh.has-pace{position:relative;padding-bottom:12px;align-items:baseline}
.lq-pace{display:inline-flex;align-items:baseline;gap:6px;margin:0;font-size:14.5px;font-weight:600;color:var(--ink-3)}
.lq-pace .lq-paceg{display:none}
.lq-pacei{align-self:center;width:17px;height:17px;fill:none;stroke:var(--study-ink);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.lq-pace .t{font:700 15px/1 var(--f-body);color:var(--ink);font-variant-numeric:tabular-nums;min-width:0}
.lq-pace.is-low .t{color:var(--study-ink)}
.lq-pace.is-over .t{color:var(--ink-3);font-weight:600}
.lq-pace.is-over .lq-pacei{stroke:var(--ink-3)}
/* the last ten seconds, for those with sound off too (owner, 10 Oct): the time eases into the accent colour, a colour change
   only (nothing moves), then settle back to the calm muted tone past the guide */
.lq-pace .t{transition:color 1.2s var(--ln-ease)}
.lq-pacetr{position:absolute;inset-inline-start:0;inset-inline-end:0;bottom:0;height:6px;border-radius:3px;background:var(--sunk);overflow:hidden}
.lq-pacetr i{display:block;height:100%;border-radius:3px;background:var(--study);transform-origin:left center;will-change:transform}
.lq-pace.is-over .lq-pacetr i{background:transparent}
.lq-pace.is-done{opacity:.6}
.lq-pace.is-still .t{color:var(--ink-2)}

.lq-pacer{align-self:center;display:inline-grid;place-items:center;width:28px;height:28px;margin:-6px 0 -6px 2px;padding:0;border:0;border-radius:8px;background:none;color:var(--ink-3);cursor:pointer}
.lq-pacer svg{fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.lq-pacer:hover{color:var(--ink);background:var(--sunk)}
.lq-pacer:focus-visible{outline:3px solid var(--study);outline-offset:2px}
.lq-pace.is-done .lq-pacer{display:none}
/* 44 px to tap everywhere (friction audit, 12 Oct); the negative margins keep the line where it was */
.lq-pacer{width:44px;height:44px;margin:-14px -8px -14px -6px}

/* on the way out (owner, 9 Oct): a busy button and a slim teal bar along the top */
.lp-btn.is-busy{cursor:progress;display:inline-flex;align-items:center;justify-content:center;gap:10px}
.lp-btn.is-busy,.lp-btn.danger.is-busy{opacity:1}
.lp-spin{flex:none;width:16px;height:16px;border-radius:50%;border:2.5px solid currentColor;border-inline-end-color:transparent;animation:lpSpin .7s linear infinite}
@keyframes lpSpin{to{transform:rotate(360deg)}}
.lp-navbar{position:fixed;inset-inline-start:0;inset-inline-end:0;top:0;height:4px;z-index:80;pointer-events:none;overflow:hidden;border-radius:0 0 4px 4px}
.lp-navbar i{display:block;height:100%;width:100%;border-radius:0 4px 4px 0;background:var(--study);transform-origin:left center;animation:lpNav 2.4s cubic-bezier(.1,.6,.3,1) forwards}
@keyframes lpNav{from{transform:scaleX(.06)}to{transform:scaleX(.88)}}
.lp-navbar.is-still i{animation:none;transform:scaleX(.5)}
@media (prefers-reduced-motion:reduce){.lp-spin{animation:none;border-inline-end-color:currentColor;opacity:.6}.lp-navbar i{animation:none;transform:scaleX(.5)}}
html[data-motion="off"] .lp-spin{animation:none;border-inline-end-color:currentColor;opacity:.6}
.lp-modal.is-leaving .lp-dlg{cursor:progress}
.lp-x.is-busy{color:var(--study);cursor:progress}
.lp-modal.is-leaving .lp-btn:disabled:not(.is-busy){opacity:.5;cursor:default}

/* Questions fit the screen (owner, 9 Oct: "show the bottom when I correct an answer, so ideally all answers are
   visible"; "image on the left and answers on the right on desktop to optimise space"). The stem, the visual, the
   question and every option sit in one screen at 1440x900 and 390x844: tighter options and gaps; below 1100 px a
   stacked layout with the visual at most about 38% of the screen's height; from 1100 px two columns, the visual and
   Noodle on the left (about 45%) scaled to the column (a tall grand staff to about 70% of the screen's height), the
   question, the options and the feedback on the right. learn.js fitFigs() sizes the notation and trims it to its
   drawing; the content keeps only the room the action bar takes (--lp-foot-h), so no empty band opens under the
   options. tests/learn/visual/fold.py checks it. */
.lp-stage{padding-bottom:calc(var(--lp-foot-h,96px) + 20px)}
/* the action bar never keeps question content under it (owner, 9 Oct: a long two-system extract's bass staff under
   Check): the stage keeps the bar's measured height (its safe-area padding included) plus 20 px below the content, so
   at full scroll the end of the score and the options sit clear of it; anything scrolled to or focused (a field, a
   Tab stop, scrollIntoView) stops above the bar too. The bar reads as floating: a soft shadow above it, no line.
   tests/learn/visual/foot_clear.py checks it. */
html:has(body.ln-play){scroll-padding-bottom:calc(var(--lp-foot-h,96px) + 16px)}
.lp-foot,.lp-foot:has(.lp-sheet.is-right){box-shadow:0 -3px 10px rgba(21,54,90,.08)}   /* a soft edge, not a 24 px band that fades the text it passes over (owner, 11 Oct) */
:root[data-theme="dark"] .lp-foot,:root[data-theme="dark"] .lp-foot:has(.lp-sheet.is-right){box-shadow:0 -3px 12px rgba(0,0,0,.4)}
.lq-tile{min-height:56px;padding-top:9px;padding-bottom:9px}
.t-mcq{gap:10px}
.lq-in{margin-top:10px}
.lq-mkh{margin-bottom:10px}
.lq-say.has-fig{margin:0 0 4px}
.lq-sayr .mn-sheet{padding:10px 12px}
@media (min-width:1000px){.lq-tile{min-height:64px;padding-top:10px;padding-bottom:10px}}
/* Noodle is the question's speaker (owner, 9 Oct: "find another place for Noodle"): a small Noodle at the left of the
   question bubble, its tail pointing to him, the two one unit above the options; on every width */
.lq-say{display:block;margin:0 0 4px}
.lq-say > .mn-fig,.lq-say > figure.lgraph{margin:0 0 12px}
.lq-sayu{display:grid;grid-template-columns:76px minmax(0,1fr);gap:24px;align-items:end}   /* room for the tail and 8 px clear of Noodle (bl-bubble.js) */
.lq-sayc{width:76px;height:79px}
body.ln-play.coach-say .lq-sayc .lp-coach{width:76px;height:79px}
.lq-sayu .lq-sayb{margin:0;align-self:center}
@media (max-width:699px){.lq-sayu{grid-template-columns:56px minmax(0,1fr);gap:22px}.lq-sayc,body.ln-play.coach-say .lq-sayc .lp-coach{width:56px;height:58px}.lq-sayu .lq-sayb{padding:12px 16px}.lq-sayu .lq-prompt{font-size:16.5px;line-height:1.45}}
@media (min-width:1100px){
  .lp-stage:has(.lq-say.has-fig){max-width:1180px}
  /* the visual takes the whole left column; Noodle and the bubble, then the options and the feedback, on the right */
  .lq-part:has(> .lq-say.has-fig){display:grid;grid-template-columns:minmax(0,.82fr) minmax(0,1fr);grid-template-rows:auto auto 1fr;
    grid-template-areas:"fig unit" "fig opts" "fig res";column-gap:28px;align-items:start}
  .lq-part:has(> .lq-say.has-fig) > .lq-say{display:contents}
  .lq-part:has(> .lq-say.has-fig) > .lq-say > :not(.lq-sayu){grid-area:fig;margin:0;justify-items:center;justify-self:stretch;align-self:start;align-content:start}
  .lq-part:has(> .lq-say.has-fig) .mn-fig .mn-sheet{margin:0 auto}
  .lq-part:has(> .lq-say.has-fig) > .lq-say > .lq-sayu{grid-area:unit}
  .lq-part:has(> .lq-say.has-fig) > .lq-in{grid-area:opts;margin-top:12px}
  .lq-part:has(> .lq-say.has-fig) > .lq-res{grid-area:res}
}
@media (max-width:699px){
  .t-mcq.is-short{grid-template-columns:repeat(2,minmax(0,1fr))}   /* (two equal columns that never push past the row: a tile's own content is checked by learn.js fitFigs) */
  .t-mcq.is-short > .lq-tile .c{white-space:nowrap}   /* two to a row only if each option fits one line: a wider one overflows, and learn.js fitFigs puts them back one to a row (sin⁻¹(15/30) broke inside itself at 320) */
  .t-mcq.is-short > .lq-tile{padding-left:12px;padding-right:10px;gap:10px}   /* "Diminished" and "Augmented" fit two to a row at 390 (r67 fold) */
  .lq-title{font-size:clamp(22px,6vw,26px);margin:6px 0 8px}
  .lq-learnfirst{margin:0 0 6px}
}
/* the marker's line shows once: in the panel (owner, 9 Oct), not again under the options of a one-part question */
.lp-screen.lp-q .lq:not(:has(.lq-part ~ .lq-part)) .lq-res .say{display:none}
/* Finish! (owner, 9 Oct): the quiet grey button reads as a button, not as disabled: ink label (AA), the usual lip,
   a hover and the lip-aware focus ring (brainlag.css) */
.lp-done2 .lp-btn.quiet:hover,.lp-actions .lp-btn.quiet:hover{background:var(--btn-2-hover)}

/* The lesson top bar is the same in every state (owner, 9 Oct: "keep top bar items in common positions"): the cross
   at the far left, the place line and the progress track (empty when there is no progress yet, a locked lesson too)
   in the middle, then settings, Sparks and sound on the right in that order, whatever order the scripts added them
   in. Sparks has a fixed width, and where a state has no Sparks its slot is kept, so nothing moves.
   tests/learn/visual/topbar.py checks the positions in every state. */
.lp-top > .lp-x{order:0}.lp-top > .lp-loc{order:1}.lp-top > .lp-bar{order:2}
.lp-top > .lp-meta{order:3;margin-inline-start:-14px}
.lp-top > .ls-ui{order:10}.lp-top > .lh-topcount{order:11;width:72px;min-width:72px;justify-content:center}.lp-top > .lp-snd{order:12}
.lp-top:not(:has(> .lh-topcount))::after{content:'';order:11;flex:none;width:72px;height:44px}   /* the Sparks slot, kept */
/* a screen with no progress (a flashcard deck's start, a review's list) hides the track but keeps its room, so the
   icons stay on the right rather than bunching after the cross (owner, 13 Oct) */
.lp-top > .lp-bar[hidden]{display:block!important;visibility:hidden}
@media (max-width:560px){.lp-top > .lp-loc{order:20}}
@media (max-width:440px){.lp-top > .lp-meta{margin-inline-start:-6px}}
@media (max-width:359px){.lp-top > .lp-meta{margin-inline-start:-4px}}

/* the checkpoint between questions (owner, 9 Oct: "adaptive to spacing"): one group centred in the space between the
   top bar and the action bar, scaled to the screen: Noodle about a quarter of its height, the line up to 56 px, the
   progress as steps, and on a wide screen Continue right under them */
.lp-break{padding-top:0;min-height:calc(100dvh - 72px - var(--lp-foot-h,96px) - 40px);display:grid;place-items:center}
.lp-break-in{display:grid;justify-items:center;gap:clamp(10px,2vh,20px)}
.lp-break-coach{width:clamp(140px,25vh,250px);height:clamp(144px,25.8vh,258px)}
.lp-break > .lp-break-in > h1{font-size:clamp(32px,4.5vw,56px);margin:0;line-height:1.1}
.lp-break:not(.reduce) > .lp-break-in > h1{animation:lnRiseT .3s .12s var(--ln-spring) both}
.lp-break .lp-sub{font-size:clamp(17px,1.4vw,21px);margin:0;color:var(--ink-2)}
.lp-steps{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;max-width:min(92vw,520px)}
.lp-steps i{width:clamp(18px,2vw,28px);height:10px;border-radius:5px;background:var(--sunk)}
.lp-steps i.on{background:var(--study)}
.lp-break-go{min-width:220px;margin-top:clamp(4px,1.5vh,14px)}
@media (min-width:700px){body:has(.lp-break.is-on) .lp-foot{visibility:hidden}}
@media (prefers-reduced-motion:reduce){.lp-break > .lp-break-in > h1{animation:none}}

/* the question's shape while it loads: soft blocks, the two columns where there is music */
.lp-skel{display:grid;gap:12px;position:relative;width:100%}
.lp-screen:has(> .lp-skel){width:100%;align-self:stretch}
/* its body under the title rows, where the question's own starts (brainlag.css centred it in the stage: on a phone
   the stage filled a frame after the first paint, so the shape dropped 129 px, CLS 0.077 at 390; the question that
   replaces it sits at the top too) */
.lp-q.is-on > .lp-skel > .lp-skel-b{align-self:start}
@media (min-width:1100px){.lp-stage:has(.lp-skel.has-fig){max-width:1180px}}
.lp-skel i{display:block;border-radius:14px;background:var(--sunk)}
.lp-skel .t{height:30px;width:min(70%,420px)}.lp-skel .m{height:16px;width:180px;margin-bottom:6px}
.lp-skel-b{display:grid;gap:14px;justify-items:stretch}.lp-skel-r{display:grid;gap:10px}
.lp-skel .fig{height:min(30vh,260px);border-radius:16px}
.lp-skel .bub{height:72px;border-radius:20px}.lp-skel .o{height:56px}
@media (min-width:1100px){.lp-skel.has-fig .lp-skel-b{grid-template-columns:minmax(0,.82fr) minmax(0,1fr);column-gap:28px}.lp-skel.has-fig .fig{height:min(58vh,520px)}.lp-skel .o{height:64px}}
@media (max-width:699px){.lp-skel .fig{height:22vh}}
.lp-skel .ld{position:absolute;inset-inline-start:0;inset-inline-end:0;top:40%;pointer-events:none}
@media (prefers-reduced-motion:no-preference){.lp-skel i{animation:lnSkel 1.4s var(--ease-io,cubic-bezier(.45,0,.55,1)) infinite alternate}}
@keyframes lnSkel{from{opacity:1}to{opacity:.55}}

/* question lists and unit lists without hairlines (owner's standing rule: no hairline dividers): each row a soft
   tinted card rounded on every side, the groups apart by spacing */
.ln-units,.ln-qlist{border-top:0;display:grid;gap:8px}
.ln-units > li,.ln-qlist > li{border-bottom:0;background:var(--sunk);border-radius:14px}
.ln-units a,.ln-qlist a{padding:14px 16px;border-radius:14px}
.ln-units a:hover,.ln-qlist a:hover{background:color-mix(in srgb,var(--study) 8%,var(--sunk))}
.ln-qlist > li > span{padding:12px 16px 0}.ln-qlist > li > span.m{padding:2px 16px 12px}
.ln-qlist + h2,.ln-qlist + h3{margin-top:26px}

/* the hint and the lesson (owner, 9 Oct: "better vis for those"): quiet secondary buttons side by side under the
   choices, the drawn bulb and book, a tinted fill and the house lip; below Check in weight; the hint opens as a
   tinted panel under them */
.lq-aids{display:flex;flex-wrap:wrap;gap:10px;margin:14px 0 0}
.lq-aids:empty{display:none}
.lq-aid{display:inline-flex;align-items:center;gap:8px;min-height:44px;margin:0;padding:0 16px 0 13px;border:2px solid var(--btn-2-edge);border-radius:14px;background:var(--btn-2);
  color:var(--ink);font:650 16px/1 var(--f-body);cursor:pointer;box-shadow:none;transition:background-color .12s var(--ln-ease),transform .09s var(--ln-spring);--lip:3px;--ring-r:19px}
.lq-aid .i{flex:none;color:var(--study-ink)}
.lq-aid:hover{background:var(--btn-2-hover)}
.lq-aid:active{background:var(--btn-2-press)}
.lq-aid:active{transform:scale(.98);box-shadow:none;--lip:0px}
.lq-aid.is-open{background:var(--study-tint)}
.lq-aid.is-offer{background:var(--study-tint);color:var(--study-ink)}
.lq-aid:focus-visible{outline:none;position:relative}
.lq-aid:focus-visible::after{content:"";position:absolute;inset:-5px -5px calc(-5px - var(--lip)) -5px;border:3px solid var(--study-ink);border-radius:var(--ring-r);pointer-events:none}
.lq-hintbtn.is-offer{font-size:16px}
.lq-hint{margin:12px 0 0}
.lq-hint[hidden]{display:none}
.lq-more{display:inline-flex;margin-top:8px;padding:6px 0;border:0;background:none;color:var(--study-ink);font:700 15.5px/1.3 var(--f-body);cursor:pointer}
.lq-more:focus-visible{outline:3px solid var(--study-ink);outline-offset:2px;border-radius:6px}
@media (max-width:420px){.lq-aids{gap:8px}.lq-aid{flex:1 1 auto;justify-content:center;padding:0 12px}}
@media (min-width:1100px){
  /* the answer and the mark scheme go under the picture once marked, not under the options: the right column (bubble,
     options, hint) ran far below a short score and left a dead band before the result (owner, 12 Oct: "broken") */
  .lq-part:has(> .lq-say.has-fig){grid-template-rows:auto auto auto auto 1fr;grid-template-areas:"fig unit" "fig opts" "res aids" "res hint" "res ."}
  /* a picture taller than the bubble gives its extra height to the options' row, not the bubble's: no dead band
     between the question and its options (owner, 12 Oct) */
  .lq-part:has(> .lq-say.has-fig){grid-template-rows:min-content 1fr auto auto auto}
  .lq-part:has(> .lq-say.has-fig) > .lq-res{margin-top:14px}
  .lq-part:has(> .lq-say.has-fig) > .lq-aids{grid-area:aids}
  .lq-part:has(> .lq-say.has-fig) > .lq-hint{grid-area:hint}
}
/* a score gets the wider column from 1200 px (coordinator, 12 Oct: two four-bar phrases on two lines): about 58% to the
   music, 42% to the answers */
@media (min-width:1200px){.lq-part:has(> .lq-say.has-fig .mn-fig){grid-template-columns:minmax(0,58fr) minmax(0,42fr)}}
/* Review the lesson: a side sheet on wider screens (the question stays as it is behind it), a bottom sheet on phones */
@media (min-width:700px){
  dialog.lp-revisit{margin:0 0 0 auto;width:min(620px,92vw);max-width:none;height:100dvh;max-height:100dvh;border-radius:22px 0 0 22px}
}
@media (forced-colors:active){.lq-aid{border:2px solid ButtonText}.lq-aid:focus-visible::after{border-color:Highlight}}
@media (prefers-reduced-motion:reduce){.lq-aid{transition:none}}

/* adaptive difficulty (docs/plans/ADAPTIVE.md): the Stretch marker, the step-up line, the Questions setting and the
   skills meter (Learning, Secure, Stretch); calm, no pressure */
.lq-stretch{display:inline-flex;align-items:center;margin-inline-end:10px;padding:2px 9px;border-radius:8px;background:var(--study-tint);color:var(--study-ink);font:700 13.5px/1.6 var(--f-body)}
.lq-upnote{margin:-4px 0 10px;color:var(--study-ink);font-weight:650;font-size:16px}
.ls-adapt{display:grid;gap:6px;padding:8px 0 6px}
.ls-adapt-t{font-weight:600;font-size:16px;color:var(--ink)}
.ls-adapt-b{display:grid;grid-template-columns:1fr;justify-items:stretch;gap:6px}
.ls-adapt button{width:100%;max-width:none;margin:0;min-height:44px;padding:4px 12px;white-space:normal;text-align:start;border:1px solid var(--rule-2);border-radius:10px;background:none;color:var(--ink-2);font:600 15px var(--f-body,inherit);cursor:pointer}
.ls-adapt button[aria-checked="true"]{border-color:var(--study-ink);background:var(--study-tint);color:var(--study-ink)}
.ls-adapt button:focus-visible{outline:3px solid var(--study-ink);outline-offset:2px}
.ln-skills{margin:22px 0 0;text-align:start;width:100%;max-width:560px}
.lp-done-body .ln-skills{margin-top:18px}
main.my .ln-skills{margin:28px 0 32px}
.ln-skills h2{font-size:19px;margin:0 0 10px}
.ln-skills ul{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.ln-skills li{display:grid;grid-template-columns:minmax(0,1fr) auto 74px;align-items:center;gap:12px;padding:10px 14px;border-radius:14px;background:var(--sunk)}
.ln-skills .t{font-weight:600}
.ln-skills .lv{display:flex;gap:4px}
.ln-skills .lv i{width:22px;height:8px;border-radius:4px;background:color-mix(in srgb,var(--ink-3) 30%,transparent)}
.ln-skills .lv i.on{background:var(--study)}
.ln-skills .w{font-size:14.5px;color:var(--ink-2);text-align:end}
@media (max-width:420px){.ln-skills li{grid-template-columns:minmax(0,1fr) auto}.ln-skills .w{grid-column:1/-1;text-align:start;margin-top:-6px}}

/* a music card with its Play in the corner fills the question's column at every width, the music centred in it */
.lq .mn-fig > .mn-sheet{width:100%;box-sizing:border-box;display:grid;justify-items:center}   /* with or without Play: every question's card is the column's width (coordinator, 12 Oct) */

/* the time summary on results screens: a line, a dot per question, one remark, the exam context and 1 to 3 tips */
.lp-time{width:100%;max-width:560px;margin:20px auto 0;text-align:start}
.lp-result .lp-time{margin-bottom:8px}
.lp-time .lp-dh{margin:0 0 6px}
.lp-time-sum{margin:0;color:var(--ink-2);font-weight:600;font-variant-numeric:tabular-nums}
.lp-time-sum b{color:var(--ink)}
.lp-time-dots{display:flex;flex-wrap:wrap;gap:6px;margin:10px 0 0;padding:0;list-style:none}
.lp-time-dots li,.lp-time-key i{width:14px;height:14px;border-radius:50%;box-sizing:border-box;background:var(--study)}
.lp-time-dots li.over,.lp-time-key i.over{background:color-mix(in srgb,var(--gold) 60%,var(--sunk))}
.lp-time-dots li.miss,.lp-time-key i.miss{background:transparent;border:3px solid var(--study)}
.lp-time-dots li.over.miss{background:transparent;border-color:color-mix(in srgb,var(--gold) 70%,var(--ink-3))}
.lp-time-key i.miss{border-color:var(--ink-3)}
.lp-time-key{display:flex;flex-wrap:wrap;gap:4px 14px;margin:8px 0 0;color:var(--ink-3);font-size:13.5px}
.lp-time-key span{display:inline-flex;align-items:center;gap:6px}
.lp-time-key i{display:inline-block;width:10px;height:10px}
.lp-time-key i.miss{border-width:2px}
.lp-time-rem{margin:12px 0 0;color:var(--ink);font-weight:650;font-size:17px}
.lp-time-exam{margin:6px 0 0;color:var(--ink-2)}
.lp-time-th{margin:16px 0 8px;font-size:16px}
.lp-tips{display:grid;gap:8px;margin:0;padding:0;list-style:none}
.lp-tips li{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;padding:12px 14px;border-radius:14px;background:var(--sunk)}
.lp-tips p{margin:0}
.lp-tips .lp-tipgo{white-space:nowrap}
@media (max-width:520px){.lp-tips li{grid-template-columns:1fr}.lp-tips .lp-tipgo{justify-self:start}}
.lq-pace .pz{display:none}
.lq-pace.is-paused:not(.is-done) .pz{display:inline}
.lq-pace.is-paused:not(.is-done) .w,.lq-pace.is-paused:not(.is-done) .t{display:none}
.lp-clock.is-paused,.lp-clock.over{color:var(--ink-3)}
/* the test clock never touches the progress bar: the bar's row keeps 10 px before it at every width; on a phone the
   word after the time drops (the clock's aria-label keeps it) */
.lp-top > .lp-meta:has(.lp-clock){margin-inline-start:-4px}
.lp-clock{white-space:nowrap}
@media (max-width:440px){.lp-clock .w{display:none}.lp-top > .lp-meta:has(.lp-clock){margin-inline-start:4px}}
@media (max-width:359px){.lp-top > .lp-meta:has(.lp-clock){margin-inline-start:6px;font-size:13.5px}}

/* the warm line on results screens (owner, 9 Oct: hype the learner up about something true) */
.lp-cheer{margin:10px 0 0;color:var(--ink);font:650 clamp(17px,.6vw + 13px,20px)/1.4 var(--f-body);text-wrap:pretty}
.lp-result .lp-cheer{max-width:560px;margin:8px auto 4px;text-align:center}
@media (min-width:900px){.lp-done2 .lp-cheer{text-align:start}}

/* the Stretch bonus under the XP (adaptive, docs/plans/ADAPTIVE.md) */
.lp-stretchxp{margin:6px 0 0;color:var(--study-ink);font-weight:650;font-size:15px}

/* Learn articles at every width (owner, 9 Oct; learn.js capScores and articleSplit):
   - a score keeps its natural size: a staff space never over 12 px (13 from 1920 px), centred in its card; on a phone
     the card's width sets it;
   - a part with one figure is a split (words left, figure right at its natural width) wherever the words keep 380 px
     beside it (.is-side, from about 760 px); otherwise the figure sits under its paragraph;
   - wider screens grow the column and the text; tests/learn/visual/la_layout.py checks for cut-off text, empty space
     and a staff space over the cap. */
.la,.la .lp-prose,.la .la-sec,.la .g6-art-part,.la .lp-prose > *{min-width:0;max-width:100%}
.la .la-split{display:flex;flex-direction:column}
.la .la-text,.la .la-fig{display:contents}
.la figure.g6-ex{justify-items:stretch}
.la figure.g6-ex .mn-sheet{width:100%;max-width:none;box-sizing:border-box}
.la figure.g6-ex .mn-host > svg:only-child{width:100% !important;height:auto;margin:0 auto;display:block}
.la figure.g6-ex .mn-host:has(> svg + svg){display:flex;flex-wrap:wrap;gap:12px 28px;justify-content:center;align-items:flex-start}
.la figure.g6-ex .mn-host:has(> svg + svg) > svg{flex:1 1 240px;width:auto !important;height:auto}
.la .lp-prose p,.la .lp-prose ul,.la .lp-prose ol,.la .lp-prose li,.la-sec > h2,.la-body h2{max-width:62ch}
.la .la-split.is-side{display:grid;column-gap:40px;align-items:start;justify-content:start}
.la .la-split.is-side > .la-text{display:block}
.la .la-split.is-side > .la-text > *{order:0 !important}
.la .la-split.is-side > .la-fig{display:block;position:sticky;top:88px}
.la .la-split.is-side figure.g6-ex{margin:4px 0 0}
@media (min-width:1200px){.lp-stage:has(> .la.is-on){max-width:1180px}.la .lp-video{max-width:none}}
@media (min-width:2200px){.lp-stage,.lp-stage:has(.lq.has-vis),.lp-stage:has(.lq-say.has-fig),.lp-stage:has(.lp-skel.has-fig),.lp-stage:has(.lp-try.is-on){max-width:1560px}}
@media (min-width:1600px){.lp-stage:has(> .la.is-on){max-width:1320px}.la .lp-prose p,.la .lp-prose li{font-size:19px}}
@media (min-width:2200px){.lp-stage:has(> .la.is-on){max-width:1560px}.la .lp-prose p,.la .lp-prose li{font-size:20px}}
/* a lesson's reading column, centred (coordinator, 14 Oct, the place-value lesson at 1440: a 570 px column hard left with
   dead space beside it, and the question card wider than the words above it): an article with no music parts (which
   lay their figures beside the words) is one column as wide as its text, 62ch at the text's size (the article itself is set at 17 px), and the Have a go
   card, the think-first box and the Practise panel take that column's width. In px (62ch of BL Body at 18, 19 and 20 px),
   not ch: a ch is the width of the 0 in whichever font is drawn, so the column changed width when the fonts swapped in */
@media (min-width:1200px){.lp-stage > .la.is-on:not(:has(.g6-art-part)){box-sizing:border-box;width:100%;max-width:742px;margin-inline:auto}
  .la.is-on:not(:has(.g6-art-part)) .lpq,.la.is-on:not(:has(.g6-art-part)) #lpqHold{max-width:none}}
@media (min-width:1600px){.lp-stage > .la.is-on:not(:has(.g6-art-part)){max-width:783px}}
@media (min-width:2200px){.lp-stage > .la.is-on:not(:has(.g6-art-part)){max-width:824px}}
/* the Plus lock screen (the free first screen, then the stop) as wide as the lesson it stands in for: without this it
   stayed at 900 px from 1700 px while the unlocked lesson grows (music agent, 10 Oct) */
.lp-lock .pm-card .lq-tscroll{--paper:var(--surface)}   /* the scroll edge fades into the card, not the page colour */
@media (min-width:1200px){.lp-stage:has(> .lp-lock.is-on){max-width:1180px}.lp-lock .pm{max-width:none}}
@media (min-width:1600px){.lp-stage:has(> .lp-lock.is-on){max-width:1320px}.lp-lock .pm-prose p,.lp-lock .pm-prose li{font-size:19px}}
@media (min-width:2200px){.lp-stage:has(> .lp-lock.is-on){max-width:1560px}.lp-lock .pm-prose p,.lp-lock .pm-prose li{font-size:20px}}

/* the worked solution in the feedback panel (learn.js wsToSheet; owner, 9 Oct): large, every step a numbered line */
.lp-sheet .lq-ws.in-sheet{margin:14px 0 4px;padding:14px 16px 16px;border:0;border-radius:16px;background:var(--surface);color:var(--ink)}
.lp-sheet .lq-ws.in-sheet h2{font-size:19px;margin:0 0 10px}
.lp-sheet .lq-ws.in-sheet ol{gap:10px;padding-inline-start:28px;font-size:18px;line-height:1.5;font-variant-numeric:tabular-nums}
.lp-sheet .lq-ws.in-sheet li{padding-inline-start:4px}
.lp-sheet .lq-ws.in-sheet li::marker{color:var(--ink-3);font-weight:700}
@media (max-width:600px){.lp-sheet .lq-ws.in-sheet{padding:12px 12px 14px}.lp-sheet .lq-ws.in-sheet ol{font-size:18px}}

/* a question's music: Play in a small toolbar row above the score, right-aligned, so the notation has the card's full
   width (coordinator, 12 Oct: a column beside the score clipped the music under the button) */
.lq .mn-fig .mn-sheet > .mn-sheet-bar{display:flex;justify-content:flex-end;align-items:center;width:100%;height:44px;margin:0 0 2px}
.lq .mn-fig > .mn-sheet{padding:12px}   /* Play inset by the card's own padding, clear of the rounded corner (owner, 12 Oct) */
@media (min-width:700px){.lq .mn-fig > .mn-sheet{padding:16px}}
.lq .mn-fig .mn-sheet > .mn-host{min-width:0;width:100%}

/* the panel leads with the result (wsToSheet): the answer large, then the ticks for method marks */
.lp-sheet .lp-ans-big{margin:4px 0 8px;font:700 clamp(22px,2vw + 14px,28px)/1.25 var(--f-body);color:var(--ink);font-variant-numeric:tabular-nums}
.lp-sheet .ms.in-sheet{margin:8px 0 6px;padding:10px 14px 12px;border:0;border-radius:14px;background:var(--surface);color:var(--ink)}
.lp-sheet .ms.in-sheet .msh{margin:0 0 6px;font-weight:700}
.lp-sheet .ms.in-sheet ul{margin:0;padding:0;list-style:none;display:grid;gap:6px}
.lp-sheet .ms.in-sheet label{display:flex;gap:10px;align-items:flex-start;min-height:44px;align-items:center;cursor:pointer}
.lp-sheet .ms.in-sheet input[type=checkbox]{width:22px;height:22px;flex:none;accent-color:var(--study-btn)}
.lp-sheet .ms.in-sheet .lq-hint{display:none}
/* a label and its value on each row (learn.js kvTable): each label on the first line of its value, the values' lines
   wrapping under each other from one start; the labels kept on one line while that needs at most 45% of the room (.kv-one),
   or else the label column held to 45% (never under its longest word) so the values keep 55% */
.lq-tscroll > table.is-kv{display:table}
table.is-kv tr > th,table.is-kv tr > td,.lq-tscroll > table.is-kv tr > :is(th,td){vertical-align:baseline;text-align:start}
table.is-kv tr > :first-child{padding-inline-end:16px}
table.is-kv[style*="--kv-fs"] tr > :is(th,td){font-size:var(--kv-fs)}   /* learn.js kvFit: steps the type down (at most 18%) when a long word would push the table sideways; words never split */
table.is-kv.kv-wrap tr > :last-child{overflow-wrap:anywhere}   /* the last resort, for one word wider than the room */
table.is-kv.kv-one tr > :first-child{white-space:nowrap;width:var(--kv-l,auto)}
.lq-tscroll > table.is-kv:not(.kv-one){width:100%}
table.is-kv:not(.kv-one) tr > :first-child{width:45%}
/* the "in a row" streak (owner, 10 Oct: "spaced badly"; it hung under the bar's rounded end, touching it): on a wide
   screen it sits IN the header row, right of the bar and centred on it, in a slot kept the same width whether or not
   a streak shows (7.5em holds "✦ 100 in a row"), so the bar never moves when it comes or goes; at least 12 px clear
   of the bar's end. On a phone it sits at the right of the lesson line under the bar, centred on that line, which
   keeps room for it. The spark is cap height (0.9em box, its tips at the caps' top and the baseline), 0.35em from
   the figure. */
.lp-top .lp-combo{position:static;display:inline-flex;align-items:center;justify-content:flex-end;gap:.35em;min-width:7.5em;margin-inline-start:12px;font-size:14px;line-height:1;white-space:nowrap;pointer-events:none;transform-origin:100% 50%}
.lp-top .lp-combo[hidden]{display:inline-flex;visibility:hidden}
.lp-top .lp-combo svg{width:.9em;height:.9em}
@media (max-width:560px){
  .lp-top .lp-combo{position:absolute;inset-inline-end:max(10px,env(safe-area-inset-right));bottom:calc(10px + 4px + 10.5px - .5em);min-width:0;margin:0;height:1em}
  .lp-top .lp-combo[hidden]{display:none}
  .lp-top:has(.lp-combo) > .lp-loc{padding-inline-end:64px}
}
/* the answer-feedback footer (owner, 10 Oct: "Spacing of buttons?"): on a wide screen the message (mark, title, line)
   and the buttons share one row inside the content column, the buttons centred on the message, with 24 px above and
   below; Correct, Not yet and the shown answer all use it, so the footer keeps its shape between states. A phone keeps
   message over buttons (side by side, 12 px apart, the main one last, safe-area padding below). */
@media (min-width:700px){
  .lp-foot:has(> .lp-sheet:not(:empty)){display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:28px;align-items:center;min-height:132px;box-sizing:border-box;
    padding:24px max(16px,calc((100% - 820px) / 2)) calc(24px + env(safe-area-inset-bottom))}
  .lp-foot:has(> .lp-sheet:not(:empty)) > .lp-sheet{max-width:none;width:auto;margin:0;padding:0;max-height:calc(100dvh - 160px)}
  .lp-foot:has(> .lp-sheet:not(:empty)) > .lp-actions{max-width:none;width:auto;margin:0;padding:0;flex-wrap:nowrap}
}
@media (min-width:1700px){.lp-foot:has(> .lp-sheet:not(:empty)){padding-inline-start:max(16px,calc((100% - 900px) / 2));padding-inline-end:max(16px,calc((100% - 900px) / 2))}}
/* the second button on a coloured band: an edge that holds at 3:1 against the band (the band's own ink, softened) */
.lp-foot:has(.lp-sheet.is-right) .lp-btn.quiet{border-color:color-mix(in srgb,var(--ink) 62%,var(--ln-right-bg))}
.lp-foot:has(.lp-sheet.is-wrong) .lp-btn.quiet{border-color:color-mix(in srgb,var(--ink) 62%,var(--ln-wrong-bg))}
.lp-foot:has(.lp-sheet.is-neutral) .lp-btn.quiet{border-color:color-mix(in srgb,var(--ink) 62%,var(--ln-self-bg))}
/* the course row (courses-nav's unit-intro.php 'back': "< course", previous and next lesson): one slim line under the
   header, as wide as the content under it, clear of the bar and the streak */
.lp-unavrow{box-sizing:border-box;width:100%;max-width:820px;margin:0 auto;padding:0 16px}
.lp-unavrow .ln-unav{margin:0;font-size:14px;gap:2px 18px;flex-wrap:nowrap}
.lp-unavrow .ln-unav-pn{width:auto;flex-wrap:nowrap;justify-content:flex-end;min-width:0}
.lp-unavrow .ln-unav-tt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.lp-unavrow .ln-unav a{min-height:36px}
@media (min-width:1100px){body:has(.lp-stage .lq-say.has-fig) .lp-unavrow,body:has(.lp-stage .lq.has-vis) .lp-unavrow{max-width:1180px}}
@media (min-width:1200px){body:has(.lp-stage > .la.is-on) .lp-unavrow,body:has(.lp-stage > .lp-lock.is-on) .lp-unavrow{max-width:1180px}}
@media (min-width:1600px){body:has(.lp-stage > .la.is-on) .lp-unavrow,body:has(.lp-stage > .lp-lock.is-on) .lp-unavrow{max-width:1320px}}
@media (min-width:1700px){.lp-unavrow{max-width:900px}}
@media (min-width:2200px){body:has(.lp-stage > .la.is-on) .lp-unavrow,body:has(.lp-stage > .lp-lock.is-on) .lp-unavrow,body:has(.lp-stage .lq.has-vis) .lp-unavrow,body:has(.lp-stage .lq-say.has-fig) .lp-unavrow{max-width:1560px}}
@media (max-width:440px){.lp-unavrow{padding:0 10px}}
/* the mastery view (learn-mastery-ui.js; docs/efficacy/MASTERY_VIEW_SPEC.md): a status word per lesson on the unit page,
   in a column kept for it before it fills (My learning's cards are in course.css, .lm). Subject tints only;
   Fading is a calm amber outline, never red; every state is written as words. No pills: small rounded tags. */
.lm-scope{--ci:var(--blue-ink);--ct:var(--blue-tint)}
.lm-scope[data-s="science"]{--ci:var(--study-ink);--ct:var(--study-tint)}
.lm-scope[data-s="cs"]{--ci:var(--play-ink);--ct:var(--play-tint)}
.lm-scope[data-s="music"]{--ci:var(--music-ink);--ct:var(--music-tint)}
.lm-scope:not([data-music]) .lsr{display:grid;grid-template-columns:minmax(0,1fr) 7.4em;align-items:center;column-gap:6px}
.lm-st{justify-self:end;padding:5px 8px;border-radius:7px;font:700 13px/1 var(--f-body);white-space:nowrap;color:var(--ink-3)}
.lm-st.is-learning{color:var(--ci);box-shadow:inset 0 0 0 2px var(--ct)}
.lm-st.is-secure{color:var(--ci);background:var(--ct)}
.lm-st.is-fading{color:var(--gold-ink);box-shadow:inset 0 0 0 2px var(--gold)}
.lm-note{margin:8px 0 0;color:var(--ink-3);font-size:13.5px;max-width:60ch}
/* a code part (learn-code.js; .lqc, since learn-calc.css owns .lc): an editor in the body's mono face, Run and "Run the tests", what it printed, and the
   public tests, each passing or not in words as well as by its mark. No red: a failing test is the amber "not yet". */
.lqc{display:grid;gap:10px;margin:6px 0 0}
.lqc-code{display:block;width:100%;box-sizing:border-box;min-height:9em;resize:vertical;padding:12px 14px;border:2px solid var(--rule-2);border-radius:14px;background:var(--surface);color:var(--ink);
  font:500 15.5px/1.55 var(--f-mono,ui-monospace,Menlo,monospace);tab-size:4;white-space:pre;overflow:auto}
/* no ring on a click into the editor (a text box is always :focus-visible; owner, 15 Oct, "Fix outline"): it keeps its
   card border and the caret shows focus, as on the code site; from the keyboard (html.kb-nav, learn-code.js) the
   site's 2 px ring goes round it */
.lqc-code:focus-visible{outline:none!important}   /* over the site-wide ring, which is !important */
html.kb-nav .lqc-code:focus{outline:2px solid var(--study-ink)!important;outline-offset:2px!important}
.lqc-bar{display:flex;flex-wrap:wrap;align-items:center;gap:10px}
.lqc-btn{min-height:44px;padding:0 16px;border-radius:12px;border:2px solid var(--btn-2-edge);background:var(--btn-2);color:var(--ink);font:700 15.5px var(--f-body);cursor:pointer;box-shadow:none}
.lqc-btn.is-main{background:var(--study-btn);color:var(--on-study-btn);border-color:transparent;box-shadow:none}
.lqc-btn:disabled{opacity:.55;cursor:default}
.lqc-st{color:var(--ink-2);font-size:15px}
.lqc-out{margin:0;padding:10px 14px;border-radius:12px;background:var(--sunk);color:var(--ink);font:500 14.5px/1.5 var(--f-mono,ui-monospace,Menlo,monospace);white-space:pre-wrap;overflow-wrap:anywhere;max-height:16em;overflow:auto}
/* SQL code parts: the tables' setup script, folded; Run's result as a table that scrolls sideways in its own box */
.lqc-setup{margin:0 0 10px}.lqc-setup summary{cursor:pointer;font-weight:700;color:var(--study-ink);min-height:44px;padding:10px 0;box-sizing:border-box}   /* 44 px (mobile audit LRN-15: 33 px) */
.lqc-setup pre{margin:6px 0 0;padding:10px 14px;border-radius:12px;background:var(--sunk);font:500 14px/1.5 var(--f-mono,ui-monospace,Menlo,monospace);white-space:pre;overflow-x:auto}
.lqc-out.is-sql{white-space:normal;overflow-x:auto}.lqc-out.is-sql p,.lqc-out.is-sql pre{margin:0}
.lqc-tbl{border-collapse:collapse;font:500 14px/1.4 var(--f-mono,ui-monospace,Menlo,monospace)}
.lqc-tbl th,.lqc-tbl td{padding:4px 12px;border-bottom:2px solid var(--rule);text-align:start;white-space:nowrap}.lqc-tbl th{font-weight:700}
.lqc-tests{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.lqc-t{display:grid;grid-template-columns:22px minmax(0,1fr);column-gap:8px;row-gap:6px;align-items:start;padding:10px 12px;border-radius:12px;background:var(--sunk);font-size:15px}
.lqc-t > :not(.lqc-ic){grid-column:2}
.lqc-t .lqc-tn{font-weight:700;color:var(--ink)}
.lqc-spec{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px 16px}
@media (max-width:520px){.lqc-spec{grid-template-columns:minmax(0,1fr)}}
.lqc-col,.lqc-got{display:flex;flex-direction:column;align-items:flex-start;min-width:0}
.lqc-h{font-size:13px;font-weight:600;color:var(--ink-3)}
.lqc-v{display:block;max-width:100%;font:500 14.5px/1.45 var(--f-mono,ui-monospace,Menlo,monospace);white-space:pre-wrap;overflow-wrap:anywhere;color:var(--ink)}   /* a value breaks only if it alone is wider than the column */
.lqc-ic{grid-row:1;width:16px;height:16px;border-radius:50%;box-shadow:inset 0 0 0 2px var(--ink-3);margin-top:3px}
.lqc-t.is-pass{background:var(--ln-right-bg)}.lqc-t.is-pass .lqc-ic{background:var(--ln-right);box-shadow:none}
.lqc-t.is-fail{background:var(--ln-wrong-bg)}.lqc-t.is-fail .lqc-ic{box-shadow:inset 0 0 0 3px var(--ln-wrong)}
.lqc-got{color:var(--ink-2)}.lqc-got:empty{display:none}
/* a required output in a prompt (<strong><code>Access granted</code></strong>) stands out: bold monospace */
.lq :is(strong,b) > code,.lq code > :is(strong,b){font-weight:700;font-family:var(--f-mono,ui-monospace,Menlo,monospace)}
/* a list or exact-text answer (learn.js, text part modes seq and exact) is a one-line textarea that grows onto more lines as it fills */
textarea.lq-field.t-grow{display:block;box-sizing:border-box;resize:none;overflow:hidden;line-height:1.4;white-space:pre-wrap;overflow-wrap:break-word}
.lq-line:has(> textarea.t-grow){align-items:flex-start}
/* speech bubbles hug their words (owner, 11 Oct: "That long of a bubble needed for small text?"): Noodle's question
   bubble and the unit tip are as wide as their lines need, at most 38 characters or the room there is, beside him;
   a question bubble that holds a table, code, a figure or an answer box keeps the row's width. Lines are balanced so
   the last is never one short word. The tail is drawn to fit (sayDraw). */
.lq-sayu .lq-sayb{justify-self:start;width:fit-content;max-width:min(38ch,100%);min-width:7em}
.lq-sayu .lq-sayb:has(table,pre,figure,svg:not(.lq-saybg),input,textarea,.lq-tscroll){justify-self:stretch;width:auto;max-width:none}
.lq-sayb .lq-prompt .pt,.ln-tip-b{text-wrap:pretty;text-wrap:balance}
.ln-tip-b{width:fit-content;max-width:min(38ch,100%)}

/* ---- the question screen, owner 12 Oct (a GCSE "Your turn" at about 960 px, dark) ------------------------------------
   1. The guide time's bar sits right under its words, in every question: a 4 px track across the content, 8 px under
      the words (learn.js puts a question without a marks line into the same .lq-mkh.has-pace row, so the bar no longer
      falls to the foot of the question).
   2. The question's body starts 24 px under its header (it was centred in the room above the bar: about 120 px of
      nothing at 960 px).
   3. Desktop (a pointer that hovers, 700 px and up): the action row follows the question, at the bottom right of the
      content, in the page (no band over a tall question: owner, 12 Oct); the result is scrolled into view after Check
      (learn.js sheetSay). Phones keep the pinned bar.
   4. The symbol palette under Working is out of the Tab order (learn.js: one roving stop, Alt+P). */
.lq-mkh.has-pace{padding-bottom:12px}
/* the guide time's bar is a quiet hairline under its words, never a second progress bar (coordinator, 13 Oct): thin,
   in the muted ink, on a transparent track */
.lq-pacetr{height:2px;border-radius:1px;background:transparent}
.lq-pacetr i{border-radius:1px;background:var(--ink-3);opacity:.45}
body .lp-q.is-on > .lq{--lq-head-gap:24px}
body .lp-q.is-on > .lq > :is(.ls-read,.lq-title,.lq-upnote,.lq-mkh,.lq-pace,.lr-top) + :not(.ls-read,.lq-title,.lq-upnote,.lq-mkh,.lq-pace,.lr-top){margin-top:0}
/* "a question is on screen" is the body's own class too, ln-qview (index.php on the Practice page from the first paint,
   learn.js screen() after): Chrome kept the :has() result stale for a frame, so at 1440 the bar went into the page a
   frame before the stage lost its room under it and the bar dropped 272 px (CLS 0.024). .ln-qview.ln-qview: the
   :has() selector's own weight, so no rule's order changes */
@media (min-width:700px) and (hover:hover) and (pointer:fine){
  body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-stage{flex:none;padding-bottom:8px}
  body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-stage > #lpDyn,body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-q.is-on,body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-q.is-on > .lq{flex:none}
  body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-foot{position:static;bottom:auto;width:100%;max-width:820px;margin:0 auto;padding-inline:16px;box-sizing:border-box;border-radius:var(--r2,16px);box-shadow:none;background:var(--paper)}
  body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-foot:has(.lp-sheet.is-right),body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-foot:has(.lp-sheet.is-wrong),body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-foot:has(.lp-sheet.is-neutral){box-shadow:none}
  body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-actions{padding-inline:0}
  /* one box in every state (r79, 16 Oct): the bar under a question is already the feedback panel's row before Check,
     14 px inside at the top and 24 px at the sides, the buttons at the top of the second column; the panel comes into
     the first. Before, Check's bar was a column of its own and the panel's arrival added a margin and padding and
     centred the buttons on the panel: they moved 25 px at Check and again as Show the answer grew it (CLS 0.017 and
     0.036 at 1440). The buttons now stay where Check was, 14 px below the bar's top, as before (r67: on screen) */
  body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-foot{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:28px;align-items:start;min-height:86px;margin-top:0;padding:14px 24px 18px}
  body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-foot > .lp-sheet{grid-column:1;max-height:none;overflow:visible}   /* in the page the panel grows with what it says: no scroll of its own, nothing cut off at its top (owner, 20 Oct: "Correct +1" clipped, a scrollbar inside the bar) */
  body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-foot > .lp-actions{grid-column:2;align-self:start;display:flex;align-items:center;justify-content:flex-end;padding-block:0}
  /* the result keeps its tinted band in the page as on a phone (owner, 12 Oct: "No background for the bottom
     correction like throughout the rest of the site?"): the same tokens, across the question's whole width */
  body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-foot:has(.lp-sheet.is-right){background:var(--ln-right-bg)}
  body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-foot:has(.lp-sheet.is-wrong){background:var(--ln-wrong-bg)}
  body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-foot:has(.lp-sheet.is-neutral){background:var(--ln-self-bg)}
  body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-foot:has(.lp-sheet.is-right,.lp-sheet.is-wrong,.lp-sheet.is-neutral){padding:14px 24px 18px;margin-top:0}   /* the bar's own box, as before Check (above) */
}
@media (min-width:1700px) and (hover:hover) and (pointer:fine){body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-foot{max-width:900px}}
/* the action row as wide as the question's own column (a question with a picture or a score is wider), so Check ends
   at the content's right edge */
@media (min-width:1000px) and (hover:hover) and (pointer:fine){body.ln-play:has(.lp-q.is-on .lq.has-vis) .lp-foot{max-width:1180px}}
@media (min-width:1100px) and (hover:hover) and (pointer:fine){body.ln-play:has(.lp-q.is-on .lq-say.has-fig) .lp-foot{max-width:1180px}}
@media (min-width:2200px) and (hover:hover) and (pointer:fine){body.ln-play:has(.lp-q.is-on .lq.has-vis) .lp-foot,body.ln-play:has(.lp-q.is-on .lq-say.has-fig) .lp-foot{max-width:1560px}}

/* ---- The lesson's result card (owner and coordinator, 12 Oct: "a designed result card, graphics first"; learn.js
   finishFX). The celebrating Noodle and the title; one ring of a segment per question with the score in it, a caption
   in the segments' colours, the time and the skill level beside it; "Went best"; one thing to practise next. Stacked
   and centred above the fold on a phone; on a wide screen a left-aligned card, Noodle beside the title and the ring on
   the left. The actions stay in the pinned bar, with a small progress bar under them. Teal right first time, amber
   to look at again (never red). */
.lp-done.eol2{max-width:700px;margin:0 auto;padding:6px 0 28px;text-align:start}
.eol-hero{display:flex;flex-direction:column;align-items:center;text-align:center}
.eol-hero .ln-noodle.eol-cel{width:140px;height:145px;margin:0}
/* a calm pose (a result under 80%): the plain drawing, no padding for a jump, so a little smaller */
.eol-hero .ln-noodle.eol-calm{width:104px;height:108px;margin:4px 0 6px;animation:none}
@media (min-width:760px){.eol-hero .ln-noodle.eol-calm{width:112px;height:116px;margin:0}}
.eol-ttl h1{margin:0;font-size:clamp(30px,2.4vw + 18px,44px);line-height:1.05;animation:none}
.eol2 .lp-done-name{margin:6px 0 0;text-align:inherit;font:600 clamp(18px,.6vw + 15px,21px)/1.3 var(--f-display);color:var(--ink-2)}
.eol-meta{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:4px 12px;margin:8px 0 0;font-size:14.5px;font-weight:700}
.eol-xp{color:var(--gold-ink)}
.eol-meta .lp-earn{display:none}
.eol-meta .lh-earned{display:inline-flex;align-items:center;gap:4px;margin:0;font:inherit;color:var(--ink-2)}
.eol-meta .lh-earned svg,.eol-meta .lh-earned img{width:18px;height:18px}
.eol-meta .lh-earned.lh-full{flex-basis:100%;justify-content:center;font-weight:500}
.lp-done-body.eol{max-width:none;margin:22px 0 0;text-align:start}
/* the ring and its facts */
.eol-res{display:flex;flex-direction:column;align-items:center;gap:14px}
.eol-ring{position:relative;flex:none;width:184px;height:184px}
.eol-ring svg{display:block;width:100%;height:100%;overflow:visible}
.eol-track{fill:none;stroke:var(--sunk);stroke-width:13}
.eol-seg{fill:none;stroke-width:13;stroke-linecap:butt;cursor:pointer;outline:none;transition:stroke-width .15s ease}
.eol-seg.ok{stroke:var(--study)}
.eol-seg.no{stroke:var(--gold)}
.eol-seg:hover,.eol-seg.is-on,.eol-seg:focus-visible{stroke-width:17}
.eol-seg.is-draw{stroke-dasharray:100;stroke-dashoffset:100;animation:eolDraw .32s cubic-bezier(.22,1,.36,1) forwards;animation-delay:calc(220ms + var(--i) * 70ms)}
@keyframes eolDraw{to{stroke-dashoffset:0}}
.eol-score{position:absolute;inset:0;margin:0;display:flex;flex-direction:column;align-items:center;justify-content:center;pointer-events:none}
.eol-score b{font:700 52px/1 var(--f-display);color:var(--ink);font-variant-numeric:tabular-nums}
.eol-score span{margin-top:2px;font-weight:700;font-size:15px;color:var(--ink-3)}
.eol-side{display:flex;flex-direction:column;align-items:center;gap:14px;min-width:0;width:100%}
.eol-cap{min-height:1.45em;margin:0;text-align:center;font-weight:600;font-size:15px;color:var(--ink-2)}
.eol-cap .ok{color:var(--study-ink)}
.eol-cap .no{color:var(--gold-ink)}
.eol-facts{display:flex;flex-wrap:wrap;justify-content:center;gap:12px 36px;margin:0}
.eol-f{display:flex;flex-direction:column;gap:3px;min-width:0}
.eol-f dt{display:flex;align-items:center;gap:6px;font-size:13.5px;font-weight:600;color:var(--ink-3)}
.eol-f dd{margin:0;display:flex;align-items:baseline;flex-wrap:wrap;gap:2px 8px}
.eol-f dd b{font:700 24px/1.1 var(--f-display);color:var(--ink);font-variant-numeric:tabular-nums}
.eol-f dd span{font-size:14.5px;color:var(--ink-2)}
.eol-fi{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round}
/* Went best, then one thing to practise next */
.eol-best{display:flex;align-items:flex-start;gap:10px;margin:26px 0 0;font-size:16.5px;line-height:1.4;color:var(--ink-2)}
.eol-best b{color:var(--ink);font-weight:700}
.eol-bi{flex:none;display:grid;place-items:center;width:26px;height:26px;border-radius:50%;background:color-mix(in srgb,var(--study) 18%,transparent);color:var(--study-ink)}
.eol-pn{margin:16px 0 0}
.eol-h{margin:0 0 8px;font:700 13.5px/1.2 var(--f-body);letter-spacing:.02em;color:var(--ink-3)}
.eol-pl{list-style:none;margin:0;padding:0}
.eol-pl li{display:flex;align-items:center;gap:14px;padding:12px 14px 12px 16px;border-radius:16px;background:var(--sunk)}
.eol-pt{flex:1;min-width:0;display:grid;gap:2px}
.eol-pt b{font-weight:700;line-height:1.3}
.eol-pt .say{color:var(--ink-2);font-size:15px;line-height:1.4;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden}
.eol-pl .eol-pgo.lp-btn{flex:none;min-width:0;min-height:44px;padding:0 16px;font-size:15px;box-shadow:none}
.eol-all{margin:6px 0 0}.eol-all a{display:inline-flex;align-items:center;min-height:44px;color:var(--study-ink);font-weight:700;font-size:15px}
/* what other scripts add (skills for two or more, quick cards, the Plus line, Save your progress, Was this helpful): quiet, after */
.lp-done-body.eol > .ln-skills:not(:has(li + li)){display:none}
.lp-done-body.eol > .ln-skills,.lp-done-body.eol > .lp-save{margin-top:26px}
.lp-done-body.eol > .lr-after{margin:20px 0 0;text-align:start}
.lp-done-body.eol > .lp-keep{text-align:start}
.lp-done-body.eol > .lmfb{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px;margin:26px 0 0;padding:0;background:none;font-size:14.5px}
.lp-done-body.eol > .lmfb > p{margin:0;font-weight:600;color:var(--ink-2)}
.lp-done-body.eol > .lmfb > :not(p):not(.lmfb-r){flex:1 1 100%}
/* the pinned bar on this screen: Next and Back to the unit side by side, the long title wraps; the unit's progress under them */
body:has(.lp-done.eol2.is-on) .lp-actions{flex-wrap:wrap}
body:has(.lp-done.eol2.is-on) .lp-actions .lp-btn{white-space:normal;line-height:1.25;padding-block:10px;box-shadow:none}
body:has(.lp-done.eol2.is-on) .lp-actions .lp-btn:not(.quiet){flex:1 1 60%}
body:has(.lp-done.eol2.is-on) .lp-actions .lp-btn.quiet{flex:1 1 30%}
.eol-prog{order:9;flex:1 1 100%;display:flex;align-items:center;gap:10px;font-size:13.5px;font-weight:600;color:var(--ink-3)}
.eol-pb{flex:1;height:6px;border-radius:3px;background:var(--sunk);overflow:hidden}
.eol-pb i{display:block;height:100%;border-radius:3px;background:var(--study)}
@media (min-width:700px){body:has(.lp-done.eol2.is-on) .lp-actions .lp-btn{flex:0 1 auto}.eol-prog{max-width:none}}
/* a wide screen: left-aligned, Noodle beside the title, the ring on the left with its facts beside it */
@media (min-width:760px){
  .lp-done.eol2{padding-top:18px}
  .eol-hero{flex-direction:row;align-items:center;gap:18px;text-align:start}
  .eol-hero .ln-noodle.eol-cel{width:128px;height:132px;margin:-8px 0 -8px -14px}
  .eol-meta{justify-content:flex-start}
  .eol-res{flex-direction:row;align-items:center;gap:36px;padding:22px 26px;border-radius:24px;background:color-mix(in srgb,var(--sunk) 55%,transparent)}
  .eol-side{align-items:flex-start;width:auto;flex:1}
  .eol-cap{text-align:start;font-size:16px}
  .eol-facts{justify-content:flex-start;gap:14px 40px}
}
@media (prefers-reduced-motion:reduce){.eol-seg.is-draw{animation:none;stroke-dashoffset:0}.eol-seg{transition:none}}
html[data-motion="off"] .eol-seg.is-draw{animation:none;stroke-dashoffset:0}
/* a phone: Noodle small and close to the top (his SVG is padded for the jump); "Back to the unit" on one line */
@media (max-width:759px){
  .eol-hero .ln-noodle.eol-cel{width:120px;height:124px;margin:-14px 0 -4px}   /* about 120 px (coordinator, 12 Oct): the ring sits higher */
  .lp-done.eol2{padding-top:0}
  .lp-done-body.eol{margin-top:16px}
  body:has(.lp-done.eol2.is-on) .lp-actions .lp-btn.quiet{flex:0 1 auto;max-width:50%;padding-inline:16px}
  body:has(.lp-done.eol2.is-on) .lp-actions .lp-btn:not(.quiet){flex:1 1 0}
}

/* ---- graphs, owner 12 Oct: variable names at the ends of the axes, upright and italic as in maths; the axis numbers
   over the lines with a halo in the ground's colour (--lgr-bg where a graph sits on a card) */
.lgr .lab.var{font-style:italic;font-weight:600;font-size:16px;font-family:var(--f-body)}
.lgr .ticks text{paint-order:stroke;stroke:var(--lgr-bg,var(--paper));stroke-width:4px;stroke-linejoin:round}
/* the number pad open on a phone (learn.js padFit): Working folded to its header, and, when the question still cannot
   show above the pad, its first line in a strip under the top bar */
.lq-work.is-padshut .lq-worktog svg{transform:rotate(-90deg)}
.lq-work.is-padshut .lq-workb,.lq-work.is-padshut .lq-workmono{display:none}
.lq-qstrip{position:fixed;inset-inline:0;z-index:29;padding:8px 16px;background:var(--surface);color:var(--ink);font-size:15px;line-height:1.35;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;box-shadow:0 1px 0 var(--rule)}
/* the tools under the answer on a phone (owner, 12 Oct: Hint was a full-width tile, its icon over the word): ordinary
   inline buttons, icon then the short word, left-aligned, the height of the other secondary buttons */
@media (max-width:480px){
  body.ln-play .lq .lq-aids{flex-wrap:wrap;justify-content:flex-start}
  body.ln-play .lq .lq-aids > :is(.lq-aid,.lq-calcbtn){flex:0 0 auto;flex-direction:row;justify-content:flex-start;gap:6px;padding:0 14px 0 12px;font-size:14.5px;line-height:1}
}
/* the result mark (owner, 12 Oct: "the tick is broken"): the sheet scrolls (overflow-y:auto), so the mark's -3 px lift
   and its spring-in were clipped flat at the top; it now sits inside the sheet with room for the overshoot */
.lp-sheet .lp-sh{padding-top:4px}
.lp-sheet .lp-mk{margin-top:0}
/* the question screen's action row (owner, 12 Oct): never stacked; the quiet action on the left, the main one on the
   right; on a phone they share the row and their words wrap (a long label has a short form, setActions) */
body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-actions .lp-btn.quiet{order:-1}
@media (max-width:699px){
  body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-actions{flex-wrap:nowrap}
  body.ln-play:is(.ln-qview.ln-qview,:has(.lp-q.is-on)) .lp-actions .lp-btn{flex:1 1 0;min-width:0;white-space:normal;line-height:1.2;padding-inline:12px;text-align:center}
}
/* no breadcrumbs on a phone (owner rule): the "Course, Unit n, Lesson n of m" locator shows from 700 px up only */
@media (max-width:699px){.lp-top > .lp-loc{display:none}}
/* ---- The result card, laid out again (owner, 12 Oct: "Better way of formatting it?"; learn.js finishFX, and the test
   result's top). One column, everything centred but the insights panel; at 1440 a centred card up to 560 px. Noodle in
   his mood beside the title, the ring the hero with two legend chips, one rewards row, one insights panel, a slim guest
   banner. Fits 390 x 844 without scrolling for the usual lesson. */
.lp-done.eol2,.lp-result.eol-t{max-width:560px;margin-inline:auto}
.eol2 .eol-hero,.eol-hero-t{display:flex;flex-direction:row;align-items:center;justify-content:center;gap:14px;text-align:start}
.eol2 .eol-hero .ln-noodle.eol-calm,.eol-hero-t .ln-noodle.eol-calm{width:66px;height:68px;margin:0;flex:none}
.eol2 .eol-hero .ln-noodle.eol-cel{width:86px;height:89px;margin:-12px -8px -12px -12px;flex:none}
.eol2 .eol-ttl h1,.eol-hero-t h1{margin:0;font-size:clamp(26px,1.4vw + 19px,34px);line-height:1.08;text-align:start}
.eol2 .eol-ttl .lp-done-name{margin:3px 0 0;font-size:16.5px;text-align:start}
.lp-done-body.eol{margin-top:12px}
.lp-done-body.eol .eol-res{display:flex;flex-direction:column;align-items:center;gap:0;padding:0;background:none;border-radius:0}
.lp-done-body.eol .eol-ring{width:164px;height:164px}
.lp-done-body.eol .eol-score b{font-size:48px}
/* the legend chips, in the ring's colours */
.eol-chips{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-wrap:wrap;justify-content:center;gap:8px}
.eol-chips li{display:inline-flex;align-items:center;gap:7px;min-height:32px;padding:0 12px;border-radius:999px;background:var(--sunk);color:var(--ink);font-weight:700;font-size:14.5px}
.eol-chips i{width:10px;height:10px;border-radius:50%;background:var(--study)}
.eol-chips i.no{background:var(--gold)}
.lp-done-body.eol .eol-cap{margin:8px 0 0;min-height:0;text-align:center;font-weight:600;font-size:14px;color:var(--ink-2)}
.lp-done-body.eol .eol-cap[hidden]{display:none}
/* one rewards row: icon and value, one size, one baseline, no boxes */
.eol-rw{list-style:none;margin:14px 0 0;padding:0;display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:6px 16px}
.eol-rw li{display:inline-flex;align-items:center;gap:5px;font:700 14.5px/1.2 var(--f-body);color:var(--ink-2);white-space:nowrap}
.eol-ri{width:18px;height:18px;flex:none;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.eol-rxp{color:var(--gold-ink)}.eol-rxp .eol-ri{fill:var(--gold);stroke:var(--gold-ink);stroke-width:1.6}
.eol-rsp .lp-sub{display:none}
.eol-rsp:not(:has(.lh-earned)){display:none}
.eol-rw .lh-earned{display:inline-flex;align-items:center;gap:6px;margin:0;font:inherit;color:inherit}
.eol-rw .lh-earned svg,.eol-rw .lh-earned img{width:18px;height:18px}
.eol-rw .lh-earned.lh-full{font-weight:500}
/* the insights panel: flat, left-aligned, two rows at most */
.eol-ins{margin:16px 0 0;padding:2px 14px;border-radius:16px;background:var(--sunk);text-align:start}
.eol-ins p{display:flex;align-items:center;gap:10px;min-height:44px;margin:0;font-size:15.5px;line-height:1.35;color:var(--ink-2)}
.eol-ins b{color:var(--ink);font-weight:700}
.eol-ins .eol-bi{width:26px;height:26px}
.eol-ins .eol-bi.no{background:color-mix(in srgb,var(--gold) 26%,transparent);color:var(--gold-ink)}
.eol-ins-go{flex:none;margin-inline-start:auto;display:inline-flex;align-items:center;min-height:44px;padding:0 4px;color:var(--study-ink);font-weight:700;text-decoration:none}
.eol-ins-go:hover{text-decoration:underline;text-underline-offset:3px}
/* a guest: one slim banner, words and a button */
.lp-done-body.eol > .eol-keep{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:12px 0 0;padding:8px 8px 8px 14px;border-radius:14px;background:color-mix(in srgb,var(--study) 12%,var(--paper));text-align:start}
.eol-keep span{font-size:14.5px;line-height:1.3;color:var(--ink-2)}
.eol-keep a{flex:none;display:inline-flex;align-items:center;min-height:40px;padding:0 14px;border-radius:12px;background:var(--study-btn);color:var(--on-study-btn);font-weight:700;font-size:14.5px;text-decoration:none}
.eol-keep a:active{transform:scale(.98)}
/* the earlier layout's wide-screen card and phone sizes give way to this one */
@media (min-width:760px){.lp-done.eol2{padding-top:12px}.lp-done-body.eol .eol-ring{width:184px;height:184px}.lp-done-body.eol .eol-score b{font-size:52px}.eol2 .eol-hero .ln-noodle.eol-calm{width:72px;height:74px}}
@media (max-width:759px){.eol2 .eol-hero .ln-noodle.eol-cel{width:86px;height:89px;margin:-12px -8px -12px -12px}.lp-done.eol2{padding-top:0}}
/* what other scripts add under the card (quick cards, Was this helpful) is centred like the rest: one alignment */
.lp-done-body.eol > .lr-after{text-align:center}
.lp-done-body.eol > .lmfb{justify-content:center}
@media (min-width:760px){.eol2 .eol-hero .ln-noodle.eol-cel{width:104px;height:108px;margin:-14px -8px -14px -14px}}
/* a wide screen: the ring about 1.3 times (240 px) and the words one step up, in the same 560 px card (coordinator, 12 Oct) */
@media (min-width:760px){
  .lp-done-body.eol .eol-ring{width:240px;height:240px}
  .lp-done-body.eol .eol-score b{font-size:64px}
  .lp-done-body.eol .eol-score span{font-size:17px}
  .eol2 .eol-ttl h1{font-size:40px}
  .eol2 .eol-ttl .lp-done-name{font-size:18.5px}
  .eol-chips li{min-height:36px;padding:0 14px;font-size:16px}
  .eol-chips i{width:11px;height:11px}
  .eol-rw li{font-size:16px}
  .eol-ri,.eol-rw .lh-earned svg,.eol-rw .lh-earned img{width:20px;height:20px}
  .eol-rw{gap:8px 22px;margin-top:16px}
  .eol-ins p{font-size:16.5px}
}
/* no breadcrumbs on a phone (owner rule): the "Course, Unit n, Lesson n of m" locator shows from 700 px up only */
@media (max-width:699px){.lp-top > .lp-loc{display:none}}
/* the question's music card hugs its music (owner, 12 Oct): sized by the staff space (learn.js staffCap), not stretched */
@media (min-width:1100px){.lq-part:has(> .lq-say.has-fig) .mn-fig .mn-sheet{width:fit-content;min-width:min(100%,320px);max-width:100%}}
/* the question's music card hugs its music in height too (owner, 12 Oct): the Play button sits in the card's top
   right corner, in a gutter of its own beside the music (never over a staff line), not in a band above it */
.lq-say.has-fig .mn-fig .mn-sheet.has-play{position:relative;padding:16px}
.lq-say.has-fig .mn-fig .mn-sheet.has-play > .mn-sheet-bar{position:absolute;top:16px;right:16px;width:auto;margin:0}
.lq-say.has-fig .mn-fig .mn-sheet.has-play > .mn-host{padding-right:52px;box-sizing:border-box}   /* the Play button's gutter: no staff line runs under it */
.lq-say.has-fig .mn-fig .mn-sheet.has-play.mn-play-row > .mn-sheet-bar{position:static;width:100%;display:flex;justify-content:flex-end;margin:0 0 4px}
.lq-say.has-fig .mn-fig .mn-sheet.has-play.mn-play-row > .mn-host{padding-right:0}
@media (max-width:599px){.lq-say.has-fig .mn-fig .mn-sheet.has-play{padding:12px}.lq-say.has-fig .mn-fig .mn-sheet.has-play > .mn-sheet-bar{top:12px;right:12px}.lq-say.has-fig .mn-fig .mn-sheet.has-play > .mn-host{padding-right:52px}}
/* music that needs the card's full width (fitFigs mn-play-row): Play leaves the card for a row just under it, so the
   score starts at the card's top (coordinator, 19 Oct: Play's own row at the top cost 110 px of empty card at 320).
   The card's bottom margin keeps that row's room from the first paint of the layout; a figure in its box
   (learn-parts.js) has "See figure" in the same row, after Play */
.lq-say.has-fig .mn-fig .mn-sheet.has-play.mn-play-row{margin-bottom:52px}
.lq-say.has-fig .mn-fig .mn-sheet.has-play.mn-play-row > .mn-sheet-bar{position:absolute;top:calc(100% + 8px);left:0;right:auto;width:auto;height:44px;margin:0}
/* a question with music on a phone: the options and Check above the fold at 390x844 (r67 fold, Grade 6 chord
   questions 12-24 px under it): the gaps between the marks line, the music, the words and the options tightened */
@media (max-width:599px){
  .lq:has(.lq-say.has-fig) > .lq-mkh.has-pace{margin-bottom:12px}
  .lq:has(.lq-say.has-fig) > .lq-part{padding-top:6px}
  .lq-part > .lq-say.has-fig .mn-fig{margin-bottom:8px}
  .lq-part:has(> .lq-say.has-fig) > .lq-in{margin-top:8px}
  .lq-part:has(> .lq-say.has-fig) > .lq-in.t-mcq{gap:8px}
  .lq-part:has(> .lq-say.has-fig) > .lq-in.t-mcq > .lq-tile{min-height:50px;padding-top:6px;padding-bottom:6px}   /* 50 px a tile: over the 44 px touch size */
}
.lq-say.has-fig .mn-fig .mn-host{min-height:0}
/* a phone: what follows a question's score waits unseen until the score is drawn (learn.js holdBelow), then fades in */
.lq-held{visibility:hidden}
.lq-shown{animation:lqShown .2s ease-out}
@keyframes lqShown{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){.lq-shown{animation:none}}
@media (max-width:599px){.lq-say.has-fig .mn-fig .mn-host[aria-busy]{min-height:calc(var(--mn-st,1) * 81px)}}   /* a stave at 6 px a space, about 13.5 spaces tall, held until it is drawn (fitFigs' floor) */
/* music wider than its card at 6 px a space scrolls sideways: the edge it runs past fades, so it reads as more to see (learn.js fitFigs) */
.lq .mn-host.mn-sx{-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 32px),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - 32px),transparent)}
.lq .mn-host.mn-sx.at-end{-webkit-mask-image:linear-gradient(90deg,transparent,#000 32px);mask-image:linear-gradient(90deg,transparent,#000 32px)}
/* a choice with a small figure (part.figs): the figure leads, the choice's own words small under it */
/* (owner, 12 Oct, the harp pedal choices: the figure is the choice): the figure in the row where the words would be,
   the words kept for screen readers only (the button's aria-label carries them too) */
.lq-tile.has-fig{align-items:center;gap:14px;padding-block:10px}
.lq-tile .lq-tfig{display:block;line-height:0;min-width:0}
.lq-tile .lq-tfig svg{display:block;max-width:100%;height:auto;max-height:96px;color:inherit}
/* a choice drawn as music (learn.js figChoice): the engraving on its own white card, as every figure is, in either theme */
.lq-tile .lq-tfig:has(.mn-figchoice){flex:1 1 auto;align-self:stretch;display:flex;align-items:center}
.lq-tile .mn-figchoice{display:block;width:100%;min-width:84px;padding:2px 8px;border-radius:8px;background:#fff;color:#111}
.lq-tile .mn-figchoice svg{display:block;width:100%;height:auto;max-height:72px}
.lq-tile.has-fig > .c{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
/* the "in a row" count on a phone (owner, 12 Oct: "Badly positioned 4?"): with the lesson line gone under 700 px it was
   placed for that line and landed on the speaker's corner. It is the run's own chip now, in the header row after the
   helpers and the speaker: a small gold pill with the spark and the figure, the words kept for screen readers */
@media (max-width:560px){
  .lp-top .lp-combo{position:static;height:auto;min-width:0;margin:0 0 0 2px;padding:4px 8px;border-radius:999px;background:var(--gold-tint);color:var(--gold-ink);font-size:13.5px;line-height:1}
  .lp-top .lp-combo[hidden]{display:none}
  .lp-top:has(.lp-combo) > .lp-loc{padding-inline-end:0}
}
@media (max-width:440px){.lp-top .lp-combo .w{display:inline;position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}}
/* the result card's headline (owner, 12 Oct): the score at display size under "Lesson complete" */
.eol2 .eol-ttl h1{font:700 17px/1.2 var(--f-body);color:var(--ink-2)}
.eol-big{display:flex;align-items:baseline;flex-wrap:wrap;gap:2px 10px;margin:2px 0 0;color:var(--ink)}
.eol-big b{font:700 clamp(40px,2vw + 30px,56px)/1 var(--f-display);font-variant-numeric:tabular-nums}
.eol-big span{font:700 16px/1.3 var(--f-body);color:var(--ink-2)}
.eol-folds{align-self:stretch;margin:14px 0 0;text-align:start}
.eol2 .eol-ttl .lp-done-name{margin-top:4px;font-size:15px}
/* the busy step (setActions {busy: true}): the primary at its own colours, a touch softer; "Loading" and three dots in a
   rising wave, white on the teal; nothing for the first 250 ms so a quick load never flashes; static "Loading…" with
   reduced motion */
.lp-btn.is-busy,.lp-btn.is-busy:disabled,:root[data-theme="dark"] .lp-btn.is-busy:disabled{background:color-mix(in srgb,var(--study-btn) 86%,var(--paper));color:var(--on-study-btn);box-shadow:none;border:0;cursor:progress;opacity:1}
.lp-busy{display:inline-flex;align-items:center;gap:8px;opacity:0;animation:lpBusyIn .15s ease .25s forwards}
@keyframes lpBusyIn{to{opacity:1}}
.lp-dots{display:inline-flex;align-items:flex-end;gap:4px;height:12px}
.lp-dots i{width:6px;height:6px;border-radius:50%;background:currentColor;opacity:.45;animation:lpDot 1s ease-in-out infinite}
.lp-dots i:nth-child(2){animation-delay:.15s}.lp-dots i:nth-child(3){animation-delay:.3s}
@keyframes lpDot{0%,60%,100%{transform:none;opacity:.45}30%{transform:translateY(-5px);opacity:1}}
@media (prefers-reduced-motion:reduce){.lp-busy{animation:none;opacity:1}.lp-dots{display:none}.lp-busy .t::after{content:"\2026"}}
html[data-motion="off"] .lp-busy{animation:none;opacity:1}
html[data-motion="off"] .lp-dots{display:none}
html[data-motion="off"] .lp-busy .t::after{content:"\2026"}
/* the answer bar (owner, 12 Oct): one row, one segment per question, never wrapping; right first time filled with a
   tick, right on a retry half filled, missed an outline only (shape as well as colour, never red); each segment a 44 px
   hit area; it fills left to right 60 ms a segment, a perfect run then gets one gold sweep; reduced motion: at once */
.sbar-w{display:flex;flex-direction:column;align-items:center;gap:6px;align-self:stretch;width:100%;margin:14px 0 0}
.sbar{position:relative;display:flex;gap:4px;width:100%;max-width:560px;margin:0;padding:0;list-style:none;overflow:hidden;border-radius:10px}
.sbar.is-thin{gap:2px}
.sbar li{flex:1 1 0;min-width:0;display:flex}
.sbar-s{flex:1;display:flex;align-items:center;min-width:0;height:44px;padding:0;border:0;background:none;color:inherit;text-decoration:none;cursor:default;-webkit-tap-highlight-color:transparent}
a.sbar-s,button.sbar-s{cursor:pointer}
.sbar-v{position:relative;display:grid;place-items:center;width:100%;height:20px;border-radius:6px;box-sizing:border-box;transform-origin:left center;animation:sbarIn .26s cubic-bezier(.22,1,.36,1) both;animation-delay:calc(var(--i) * 60ms)}
.sbar.is-thin .sbar-v{height:24px;border-radius:3px}
.sbar-s.ok .sbar-v{background:var(--study)}
.sbar-s.retry .sbar-v{background:linear-gradient(90deg,var(--study) 50%,transparent 50%);box-shadow:inset 0 0 0 2px var(--study)}
.sbar-s.miss .sbar-v{background:transparent;box-shadow:inset 0 0 0 2px var(--ink-3)}
.sbar-s.is-on .sbar-v{box-shadow:inset 0 0 0 2px var(--gold-ink)}
.sbar-v svg{width:14px;height:14px;fill:none;stroke:var(--on-study-btn,#fff);stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round}
@keyframes sbarIn{from{transform:scaleX(0);opacity:0}}
.sbar.is-all::after{content:"";position:absolute;top:12px;bottom:12px;left:0;width:30%;background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--gold) 75%,transparent),transparent);transform:translateX(-110%);animation:sbarSweep .7s ease-out forwards;animation-delay:calc(var(--n,8) * 60ms + 320ms);pointer-events:none}
@keyframes sbarSweep{to{transform:translateX(360%)}}
.sbar-go{display:inline-flex;align-items:center;min-height:44px;padding:0 6px;border:0;background:none;color:var(--study-ink);font:700 15.5px var(--f-body);text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.sbar-said{min-height:1.3em;margin:0;font-weight:700;font-size:15px;color:var(--ink-2)}
.sbar-said:empty{display:none}
@media (prefers-reduced-motion:reduce){.sbar-v{animation:none}.sbar.is-all::after{display:none}}
html[data-motion="off"] .sbar-v{animation:none}
html[data-motion="off"] .sbar.is-all::after{display:none}
/* the rewards row on one line where it fits */
@media (max-width:440px){.eol-rw{gap:6px 12px}.eol-rw li{font-size:13.5px}.eol-ri{width:16px;height:16px}}
/* a topic test's or a paper's result, as a lesson's card (owner, 12 Oct) */
.eol-t .eol-ttl h1{font:700 17px/1.2 var(--f-body);color:var(--ink-2);text-align:start}
.eol-t .eol-hero-t{margin-bottom:6px}
.eol-t .eol-rw .eol-rg b{color:var(--ink);font-weight:700}
.eol-t .lp-time-dots,.eol-t .lp-time-key{display:none}   /* the answer bar is the record of each question; the time keeps its words */
/* the grade as a chip under the score; its note behind (i) */
.eol-gr{margin:8px 0 0}
.eol-gr summary{display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:0;color:var(--ink-2);font:600 14.5px/1.2 var(--f-body);cursor:pointer;list-style:none}   /* plain text with its info icon, as the lines above it (no pills) */
.eol-gr summary::-webkit-details-marker{display:none}
.eol-gr summary b{color:var(--ink)}
.eol-gi{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.eol-gr p{margin:8px 0 0;max-width:46ch;font-size:14.5px;line-height:1.45;color:var(--ink-2)}
.eol-t .eol-self{margin:10px 0 0;font-size:14.5px}
.eol-sofar{font-size:.42em;font-weight:700;letter-spacing:0;margin-left:.15em;color:var(--ink-2)}   /* "3% so far": the whole paper's marks, the learner's own marking still to come */
/* the answer bar always fits: the gap shrinks with the count, thin from 20 */
.sbar{gap:clamp(1px,calc(60px / var(--n,10)),4px)}
.sbar li{min-width:2px}
/* a test with more than 12 questions: one marks bar, full width, the marks filled in the accent (owner, 12 Oct: the
   barcode of 30 segments was unreadable); the breakdown is By lesson, weakest first */
.tmb{position:relative;align-self:stretch;height:16px;margin:16px 0 0;border-radius:999px;background:var(--sunk);overflow:hidden}
.tmb span{position:absolute;inset:0;border-radius:999px;background:var(--study);transform-origin:left center;transform:scaleX(var(--f,0));transition:transform .6s cubic-bezier(.22,1,.36,1)}
[dir=rtl] .tmb span{transform-origin:right center}
.eol-coach{margin:8px 0 0;font-weight:400;font-size:15px;color:var(--ink-3);text-align:center}   /* under the time line, a quiet tip (coordinator, 12 Oct) */
.lr-rows{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.lr-row{display:grid;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:4px 10px;min-height:56px;padding:8px 12px;border-radius:14px;background:var(--surface);color:var(--ink);text-decoration:none}
.lr-row:hover{background:var(--sunk)}
.lr-t{font-weight:650;line-height:1.3}
.lr-v{font-variant-numeric:tabular-nums;font-weight:700;color:var(--ink-2)}
.lr-chev{display:grid;place-items:center;width:20px;height:20px;color:var(--study-ink)}
.lr-chev svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}
.lr-row.is-full .lr-v{color:var(--study-ink)}
.lr-bar{grid-column:1 / -1;display:block;height:8px;border-radius:999px;background:var(--sunk);overflow:hidden}
.lr-bar i{display:block;height:100%;border-radius:999px;background:var(--study);transform-origin:left center}
@media (prefers-reduced-motion:reduce){.tmb span{transition:none}}
/* ---- science figures (docs/audit/SCIENCE_FIGURES_2026-10.md): one colour language across every lesson, built from
   the site tokens so light and dark both follow. A part keeps its hue in every figure: genetic material (nucleus, DNA,
   plasmids) purple, membranes and cytoplasm blue, walls gold, chloroplasts green, vacuoles teal, mitochondria pink.
   Each figure is <figure class="sf"> holding one or more <svg role="img">; the drawing's own attributes are a plain
   outline fallback, these rules paint it. Labels are the site font, 14 units (14 px at 1:1, the size at 390 px). */
:root{
  --sf-line:var(--ink); --sf-lead:var(--ink-3);
  --sf-mem:var(--blue-ink); --sf-cyto:color-mix(in srgb,var(--blue) 9%,var(--surface));
  --sf-gen:var(--play-ink); --sf-gen-tint:var(--play-tint);
  --sf-wall:var(--gold-ink); --sf-wall-tint:color-mix(in srgb,var(--gold) 30%,var(--surface));
  --sf-chl:var(--free); --sf-chl-tint:color-mix(in srgb,var(--free) 28%,var(--surface));
  --sf-vac:var(--study-ink); --sf-vac-tint:color-mix(in srgb,var(--study) 15%,var(--surface));
  --sf-mito:var(--pink-ink); --sf-mito-tint:var(--pink-tint);
  --sf-dot:var(--ink-2);
}
.lp-prose figure.sf{display:flex;flex-wrap:wrap;align-items:flex-start;gap:24px 32px;margin:20px 0 26px;max-width:none}
.lp-learn .lp-prose > figure.sf-wide{grid-column:1 / -1;grid-row:auto}   /* a row of drawings spans both columns on a wide screen */
figure.sf > svg{display:block;flex:0 1 auto;max-width:100%;height:auto}
figure.sf svg{stroke-linejoin:round;stroke-linecap:round}
figure.sf text{font-family:var(--f-body);fill:var(--ink);stroke:none}
figure.sf .sf-t{font-weight:700}
figure.sf .sf-note{fill:var(--ink-3)}
figure.sf .sf-ld{fill:none;stroke:var(--sf-lead);stroke-width:1.75}   /* 1.75: still over 1.5 px when a wide screen sets the figure beside the words, a little under 1:1 */
figure.sf .sf-ldd{fill:var(--sf-lead);stroke:none}
figure.sf .sf-cyto{fill:var(--sf-cyto);stroke:var(--sf-mem)}
figure.sf .sf-mem{fill:none;stroke:var(--sf-mem)}
figure.sf .sf-wall{fill:var(--sf-wall-tint);stroke:var(--sf-wall)}
figure.sf .sf-nuc{fill:var(--sf-gen-tint);stroke:var(--sf-gen)}
figure.sf .sf-gen{fill:none;stroke:var(--sf-gen)}
figure.sf .sf-genf{fill:var(--sf-gen);stroke:none;opacity:.45}
figure.sf .sf-chl{fill:var(--sf-chl-tint);stroke:var(--sf-chl)}
figure.sf .sf-chll{fill:none;stroke:var(--sf-chl)}
figure.sf .sf-vac{fill:var(--sf-vac-tint);stroke:var(--sf-vac)}
figure.sf .sf-mito{fill:var(--sf-mito-tint);stroke:var(--sf-mito)}
figure.sf .sf-mitol{fill:none;stroke:var(--sf-mito)}
figure.sf .sf-rib{fill:var(--sf-dot);stroke:none}
figure.sf .sf-line{fill:none;stroke:var(--sf-line)}
/* physics: magnetic field blue, conventional current gold, force in ink (the answer reads boldest); a north pole
   pink, a south pole blue. Arrowheads (…h) are filled in their line's colour. */
:root{
  --sf-field:var(--blue-ink); --sf-cur:var(--gold-ink); --sf-force:var(--ink);
  --sf-n:var(--pink-ink); --sf-n-tint:color-mix(in srgb,var(--pink) 22%,var(--surface));
  --sf-s:var(--blue-ink); --sf-s-tint:color-mix(in srgb,var(--blue) 22%,var(--surface));
}
figure.sf .sf-fld{fill:none;stroke:var(--sf-field)}
figure.sf .sf-fldh{fill:var(--sf-field);stroke:var(--sf-field)}
figure.sf .sf-cur{fill:var(--surface);stroke:var(--sf-cur)}
figure.sf .sf-curl{fill:none;stroke:var(--sf-cur)}
figure.sf .sf-curh{fill:var(--sf-cur);stroke:var(--sf-cur)}
figure.sf .sf-frc{fill:none;stroke:var(--sf-force)}
figure.sf .sf-frch{fill:var(--sf-force);stroke:var(--sf-force)}
figure.sf .sf-poleN{fill:var(--sf-n-tint);stroke:var(--sf-n)}
figure.sf .sf-poleS{fill:var(--sf-s-tint);stroke:var(--sf-s)}
figure.sf text.sf-on{font-weight:700}
/* Earth's layers (crust gold, mantle warm, liquid outer core gold, solid inner core rose), seismic rays (P teal,
   S pink and dashed, so they differ without colour), objects in a mechanics drawing (a pale blue body) */
:root{
  --sf-crust:color-mix(in srgb,var(--gold) 55%,var(--surface)); --sf-mantle:color-mix(in srgb,var(--pink) 12%,var(--surface));
  --sf-ocore:color-mix(in srgb,var(--gold) 34%,var(--surface)); --sf-icore:color-mix(in srgb,var(--pink) 40%,var(--surface));
  --sf-pw:var(--study-ink); --sf-sw:var(--pink-ink);
  --sf-body:color-mix(in srgb,var(--blue) 16%,var(--surface));
}
figure.sf .sf-crust{fill:var(--sf-crust);stroke:var(--gold-ink)}
figure.sf .sf-mantle{fill:var(--sf-mantle);stroke:var(--gold-ink)}
figure.sf .sf-ocore{fill:var(--sf-ocore);stroke:var(--gold-ink)}
figure.sf .sf-icore{fill:var(--sf-icore);stroke:var(--pink-ink)}
figure.sf .sf-pw{fill:none;stroke:var(--sf-pw)}
figure.sf .sf-sw{fill:none;stroke:var(--sf-sw);stroke-dasharray:7 5}
figure.sf .sf-pwz{fill:none;stroke:var(--sf-pw);opacity:.55}
figure.sf .sf-swz{fill:none;stroke:var(--sf-sw);opacity:.55}
figure.sf .sf-body{fill:var(--sf-body);stroke:var(--ink)}
figure.sf .sf-solid{fill:var(--ink-2);stroke:none}
figure.sf .sf-pt{fill:var(--ink);stroke:none}
/* biology apparatus and body parts: enzymes teal, their substrate gold, nerve tissue slate, muscle and skin rose,
   water pale blue, glass and lines in slate, heat and light gold */
:root{
  --sf-enz-tint:color-mix(in srgb,var(--study) 18%,var(--surface)); --sf-water:color-mix(in srgb,var(--blue) 15%,var(--surface));
  --sf-musc:color-mix(in srgb,var(--pink) 34%,var(--surface)); --sf-skin:color-mix(in srgb,var(--pink) 14%,var(--surface));
  --sf-greym:color-mix(in srgb,var(--ink) 10%,var(--surface)); --sf-nerve:var(--ink-2);
}
figure.sf .sf-wallq{fill:var(--sf-wall-tint);stroke:var(--sf-wall);opacity:.6}
figure.sf .sf-enz{fill:var(--sf-enz-tint);stroke:var(--study-ink)}
figure.sf .sf-sub{fill:var(--sf-wall-tint);stroke:var(--gold-ink)}
figure.sf .sf-cord{fill:var(--sf-cyto);stroke:var(--blue-ink)}
figure.sf .sf-grey{fill:var(--sf-greym);stroke:var(--ink-3)}
figure.sf .sf-skin{fill:var(--sf-skin);stroke:var(--pink-ink)}
figure.sf .sf-musc{fill:var(--sf-musc);stroke:var(--pink-ink)}
figure.sf .sf-heat,figure.sf .sf-ray{fill:none;stroke:var(--gold-ink)}
figure.sf .sf-rec,figure.sf .sf-bulb,figure.sf .sf-org{fill:var(--sf-wall-tint);stroke:var(--gold-ink)}
figure.sf .sf-nrv{fill:none;stroke:var(--sf-nerve)}
figure.sf .sf-nrvb{fill:var(--surface);stroke:var(--sf-nerve)}
figure.sf .sf-nrvh,figure.sf .sf-knob{fill:var(--sf-nerve);stroke:var(--sf-nerve)}
figure.sf .sf-water,figure.sf .sf-waterf{fill:var(--sf-water);stroke:var(--ink-2)}
figure.sf .sf-waterf{stroke:none}
figure.sf .sf-glass{fill:none;stroke:var(--ink-2)}
figure.sf .sf-bub,figure.sf .sf-sodalime{fill:var(--surface);stroke:var(--ink-2)}
figure.sf .sf-drop{fill:var(--pink-ink);stroke:none}
/* chemistry: carbon atoms and bonds in slate, weak forces dashed; positive ions blue, negative ions rose; inert
   electrodes grey; the atmosphere pale blue, the ground green; sunlight gold, infrared rose */
:root{ --sf-elec:color-mix(in srgb,var(--ink) 30%,var(--surface)); --sf-ground:color-mix(in srgb,var(--free) 24%,var(--surface)); }
figure.sf .sf-bond{fill:none;stroke:var(--ink-2)}
figure.sf .sf-carbon{fill:var(--ink);stroke:none}
figure.sf .sf-weak{fill:none;stroke:var(--ink-3);stroke-dasharray:4 4}
figure.sf .sf-cat{fill:var(--sf-s-tint);stroke:var(--blue-ink)}
figure.sf .sf-an{fill:var(--sf-n-tint);stroke:var(--pink-ink)}
figure.sf .sf-elec{fill:var(--sf-elec);stroke:var(--ink-2)}
figure.sf .sf-elyte{fill:var(--sf-water);stroke:none}
figure.sf .sf-atmos{fill:var(--sf-cyto);stroke:var(--blue-ink)}
figure.sf .sf-mol{fill:var(--ink-3);stroke:none}
figure.sf .sf-ground{fill:var(--sf-ground);stroke:var(--free)}
figure.sf .sf-sw-in{fill:none;stroke:var(--gold-ink)}
figure.sf .sf-sw-inh{fill:var(--gold-ink);stroke:var(--gold-ink)}
figure.sf .sf-ir{fill:none;stroke:var(--pink-ink)}
figure.sf .sf-irh{fill:var(--pink-ink);stroke:var(--pink-ink)}
/* nuclear and energy figures: neutrons slate, uranium-235 gold, fission products rose; a Sankey diagram's useful
   energy teal and wasted energy rose; iron cores grey, field equipotentials dashed rose, a planet green */
:root{ --sf-useful:color-mix(in srgb,var(--study) 26%,var(--surface)); --sf-waste:color-mix(in srgb,var(--pink) 24%,var(--surface)); --sf-u:color-mix(in srgb,var(--gold) 42%,var(--surface)); }
figure.sf .sf-nline{fill:none;stroke:var(--ink-2)}
figure.sf .sf-nlineh,figure.sf .sf-neut{fill:var(--ink-2);stroke:var(--ink-2)}
figure.sf .sf-neut{stroke:none}
figure.sf .sf-u235{fill:var(--sf-u);stroke:var(--gold-ink)}
figure.sf .sf-daught{fill:var(--sf-n-tint);stroke:var(--pink-ink)}
figure.sf .sf-useful{fill:var(--sf-useful);stroke:var(--study-ink)}
figure.sf .sf-waste{fill:var(--sf-waste);stroke:var(--pink-ink)}
figure.sf .sf-core{fill:var(--sf-elec);stroke:var(--ink-2)}
figure.sf .sf-src{fill:var(--surface);stroke:var(--ink)}
figure.sf .sf-eqp{fill:none;stroke:var(--pink-ink);stroke-dasharray:6 5}
figure.sf .sf-planet{fill:var(--sf-ground);stroke:var(--free)}
/* more chemistry: a fractionating column shaded hot (rose) to cool (blue); electrons as dots in ink and crosses in
   rose; shells slate; an alloy's other atom gold; flow-chart boxes: water blue, a step plain, the result teal */
figure.sf .sf-column{fill:url(#sf-fd-grad);stroke:var(--ink-2)}
figure.sf .sf-stop-hot{stop-color:var(--sf-waste)}
figure.sf .sf-stop-cool{stop-color:var(--sf-cyto)}
figure.sf .sf-edot{fill:var(--ink);stroke:none}
figure.sf .sf-ecross{fill:none;stroke:var(--pink-ink)}
figure.sf .sf-shell{fill:none;stroke:var(--ink-3)}
figure.sf .sf-shellq{fill:none;stroke:var(--ink-3);stroke-dasharray:4 4}
figure.sf .sf-alloy{fill:var(--sf-u);stroke:var(--gold-ink)}
figure.sf .sf-sea{fill:var(--sf-cyto);stroke:none}
figure.sf .sf-paper{fill:var(--surface);stroke:var(--ink-3)}
figure.sf .sf-spot1{fill:var(--pink-ink)}figure.sf .sf-spot2{fill:var(--gold-ink)}figure.sf .sf-spot3{fill:var(--study-ink)}
figure.sf .sf-boxw{fill:var(--sf-water);stroke:var(--blue-ink)}
figure.sf .sf-boxp{fill:var(--surface);stroke:var(--ink-2)}
figure.sf .sf-boxok{fill:var(--sf-useful);stroke:var(--study-ink)}
figure.sf .sf-n2{fill:var(--sf-s-tint);stroke:var(--blue-ink)}
figure.sf .sf-o2{fill:var(--sf-useful);stroke:var(--study-ink)}
figure.sf .sf-other{fill:var(--sf-u);stroke:var(--gold-ink)}
figure.sf .sf-tline{fill:none;stroke:var(--study-ink)}
/* light and matter: rays gold with arrowheads, normals dashed, glass pale blue, angle arcs and their letters in
   ink; protons rose, neutrons grey, electrons blue; paper, aluminium and lead from light to dark; a bob slate */
:root{ --sf-glassb:color-mix(in srgb,var(--blue) 13%,var(--surface)); --sf-alu:color-mix(in srgb,var(--ink) 18%,var(--surface)); --sf-lead:color-mix(in srgb,var(--ink) 55%,var(--surface)); }
figure.sf .sf-lray{fill:none;stroke:var(--gold-ink)}
figure.sf .sf-lrayh{fill:var(--gold-ink);stroke:var(--gold-ink)}
figure.sf .sf-normal{fill:none;stroke:var(--ink-3);stroke-dasharray:6 5}
figure.sf .sf-glassb{fill:var(--sf-glassb);stroke:var(--ink-2)}
figure.sf .sf-angle{fill:none;stroke:var(--ink-2)}
figure.sf text.sf-it{font-style:italic;font-weight:600}
figure.sf .sf-proton{fill:var(--sf-n-tint);stroke:var(--pink-ink)}
figure.sf .sf-neutron{fill:var(--sf-alu);stroke:var(--ink-2)}
figure.sf .sf-electron{fill:var(--blue-ink);stroke:none}
figure.sf .sf-alu{fill:var(--sf-alu);stroke:var(--ink-2)}
figure.sf .sf-lead{fill:var(--sf-lead);stroke:var(--ink-2)}
figure.sf .sf-bob{fill:var(--sf-body);stroke:var(--ink)}
figure.sf.sf-trio{gap:16px}
figure.sf.sf-trio > svg{flex:0 0 auto}
/* waves, stars and spectra: spring coils slate; a star gold; star-stage boxes by colour (giants rose, a supernova
   gold, the remnant grey); a spectrum from violet to red in the site's hues, its absorption lines navy */
figure.sf .sf-coil{fill:none;stroke:var(--ink-2)}
figure.sf .sf-star,figure.sf .sf-starbox{fill:var(--sf-u);stroke:var(--gold-ink)}
figure.sf .sf-boxred{fill:var(--sf-waste);stroke:var(--pink-ink)}
figure.sf .sf-boxdark{fill:var(--sf-alu);stroke:var(--ink-2)}
figure.sf .sf-spectrum{fill:url(#sf-rs-grad);stroke:var(--ink-2)}
figure.sf .sf-sp1{stop-color:var(--play)}figure.sf .sf-sp2{stop-color:var(--blue)}figure.sf .sf-sp3{stop-color:var(--free)}figure.sf .sf-sp4{stop-color:var(--gold)}figure.sf .sf-sp5{stop-color:var(--pink)}
figure.sf .sf-absline{fill:none;stroke:var(--navy)}
/* A-level physics: an optical fibre's cladding, a paler glass round the core */
figure.sf .sf-clad{fill:var(--sf-cyto);stroke:var(--ink-2)}
/* circuits: components outlined on the page colour, meters pale blue with their letter inside, a test wire gold */
figure.sf .sf-comp{fill:var(--surface);stroke:var(--ink)}
figure.sf .sf-meter{fill:var(--sf-cyto);stroke:var(--blue-ink)}
figure.sf .sf-testwire{fill:none;stroke:var(--gold-ink)}
/* figures in dark mode: no darkened gold grounds (dark_mud, owner 14 Oct, "Not poop colour"): the site's rich tones
   under the gold outlines, as theme fix d59adff29: wine for stars, nuclei, alloy atoms and the stable band; petrol for
   cell walls and substrates; plum for the Earth's liquid outer core */
:root[data-theme="dark"]{--sf-u:#551c2a;--sf-wall-tint:#0b3943;--sf-ocore:#4c1f44}
/* a figure outside a lesson's column (a question's stem): no browser margin of 40 px a side, which drew a 350 px
   circuit at 278 px on a phone; a lesson's own .lp-prose figure.sf rule still sets its spacing there */
figure.sf{margin:16px 0}

/* "Report a problem with this question" (learn.js reportBox; trust audit D1): quiet, under the question, 44 px targets */
.lq-rep{margin:20px 0 4px}
.lq-rep-open,.lq-rep-x{background:none;border:0;padding:12px 0;min-height:44px;color:var(--muted);font:inherit;font-size:14px;text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.lq-rep-form{max-width:560px}
.lq-rep-form fieldset{border:0;margin:0;padding:0}
.lq-rep-form legend{font-weight:700;margin-bottom:6px;color:var(--ink)}
.lq-rep-form label,.lq-rep-form textarea{color:var(--ink)}   /* in the feedback panel too, whose own text is quieter */
.lq-rep-form label{display:flex;align-items:center;gap:10px;min-height:44px}
.lq-rep-form input[type="radio"]{appearance:none;-webkit-appearance:none;flex:none;width:22px;height:22px;margin:0;border:2px solid var(--rule-2);border-radius:50%;background:var(--surface);cursor:pointer}   /* 22 px, not the browser's 14 (coordinator, 19 Oct) */
.lq-rep-form input[type="radio"]:checked{border-color:var(--study);background:var(--study);box-shadow:inset 0 0 0 4px var(--surface)}
.lq-rep-form input[type="radio"]:focus-visible{outline:3px solid var(--study);outline-offset:2px}
.lq-rep-form .lq-rep-nl{min-height:0;margin-top:10px}
.lq-rep-form textarea{width:100%;box-sizing:border-box;margin-top:6px;padding:10px 12px;border:2px solid var(--rule-2);border-radius:12px;background:var(--surface);font:inherit;resize:vertical}
.lq-rep-h{display:flex;align-items:baseline;justify-content:space-between;gap:12px;font-size:13px;color:var(--muted);margin:6px 0 0}
.lq-rep-c{flex:none;white-space:nowrap;font-variant-numeric:tabular-nums}   /* the count on the hint's line, at its end */
.lq-rep-acts{display:flex;gap:16px;align-items:center;margin-top:10px}
.lq-rep-send{min-height:44px;padding:0 20px;border-radius:12px;border:0;background:var(--study-btn);color:var(--on-study-btn);font:inherit;font-weight:700;cursor:pointer}   /* the player's own button tokens (white on --study was 3.4:1) */
.lq-rep-send[disabled]{opacity:.6}
.lq-rep-msg,.lq-rep-done{font-size:14px;margin:8px 0 0}
/* the lesson-complete screen's "Revise it: <note>" (learn.js finish): a long note title wraps, never runs off the screen */
.lp-keep.eol-notes .lp-link{white-space:normal;text-align:start}

/* ================================================================ the lesson-complete card, decluttered (owner, 19 Oct, three rounds)
   the hero; small dots with the misses as rings; one rewards row; What went well and Even better if as two short
   labelled lines; "Go over N mistakes" (the fix) and two equal buttons, Revise it and the quick cards; at most one
   card (a guest's slim Save row, or the plan); Next alone in the bar. Fits 390 x 844 with the bar in view. */
.eol3{display:flex;flex-direction:column;align-items:stretch}
.eol-dots{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin:12px 0 0;padding:0;list-style:none}
.eol-dots li{width:14px;height:14px;border-radius:50%;background:var(--study)}
.eol-dots li.m{background:var(--surface);box-shadow:inset 0 0 0 2.5px var(--miss-ink)}
.eol-rw2{display:flex;justify-content:center;align-items:center;gap:6px 22px;min-height:72px;margin:14px 0 0;padding:8px 14px;box-sizing:border-box;list-style:none;border-radius:18px;background:var(--sunk)}
.eol-rw2 > li,.eol-rw2 .eol-rstk > a{display:inline-grid;grid-template-columns:auto auto;grid-template-rows:auto auto;column-gap:7px;align-items:center;color:var(--ink);text-decoration:none;white-space:nowrap}
.eol-rw2 > li > svg,.eol-rw2 > li > img,.eol-rw2 .eol-rstk > a > img{grid-row:span 2}   /* the icon, then the number over its word, tight */
.eol-rw2 .eol-rstk > a{min-height:44px}
.eol-rw2 svg.eol-ri,.eol-rw2 .lh-earned svg,.eol-rw2 .lh-earned img,.eol-rw2 .eol-rstk img{width:28px;height:28px;flex:none}
.eol-rw2 .eol-rxp .eol-ri{fill:var(--gold);stroke:var(--gold-ink);stroke-width:1.4}
.eol-rw2 .eol-rc{fill:none;stroke:var(--study-ink);stroke-width:2}
.eol-rw2 b{font:800 24px/1 var(--f-display);color:var(--ink)}
.eol-rw2 span:not(.lp-sub){font:650 14px/1.1 var(--f-body);color:var(--ink-2)}
.eol-rw2 .eol-rsp .lp-sub{display:none}
.eol-rw2 .eol-rsp:not(:has(.lh-earned)){display:none}
.eol-rw2 .lh-earned{display:inline-grid;grid-template-columns:auto auto;column-gap:7px;align-items:center;margin:0;font:inherit}
.eol-rw2 .lh-earned > svg,.eol-rw2 .lh-earned > img{grid-row:span 2}
.eol-rw2 .lh-earned > span{display:grid;font:650 14px/1.1 var(--f-body);color:var(--ink-2)}
.eol-rw2 .lh-earned > span > b{display:block}
.eol-rw2 .lh-earned.lh-full > span{white-space:normal;font-weight:500}
.eol-fb{display:grid;gap:8px;margin:16px 0 0}
.eol-fb p{display:grid;grid-template-columns:26px 1fr;column-gap:10px;margin:0;line-height:1.35;color:var(--ink)}
.eol-fb .ic{grid-row:span 2;width:26px;height:26px;border-radius:50%;display:grid;place-items:center;align-self:start;margin-top:2px}
.eol-fb .ok .ic{color:var(--ln-right);background:var(--ln-right-bg)}
.eol-fb .eb .ic{color:var(--play-ink);background:var(--play-tint)}
.eol-fb b{font:700 13.5px/1.2 var(--f-body);color:var(--ink-3)}
.eol-fb p > span:last-child{font-size:16.5px}
.eol-wide,.eol-2b,.eol-two .lr-after .lp-btn{display:flex;align-items:center;justify-content:center;gap:10px;min-height:50px;padding:0 12px;box-sizing:border-box;border-radius:14px;border:2px solid var(--btn-2-edge);background:var(--btn-2);color:var(--ink);font:700 16px var(--f-body);text-decoration:none;cursor:pointer}
.eol-wide{margin:16px 0 0}
.eol-two{display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:12px;margin:12px 0 0}
.eol-two:empty{display:none}
.eol-two .lr-after{display:contents}
.eol-two .lr-after .lp-btn{width:100%;margin:0;flex:none}
.eol-wide svg,.eol-2b svg,.eol-two .lr-after .lp-btn svg{flex:none}
.eol-save{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:14px 0 0;font-size:15px;color:var(--ink-3)}
.eol-saveb{display:inline-flex;align-items:center;min-height:44px;padding:0 16px;border-radius:12px;border:2px solid var(--btn-2-edge);color:var(--ink);font:700 15px var(--f-body);text-decoration:none;flex:none}
.eol-plan{margin:16px 0 0;padding:14px 16px;border-radius:18px;background:var(--surface);box-shadow:0 10px 30px -18px rgba(13,40,70,.3)}
.eol-plan h3{margin:0 0 2px;font:700 17px/1.2 var(--f-display);color:var(--ink)}
.eol-plan p{margin:0 0 10px;color:var(--ink-2);font-size:15.5px;line-height:1.4}
.eol-planb{display:flex;flex-direction:column;justify-content:center;min-height:52px;padding:6px 16px;border-radius:14px;border:2px solid var(--btn-2-edge);background:var(--btn-2);color:var(--ink);font:700 16px var(--f-body);text-decoration:none}
.eol-planb small{font:600 13.5px var(--f-body);color:var(--ink-3)}
.eol-info{display:flex;align-items:center;gap:10px;margin:14px 0 0;color:var(--ink-2);font-size:15.5px}
.eol-info svg{flex:none;color:var(--ink-3)}
.eol-rw2 .eol-rstk > a{border-radius:12px;padding:0 4px;margin:0 -4px}
.eol-rw2 .eol-rstk > a:hover b,.eol-rw2 .eol-rstk > a:hover span{text-decoration:underline;text-underline-offset:3px}
.eol-rw2 .eol-rstk > a:focus-visible{outline:3px solid var(--study);outline-offset:2px}
/* "Was this lesson helpful?" (bl-measure.js, its style only): one quiet line, the answers as plain text buttons with
   the outlined buttons' radius, an edge only on hover or focus, 44 px (coordinator, 19 Oct: no pills) */
.lp-done-body.eol3 > .lmfb{flex-wrap:nowrap;justify-content:center;gap:4px 8px;margin:14px 0 0;padding:0;background:none;color:var(--ink-2)}
.lp-done-body.eol3 > .lmfb > p{margin:0;font-weight:600;color:var(--ink-3);white-space:nowrap}
.lp-done-body.eol3 > .lmfb .lmfb-r{flex-wrap:nowrap;gap:4px}
.lp-done-body.eol3 > .lmfb button{min-height:44px;padding:0 12px;border-radius:12px;border:2px solid transparent;background:none;color:var(--ink-2);font-weight:650}
.lp-done-body.eol3 > .lmfb button:hover,.lp-done-body.eol3 > .lmfb button:focus-visible{border-color:var(--btn-2-edge);outline:none}
.lp-done-body.eol3 > .lmfb button[aria-pressed="true"]{border-color:var(--study);background:none;color:var(--study-ink)}
.lp-btn.link{background:none;border:0;box-shadow:none;color:var(--study-ink);text-decoration:underline;text-underline-offset:3px;min-height:44px}
.lp-btn.link:not(:disabled):hover{background:none}
@media (max-width:359px){.eol-rw2{gap:6px 14px;padding:8px 10px}.eol-rw2 b{font-size:21px}}
/* at 1440 Next is a button of its own width at the right of the bar, the unit's progress on the left */
@media (min-width:700px){
  body:has(.lp-done.eol2.is-on) .lp-actions{flex-wrap:nowrap;align-items:center}
  body:has(.lp-done.eol2.is-on) .lp-actions .lp-btn:not(.link){flex:0 0 auto;min-width:320px;max-width:360px}
  body:has(.lp-done.eol2.is-on) .eol-prog{order:-1;flex:1 1 auto;max-width:420px;margin-inline-end:auto}
}
/* a test or paper on a 320 px phone (LRN-08, 19 Oct): the top bar is one row: its clock takes the room the Sparks count
   had (no Sparks are earned mid-test), and the gaps close up; the cross, the bar, the clock, settings and sound stay */
@media (max-width:379px){
  body.ln-play:has(.lp-top .lp-clock:not([hidden])) .lp-top{gap:8px}
  body.ln-play:has(.lp-top .lp-clock:not([hidden])) .lp-top .lh-topcount{display:none}
}
