/* Exam and learn trainers: layout, question cards, verdicts, and stats */

/* ---- multiple choice mode (shares learn's tokens and header) ---- */
body.exammode #examcol { display: flex; }
body.papermode #papercol { display: flex; }
body.papermode .app { display: none; }
body.papermode #openTasks { display: none !important; }
body.exammode .app { display: none; }
body.exammode #openTasks { display: none !important; }

/* shared with exam mode and the chat: the stats chip and the send disc.
   Learn's own header button and composer no longer use them */
/* the exam header's stats chip; it ellipsizes on narrow screens */
.stattxt { display: inline-flex; align-items: center; gap: 7px;
  max-width: 52vw; border: 1px solid var(--border);
  background: var(--panel); color: var(--text); border-radius: 10px;
  padding: 8px 13px; font-size: 12.5px; font-weight: 600; cursor:
  pointer; font-family: inherit; flex-shrink: 0; transition:
  border-color .15s, color .15s; }
.stattxt svg { color: var(--dim); flex-shrink: 0; }
.stattxt span { overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.stattxt:hover { border-color: var(--hodb); }
.stattxt:hover svg { color: var(--text); }
/* the back state gets a size and accent bump so it never hides in the header */
.stattxt.back { font-size: 13px; font-weight: 700; padding: 9px 16px;
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
  background: color-mix(in srgb, var(--accent) 9%, transparent); }
.stattxt.back svg { color: var(--accent2); }
.sendbtn { border: none; background: var(--accent); color: #fff;
  width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
  display: grid; place-items: center; flex-shrink: 0; transition:
  filter .15s; }
.sendbtn:hover { filter: brightness(1.15); }
.sendbtn:disabled { opacity: .4; cursor: default; }

/* ---- learn mode ---- */
/* one canvas, one surface (the verdict), one hairline, one accent. Every
   rule is scoped to #learncol or a learn-only class, so exam mode and the
   chat keep theirs */
#learncol, #examcol, #papercol, #labcol { display: none; position: fixed; inset: 0; z-index: 35;
  background: var(--chatbg); flex-direction: column;
  --lsurf: color-mix(in srgb, var(--panel) 80%, var(--chatbg));
  --lhair: rgba(255,255,255,.08);
  --lcodebg: color-mix(in srgb, var(--chatbg) 80%, black);
  --lstem: color-mix(in srgb, var(--text) 81%, #10141d);   /* the question text before the redesign */
  --lprose: color-mix(in srgb, var(--text) 93%, var(--lsurf));
  --lmuted: color-mix(in srgb, var(--text) 82%, var(--lsurf));
  --lradius: 12px;
  /* the answer box: a step lighter than the canvas, same hue (the
     oklch mix is the fallback for browsers without relative colours) */
  --lcomposer: color-mix(in srgb, var(--chatbg) 88%, white);
  --lcomposer: oklch(from var(--chatbg) calc(l + 0.05) c h);
  --lcomposerline: rgba(255,255,255,.07); }
body.learnmode #learncol { display: flex; }
body.learnmode { overflow: hidden; }
#learnbtn.hidden { display: none; }
#readerbtn.hidden { display: none; }
body.learnmode .app { display: none; }
body.learnmode #openTasks { display: none !important; }

/* header: a 48px strip, nothing in it has a box */
.learnhead { display: flex; align-items: center; gap: 2px; height: 42px;
  padding: 0 6px 0 4px; flex-shrink: 0; }
.learnhead .lghost { width: 40px; height: 40px; padding: 0; border: 0;
  background: none; color: var(--dim2); border-radius: 10px;
  display: grid; place-items: center; cursor: pointer;
  transition: color .15s, background .15s; }
.learnhead .lghost:hover { color: var(--text);
  background: rgba(255,255,255,.05); }
.learnhead .ltitle { flex: 1; min-width: 0; height: 40px; padding: 0 8px;
  border: 0; background: none; color: var(--text);
  font: 600 15px/1.2 Geist, Inter, system-ui, sans-serif; text-align: left;
  display: flex; align-items: center; gap: 6px; border-radius: 10px;
  cursor: default; }
@keyframes crumbswap { from { opacity: 0; } to { opacity: 1; } }
.learnhead .ltitle span.swap { animation: crumbswap .4s ease-out; }
.learnhead .ltitle span { overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.learnhead .ltitle .chev { flex-shrink: 0; color: var(--dim); display: none; }
.learnhead .ltitle.pick { cursor: pointer; }
.learnhead .ltitle.pick .chev { display: block; }
.learnhead .ltitle.pick:hover { background: rgba(255,255,255,.04); }
/* during a question the title is the place: "1.2 Topic", a tap away from
   Progress; the course picker's chevron stays off */
.learnhead .ltitle .chev { transition: transform .15s; }
.learnhead .ltitle.pick.open .chev { transform: rotate(180deg); }
.learnhead .ltitle.pick.open { background: rgba(255,255,255,.04); }
.learnhead .ltitle.place { cursor: pointer; }
.learnhead .ltitle.place .chev { display: none; }
.learnhead .ltitle.place:hover { background: rgba(255,255,255,.04); }
.learnhead .ltext { flex-shrink: 0; height: 40px; padding: 0 12px; border: 0;
  background: none; color: var(--dim);
  font: 600 14px/1 Geist, Inter, system-ui, sans-serif; display: inline-flex;
  align-items: center; gap: 7px; border-radius: 10px; cursor: pointer;
  transition: color .15s; }
.learnhead .ltext:hover { color: var(--text); }
.learnhead .ltext.back { color: var(--accent2); }
.learnhead .ltext svg { flex-shrink: 0; }
/* the reader's progress hairline: how far along, without a number */
.lprog { height: 2px; flex-shrink: 0; background: rgba(255,255,255,.06); }
.lprog i { display: block; height: 100%; width: 0; background: var(--accent);
  transition: width .4s ease-out;
  opacity: .5; transition: width .4s ease; }

.learnwrap { flex: 1; min-height: 0; display: flex; flex-direction: column;
  width: 100%; position: relative; }
/* the ladder overlays the session; showing it never touches the thread */
.learnhome { position: absolute; inset: 0; z-index: 6;
  background: var(--chatbg); overflow-y: auto; scrollbar-gutter: stable;
  padding: 12px max(16px, calc((100% - 820px) / 2)) 40px; }
.learnhome.hidden { display: none; }
.learnsession { flex: 1; min-height: 0; display: flex;
  flex-direction: column; position: relative; }
/* no top padding: a landed verdict's top meets the scrollport's edge.
   The 12px landing gap sits on the first child */
.learnmain { flex: 1; min-height: 0; overflow-y: auto;
  scrollbar-gutter: stable;
  padding: 0 max(16px, calc((100% - 820px) / 2)) 20px;
  display: flex; flex-direction: column; gap: 20px; }
/* under 901px the sitting starts at the top while the keyboard is down;
   with the keyboard up (body.kbopen, set in learn.js) it rests on the
   answer box, a little above it, so the stem stays next to what you type;
   the place is in the header */
.learnmain > :first-child { margin-top: 0; padding-top: 12px; }
@media (max-width: 900px) {
  /* the bar is a pane of glass over the thread (--lbarh is its height,
     set by learnAutogrow): the thread pads by it, so nothing rests
     under it, and text slides beneath it as you scroll */
  .inputwrap.learninput { position: absolute; left: 0; right: 0; bottom: 0;
    z-index: 3; }
  .learnmain { padding-bottom: calc(var(--lbarh, 96px) + 2px); }
  body.kbopen .learnmain > :first-child { margin-top: auto; }
  /* with the keyboard up the question rests 48px above the box */
  body.kbopen .learnmain { padding-bottom: calc(var(--lbarh, 96px) + 48px); }
}
/* slack: when the thread is too short for a verdict to reach the top,
   learnScrollToCard gives the scroller the missing height here, so the
   card always lands with its header pinned (the gap is cancelled, so an
   empty spacer costs nothing) */
.learnmain::after { content: ""; flex-shrink: 0; margin-top: -20px;
  height: var(--lslack, 0px); }
.learnmain.stale > :not(.lload) { opacity: .35; }

/* the flag: a quiet text action at the right of the verdict's header,
   once the question is judged; red once set. The flagged question shows
   a red flag above its stem */
.lv .vtop .vflag { margin-left: auto; flex-shrink: 0; padding: 4px 0 4px 10px;
  border: 0; background: none; font: 500 12px/1 Geist, Inter, system-ui, sans-serif;
  color: var(--dim); cursor: pointer; transition: color .15s; }
.lv .vtop .vsub:not(:empty) + .vflag { margin-left: 0; }
.lv .vtop .vflag:hover { color: var(--dim2); }
.lv .vtop .vflag .on, .lv .vtop .vflag.on .off { display: none; }
.lv .vtop .vflag.on .on { display: inline; }
.lv .vtop .vflag.on, .lv .vtop .vflag.on:hover { color: var(--flag); }
/* the flag: a dim mark in the chips row while the question is flagged;
   a row holding nothing else stays out of the way */
.lq .qflag { display: none; align-items: center; min-height: 24px; padding: 0 2px;
  font-size: 11px; line-height: 1; color: color-mix(in srgb, var(--dim) 80%, transparent); }
.lq.flagged .qflag { display: inline-flex; }
.lq:not(.flagged) .qstem .qchips:not(:has(> :not(.qflag))) { display: none; }
/* the question's own state: a chip like the others, dim, with only a small
   dot in the state's colour (unknown red, familiar yellow, known green,
   skipped the accent), all of them muted */
.lq .qstate { display: inline-flex; align-items: center; gap: 6px; min-height: 24px;
  padding: 4px 9px; border-radius: 12px; box-sizing: border-box;
  box-shadow: inset 0 0 0 .5px rgba(255,255,255,.14);
  font: 500 11.5px/1.25 Geist, Inter, system-ui, sans-serif;
  color: color-mix(in srgb, var(--dim) 80%, transparent); }
.lq .qstate::before { content: ""; width: 5px; height: 5px; border-radius: 50%;
  flex-shrink: 0; background: var(--dot, var(--faint)); opacity: .75; }
.lq .qstate.unknown { --dot: var(--red); }
.lq .qstate.familiar { --dot: var(--amber); }
.lq .qstate.known { --dot: var(--green); }
.lq .qstate.skipped { --dot: var(--accent2); }

/* question: the exam's voice, a book serif a step quieter than the UI,
   so the question reads as the paper and the chrome stays chrome. Its
   own weight, so the exam's 650 .qstem never leaks in. The measure sits
   on the text, so the code slab shares the column's right edge with the
   verdict and the answer box */
.lq .qstem { margin: 0;
  font: 400 15.5px/1.55 Literata, "Source Serif 4", Georgia, serif;
  color: var(--dim2); text-wrap: pretty; }
.lq .qstem > * { max-width: 44rem; }
.lq .qstem p { margin: 0; white-space: pre-line; }
/* the framing chips: which reading (book mark) and whose, or the topic */
.lq .qstem .qchips { display: flex; flex-wrap: wrap; gap: 6px;
  margin: 0 0 12px; }
.lq .qstem .qchip { display: inline-flex; align-items: center; gap: 5px;
  min-height: 24px; padding: 4px 9px; border-radius: 12px;
  box-shadow: inset 0 0 0 .5px rgba(255,255,255,.14);
  font: 500 11.5px/1.25 Geist, Inter, system-ui, sans-serif;
  color: color-mix(in srgb, var(--dim) 80%, transparent); }
.lq .qstem .qchip svg { flex-shrink: 0; }
.lq .qstem p + .parts { margin-top: 10px; }
.lq .qstem .pts { color: var(--dim); font-weight: 400; white-space: nowrap; }
.lq .parts { list-style: none; margin: 0; padding: 0; display: flex;
  flex-direction: column; gap: 8px; }
.lq .parts li { display: grid; grid-template-columns: 2.2ch 1fr; gap: 0 4px; }
.lq .parts b { font-weight: 600; color: var(--dim2); }
/* code: one neutral slab, weight 500, wraps with a per-line hanging indent
   (--i set by learnCodeHtml from the line's own leading spaces) */
/* the slab's bottom padding pulls back out, so the last line of code ends
   where a last line of text would: the same height above the answer box */
.lq .qcode { margin: 10px 0 -10px; padding: 10px 16px; border: 0;
  border-radius: var(--lradius); background: var(--lcodebg);
  overflow: visible; }
.lq .qcode code { display: block; padding: 0; min-width: 0; border: 0;
  background: none;
  font: 600 13.5px/1.7 "JetBrains Mono", ui-monospace, "SF Mono", Menlo,
    monospace;
  color: var(--lmuted); white-space: pre-wrap; overflow-wrap: anywhere;
  overflow-x: visible; tab-size: 4;
  --tok-kw: color-mix(in srgb, #c678dd 75%, var(--text));
  --tok-str: color-mix(in srgb, #98c379 75%, var(--text));
  --tok-num: color-mix(in srgb, #d19a66 75%, var(--text));
  --tok-bi: color-mix(in srgb, #61afef 75%, var(--text));
  --tok-com: var(--dim); }
.lq .qcode .ln { display: block; min-height: 1.7em;
  padding-left: calc(var(--i, 0ch) + 4ch);
  text-indent: calc(-1 * (var(--i, 0ch) + 4ch)); }
.qcode .lno { color: var(--dim2); }

/* the student's answer: a margin note, same size it was typed in */
.lmine { align-self: stretch; max-width: 66ch; padding: 2px 0 2px 14px;
  border-left: 2px solid rgba(255,255,255,.16); color: var(--dim2);
  font: 400 15px/1.6 Geist, Inter, system-ui, sans-serif; white-space: pre-wrap;
  text-wrap: pretty; transition: color .3s, border-color .3s; }
.lmine::before { content: "Your answer"; display: block;
  font: 600 11px/1 "JetBrains Mono", ui-monospace, monospace;
  letter-spacing: .06em; text-transform: uppercase; color: var(--dim);
  margin-bottom: 6px; transition: color .3s; }
/* the answer is the verdict: right turns it green with a check, wrong
   red with a cross, label and text and mark in one colour */
.lmine.wait::before { animation: lwait 1.2s ease-in-out infinite; }
@keyframes lwait { 50% { opacity: .45; } }
.lmine.good { color: var(--green); border-left-color: var(--green); }
.lmine.bad { color: var(--red); border-left-color: var(--red); }
.lmine.good::before, .lmine.bad::before { color: inherit; opacity: .85; }
.lmine.good::before { content: "Your answer  ✓"; }
.lmine.bad::before { content: "Your answer  ✗"; }
.lmine.code { font: 500 16px/1.6 "JetBrains Mono", ui-monospace, monospace; }
/* rapid-fire: one line per part, each with its own mark */
.lmine .pl { display: block; color: var(--green);
  font: 500 15px/1.75 "JetBrains Mono", ui-monospace, monospace; }
.lmine .pl.x { color: var(--red); }
.lmine .pl .m { opacity: .85; margin-left: 8px; }

/* a miss: the Correct answer block in the margin, green rule and label,
   the official answer open, the trace and the why under it, the feedback
   last. Show answer and a give-up land here too */
.lmodel { align-self: stretch; max-width: 66ch; padding: 2px 0 2px 14px;
  border-left: 2px solid color-mix(in srgb, var(--green) 60%, transparent); }
.lmodel::before { content: "Correct answer"; display: block;
  font: 600 11px/1 "JetBrains Mono", ui-monospace, monospace;
  letter-spacing: .06em; text-transform: uppercase; color: var(--green);
  margin-bottom: 6px; }
.lmodel .vtop { display: none; }
.lmodel .lreveal { margin: 0; padding: 0; border: 0; }
.lmodel .lans { font: 400 16.5px/1.55 Newsreader, "Source Serif 4", Georgia,
  serif; color: var(--lprose); }
/* the short concrete answer: a shade heavier, in the text colour */
.lmodel .lans.short { font: 500 17px/1.5 Newsreader, "Source Serif 4",
  Georgia, serif; color: var(--text); }
.lmodel .lans.v { font: 500 17px/1.5 "JetBrains Mono", ui-monospace, monospace;
  color: var(--text); white-space: pre-wrap; }
.lmodel .lans.v .pl { display: block; line-height: 1.75; }
.lmodel .lans b, .lmodel .lexp b, .lmodel .md strong {
  font-weight: 600; color: color-mix(in srgb, var(--green) 80%, var(--text)); }
.lmodel .lexp { margin-top: 8px; }
/* the judge's why: sans, muted, the key terms in the answer's green */
.lmodel .md { margin-top: 8px; font: 400 14.5px/1.6 Geist, Inter, system-ui,
  sans-serif; color: var(--lmuted); }
.lmodel .md > *, .lmodel .md > .mtail > * { max-width: 66ch; }
.lmodel .md p { margin: 0 0 8px; text-wrap: pretty; }
.lmodel .md p:last-child { margin-bottom: 0; }
.lmodel .md p br { display: block; content: ""; margin-bottom: 8px; }
.lmodel .md code, .lfoot .md code { font: 500 13px "JetBrains Mono",
  ui-monospace, monospace; background: rgba(255,255,255,.07);
  padding: 1px 5px; border-radius: 4px; }
.lmodel .md.hidden, .lfoot .md.hidden { display: none; }
/* the trace: a slab under the value, one state per line; the student's
   wrong step struck through in red, the corrected line green */
.lmodel .md pre { margin: 0 0 8px; padding: 10px 14px; border: 0;
  border-radius: var(--lradius); background: var(--lcodebg); }
.lmodel .md pre .ln { display: block; min-height: 1.75em;
  padding-left: calc(var(--i, 0ch) + 4ch);
  text-indent: calc(-1 * (var(--i, 0ch) + 4ch)); }
.lmodel .md pre code { display: block; padding: 0; min-width: 0;
  background: none; border: 0; color: var(--lmuted);
  font: 500 13.5px/1.75 "JetBrains Mono", ui-monospace, monospace;
  white-space: pre-wrap; overflow-wrap: anywhere; tab-size: 4;
  --tok-kw: color-mix(in srgb, #c678dd 75%, var(--text));
  --tok-str: color-mix(in srgb, #98c379 75%, var(--text));
  --tok-num: color-mix(in srgb, #d19a66 75%, var(--text));
  --tok-bi: color-mix(in srgb, #61afef 75%, var(--text));
  --tok-com: var(--dim); }
.lmodel .md pre .ln.x { color: var(--red); text-decoration: line-through;
  text-decoration-color: color-mix(in srgb, var(--red) 55%, transparent); }
.lmodel .md pre .ln.x * { color: inherit; }
.lmodel .md pre .ln.ok { color: color-mix(in srgb, var(--green) 80%, var(--text)); }
.lmodel .md pre .ln.ok * { color: inherit; }
/* the feedback: one italic line, no label, the key terms in the text colour */
.lmodel .lfix, .lfoot .lfix { margin-top: 10px; }
.lmodel .lfix.hidden, .lfoot .lfix.hidden { display: none; }
.lmodel .fixline, .lfoot .fixline { font: italic 400 16px/1.55 Newsreader,
  "Source Serif 4", Georgia, serif; color: var(--lprose); max-width: 66ch; }
.lmodel .fixline strong, .lfoot .fixline strong { font-weight: 600;
  color: var(--text); }
.lmodel .fixline code, .lfoot .fixline code { font-style: normal; }
/* a pass: no block, only the judge's footnote when the wording was loose */
.lfoot { align-self: stretch; max-width: 66ch; padding-left: 14px;
  font: 400 13.5px/1.5 Geist, Inter, system-ui, sans-serif; color: var(--dim); }
.lfoot .vtop, .lfoot .lreveal { display: none; }
.lfoot .md p { margin: 0 0 6px; }
.lfoot .md p.official { color: var(--dim); }
.lfoot .md p.official code { color: var(--dim2); background: none; padding: 0; }
.lfoot .md strong { font-weight: 500; color: var(--dim2); }
.lfoot.hidden { display: none; }
/* the flag control under a graded answer: a text button, blue when on */
.lflagfoot { margin-top: 10px; display: flex; }
.lflagfoot .vflag { background: none; border: 0; padding: 4px 0; cursor: pointer;
  font: 500 13px/1.3 Geist, Inter, system-ui, sans-serif; color: var(--dim); }
.lflagfoot .vflag:hover { color: var(--dim2); }
.lflagfoot .vflag .on, .lflagfoot .vflag.on .off { display: none; }
.lflagfoot .vflag.on .on { display: inline; }
.lflagfoot .vflag.on, .lflagfoot .vflag.on:hover { color: var(--flag); }

/* verdict: the one surface. State is a soft 2px left rule and an outlined
   badge; the title stays in the text colour, so a miss is a state, not a
   shout. Nothing pins: the header scrolls with its prose */
.lv { position: relative; background: var(--lsurf);
  border-radius: var(--lradius); border-left: 2px solid transparent;
  padding: 0 18px 18px 16px; }
.lv.good { --vc: var(--green); } .lv.warn { --vc: var(--amber); }
.lv.bad { --vc: var(--red); } .lv.dim { --vc: var(--dim); }
/* the spine whispers the state; the badge says it */
.lv.good, .lv.warn, .lv.bad { border-left-color: color-mix(in srgb,
  var(--vc) 40%, var(--lsurf)); }
.lv .vtop { display: flex; align-items: center; gap: 0 10px;
  margin: 0 -18px 4px -16px; padding: 14px 18px 10px 16px; }
.vbadge { width: 24px; height: 24px; flex-shrink: 0; border-radius: 50%;
  border: 1.5px solid currentColor; color: var(--vc, var(--dim));
  background: none; display: grid; place-items: center;
  font: 700 13px/1 Geist, Inter, system-ui, sans-serif; }
.vbadge svg { width: 12px; height: 12px; }
.vtitle { min-width: 0; font: 600 17px/1.2 Geist, Inter, system-ui, sans-serif;
  color: var(--text); }
.vsub { margin-left: auto; flex-shrink: 0; max-width: 45%; font-size: 13px;
  color: var(--dim); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-variant-numeric: tabular-nums; }
.vsub:empty { display: none; }
/* the judge's misconception: the first line of the body, aligned with
   the title (badge 24 + gap 10). Read once at landing, then it scrolls
   away with the prose; a miss is a state, not a banner */
.vmis { margin: 0 0 10px 34px; max-width: 60ch;
  font: 400 13px/1.45 Geist, Inter, system-ui, sans-serif; color: var(--dim);
  text-wrap: pretty; }

/* tutor prose: one step above the stem's size, a single newline is a
   paragraph (both marked and smd emit <br> for it; the br becomes a gap) */
.lv .md { font: 400 18px/1.6 Newsreader, "Source Serif 4", Georgia, serif;
  color: var(--lprose); }
/* the measure sits on the text blocks (smd streams into a .mtail wrapper),
   so a code band can span the card */
.lv .md > :not(pre, .mtail), .lv .md > .mtail > :not(pre) {
  max-width: 66ch; }
.lv .md p { margin: 0 0 10px; text-wrap: pretty; }
.lv .md p:last-child { margin-bottom: 0; }
.lv .md p br { display: block; content: ""; margin-bottom: 10px; }
.lv .md h1, .lv .md h2, .lv .md h3 { font: 600 15px/1.3 Geist, Inter, system-ui,
  sans-serif; margin: 14px 0 6px; color: var(--text); text-wrap: balance; }
.lv .md h1:first-child, .lv .md h2:first-child,
.lv .md h3:first-child { margin-top: 0; }
.lv .md ul, .lv .md ol { margin: 4px 0 10px; padding-left: 20px; }
.lv .md li { margin-bottom: 4px; padding-left: 2px; }
.lv .md li::marker { color: var(--dim); }
.lv .md code { font: 500 13.5px "JetBrains Mono", ui-monospace, "SF Mono",
  Menlo, monospace; background: rgba(255,255,255,.07); padding: 1px 5px;
  border-radius: 4px; }
.lv .md a { color: var(--accent); text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--accent) 40%, transparent);
  text-underline-offset: 2px; }
.lv .md hr { border: none; border-top: 1px solid var(--lhair); margin: 12px 0; }
.lv .md blockquote { margin: 4px 0 10px; padding: 2px 0 2px 12px;
  border-left: 2px solid var(--lhair); color: var(--dim); }
/* tutor code: a band to the card's edges; each line is a .ln (rebuilt by
   learnCodeBands) that wraps with a hanging indent, so a long comment's
   tail hangs under its code instead of dropping to column 0 */
.lv .md pre { margin: 10px -18px 10px -16px; padding: 12px 18px 12px 16px;
  border: 0; border-radius: 0; background: var(--lcodebg); }
.lv .md pre .ln { display: block; min-height: 1.7em;
  padding-left: calc(var(--i, 0ch) + 4ch);
  text-indent: calc(-1 * (var(--i, 0ch) + 4ch)); }
.lv .md pre code { display: block; padding: 0; min-width: 0;
  background: none; border: 0; color: var(--lmuted);
  font: 500 13.5px/1.7 "JetBrains Mono", ui-monospace, "SF Mono", Menlo,
    monospace;
  white-space: pre-wrap; overflow-wrap: anywhere; overflow-x: visible;
  tab-size: 4;
  --tok-kw: color-mix(in srgb, #c678dd 75%, var(--text));
  --tok-str: color-mix(in srgb, #98c379 75%, var(--text));
  --tok-num: color-mix(in srgb, #d19a66 75%, var(--text));
  --tok-bi: color-mix(in srgb, #61afef 75%, var(--text));
  --tok-com: var(--dim); }
/* the one thing to act on, last: a tinted line in the verdict colour */
.lv .fixline { display: flex; gap: 10px; align-items: baseline; margin: 14px 0 0;
  padding: 10px 12px; border-radius: 10px;
  background: color-mix(in srgb, var(--vc, var(--dim)) 8%, transparent);
  font: 500 15px/1.5 Geist, Inter, system-ui, sans-serif; color: var(--text);
  max-width: 66ch; }
.lv .lfix.hidden { display: none; }
.lv .md.hidden { display: none; }

/* the model answer, open, and the why under it: a section of the verdict
   (hairline across the card, mono label), never a box in it */
.lreveal { margin: 18px -18px 0 -16px; padding: 14px 18px 0 16px;
  border-top: 1px solid var(--lhair); }
.lreveal.hidden { display: none; }
.lreveal > * { max-width: 66ch; }
.llabel { display: block; font: 600 11px/1 "JetBrains Mono", ui-monospace,
  monospace; letter-spacing: .06em; text-transform: uppercase;
  color: var(--dim2); margin-bottom: 10px; }
.lans { margin: 0; font: 400 18px/1.6 Newsreader, "Source Serif 4", Georgia, serif;
  color: var(--lprose); white-space: pre-line; text-wrap: pretty; }
ol.lans { list-style: none; padding: 0; display: flex;
  flex-direction: column; gap: 8px; white-space: normal; }
.lans li { display: grid; grid-template-columns: 2.2ch 1fr; gap: 0 4px; }
.lans li b { font-weight: 600; color: var(--dim2); }
.lans.short { font: 600 17px/1.5 Geist, Inter, system-ui, sans-serif;
  color: var(--text); }
.lexp { margin-top: 12px; font: 400 14.5px/1.6 Geist, Inter, system-ui, sans-serif;
  color: var(--lmuted); }
.lexp p { margin: 0 0 6px; text-wrap: pretty; }
.lexp p:last-child { margin-bottom: 0; }

/* moments and states in the thread: lines and blocks, no pills */
.lload { font-size: 14px; color: var(--dim); padding: 4px 0; }
/* exam mode shares .lload for its intro and done screens: keep its look */
#examcol .lload { align-self: center; font-size: 12px;
  animation: cardin .25s cubic-bezier(.2,.7,.3,1); }
.ldone { max-width: 44rem; }
.ldone .t { font: 450 17px/1.55 Geist, Inter, system-ui, sans-serif;
  color: var(--lstem); margin: 0 0 6px; }
.ldone .s { font-size: 14px; line-height: 1.5; color: var(--dim); margin: 0; }
/* composer: a ghost bar that recedes; lilac only on the armed send disc.
   Give up sits above the disc and leaves once you type */
.inputwrap.learninput { flex-shrink: 0; max-width: none;
  padding: 4px max(16px, calc((100% - 820px) / 2))
    calc(8px + env(safe-area-inset-bottom, 0px) + var(--kb, 0px)
      + var(--kbx, 0px));   /* --kb: the iOS band; --kbx: a keyboard on its way */
  /* the thread reserves a classic scrollbar's width; the composer
     reserves the same, so the cards and the bar share a right edge */
  padding-right: calc(max(16px, (100% - 820px) / 2) + var(--lgutter, 0px)); }
/* nothing veils the thread above the box: the chat's fade band is off */
.inputwrap.learninput::before { display: none; }
/* two rows, like the chat's composer: the field and Give up on top, the
   disc below. The recessed fill marks the field; the hairline only finds
   its edge */
.lbar { display: flex; flex-direction: column; gap: 0;
  padding: 2px 6px 4px;
  background: color-mix(in srgb, var(--lcomposer) 60%, transparent);
  -webkit-backdrop-filter: blur(20px) saturate(1.2);
  backdrop-filter: blur(20px) saturate(1.2);
  /* the edge: a thin light hairline on top and the sides, a thicker one
     along the bottom (Claude's bevel), a deep soft shadow below */
  border: 1px solid rgba(255,255,255,.07);
  border-bottom: 2px solid rgba(255,255,255,.1); border-radius: 20px;
  box-shadow: 0 10px 28px rgba(0,0,0,.45),
    inset 0 1px 0 rgba(255,255,255,.04);
  transition: opacity .2s; }
.lbar .lrow1 { display: flex; align-items: flex-start; gap: 2px; }
.lbar .lrow2 { display: flex; align-items: center; justify-content: flex-end; }
/* the two quiet actions of an open question: Answer at the far left,
   Skip beside the disc. Small ghost pills, out while the field is empty,
   faded once you type (then the disc is the one lit thing) */
.lbar .lact { height: 25px; padding: 0 10px; border: 0; border-radius: 13px;
  background: none; box-shadow: inset 0 0 0 .5px rgba(255,255,255,.14);
  color: color-mix(in srgb, var(--dim) 72%, transparent);
  font: 500 11.5px/1 Geist, Inter, system-ui, sans-serif;
  flex-shrink: 0; cursor: pointer; opacity: 0; visibility: hidden;
  transition: opacity .15s, visibility .15s, background .15s, color .15s; }
.lbar.ask .lact { opacity: 1; visibility: visible; }
.lbar .lanswer { margin-right: auto; margin-left: 2px; }
.lbar .lskip { margin-right: 8px; }
.lbar .lact:hover { background: rgba(255,255,255,.05); color: var(--dim2); }
.lbar .lact:active { background: rgba(255,255,255,.1); color: var(--text); }
/* the disc rests while the field is empty: dimmed as a solid colour, the
   arrow waiting, not greyed out as a disabled control */
.lbar.ask .sendbtn:disabled { opacity: 1;
  background: color-mix(in srgb, var(--accent) 34%, var(--lcomposer));
  color: color-mix(in srgb, #fff 60%, var(--lcomposer)); }
.lbar.busy { opacity: .6; }
.lbar textarea { flex: 1; min-width: 0; border: 0; background: none;
  color: var(--text); font: 15px/22px Geist, Inter, system-ui, sans-serif;
  padding: 12px 10px 3px 12px; min-height: 50px; max-height: 140px;
  resize: none; outline: none; }
.lbar textarea::placeholder { color: var(--dim); opacity: 1; }
/* the disc: Send (up arrow) once you type; while a follow-up field is
   empty it widens into a Next pill with the word, and back as you type */
.lbar .sendbtn { width: 36px; height: 36px; border: 0; border-radius: 18px;
  background: var(--accent); color: #fff; display: grid;
  grid-template-columns: auto auto; place-content: center;
  place-items: center; flex-shrink: 0; cursor: pointer; opacity: 1;
  transition: opacity .15s, width .2s ease-out, background .2s,
    color .2s, box-shadow .2s; }
.lbar .sendbtn:hover { filter: brightness(1.15); }
.lbar .sendbtn:disabled { opacity: .3; cursor: default; filter: none; }
.lbar .sendbtn svg { grid-area: 1 / 2; transition: opacity .15s; }
.lbar .sendbtn .fwd { opacity: 0; }
.lbar .sendbtn .nl { grid-area: 1 / 1; max-width: 0;
  opacity: 0; overflow: hidden; white-space: nowrap;
  font: 600 14px/1 Geist, Inter, system-ui, sans-serif;
  transition: max-width .2s ease-out, opacity .15s, margin .2s; }
.lbar .sendbtn.next { width: 84px; }
.lbar .sendbtn.next .fwd { opacity: 1; }
.lbar .sendbtn.next .up { opacity: 0; }
.lbar .sendbtn.next .nl { max-width: 84px; opacity: 1; margin-right: 6px; }
.lbar.hidden, .lnext.hidden { display: none; }
/* after a verdict the slot changes role: one row, follow-up left, the
   primary filling the rest, so Next is always one thumb away */
.lnext { display: flex; align-items: center; gap: 8px; min-height: 48px; }
.lfollow { flex-shrink: 0; height: 48px; padding: 0 12px; border: 0;
  background: none; font: 500 14px/1 Geist, Inter, system-ui, sans-serif;
  color: var(--dim); border-radius: 999px; cursor: pointer; }
.lfollow:hover { color: var(--text); }
.lfollow.hidden { display: none; }
.lprimary { flex: 1; height: 48px; border: 0; border-radius: 24px;
  white-space: nowrap; min-width: 0;
  font: 600 15px/1 Geist, Inter, system-ui, sans-serif; color: var(--accent2);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  display: flex; align-items: center; justify-content: center; gap: 8px;
  cursor: pointer; transition: background .15s; }
.lprimary:hover { background: color-mix(in srgb, var(--accent) 24%,
  transparent); }
.lprimary .kbd { display: none; font: 500 12px/1 "JetBrains Mono",
  ui-monospace, monospace; opacity: .7; }

/* ---- home: the ladder. One list, one edge, one accent strip ---- */
.lcont { display: flex; align-items: center; gap: 12px; width: 100%;
  min-height: 56px; margin: 4px 0 0; padding: 8px 14px 8px 16px;
  border: 0; border-radius: var(--lradius); text-align: left;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  color: var(--accent2); cursor: pointer; font-family: inherit; }
.lcont .tt { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.lcont .llabel { color: var(--accent2); opacity: .8; margin-bottom: 5px; }
.lcont .t { font: 600 15px/1.3 Geist, Inter, system-ui, sans-serif;
  color: var(--text); }
.lcont .s { font: 500 13px/1.4 Geist, Inter, system-ui, sans-serif;
  color: var(--accent2); margin-top: 2px; }
.lcont .chev { flex-shrink: 0; color: var(--accent2); }
.lsec { margin: 0; }
.lsechead { display: flex; align-items: center; gap: 12px; width: 100%;
  margin: 0; min-height: 36px; padding: 4px 2px; border: 0;
  border-top: 1px solid var(--lhair); background: none; cursor: pointer;
  text-align: left; transition: background .15s; }
.lsechead:hover { background: rgba(255,255,255,.025); }
.lsechead .no { flex-shrink: 0; width: 20px; position: relative;
  font: 500 12px/1 "JetBrains Mono", ui-monospace, monospace;
  color: var(--dim); font-variant-numeric: tabular-nums; }
.lsechead .t { flex: 1; min-width: 0; color: var(--text);
  font: 400 14.5px/1.3 Geist, Inter, system-ui, sans-serif; white-space: normal;
  overflow-wrap: break-word; hyphens: auto; hyphenate-limit-chars: 18 5 5; }
.lsechead .s { flex-shrink: 0; min-width: 34px; text-align: right;
  font-size: 13px; color: var(--dim); font-variant-numeric: tabular-nums; }
.lsechead.done .s, .lsechead.done .no { color: var(--green); }
/* walked: every topic passed, some questions skipped for later. Accent,
   not green: the chapter is through, not done */
.lsechead.walked .s, .lsechead.walked .no { color: var(--accent2); }
.lsechead .pbar { flex-shrink: 0; width: 44px; height: 2px; display: flex;
  border-radius: 2px; background: rgba(255,255,255,.07); overflow: hidden; }
.lsechead .pbar i { display: block; height: 100%;
  background: color-mix(in srgb, var(--accent) 60%, transparent); }
.lsechead.done .pbar i { background: color-mix(in srgb, var(--green) 65%,
  transparent); }
.lsechead .chev { color: var(--dim2); flex-shrink: 0;
  transition: transform .18s; }
.lsechead.open .chev { transform: rotate(90deg); }
/* the current chapter: accent title and a 6px dot, no wash, no pill */
.lsechead.here .t, .lsechead.here .no { color: var(--accent2); }
.lsechead.here .no::before { content: ""; position: absolute; left: -11px;
  top: 50%; width: 6px; height: 6px; margin-top: -3px; border-radius: 50%;
  background: var(--accent); }
.lsecbody { padding: 0 0 8px; }
.lsecbody.hidden, .lqfold.hidden, .lflagsbody.hidden { display: none; }
.ltrainbig { display: inline-flex; align-items: center; gap: 5px;
  min-height: 40px; margin: 0 0 0 32px; padding: 0 2px; border: 0;
  background: none; color: var(--accent2);
  font: 600 14px/1 Geist, Inter, system-ui, sans-serif; cursor: pointer;
  font-family: inherit; }
.ltrainbig span { color: var(--dim); }
.ltrainbig.lclear { color: var(--accent2); }
/* the group of what is not done yet: Revisit and Skipped, both served
   easiest first */
.lgrouphead { padding: 8px 2px 4px;
  font: 600 11px/1 "JetBrains Mono", ui-monospace, monospace;
  letter-spacing: .06em; text-transform: uppercase; color: var(--dim); }
.ltrainbig:hover { color: var(--text); }
.lrow { display: flex; align-items: center; gap: 12px; min-height: 48px;
  padding: 6px 2px 6px 32px; border: 0; border-top: 1px solid var(--lhair);
  border-radius: 0; cursor: pointer; transition: background .15s; }
.lrow:hover { background: rgba(255,255,255,.025); }
.lnum { flex-shrink: 0; width: 34px; padding: 0; border: 0;
  text-align: left; font: 500 12px/1 "JetBrains Mono", ui-monospace,
  monospace; color: var(--dim); font-variant-numeric: tabular-nums; }
/* names keep their words: only a word of 18+ letters, one that cannot
   fit a 146px line on its own, is hyphenated (lang="nl"); shorter ones
   move to the next line whole */
.lrow .nm { flex: 1; min-width: 0; color: var(--text);
  font: 400 14.5px/1.35 Geist, Inter, system-ui, sans-serif; white-space: normal;
  overflow-wrap: break-word; hyphens: auto; hyphenate-limit-chars: 18 5 5; }
/* mastery: green share; a tried-but-uncleared topic is amber at 40%, never red */
.mbar { flex-shrink: 0; width: 44px; height: 2px; border-radius: 2px;
  display: flex; background: rgba(255,255,255,.07); overflow: hidden; }
/* the skipped share of a row's bar, in the accent: out of the way, not done */
.lsechead .pbar i.sk, .mbar i.sk {
  background: color-mix(in srgb, var(--accent2) 55%, transparent); }
.mbar i { display: block; height: 100%;
  background: color-mix(in srgb, var(--green) 65%, transparent); }
.mbar.none i { background: color-mix(in srgb, var(--amber) 40%, transparent); }
.lrow .lc { flex-shrink: 0; min-width: 34px; text-align: right;
  font-size: 13px; color: var(--dim); font-variant-numeric: tabular-nums; }
.lrow .lc.done { color: var(--green); }
.lrow .lc.walked, .lrow .lc .lt { color: var(--accent2); }
.lrow .lc .lt { font-weight: 500; }
.lrow .lc .wk { color: var(--red); font-weight: 500; }
.lrow .chev { color: var(--dim2); flex-shrink: 0; opacity: .7;
  transition: transform .18s; }
.lrow.open .chev { transform: rotate(90deg); }
.lrow.here .nm { color: var(--accent2); }
.lqfold { margin: 0 0 8px 32px; padding: 0; border: 0; background: none; }
.lqfold .ltrainbig { margin: 0; }
.lqrow { display: flex; align-items: flex-start; gap: 10px; min-height: 44px;
  padding: 10px 2px; border-top: 1px solid var(--lhair); color: var(--dim2);
  font: 400 14px/1.45 Geist, Inter, system-ui, sans-serif; }
.lqrow .qt { flex: 1; min-width: 0; white-space: normal;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; }
.lqrow.link { cursor: pointer; }
.lqrow.link:hover { color: var(--text); }
.lqrow .mark { flex-shrink: 0; width: 14px; text-align: center;
  font-weight: 700; }
.lqrow .mark.good { color: var(--green); }
.lqrow .mark.mid { color: var(--amber); }
.lqrow .mark.bad { color: var(--red); }
.lqrow .mark.dim { color: var(--dim); opacity: .5; }
.lqrow .mark.later, .lqrow .qtag.later { color: var(--accent2); }
.lqrow .qd { flex-shrink: 0; font-size: 12px; color: var(--dim); }
.lqrow .qd .wk { color: var(--red); }
.lqrow .qtag { font-size: 11px; font-weight: 600; color: var(--dim);
  margin-left: 6px; }
/* a split A/B/C question: the intro once, its parts indented under it */
.lqgroup { padding: 10px 2px 2px; border-top: 1px solid var(--lhair);
  color: var(--dim2); font: 500 14px/1.45 Geist, Inter, system-ui, sans-serif; }
.lqgroup .qn { color: var(--dim); font-weight: 600; }
.lqrow.part { border-top: 0; min-height: 36px; padding: 5px 2px 5px 18px; }
.lqrow.part + .lqrow:not(.part), .lqrow.part + .lqgroup { margin-top: 5px; }
.ldempty, .lempty { font-size: 13px; line-height: 1.5; color: var(--dim);
  padding: 10px 2px; }
.loptnote { font-size: 13px; line-height: 1.5; color: var(--dim);
  padding: 6px 2px 10px 32px; }
/* the quiet rows: exam practice at the top, what is waiting on you under
   the chapters */
.lsub { margin-top: 8px; border-bottom: 1px solid var(--lhair); }
.lsub.hidden { display: none; }
.lsub + .lsub { margin-top: 2px; }
.lrowq { display: flex; align-items: center; gap: 12px; width: 100%;
  min-height: 42px; padding: 5px 2px; border: 0;
  border-top: 1px solid var(--lhair); background: none; text-align: left;
  color: var(--text); cursor: pointer; font-family: inherit;
  transition: background .15s; }
.lrowq:hover { background: rgba(255,255,255,.025); }
.lrowq:disabled { opacity: .5; cursor: default; }
.lrowq:disabled:hover { background: none; }
.lrowq .no { flex-shrink: 0; width: 20px; font-size: 13px; color: var(--dim); }
.lrowq .t { flex: 1; min-width: 0; color: var(--dim2);
  font: 400 15px/1.35 Geist, Inter, system-ui, sans-serif; }
.lrowq .t small { display: block; font-size: 13px; color: var(--dim);
  margin-top: 2px; }
.lrowq small .tg { color: var(--amber); }
.lrowq .rbar { display: flex; gap: 2px; height: 4px; width: 120px;
  border-radius: 2px; overflow: hidden; margin-top: 7px; }
.lrowq .rbar i { display: block; height: 100%; }
.lrowq .rbar i.w { background: color-mix(in srgb, var(--red) 65%, transparent); }
.lrowq .rbar i.g { background: color-mix(in srgb, var(--amber) 70%, transparent); }
.lrowq.quiet { opacity: .6; cursor: default; }
.lrowq .chev { color: var(--dim2); flex-shrink: 0; transition: transform .18s; }
.lrowq.open .chev { transform: rotate(90deg); }
.lrowq.hidden { display: none; }
.lflagrow { display: flex; align-items: center; gap: 10px; min-height: 44px;
  padding: 8px 2px 8px 32px; border-top: 1px solid var(--lhair);
  cursor: pointer; }
.lflagrow:hover { background: rgba(255,255,255,.025); }
.lflagrow .qcol { flex: 1; min-width: 0; }
.lflagrow .qt { font-size: 14px; line-height: 1.45; color: var(--text);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; }
.lflagrow .qt .no { color: var(--dim2); font-weight: 600; margin-right: 4px; }
.lflagrow .qc { font: 400 12px/1.5 "JetBrains Mono", ui-monospace,
  monospace; color: var(--dim2); margin-top: 2px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.lflagrow .ct { flex-shrink: 0; max-width: 26%; font-size: 12px;
  color: var(--dim); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.lflagrow .unflag { flex-shrink: 0; min-height: 40px; padding: 0 10px;
  border: 0; background: none; font: 600 13px/1 Geist, Inter, system-ui,
  sans-serif; color: var(--dim); border-radius: 999px; cursor: pointer; }
.lflagrow .unflag:hover { color: var(--flag); }
#lflagshead .no { color: var(--flag); }

/* ---- motion: two motions, both explain a change ---- */
@media (prefers-reduced-motion: no-preference) {
  .lq { animation: lin .2s ease-out; }
  .lv .vtop.vin > * { animation: lin .2s ease-out; }
  .vbadge.wait { animation: lpulse 1.2s ease-in-out infinite; }
  .learnmain.stale > * { transition: opacity .15s; }
  .lreveal, .lnext, .lbar, .lmine, .lmodel, .lfoot
    { animation: lfade .15s ease-out; }
}
@keyframes lin { from { opacity: 0; transform: translateY(4px); } }
@keyframes lfade { from { opacity: 0; } }
@keyframes lpulse { 50% { opacity: .45; } }
/* the stream itself is the motion; no per-character fade in learn */
#learncol .charfade { animation: none; }

/* ---- widths ---- */
@media (max-width: 640px) {
  .learnhome { padding: 8px 16px 32px; }
  /* a phone header: tighter slots so the course title keeps its words */
  .learnhead .ltitle { padding: 0 6px; }
  .learnhead .ltext { padding: 0 10px 0 8px; gap: 6px; }
  /* ladder rows: a slimmer right cluster gives the names their words */
  .lrow, .lsechead { gap: 10px; }
  .mbar, .lsechead .pbar { width: 36px; }
  .lrow .lc, .lsechead .s { min-width: 30px; }
  /* the code slab goes full bleed: 398px of code, 49 columns at 13.5px */
  /* the slab runs edge to edge; the code inside sits inset from the
     question text, toward the middle, as it did before the redesign */
  .lq .qcode { margin: 10px -16px -10px; padding: 10px 20px 10px 32px;
    border-radius: 0; }
}
@media (max-width: 399px) {
  /* the narrowest phones: the header's one action keeps its word (a bare
     list glyph echoes the menu, a bare arrow says nothing), so the course
     name ellipsizes instead */
  .learnhead .ltitle { font-size: 14px; }
  .learnhead .ltext { padding: 0 8px 0 6px; gap: 5px; }
}
@media (max-width: 479px) {
  /* a topic's count, skipped and to-retry stack, so the name keeps room */
  .lrow .lc .sep { display: none; }
  .lrow .lc .wk, .lrow .lc .lt { display: block; line-height: 1.3; }
}
@media (min-width: 901px) {
  /* anchored, not centred: the stem starts on the same line for every
     question and the composer is pinned, so nothing re-aims. The anchor
     is the first child's margin, not scroller padding, so the verdict's
     landing still meets the top */
  .learnmain > :first-child { margin-top: clamp(36px, 10vh, 72px); }
  /* the answer box follows the question: the thread is as tall as its
     content (up to the screen), so a fresh question puts the box right
     under the stem, where your own words stay beside what they answer.
     A long verdict fills the screen and the bar rests at the bottom as
     before */
  .learnmain { flex: 0 1 auto; padding-bottom: 22px; }
  .inputwrap.learninput { padding-top: 14px; padding-bottom: 28px; }
  /* the same two rows, with a taller writing field */
  .lbar { padding: 6px 8px; }
  .lbar textarea { min-height: 68px; max-height: 240px;
    padding: 10px 10px 4px; font-size: 16px; line-height: 26px; }
  .lq .qstem { font-size: 16.5px; }
  .ldone .t { font-size: 18px; }
  .lq .qcode code { font-size: 14px; }
  .lv .md, .lans { font-size: 19px; }
  .lans.short { font-size: 18px; }
  .lexp { font-size: 15px; }
  .lprimary .kbd { display: inline; }
  /* a pill the width of the column reads heavier than the chrome */
  .lprimary { max-width: 360px; margin-left: auto; }
  .lv { margin-top: 8px; }
}

/* the header line: the skipped count in the accent */

/* a walked topic's own way to finish, above Train this topic */
.lqfold .lfinish { display: flex; }

/* the right/wrong tally of a question ever got wrong: ✗ in red, ✓ in
   yellow until it is known, then green; an unknown question carries the
   ✗ a little stronger */
.lqrow .qd .tally, .lq .qstate .qtally { display: inline-flex; gap: 6px;
  font: 500 11.5px/1 "JetBrains Mono", ui-monospace, monospace;
  font-variant-numeric: tabular-nums; }
.lqrow .qd .tally .x, .lq .qstate .qtally .x {
  color: color-mix(in srgb, var(--red) 75%, transparent); }
.lqrow .qd .tally .v, .lq .qstate .qtally .v {
  color: color-mix(in srgb, var(--amber) 80%, transparent); }
.lqrow .qd .tally.known .v, .lq .qstate.known .qtally .v {
  color: color-mix(in srgb, var(--green) 75%, transparent); }
.lqrow .qd .tally.unknown .x { color: var(--red); }
.lq .qstate .qtally { margin-left: 1px; padding-left: 7px;
  border-left: .5px solid rgba(255,255,255,.12); }
/* on a question the tally stays as dim as its chip */
.lq .qstate .qtally .x, .lq .qstate .qtally .v,
.lq .qstate.known .qtally .v { color: var(--faint); }
/* the Recall row: unknown in red, familiar in yellow */
.lrowq small .tw { color: var(--red); }

/* ---- multiple choice: the mode and the drills ----
   Learn's canvas, header, and home rows; one card per question with four
   full-width option rows. A verdict colours the rows, nothing else moves */
.mcstreak { flex-shrink: 0; padding: 0 6px; white-space: nowrap;
  font: 500 13px/1 Geist, Inter, system-ui, sans-serif; color: var(--dim); }
.mcstreak b { color: var(--text); font-weight: 600;
  font-variant-numeric: tabular-nums; display: inline-block; }
.mcstreak.hot b { color: var(--amber); }
.mcstreak.hidden { display: none; }
#examcol .learnhead .ltitle { font-size: 15px; }
.mcmain { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
  scrollbar-gutter: stable; position: relative;
  padding: 12px max(16px, calc((100% - 820px) / 2)) 40px; }
.mcmain > .empty { padding: 40px 0; text-align: center; color: var(--dim);
  font: 400 14.5px/1.5 Geist, Inter, system-ui, sans-serif; }
.mchome .lcont .llabel { padding: 0; margin-bottom: 6px; }
.mchome .lsecbody .ltrainbig { margin-bottom: 2px; }
.mchome .lrow.mcex { padding-right: 2px; }
.mcqrow { cursor: pointer; }
.mcqrow .mark { flex-shrink: 0; width: 14px; text-align: center;
  color: var(--dim); font: 500 12px/1.45 "JetBrains Mono", ui-monospace, monospace; }
.mcqrow.ok .mark { color: var(--green); }
.mcqrow.bad .mark { color: var(--red); }
.mcqrow:hover { background: rgba(255,255,255,.025); }
/* a switch row: the label left, a 36px track right */
.mcreset { min-height: 44px; padding: 0 2px; border: 0; background: none;
  font: 500 13px/1 Geist, Inter, system-ui, sans-serif; color: var(--dim);
  cursor: pointer; }
@media (hover: hover) { .mcreset:hover { color: var(--red); } }
/* on a phone the card sits low, where the thumb rests: the rows at the
   bottom of the screen and the question just above them. A slot under the
   rows keeps the key's why and Next from pushing them up on a miss */
@media (max-width: 700px) {
  .mcmain:has(> .mccard:not(.out)) { display: flex; flex-direction: column; }
  .mccard { margin-top: auto; padding-bottom: 96px; }
  .mccard:has(.mcfoot) { padding-bottom: 0; }
  .mcfoot { min-height: 80px; justify-content: flex-start; }
}

/* the card: the question in learn's serif, then the rows */
.mccard { display: flex; flex-direction: column; gap: 16px;
  max-width: 44rem; transition: opacity .18s ease-out, transform .18s ease-out; }
.mccard.in { opacity: 0; transform: translateX(24px); }
.mccard.out { position: absolute; left: max(16px, calc((100% - 820px) / 2));
  right: max(16px, calc((100% - 820px) / 2)); opacity: 0;
  transform: translateX(-24px); pointer-events: none; }
.mcmeta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 7px;
  font: 500 12px/1.4 "JetBrains Mono", ui-monospace, monospace;
  color: var(--dim); font-variant-numeric: tabular-nums; }
.mcmeta { justify-content: space-between; flex-wrap: nowrap; }
.mcmeta .w { min-width: 0; overflow-wrap: anywhere; }
.mcmeta .n { flex-shrink: 0; white-space: nowrap; color: var(--dim2); }
.mcmeta .d { color: var(--dim2); opacity: .5; }
.mcmeta .again, .ldstage .again { color: var(--amber); }
/* the Terms round before a chapter or topic: over the learn session, the
   composer out of reach */
.ldrill { position: absolute; inset: 0; z-index: 8; background: var(--chatbg);
  display: flex; flex-direction: column; animation: crumbswap .2s ease-out;
  transition: opacity .2s; }
.ldrill.out { opacity: 0; pointer-events: none; }
.ldrill.hidden { display: none; }
.ldhead { display: flex; align-items: center; gap: 10px; min-height: 44px;
  padding: 4px max(16px, calc((100% - 820px) / 2)) 0; }
.ldhead .t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font: 500 13px/1.2 Geist, Inter, system-ui, sans-serif;
  color: var(--accent2); }
.ldhead .n { flex-shrink: 0; font: 500 12px/1 "JetBrains Mono", ui-monospace, monospace;
  color: var(--dim); font-variant-numeric: tabular-nums; }
.ldskip { flex-shrink: 0; height: 40px; padding: 0 4px 0 8px; border: 0;
  background: none; font: 600 14px/1 Geist, Inter, system-ui, sans-serif;
  color: var(--dim2); cursor: pointer; }
.ldskip:hover { color: var(--text); }
.ldprog { height: 2px; margin: 4px max(16px, calc((100% - 820px) / 2)) 0;
  background: rgba(255,255,255,.06); border-radius: 2px; overflow: hidden; }
.ldprog i { display: block; height: 100%; width: 0; background: var(--accent);
  opacity: .6; transition: width .25s ease-out; }
.ldstage { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
  position: relative; padding: 20px max(16px, calc((100% - 820px) / 2)) 24px;
  display: flex; flex-direction: column; }
/* low, where the thumb is, but a little clear of the bottom edge */
.ldstage .mccard { margin-top: auto; padding-bottom: max(72px, 16vh); }
.ldstage .mcdone .t { color: var(--accent2); margin-top: auto; }
.mcstem { font: 400 16.5px/1.55 Literata, "Source Serif 4", Georgia, serif;
  color: var(--lstem); white-space: pre-line; text-wrap: pretty; }
.mccard .qcode { margin: 0; }
.mcopts { display: flex; flex-direction: column; gap: 8px; }
.mcopt { display: flex; align-items: center; gap: 14px; width: 100%;
  min-height: 56px; padding: 10px 14px; border: 0; border-radius: var(--lradius);
  background: var(--lsurf); box-shadow: inset 0 0 0 1px var(--lhair);
  color: var(--text); text-align: left; cursor: pointer;
  font: 400 15px/1.4 Geist, Inter, system-ui, sans-serif;
  transition: background .15s, box-shadow .15s, opacity .2s, color .15s; }
@media (hover: hover) {
  .mcopt:hover:not(:disabled) { background: color-mix(in srgb, var(--lsurf) 85%, white); }
}
.mcopt:active:not(:disabled) { background: color-mix(in srgb, var(--lsurf) 80%, white); }
.mcopt .k { flex-shrink: 0; width: 24px; height: 24px; border-radius: 7px;
  display: grid; place-items: center; box-shadow: inset 0 0 0 1px rgba(255,255,255,.14);
  font: 500 12px/1 "JetBrains Mono", ui-monospace, monospace; color: var(--dim); }
.mcopt .o { flex: 1; min-width: 0; white-space: pre-line; overflow-wrap: anywhere; }
/* an exam-style list option (four bracketed items) reads smaller, so the
   four rows still fit a phone */
.mcopt.long { font-size: 13.5px; line-height: 1.4; padding: 9px 12px; }
.mcopt.long .o { max-width: 100%; }
.mcopt:disabled { cursor: default; }
.mcopt.right { color: var(--text);
  background: color-mix(in srgb, var(--green) 14%, var(--lsurf));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--green) 55%, transparent); }
.mcopt.right .k { background: var(--green); color: #0c130e; box-shadow: none; }
.mcopt.wrong { background: color-mix(in srgb, var(--red) 12%, var(--lsurf));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--red) 55%, transparent); }
.mcopt.wrong .k { color: var(--red);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--red) 60%, transparent); }
.mcopt.dim { opacity: .4; }
.mcfoot { display: flex; flex-direction: column; gap: 14px; padding-top: 2px;
  animation: crumbswap .25s ease-out; }
.mcwhy { margin: 0; padding-left: 14px;
  border-left: 2px solid color-mix(in srgb, var(--green) 60%, transparent);
  font: 400 15px/1.55 Geist, Inter, system-ui, sans-serif; color: var(--lmuted); }
.mcwhy.mcerr { border-left-color: color-mix(in srgb, var(--red) 60%, transparent); }
.mcfoot .lprimary { flex: none; width: 100%; }
/* a miss in a run: the bar drains over the dwell, then the next card
   comes; the whole card is a tap target to go on now */
.mccard.flow { cursor: pointer; }
.mcwait { display: block; height: 3px; border-radius: 2px;
  background: color-mix(in srgb, var(--text) 28%, transparent);
  transform-origin: left; animation: mcdrain linear forwards; }
@keyframes mcdrain { from { transform: scaleX(1); } to { transform: scaleX(0); } }
@media (min-width: 901px) {
  .mcfoot .lprimary { width: auto; align-self: flex-start; padding: 0 22px; }
  .mcfoot .lprimary .kbd { display: inline; }
}
/* a true/false statement: one sentence large, two buttons under it. The
   verdict colours the word in the hole: green when it was the right one,
   red and struck through with the right word in green after it */
.tfstmt { font: 400 21px/1.45 Literata, "Source Serif 4", Georgia, serif;
  color: var(--lstem); text-wrap: pretty; padding: 6px 0 10px; }
.ldstage .tfstmt { font-size: 19px; }
.tfstmt .slot { border-radius: 4px; padding: 0 3px; margin: 0 -3px;
  transition: background .15s, color .15s; }
.tfstmt .slot.good, .tfstmt .slot.fix { color: var(--green); font-weight: 600;
  background: color-mix(in srgb, var(--green) 14%, transparent); }
.tfstmt .slot.fix { animation: crumbswap .25s ease-out; }
.tfstmt .slot.bad { color: var(--red); text-decoration: line-through;
  text-decoration-thickness: 1.5px;
  background: color-mix(in srgb, var(--red) 12%, transparent); }
.tfbtns { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.tfbtn { position: relative; display: flex; align-items: center; justify-content: center;
  min-height: 64px; padding: 0 14px; border: 0; border-radius: var(--lradius);
  background: var(--lsurf); box-shadow: inset 0 0 0 1px var(--lhair);
  color: var(--text); cursor: pointer;
  font: 600 17px/1 Geist, Inter, system-ui, sans-serif;
  transition: background .15s, box-shadow .15s, opacity .2s, color .15s; }
.tfbtn .k { position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  width: 22px; height: 22px; border-radius: 6px; display: grid; place-items: center;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.14);
  font: 500 11px/1 "JetBrains Mono", ui-monospace, monospace; color: var(--dim); }
@media (pointer: coarse) { .tfbtn .k { display: none; } }
@media (hover: hover) {
  .tfbtn:hover:not(:disabled) { background: color-mix(in srgb, var(--lsurf) 85%, white); }
}
.tfbtn:active:not(:disabled), .mccard.lean-yes .tfbtn.yes, .mccard.lean-no .tfbtn.no {
  background: color-mix(in srgb, var(--lsurf) 78%, white); }
.tfbtn:disabled { cursor: default; }
.tfbtn.right { background: color-mix(in srgb, var(--green) 16%, var(--lsurf));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--green) 60%, transparent); }
.tfbtn.right .k { background: var(--green); color: #0c130e; box-shadow: none; }
.tfbtn.wrong { background: color-mix(in srgb, var(--red) 13%, var(--lsurf));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--red) 55%, transparent); }
.tfbtn.dim { opacity: .4; }
.tfhint { margin: 0; font: 500 12.5px/1.4 Geist, Inter, system-ui, sans-serif;
  color: var(--dim2); }
/* a Read card: the concept's name and its blocks as a diagram, nothing
   else. A set hangs off a trunk, steps stand numbered with arrows between,
   a term carries its essence (the meaning's cues) as chips, two sides stand
   apart with a divider, a sentence is a chain of its cues with the
   relation on the arrow. A card fades in (.drawn, set by read.js a beat
   after the last one faded out): the lines draw and the cues come up one
   after another in reading order (--i), lit white. Nothing slides */
.rkcard { cursor: pointer; gap: 18px; margin-top: 0; padding-top: 6px;
  touch-action: pan-y; -webkit-user-select: none; user-select: none;
  -webkit-tap-highlight-color: transparent; }
.rkcard .mcmeta, .rktitle, .rkhint { opacity: 0; transition: opacity .3s ease-out; }
.rkcard.drawn .mcmeta, .rkcard.drawn .rktitle, .rkcard.drawn .rkhint { opacity: 1; }
.rkcard.drawn .rkhint { transition-delay: .6s; }
/* the card fills the stage, so the hint rests at the bottom of the screen
   (the swipe and the taps belong to the whole stage, read.js) */
.mcmain:has(> .rkcard) { display: flex; flex-direction: column; }
.mcmain > .rkcard, .ldstage > .rkcard { flex: 1 0 auto; margin-top: 0;
  padding-bottom: env(safe-area-inset-bottom, 0px); }
.mcmain > .rkcard.out, .ldstage > .rkcard.out { flex: none; }
.rktitle { margin: 0; font: 600 23px/1.25 Geist, Inter, system-ui, sans-serif;
  color: var(--text); letter-spacing: -.01em; text-wrap: balance; }
/* the diagram */
.rkdiag { display: flex; flex-direction: column; gap: 22px; }
.rkd { position: relative; }
.rkdlead { margin-bottom: 10px; font: 600 11px/1.3 "JetBrains Mono", ui-monospace, monospace;
  letter-spacing: .07em; text-transform: uppercase; color: var(--accent2);
  opacity: 0; transition: opacity .4s ease-out .2s; }
.drawn .rkdlead { opacity: 1; }
.rkd .rkd-nd, .rkd .rkd-mean { display: inline-block; color: var(--text); opacity: 0; }
.rkd .rkd-nd { padding: 5px 10px; border-radius: 8px; background: var(--lsurf);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 55%, transparent);
  font: 600 16px/1.3 Geist, Inter, system-ui, sans-serif; }
/* a meaning: whole, the cues bright, the words between them dim */
.rkd .rkd-mean { padding: 0 0 0 10px; max-width: 34rem;
  font: 400 15px/1.45 Geist, Inter, system-ui, sans-serif; text-wrap: pretty; }
.rkd .rkd-mean .f { color: var(--dim); text-shadow: none; }
.rkd .rkd-mean b { font-weight: 600; }
.rkd .link { cursor: pointer; text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--accent) 50%, transparent);
  text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
/* the cues come up in reading order, each to white with a short glow */
.drawn .rkd [data-k] { animation: rkin .6s ease-out both;
  animation-delay: min(calc(120ms + var(--i, 0) * 55ms), 900ms); }
@keyframes rkin {
  0% { opacity: 0; color: var(--text); text-shadow: none; }
  50% { opacity: 1; color: #fff; text-shadow: 0 0 22px rgba(255,255,255,.7); }
  100% { opacity: 1; color: #fff; text-shadow: 0 0 16px rgba(255,255,255,.35); }
}
/* a set and the terms: rows on a trunk, a tick to each */
.rkd .rkd-trunk { position: relative; display: flex; flex-direction: column; gap: 8px;
  padding-left: 18px; }
.rkd .rkd-trunk::before { content: ""; position: absolute; left: 0; top: 15px; bottom: 15px;
  width: 1px; background: color-mix(in srgb, var(--accent) 55%, transparent);
  transform: scaleY(0); transform-origin: top; transition: transform .6s ease-out; }
.drawn .rkd .rkd-trunk::before { transform: scaleY(1); }
.rkd .rkd-row { position: relative; display: flex; flex-direction: column;
  align-items: flex-start; gap: 6px; }
.rkd .rkd-row .rkd-tick { position: absolute; left: -18px; top: 15px; width: 14px; height: 1px;
  background: color-mix(in srgb, var(--accent) 55%, transparent);
  transform: scaleX(0); transform-origin: left;
  transition: transform .35s ease-out calc(.2s + var(--r, 0) * 80ms); }
.drawn .rkd .rkd-row .rkd-tick { transform: scaleX(1); }
/* steps: numbered, an arrow draws down to the next */
.rkd .rkd-steps { display: flex; flex-direction: column; }
.rkd .rkd-step { display: flex; align-items: center; gap: 12px; }
.rkd .rkd-num { flex-shrink: 0; width: 22px; height: 22px; border-radius: 7px;
  display: grid; place-items: center;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 60%, transparent);
  font: 500 11px/1 "JetBrains Mono", ui-monospace, monospace; font-style: normal;
  color: var(--accent2); opacity: 0; transition: opacity .3s calc(var(--r, 0) * 120ms); }
.drawn .rkd .rkd-num { opacity: 1; }
.rkd .rkd-ar { display: block; position: relative; height: 18px; margin: 2px 0; }
.rkd .rkd-ar.rel { height: 24px; }
.rkd .rkd-ar b { position: absolute; left: 24px; top: 50%; transform: translateY(-50%);
  font: 500 11.5px/1.2 "JetBrains Mono", ui-monospace, monospace; color: var(--dim);
  letter-spacing: .02em; opacity: 0; transition: opacity .3s calc(.3s + var(--r, 0) * 120ms); }
.rkd.k-chain .rkd-ar b { left: 28px; }
.drawn .rkd .rkd-ar b { opacity: 1; }
.rkd .rkd-ar::before { content: ""; position: absolute; left: 10.5px; top: 0; bottom: 0;
  width: 1px; background: color-mix(in srgb, var(--accent) 55%, transparent);
  transform: scaleY(0); transform-origin: top;
  transition: transform .3s ease-out calc(.1s + var(--r, 0) * 120ms); }
.rkd .rkd-ar::after { content: ""; position: absolute; left: 7px; bottom: 0;
  border: 4px solid transparent; border-bottom: 0;
  border-top: 5px solid color-mix(in srgb, var(--accent) 70%, transparent);
  opacity: 0; transition: opacity .2s calc(.35s + var(--r, 0) * 120ms); }
.drawn .rkd .rkd-ar::before { transform: scaleY(1); }
.drawn .rkd .rkd-ar::after { opacity: 1; }
/* a chain: groups of siblings, an arrow under the first node to the next */
.rkd .rkd-group { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.rkd.k-chain .rkd-ar::before { left: 14px; }
.rkd.k-chain .rkd-ar::after { left: 10.5px; }
/* two sides apart, a divider between them */
.rkd .rkd-sides { display: grid; grid-template-columns: 1fr auto 1fr; gap: 12px;
  align-items: start; }
.rkd .rkd-side { display: flex; flex-direction: column; gap: 8px; align-items: flex-start;
  min-width: 0; }
.rkd .rkd-side .rkd-mean { padding-left: 2px; }
.rkd .rkd-vsl { position: relative; align-self: stretch; width: 20px; display: grid;
  place-items: center; }
.rkd .rkd-vsl::before { content: ""; position: absolute; left: 50%; top: 0; bottom: 0;
  width: 1px; background: color-mix(in srgb, var(--accent) 45%, transparent);
  transform: scaleY(0); transition: transform .5s ease-out .15s; }
.drawn .rkd .rkd-vsl::before { transform: scaleY(1); }
.rkd .rkd-vsl b { position: relative; padding: 4px 0; background: var(--chatbg);
  font: 600 10px/1 "JetBrains Mono", ui-monospace, monospace; color: var(--faint);
  letter-spacing: .06em; opacity: 0; transition: opacity .3s .5s; }
.drawn .rkd .rkd-vsl b { opacity: 1; }
.rkhint { margin: auto 0 0; padding-top: 20px; text-align: center;
  font: 500 12.5px/1.4 Geist, Inter, system-ui, sans-serif; color: var(--faint); }
.rkhint i { font-style: normal; }
.rkhint .p { display: none; }
@media (hover: hover) and (pointer: fine) {
  .rkhint .p { display: inline; }
  .rkhint .t { display: none; }
}
.rkhint kbd { display: inline-grid; place-items: center; min-width: 18px; height: 18px;
  padding: 0 4px; border-radius: 5px; box-shadow: inset 0 0 0 1px var(--lhair);
  font: 500 11px/1 "JetBrains Mono", ui-monospace, monospace; color: var(--dim); }
/* a linked term's card, opened in place as a finished diagram; a tap
   closes it */
.rkpeek { padding: 12px 14px; border-radius: var(--lradius); background: var(--lsurf);
  box-shadow: inset 0 0 0 1px var(--lhair); animation: crumbswap .2s ease-out;
  display: flex; flex-direction: column; gap: 10px; }
.rkpeek h4 { margin: 0; font: 600 16px/1.3 Geist, Inter, system-ui, sans-serif; color: var(--text); }
.rkpeek .rkdiag { gap: 14px; }
.rkpeek .rkd .rkd-nd { background: var(--chatbg); }
@media (prefers-reduced-motion: reduce) {
  .rkcard *, .rkpeek * { animation: none !important; transition: none !important; }
  .rkd [data-k] { opacity: 1; }
}
.mcdone { display: flex; flex-direction: column; gap: 8px; padding: 28px 0; }
.mcdone .t { font: 600 17px/1.3 Geist, Inter, system-ui, sans-serif; color: var(--text); }
.mcdone .s { font: 400 14.5px/1.5 Geist, Inter, system-ui, sans-serif; color: var(--dim); }
.mcdone .lprimary { flex: none; margin-top: 12px; }

/* stats: a sheet under the header */
#examcol .examstats { position: static; transform: none; left: auto; top: auto;
  width: auto; max-height: 60vh; overflow-y: auto; margin: 0; border: 0;
  border-bottom: 1px solid var(--lhair); border-radius: 0; box-shadow: none;
  background: var(--chatbg);
  padding: 8px max(16px, calc((100% - 820px) / 2)) 16px; }
#examcol .examstats.hidden { display: none; }
.mcstiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px; padding: 8px 0 6px; }
@media (max-width: 520px) { .mcstiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.mcstiles div { display: flex; flex-direction: column; gap: 3px; }
.mcstiles b { font: 600 19px/1.1 Geist, Inter, system-ui, sans-serif;
  color: var(--text); font-variant-numeric: tabular-nums; }
.mcstiles span { font: 400 12px/1.35 Geist, Inter, system-ui, sans-serif; color: var(--dim); }
.mcsrow { display: flex; align-items: center; gap: 10px; min-height: 40px;
  border-top: 1px solid var(--lhair);
  font: 400 14px/1.35 Geist, Inter, system-ui, sans-serif; color: var(--text); }
.mcsrow .pname { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.mcsrow.low .pname { color: var(--dim); }
.mcsrow .pcount, .mcsrow .ppct { flex-shrink: 0; font-size: 12.5px; color: var(--dim);
  font-variant-numeric: tabular-nums; }
.mcsrow .ppct { min-width: 34px; text-align: right; }
.mcsrow .ppct.good { color: var(--green); }
.mcsrow .ppct.mid { color: var(--amber); }
.mcsrow .ppct.bad { color: var(--red); }
.mcsrow .mbar i.mid { background: color-mix(in srgb, var(--amber) 60%, transparent); }
.mcsrow .mbar i.bad { background: color-mix(in srgb, var(--red) 60%, transparent); }

@media (prefers-reduced-motion: reduce) {
  .mccard, .mccard.in, .mccard.out { transition: none; transform: none; }
}

/* ---- practice exam ---- */
#papercol .learnhead .ltitle { cursor: default; }
.pptimer { flex-shrink: 0; padding: 0 8px; font: 500 14px/1 "JetBrains Mono",
  ui-monospace, monospace; color: var(--dim2); font-variant-numeric: tabular-nums; }
.pptimer.low { color: var(--amber); }
.pptimer.hidden, #papercol .ltext.hidden { display: none; }
#paperhandin { color: var(--accent2); }
#paperhandin.unsaved::after { content: " ·"; color: var(--amber); }
#paperhandin.arm, #ppsubmit2.arm { color: var(--amber); }
.pphome .ppintro { margin: 0 2px; max-width: 60ch; }
.ppsheet { display: flex; flex-direction: column; gap: 8px; padding-bottom: 72px; }
.ppsec { display: flex; flex-direction: column; gap: 22px; margin-bottom: 18px; }
.ppsec .lgrouphead { padding-top: 8px; }
.ppq, .ppr { display: flex; flex-direction: column; gap: 12px; max-width: 44rem;
  scroll-margin-top: 12px; }
.ppq .qcode, .ppr .qcode { margin: 0; }
.pphd { display: flex; align-items: center; gap: 10px;
  font: 500 12px/1 "JetBrains Mono", ui-monospace, monospace; color: var(--dim); }
.pphd .no { color: var(--dim2); }
.pphd .pts { font-variant-numeric: tabular-nums; }
.ppflag { margin-left: auto; padding: 6px 0 6px 10px; border: 0; background: none;
  font: 500 12px/1 Geist, Inter, system-ui, sans-serif; color: var(--dim);
  cursor: pointer; }
.ppq.flagged .ppflag { color: var(--flag); }
.ppq.flagged .pphd .no { color: var(--flag); }
.ppopt.picked { background: color-mix(in srgb, var(--accent) 16%, var(--lsurf));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 60%, transparent); }
.ppopt.picked .k { background: var(--accent); color: #fff; box-shadow: none; }
.ppopt .k { text-transform: lowercase; }
.ppans { width: 100%; box-sizing: border-box; resize: none; min-height: 72px;
  padding: 12px 14px; border: 0; border-radius: var(--lradius);
  background: var(--lcomposer); box-shadow: inset 0 0 0 1px var(--lcomposerline);
  color: var(--text); font: 400 15.5px/1.5 Geist, Inter, system-ui, sans-serif;
  outline: none; }
.ppans:focus { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent); }
.ppans.code { font: 500 14px/1.6 "JetBrains Mono", ui-monospace, monospace;
  tab-size: 4; white-space: pre; overflow-x: auto; }
.ppend { padding-top: 8px; }
.ppend .lprimary { flex: none; width: 100%; }
@media (min-width: 901px) { .ppend .lprimary { width: auto; padding: 0 28px; } }
/* the question grid: a pill bottom right, a sheet of numbers above it */
.ppgridbtn { position: fixed; right: max(16px, calc((100% - 820px) / 2));
  bottom: calc(16px + env(safe-area-inset-bottom, 0px)); z-index: 9;
  height: 44px; padding: 0 16px; border: 0; border-radius: 22px;
  background: var(--lcomposer); box-shadow: inset 0 0 0 1px var(--lcomposerline),
    0 8px 24px rgba(0,0,0,.35);
  font: 500 14px/1 "JetBrains Mono", ui-monospace, monospace; color: var(--text);
  cursor: pointer; font-variant-numeric: tabular-nums; }
.ppgrid { position: fixed; right: max(16px, calc((100% - 820px) / 2));
  bottom: calc(68px + env(safe-area-inset-bottom, 0px)); z-index: 9;
  width: min(340px, calc(100% - 32px)); max-height: 50vh; overflow-y: auto;
  padding: 12px; border-radius: 14px; background: var(--lcomposer);
  box-shadow: inset 0 0 0 1px var(--lcomposerline), 0 12px 32px rgba(0,0,0,.45);
  display: grid; grid-template-columns: repeat(auto-fill, minmax(52px, 1fr)); gap: 6px; }
.ppgrid.hidden { display: none; }
.ppgrid button { height: 36px; border: 0; border-radius: 8px;
  background: rgba(255,255,255,.04); color: var(--dim);
  font: 500 12px/1 "JetBrains Mono", ui-monospace, monospace; cursor: pointer; }
.ppgrid button.done { color: var(--text);
  background: color-mix(in srgb, var(--accent) 22%, transparent); }
.ppgrid button.flag { box-shadow: inset 0 0 0 1px var(--flag); }
/* results */
.ppresult { display: flex; flex-direction: column; gap: 26px; padding-bottom: 40px; }
.ppscore { display: flex; align-items: center; gap: 18px; padding: 8px 0 0; }
.ppscore .g { flex-shrink: 0; font: 600 44px/1 Geist, Inter, system-ui, sans-serif;
  color: var(--text); font-variant-numeric: tabular-nums; }
.ppscore .t { font: 600 16px/1.3 Geist, Inter, system-ui, sans-serif; color: var(--text); }
.ppscore .s { margin-top: 3px; font: 400 14px/1.45 Geist, Inter, system-ui, sans-serif;
  color: var(--dim2); }
.ppscore .n { margin-top: 3px; font: 400 12.5px/1.4 Geist, Inter, system-ui, sans-serif;
  color: var(--dim); }
.ppsecs { margin-top: -8px; }
.ppr .vw { font: 600 12px/1 Geist, Inter, system-ui, sans-serif; }
.ppr .pphd .pts { margin-left: auto; }
.ppr.good .vw { color: var(--green); }
.ppr.warn .vw { color: var(--amber); }
.ppr.bad .vw { color: var(--red); }
.ppr.wait .vw { color: var(--dim); }
.ppmine { padding: 2px 0 2px 14px; border-left: 2px solid var(--lhair);
  font: 400 15px/1.5 Geist, Inter, system-ui, sans-serif; color: var(--text);
  white-space: pre-wrap; overflow-wrap: anywhere; }
.ppr.good .ppmine { border-left-color: color-mix(in srgb, var(--green) 60%, transparent); }
.ppr.warn .ppmine { border-left-color: color-mix(in srgb, var(--amber) 60%, transparent); }
.ppr.bad .ppmine { border-left-color: color-mix(in srgb, var(--red) 60%, transparent); }
.ppmine.code, .ppkey .code { font: 500 13.5px/1.6 "JetBrains Mono", ui-monospace, monospace;
  white-space: pre-wrap; }
.ppmine i { color: var(--dim); }
.ppkey { padding-left: 14px; border-left: 2px solid
  color-mix(in srgb, var(--green) 60%, transparent);
  font: 400 15px/1.5 Geist, Inter, system-ui, sans-serif; color: var(--lprose); }
.ppkey .lbl { margin-bottom: 4px; font: 600 11px/1 "JetBrains Mono", ui-monospace,
  monospace; letter-spacing: .06em; text-transform: uppercase; color: var(--green); }
.ppfb { margin: 0; font: 400 14.5px/1.55 Geist, Inter, system-ui, sans-serif;
  color: var(--lmuted); }
.ppmulti { margin-top: -4px; font: 500 13px/1.4 Geist, Inter, system-ui, sans-serif;
  color: var(--amber); }
.ppkey .lines { white-space: pre-line; }
/* code in a multiple choice card or a paper: learn's slab, one line per
   .ln with its hanging indent, no pull-back margins */
.mccard .qcode, .ppq .qcode, .ppr .qcode { padding: 10px 16px; border: 0;
  border-radius: var(--lradius); background: var(--lcodebg); overflow: visible; }
.mccard .qcode code, .ppq .qcode code, .ppr .qcode code { display: block;
  padding: 0; min-width: 0; border: 0; background: none;
  font: 600 13.5px/1.7 "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
  color: var(--lmuted); white-space: pre-wrap; overflow-wrap: anywhere; tab-size: 4;
  --tok-kw: color-mix(in srgb, #c678dd 75%, var(--text));
  --tok-str: color-mix(in srgb, #98c379 75%, var(--text));
  --tok-num: color-mix(in srgb, #d19a66 75%, var(--text));
  --tok-bi: color-mix(in srgb, #61afef 75%, var(--text));
  --tok-com: var(--dim); }
.mccard .qcode .ln, .ppq .qcode .ln, .ppr .qcode .ln { display: block;
  min-height: 1.7em; padding-left: calc(var(--i, 0ch) + 4ch);
  text-indent: calc(-1 * (var(--i, 0ch) + 4ch)); }
/* a block nested three levels deep or with a line past 80 columns (wide,
   set by learnCodeWide) would wrap into a narrow column at a phone's right
   edge; it keeps its lines whole and scrolls sideways instead. The code
   is as wide as its longest line, so the slab's padding travels with it */
.lq .qcode.wide, .mccard .qcode.wide, .ppq .qcode.wide, .ppr .qcode.wide,
.lv .md pre.wide, .lmodel .md pre.wide, .lfoot .md pre.wide {
  overflow-x: auto; overscroll-behavior-x: contain; }
.lq .qcode.wide code, .mccard .qcode.wide code, .ppq .qcode.wide code,
.ppr .qcode.wide code, .lv .md pre.wide code, .lmodel .md pre.wide code,
.lfoot .md pre.wide code {
  white-space: pre; overflow-wrap: normal; width: max-content;
  min-width: 100%; }
.lq .qcode.wide .ln, .mccard .qcode.wide .ln, .ppq .qcode.wide .ln,
.ppr .qcode.wide .ln, .lv .md pre.wide .ln, .lmodel .md pre.wide .ln,
.lfoot .md pre.wide .ln { padding-left: 0; text-indent: 0; }
/* on a wide screen the block takes the column, past the prose measure,
   so it only scrolls when the column itself is too narrow */
.lmodel .md > pre.wide, .lfoot .md > pre.wide,
.lmodel .md > .mtail > pre.wide, .lfoot .md > .mtail > pre.wide {
  max-width: none; }
/* what's new (update.js): a small plain card over a lightly dimmed page */
.updpop { position: fixed; inset: 0; z-index: 70; display: flex; align-items: center;
  justify-content: center; padding: 16px; background: rgba(6,6,10,.45);
  animation: crumbswap .2s ease-out; }
.updpop.out { opacity: 0; transition: opacity .2s; }
.updcard { width: min(340px, 100%); padding: 16px 18px 10px; border-radius: 14px;
  background: var(--panel); border: 1px solid var(--border);
  display: flex; flex-direction: column; }
.updcard .llabel { padding: 0; margin-bottom: 8px; color: var(--dim); }
.updcard p { margin: 0 0 6px; font: 400 14px/1.5 Geist, Inter, system-ui, sans-serif;
  color: var(--dim2); }
.updok { align-self: flex-end; min-height: 36px; padding: 0 12px; border: 0;
  background: none; color: var(--accent2); font: 600 14px/1 Geist, Inter, system-ui, sans-serif;
  cursor: pointer; }

/* the top-left button of Multiple choice and Practice exam: a back arrow
   to Learn's Progress */

.mcstem code, .mcqrow .qt code { font: 500 .9em "JetBrains Mono", ui-monospace,
  monospace; color: var(--text); background: rgba(255,255,255,.06);
  border-radius: 4px; padding: 0 4px; }
.mcqrow .qcol { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.mcqrow .qcol .qt { -webkit-line-clamp: 2; }
.mcqrow .qc { font: 500 12.5px/1.4 "JetBrains Mono", ui-monospace, monospace;
  color: var(--dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* results: a multiple choice question shows its options, not just the key */
.pprops .mcopt { min-height: 46px; cursor: default; }
.pprops .mcopt.dim { opacity: .5; }
.pprops .you { flex-shrink: 0; font: 500 11px/1 "JetBrains Mono", ui-monospace, monospace;
  letter-spacing: .04em; text-transform: uppercase; color: var(--dim2); }
.pprops .mcopt.right .you { color: var(--green); }
.pprops .mcopt.wrong .you { color: var(--red); }
.ppnone { margin-top: -4px; font: italic 400 13.5px/1.4 Geist, Inter, system-ui, sans-serif;
  color: var(--dim); }
.ppscore .g { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.ppscore .g .lbl { font: 600 10.5px/1 "JetBrains Mono", ui-monospace, monospace;
  letter-spacing: .08em; text-transform: uppercase; color: var(--dim); }

/* ---- Progress on one screen ----
   A top line (Basics and open questions over the course, the exam), the
   Continue card, one tile per chapter, and the practice grid. A tile
   opens its chapter in a bottom sheet: the two steps, the buttons, the
   topics. Every chapter's bar has two parts: Basics, then the open
   questions, twice as wide */
.lpwrap { display: flex; flex-direction: column; gap: 12px;
  max-width: 720px; margin: 0 auto; }
.lpwrap > * { flex-shrink: 0; }
#learnhome.fadein .lpwrap { animation: crumbswap .4s ease-out; }
/* the page fills the screen, so the grid (exams, tests, Repeats, the
   lists, the switch) rests at the bottom where the thumb is */
.learnhome { display: flex; flex-direction: column; }
.learnhome.hidden { display: none; }
.lpwrap { flex: 1 0 auto; width: 100%; }
.lpwrap > .lpbottom { margin-top: auto; display: flex; flex-direction: column;
  gap: 8px; padding-top: 8px; }
.lpbottom > .llabel { margin: 6px 2px -2px; padding: 0; color: var(--dim); }
@media (min-width: 700px) { .lpbottom .lpgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.lptop { display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; padding: 2px 2px 0; font-size: 13px; color: var(--dim2);
  font-variant-numeric: tabular-nums; }
.lptot { display: flex; gap: 12px; min-width: 0; }
.lptot > span { white-space: nowrap; }
.lptop b { color: var(--text); font-weight: 600; }
.lptot i { display: inline-block; width: 8px; height: 8px; border-radius: 2px;
  margin-right: 6px; background: var(--accent); }
.lptot i.b { background: var(--accent2); opacity: .5; }
.lpdays { white-space: nowrap; }
.lpcont { margin: 0; min-height: 0; padding: 11px 14px; border-radius: 14px; }
.lpcont .t { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lpcont .s { white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: 12.5px; }
/* Random: its note says what comes with it, so it wraps instead of cutting off */
.lprand .s { white-space: normal; overflow: visible; }
.lptiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 7px; }
.lptile { display: flex; flex-direction: column; gap: 6px; min-width: 0;
  padding: 9px 10px 10px; border-radius: 12px; cursor: pointer;
  background: var(--panel); border: 1px solid var(--border);
  transition: border-color .15s, background .15s; }
.lptile:hover { border-color: var(--hodb); }
/* every tile the same rows at the same heights, whatever it holds: the
   header a fixed line, the name two lines, the bars on the bottom edge */
.lptile .h { display: flex; justify-content: space-between; align-items: center;
  gap: 6px; height: 16px; }
.lptile .no { font: 600 12px/1 "JetBrains Mono", ui-monospace, monospace;
  color: var(--faint); }
.lptile .st { font: 500 11.5px/16px Geist, Inter, system-ui, sans-serif; color: var(--dim);
  font-variant-numeric: tabular-nums; }
.lptile .st .ok { color: var(--green); font-weight: 700; }
.lptile .t { font-size: 13px; line-height: 1.25; height: 2.5em; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  color: var(--dim2); overflow-wrap: anywhere; }
.lptile .bars { display: flex; gap: 3px; margin-top: auto; }
.lptile .bars > span { height: 4px; border-radius: 2px; background: var(--border);
  position: relative; overflow: hidden; }
.lptile .bars i { position: absolute; inset: 0 auto 0 0; border-radius: 2px; }
.lptile .bars .b { flex: 1; }
.lptile .bars .b i { background: var(--accent2); opacity: .55; }
.lptile .bars .o { flex: 2; }
.lptile .bars .o i { background: var(--accent); }
.lptile.done { background: color-mix(in srgb, var(--green) 7%, transparent);
  border-color: color-mix(in srgb, var(--green) 32%, transparent); }
.lptile.done .bars i { background: var(--green); opacity: 1; }
.lptile.here { border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 7%, transparent); }
.lptile.here .no, .lptile.here .st { color: var(--accent); }
.lptile.here .t, .lptile.open .t { color: var(--text); }
.lptile.extra { background: none; border-style: dashed; }
.lptile.extra .t { color: var(--dim); }
.lpgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.lpbtn { display: flex; align-items: center; gap: 10px; min-height: 48px;
  min-width: 0; padding: 6px 12px; border-radius: 12px; text-align: left;
  background: var(--panel); border: 1px solid var(--border); color: var(--text);
  font-family: inherit; cursor: pointer; }
.lpbtn:hover:not(:disabled) { border-color: var(--hodb); }
.lpbtn.hidden { display: none; }
.lpbtn .ic { width: 24px; height: 24px; flex-shrink: 0; border-radius: 7px;
  background: var(--panel2); color: var(--accent);
  font: 600 12px/24px "JetBrains Mono", ui-monospace, monospace; text-align: center; }
.lpbtn .tt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lpbtn .t { font-size: 14px; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
.lpbtn .s { font-size: 12px; color: var(--dim); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.lpbtn .s .hot { color: var(--amber); }
.lpbtn.quiet { cursor: default; }
.lpbtn.quiet .t { color: var(--dim2); }
.lpbtn.quiet .ic { color: var(--faint); }
/* the switch: Basics before each new chapter */
.lpsw > i { margin-left: auto; flex-shrink: 0; position: relative;
  width: 32px; height: 19px; border-radius: 10px; background: var(--border);
  transition: background .15s; }
.lpsw > i::after { content: ""; position: absolute; left: 2px; top: 2px;
  width: 15px; height: 15px; border-radius: 50%; background: var(--dim2);
  transition: transform .15s, background .15s; }
.lpsw.on > i { background: var(--accent); }
.lpsw.on > i::after { transform: translateX(13px); background: var(--bg); }

/* the sheet: a chapter, the Extra tiers, or the review lists */
.lsheet { position: fixed; inset: 0; z-index: 40; display: flex;
  flex-direction: column; justify-content: flex-end; }
.lsheet.hidden { display: none; }
.lsheet.still .lsheetbg, .lsheet.still .lsheetcard { animation: none; }
.lsheetbg { position: absolute; inset: 0; background: rgba(0,0,0,.55);
  animation: lsheetfade .18s ease-out; }
.lsheetcard { position: relative; width: 100%; max-width: 640px; margin: 0 auto;
  max-height: 86%; overflow-y: auto; overscroll-behavior: contain;
  background: var(--panel); border: 1px solid var(--border); border-bottom: 0;
  border-radius: 20px 20px 0 0;
  padding: 0 16px calc(20px + env(safe-area-inset-bottom, 0px));
  animation: lsheetup .22s cubic-bezier(.2,.8,.2,1); }
@keyframes lsheetup { from { transform: translateY(40px); opacity: .4; } }
@keyframes lsheetfade { from { opacity: 0; } }
.lsheetgrab { position: sticky; top: 0; z-index: 1; display: block; width: 100%;
  height: 22px; margin-bottom: 4px; border: 0; padding: 0; cursor: pointer;
  background: var(--panel); }
.lsheetgrab::after { content: ""; display: block; width: 38px; height: 4px;
  margin: 9px auto 0; border-radius: 2px; background: var(--border); }
.lpbody { display: flex; flex-direction: column; }
.lpbody .llabel { margin-bottom: 6px; color: var(--dim); }
.lpbody h3 { margin: 0 0 14px; font: 600 18px/1.3 Geist, Inter, system-ui, sans-serif;
  color: var(--text); text-wrap: balance; }
.lpstep { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.lpstep .k { width: 22px; height: 22px; flex-shrink: 0; border-radius: 7px;
  background: var(--panel2); color: var(--dim2); text-align: center;
  font: 600 11px/22px "JetBrains Mono", ui-monospace, monospace; }
.lpstep.on .k { background: var(--accent); color: var(--bg); }
.lpstep.ok .k { background: var(--green); color: var(--bg); }
.lpstep .t { width: 116px; flex-shrink: 0; font-size: 14px; color: var(--text); }
.lpstep .bar { flex: 1; height: 5px; border-radius: 3px; background: var(--border);
  position: relative; overflow: hidden; }
.lpstep .bar i { position: absolute; inset: 0 auto 0 0; border-radius: 3px;
  background: var(--accent); }
.lpstep.ok .bar i { background: var(--green); }
.lpstep .n { min-width: 44px; text-align: right; font-size: 12.5px; color: var(--dim);
  font-variant-numeric: tabular-nums; }
.lpstep.on .n { color: var(--accent); }
.lpstep.ok .n { color: var(--green); }
.lpnote { font-size: 13px; line-height: 1.45; color: var(--dim); margin: -2px 0 10px; }
.lpacts { display: flex; gap: 8px; margin: 6px 0 18px; }
.lpgo { flex: 1; min-height: 46px; padding: 0 14px; border-radius: 23px; border: 0;
  background: var(--accent); color: var(--bg); font: 600 14.5px/1 Geist, Inter,
  system-ui, sans-serif; cursor: pointer; }
.lpgo.ghost { flex: 0 1 auto; background: none; color: var(--dim2);
  border: 1px solid var(--border); font-weight: 500; }
.lpgo.ghost:hover { color: var(--text); border-color: var(--hodb); }
.lpbody .lptopics { margin: 0 0 2px; }
/* the Exam sheet's two tabs, and the multiple choice practice's stats:
   three figures and a strip of the last runs */
.lptabs { margin-bottom: 16px; }
.lptabs button { display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 3px; padding: 8px 10px; }
.lptabs button small { margin-left: 0; }
.lptab.hidden { display: none; }
.lpstats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px;
  margin: 0 0 10px; }
.lpstats div { display: flex; flex-direction: column; gap: 3px; padding: 10px 12px;
  border-radius: 12px; background: var(--panel2); }
.lpstats b { font: 600 20px/1.1 Geist, Inter, system-ui, sans-serif; color: var(--text);
  font-variant-numeric: tabular-nums; }
.lpstats span { font-size: 12px; line-height: 1.3; color: var(--dim); }
.lpspark { display: flex; align-items: flex-end; gap: 4px; height: 34px; margin: 0 0 14px; }
.lpspark i { flex: 1; max-width: 26px; border-radius: 3px 3px 1px 1px;
  background: color-mix(in srgb, var(--accent) 55%, transparent); }
.lpspark i:last-child { background: var(--accent); }
/* the Exam sheet's chapter rows: number, name, a bar, the count */
.lpexrows { display: flex; flex-direction: column; margin-bottom: 18px; }
.lpexrow { display: grid; grid-template-columns: 26px minmax(0, 1fr) 72px 48px;
  align-items: center; gap: 10px; min-height: 44px; padding: 0 2px; border: 0;
  border-top: 1px solid var(--lhair); background: none; color: var(--text);
  font: 400 14px/1.3 Geist, Inter, system-ui, sans-serif; text-align: left; cursor: pointer; }
.lpexrow .no { font: 600 12px/1 "JetBrains Mono", ui-monospace, monospace; color: var(--faint); }
.lpexrow .t { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lpexrow .bar { height: 4px; border-radius: 2px; background: var(--border);
  position: relative; overflow: hidden; }
.lpexrow .bar i { position: absolute; inset: 0 auto 0 0; border-radius: 2px;
  background: var(--accent); }
.lpexrow .n { text-align: right; font-size: 12.5px; color: var(--dim);
  font-variant-numeric: tabular-nums; }
.lpexrow.ok .bar i { background: var(--green); }
.lpmockrow { grid-template-columns: minmax(0, 1fr) auto; }
/* the Read sheet: a chapter's head with All, its topics as rows */
.lprdhead { display: flex; align-items: center; gap: 10px; margin: 14px 0 4px; }
.lprdhead .no { font: 600 12px/1 "JetBrains Mono", ui-monospace, monospace; color: var(--faint); }
.lprdhead .t { flex: 1; min-width: 0; font: 600 14.5px/1.3 Geist, Inter, system-ui, sans-serif;
  color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lprdall { flex-shrink: 0; min-height: 30px; padding: 0 12px; border-radius: 15px;
  border: 1px solid var(--border); background: none; color: var(--dim2);
  font: 500 12.5px/1 Geist, Inter, system-ui, sans-serif; cursor: pointer; }
.lprdrow { grid-template-columns: minmax(0, 1fr) 56px 44px; padding-left: 22px; }
.lprdrow.lpball { padding-left: 2px; margin: 4px 0 6px; border-bottom: 1px solid var(--lhair); font-weight: 600; }
/* the grid's switch spans the row */
.lpbtn.lpwide { grid-column: 1 / -1; }
/* a topic's fold: its Read cards or Basics beside Train */
.lfoldacts { display: flex; flex-wrap: wrap; gap: 0 18px; }
.lfoldacts .lprep { color: var(--accent2); }
.lpmockrow .n { min-width: 0; }
.lpmockrow b { font-weight: 600; font-variant-numeric: tabular-nums; }
.lpexrow.ok .n { color: var(--green); }
@media (hover: hover) { .lpexrow:hover { background: rgba(255,255,255,.025); } }
.lsheetcard { touch-action: pan-y; }
.lptier { margin-bottom: 14px; }
.lpbody .loptnote { padding: 0 0 10px; }
.lpbody .lempty { padding: 4px 0 12px; }
.lptierhead { display: flex; justify-content: space-between; align-items: baseline;
  margin: 8px 0 6px; font-size: 14.5px; font-weight: 600; color: var(--text); }
.lptierhead .n { font-size: 12.5px; font-weight: 400; color: var(--dim);
  font-variant-numeric: tabular-nums; }
@media (min-width: 700px) {
  .lptiles { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 9px; }
  .lpgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .lsheet { justify-content: center; padding: 24px; }
  .lsheetcard { border-radius: 20px; border-bottom: 1px solid var(--border);
    max-height: 80%; }
}

/* Review: the finished mark on Progress, the check's sheet (the pool and
   the size as two segmented rows), and the result with a bar per chapter */
.lpfin { color: var(--green); font-weight: 600; }
.lpseg { display: flex; gap: 6px; margin-bottom: 14px; }
.lpseg button { flex: 1; min-height: 42px; padding: 0 10px; border-radius: 12px;
  border: 1px solid var(--border); background: var(--panel2); color: var(--dim2);
  font: 500 14px/1.2 Geist, Inter, system-ui, sans-serif; cursor: pointer;
  font-variant-numeric: tabular-nums; }
.lpseg button small { margin-left: 4px; color: var(--faint); font-size: 12px; }
.lpseg button.on { border-color: var(--accent); color: var(--text);
  background: color-mix(in srgb, var(--accent) 12%, var(--panel2)); }
.lpseg button.on small { color: var(--accent2); }
.lpseg button:disabled { opacity: .4; cursor: default; }
.lptime { margin: -4px 0 4px; }
.lplast { font-size: 13.5px; color: var(--dim2); line-height: 1.5;
  font-variant-numeric: tabular-nums; }
.lplast b { color: var(--text); font-size: 15px; margin-right: 4px; }
.lresult .llabel { margin-bottom: 4px; }
.lresult .big { margin: 0; font: 600 44px/1.1 Geist, Inter, system-ui, sans-serif;
  color: var(--text); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.lresult .s b { color: var(--text); font-weight: 600; }
.lrchap { display: flex; flex-direction: column; gap: 9px; margin-top: 16px;
  max-width: 520px; }
.lrchap .r { display: flex; align-items: center; gap: 10px; font-size: 13.5px; }
.lrchap .nm { flex: 1; min-width: 0; color: var(--dim2); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.lrchap .r.miss .nm { color: var(--text); }
.lrchap .bar { width: 72px; height: 5px; border-radius: 3px; flex-shrink: 0;
  background: color-mix(in srgb, var(--red) 55%, var(--border));
  position: relative; overflow: hidden; }
.lrchap .bar i { position: absolute; inset: 0 auto 0 0; background: var(--green); }
.lrchap .n { width: 34px; text-align: right; color: var(--dim);
  font-variant-numeric: tabular-nums; }


/* a right answer moves on by itself: a hairline over the composer drains
   for the wait; touching the thread or typing stops it */
.inputwrap.learninput.autonext::after { content: ""; position: absolute;
  top: 0; left: max(16px, calc((100% - 820px) / 2));
  right: max(16px, calc((100% - 820px) / 2)); height: 2px; border-radius: 1px;
  background: color-mix(in srgb, var(--green) 70%, transparent);
  transform-origin: left; animation: mcdrain var(--autonext, 1400ms) linear forwards;
  pointer-events: none; }

/* the Check result in Basics and Exam training: the score and its range */
.mcresult { text-align: left; }
.mcresult .llabel { margin-bottom: 4px; }
.mcresult .big { margin: 0; font: 600 44px/1.1 Geist, Inter, system-ui, sans-serif;
  color: var(--text); font-variant-numeric: tabular-nums; }
.mcresult .s b { color: var(--text); }
.mcresult .lrchap { margin-bottom: 18px; }


/* the course picker: Learn mode's front page */
.lcpick { display: flex; flex-direction: column; gap: 10px; max-width: 620px; width: 100%;
  min-width: 0; margin: 0 auto; }
.lcpick .cdrow { min-width: 0; }
.lchead { font: 600 22px/1.25 Geist, Inter, system-ui, sans-serif; margin: 10px 0 6px; }
.lclist { display: flex; flex-direction: column; gap: 8px; }
.lcdone { margin-top: 14px; border-top: 1px solid var(--border); }
.lcdone > summary { list-style: none; cursor: pointer; display: flex; align-items: baseline;
  gap: 10px; padding: 14px 2px; font: 600 14px/1.3 Geist, Inter, system-ui, sans-serif; }
.lcdone > summary::-webkit-details-marker { display: none; }
.lcdone > summary .n { margin-left: auto; color: var(--dim); font-weight: 500; font-size: 12px; }
.lcdone > summary::after { content: "›"; color: var(--dim); transition: transform .18s; }
.lcdone[open] > summary::after { transform: rotate(90deg); }
.cdrow.wip { cursor: default; background: none; border-style: dashed; }
.cdrow.wip:hover { border-color: var(--border); }
.cdrow .wiptag, .cdrow .donetag { flex-shrink: 0; padding: 2px 8px; border-radius: 9px;
  font: 600 10.5px/1.3 Geist, Inter, system-ui, sans-serif; letter-spacing: .04em;
  text-transform: uppercase; color: var(--accent2);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); }
.cdrow .donetag { color: var(--dim); border-color: var(--border); }
.cdrow .wipnote { font-size: 12.5px; line-height: 1.4; color: var(--dim); }
/* a generated-exam course: its sizes as buttons, the first one filled */
.cdrow.gen { cursor: default; }
.cdrow .genbtns { display: flex; gap: 8px; flex-wrap: wrap; }
.cdrow .genbtns button { padding: 7px 14px; border-radius: 9px;
  border: 1px solid var(--border); background: none; color: var(--text);
  font: inherit; font-size: 13px; cursor: pointer; }
.cdrow .genbtns button:first-child { border-color: color-mix(in srgb,
  var(--accent) 60%, transparent); background: color-mix(in srgb,
  var(--accent) 14%, transparent); }
.cdrow .genbtns button:hover { border-color: var(--hodb); }

/* a course row: in the course picker */
.cdrow { display: flex; flex-direction: column; gap: 7px; width: 100%;
  padding: 10px 12px 11px; border-radius: 12px; text-align: left;
  background: var(--panel2); border: 1px solid var(--border); color: var(--text);
  font-family: inherit; cursor: pointer; transition: border-color .15s; }
.cdrow:hover { border-color: var(--hodb); }
.cdrow.on { border-color: color-mix(in srgb, var(--course, var(--accent)) 55%, transparent);
  background: color-mix(in srgb, var(--course, var(--accent)) 8%, var(--panel2)); }
.cdrow .h { display: flex; align-items: center; gap: 9px; min-width: 0; }
.cdrow .cdot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0;
  background: var(--course, var(--accent)); }
.cdrow .t { flex: 1; min-width: 0; font: 600 14.5px/1.3 Geist, Inter, system-ui,
  sans-serif; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cdrow .cur { color: var(--course, var(--accent)); font-weight: 700; font-size: 13px; }
.cdrow .cdnews { display: flex; gap: 8px; align-items: baseline; text-align: left;
  font: 400 12.5px/1.4 Geist, Inter, system-ui, sans-serif; color: var(--dim2, var(--dim)); }
.cdrow .cdnews b { flex-shrink: 0; padding: 1px 7px; border-radius: 9px;
  background: color-mix(in srgb, var(--course, var(--accent)) 16%, transparent);
  color: var(--course, var(--accent)); font: 600 10.5px/1.3 Geist, Inter, system-ui, sans-serif;
  letter-spacing: .04em; text-transform: uppercase; }
.cdrow .bar { height: 4px; border-radius: 2px; background: var(--border);
  position: relative; overflow: hidden; }
.cdrow .bar i { position: absolute; inset: 0 auto 0 0; border-radius: 2px;
  background: var(--course, var(--accent)); }
.cdrow .s { display: flex; justify-content: space-between; gap: 10px;
  font-size: 12px; color: var(--dim); font-variant-numeric: tabular-nums; }
.cdrow .s > span { white-space: nowrap; }

/* the multiple choice stats in their sheet: the four numbers as tiles */
.mcsheetstats .mcstiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 7px; margin-bottom: 14px; }
.mcsheetstats .mcstiles > div { display: flex; flex-direction: column; gap: 4px;
  padding: 10px 12px; border-radius: 12px; background: var(--panel2);
  border: 1px solid var(--border); min-width: 0; }
.mcsheetstats .mcstiles b { font: 600 20px/1.1 Geist, Inter, system-ui, sans-serif;
  color: var(--text); font-variant-numeric: tabular-nums; }
.mcsheetstats .mcstiles span { font-size: 12px; color: var(--dim); }
.lpbody .mcreset { align-self: flex-start; margin-top: 10px; }

/* tapping an answer, a card, a tile or a grid button never selects its
   text or pops up the phone's copy menu */
.mccard, .mcopt, .ldrill, .lptile, .lpbtn, .lpgo, .lcont, .cdrow, .lpseg button {
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent; }
/* a chapter sheet's buttons wrap; Exam questions takes a row of its own */
.lpacts { flex-wrap: wrap; }
.lpgo.wide { flex-basis: 100%; }

/* Tap: a named list as chips among close ones; tap as many as it holds */
.tapcard { gap: 18px; }
.tapq { display: flex; flex-direction: column; gap: 6px; }
.tapwhere { font: 600 11px/1.3 "JetBrains Mono", ui-monospace, monospace;
  letter-spacing: .06em; text-transform: uppercase; color: var(--dim); }
.taptitle { font: 500 21px/1.3 Literata, "Source Serif 4", Georgia, serif;
  color: var(--text); text-wrap: balance; }
.taplead { font: 400 16px/1.45 Geist, Inter, system-ui, sans-serif; color: var(--text); }
.taphint { font: 400 14px/1.4 Geist, Inter, system-ui, sans-serif; color: var(--dim);
  min-height: 20px; }
.taphint b { color: var(--accent2); font-weight: 600; }
.taphint .again { color: var(--amber); }
.taphint .tapok { color: var(--green); font-weight: 600; }
.taphint .tapno { color: var(--red); font-weight: 600; }
/* a pile: each chip its own width, a little tilt and lift; it sorts
   itself into a column once judged (tapSettle) */
.tapchips { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px 8px;
  padding: 4px 0; }
.tapchip { flex: 0 1 auto; min-height: 46px; max-width: 100%; padding: 10px 15px;
  transform: rotate(var(--r, 0deg)) translateY(var(--y, 0px));
  border: 0; border-radius: 14px; background: var(--lsurf);
  box-shadow: inset 0 0 0 1px var(--lhair); color: var(--text); cursor: pointer;
  font: 400 15px/1.35 Geist, Inter, system-ui, sans-serif; text-align: center;
  overflow-wrap: anywhere; transition: background .15s, box-shadow .15s, opacity .2s;
  -webkit-tap-highlight-color: transparent; user-select: none; -webkit-user-select: none; }
@media (hover: hover) {
  .tapchip:hover:not(:disabled):not(.on) { background: color-mix(in srgb, var(--lsurf) 85%, white); }
}
.tapchip.on { background: color-mix(in srgb, var(--accent) 22%, var(--lsurf));
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--accent) 75%, transparent); }
/* judged: the chips let a tap through to the card (tap to go on) */
.tapcard.judged .tapchip { pointer-events: none; }
.tapchip.good { background: color-mix(in srgb, var(--green) 16%, var(--lsurf));
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--green) 65%, transparent); }
/* in the list but not tapped: a dashed green ring */
.tapchip.miss { box-shadow: none; color: var(--text);
  outline: 1.5px dashed color-mix(in srgb, var(--green) 70%, transparent); outline-offset: -1.5px; }
.tapchip.bad { background: color-mix(in srgb, var(--red) 13%, var(--lsurf));
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--red) 60%, transparent); }
.tapchip.dim { opacity: .35; }
.tapchip.gone { opacity: 0; transform: rotate(var(--r, 0deg)) translateY(var(--y, 0px)) scale(.85);
  transition: opacity .25s ease-out, transform .25s ease-out; }
.tapchips.settled { flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 8px; }
.tapchips.settled .tapchip { flex: none; text-align: left; transform: none; }
.tapchips.ordered .tapchip { display: flex; align-items: baseline; gap: 12px; }
.tapchips.ordered .tapchip::before { content: attr(data-no); flex: none; min-width: 12px;
  font: 600 12px/1 "JetBrains Mono", ui-monospace, monospace; color: var(--dim); }
@media (prefers-reduced-motion: reduce) {
  .tapchip { transform: none; }
}
/* ---- Progress in the open questions mode (Inleiding Programmeren, and
   Governance's Legacy): laid out as Multiple choice mode's (lab.css), with
   tiles that name the chapter whole, a count by the bar ---- */
.lptile:not(.lpmc):not(.extra) .t { color: var(--text); font-weight: 500; }
.lptile:not(.lpmc) .no { color: var(--dim2); }
.lptile.here:not(.lpmc) .no { color: var(--accent); }
.lptile .bars { align-items: center; }
.lptile:not(.lpmc) .bars em { font: 500 10.5px/1 "JetBrains Mono", ui-monospace, monospace; font-style: normal;
  color: var(--dim); font-variant-numeric: tabular-nums; margin-left: 3px; }
@media (max-width: 699px) {
  .lptile:not(.lpmc) .t { -webkit-line-clamp: 3; height: 3.75em;
    font-size: 12.5px; overflow-wrap: break-word; hyphens: manual; }
}
.lptile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* ---- Learn mode, one calm look (as Multiple choice mode's run, lab.css):
   the question in the open questions' serif, answers as rounded cards
   with a round letter badge, soft fills for right, wrong and picked; for the
   Basics round, Exam training, the past exams and the open questions ---- */
.mcmeta { font: 500 12.5px/1.4 Geist, Inter, system-ui, sans-serif; color: var(--dim2); }
.mcopts { gap: 10px; }
.mcopt { gap: 12px; padding: 13px 16px 13px 12px; border-radius: 16px;
  background: color-mix(in srgb, white 2.5%, var(--panel)); box-shadow: inset 0 0 0 1px rgba(255,255,255,.055);
  font: 400 15px/1.5 Geist, Inter, system-ui, sans-serif;
  transition: transform .12s ease, background-color .3s ease, box-shadow .3s ease, opacity .35s ease; }
.mcopt:active:not(:disabled) { transform: scale(.99); }
@media (hover: hover) { .mcopt:hover:not(:disabled) { box-shadow: inset 0 0 0 1px var(--hodb); } }
.mcopt:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.mcopt .k { width: 28px; height: 28px; border-radius: 50%; box-shadow: none; background: rgba(255,255,255,.06);
  color: var(--dim2); font: 600 12.5px/1 Geist, Inter, system-ui, sans-serif; }
.mcopt.long { font-size: 14.5px; padding: 12px 14px 12px 12px; }
.mcopt.right { background: color-mix(in srgb, var(--green) 11%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--green) 45%, transparent); }
.mcopt.right .k { background: var(--green); color: #0c0b0f; }
.mcopt.wrong { background: color-mix(in srgb, var(--red) 9%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--red) 42%, transparent); }
.mcopt.wrong .k { background: var(--red); color: #0c0b0f; box-shadow: none; }
.mcopt.dim { opacity: .38; }
.ppopt.picked { background: color-mix(in srgb, var(--accent) 12%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 50%, transparent); }
.ppopt.picked .k { background: var(--accent); color: #0c0b0f; }
@media (prefers-reduced-motion: reduce) { .mcopt:active:not(:disabled) { transform: none; } }
/* ---- the Read cards, calm: the trunk and outlined chips as before, the
   accent only on the lines; each item numbered on the trunk (how many
   there are is part of the fact), no glow ---- */
.rkdlead { text-transform: none; letter-spacing: 0; font: 600 13px/1.3 Geist, Inter, system-ui, sans-serif; }
@keyframes rkin { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
.rkd .rkd-mean .f { color: var(--dim2); }
.rkd .rkd-trunk { padding-left: 28px; }
.rkd .rkd-trunk::before { left: 9px; }
.rkd .rkd-row .rkd-tick { left: -28px; top: 6px; width: 19px; height: 19px; border-radius: 50%; display: grid;
  place-items: center; background: var(--chatbg); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent);
  transform: none; opacity: 0; transition: opacity .3s calc(.2s + var(--r, 0) * 80ms);
  font: 600 10.5px/1 Geist, Inter, system-ui, sans-serif; font-style: normal; color: var(--dim2); }
.drawn .rkd .rkd-row .rkd-tick { opacity: 1; }
.rkd .rkd-ar b { font: italic 400 13px/1.2 Literata, "Source Serif 4", Georgia, serif; letter-spacing: 0; color: var(--dim2); }
.rkd .rkd-vsl b { font: 500 11px/1 Geist, Inter, system-ui, sans-serif; letter-spacing: 0; color: var(--dim); }
/* steps numbered like the list items: a small outlined circle */
.rkd .rkd-num { width: 19px; height: 19px; border-radius: 50%; background: var(--chatbg);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent);
  font: 600 10.5px/1 Geist, Inter, system-ui, sans-serif; color: var(--dim2); }
.rkd .rkd-step { gap: 10px; }
.rkd .rkd-ar::before { left: 9px; }
.rkd .rkd-ar::after { left: 5.5px; }
.rkd .rkd-ar b { left: 22px; }
/* a tree (fault tree, event tree): top down, each node centred over its
   children, the joins as thin accent lines, a gate as a small outlined tag
   under its node, an edge label on the line down to a child */
.rkt { overflow-x: auto; padding-bottom: 2px; --tl: color-mix(in srgb, var(--accent) 45%, transparent); }
.rkt-n { position: relative; display: flex; flex-direction: column; align-items: center; flex: 1 1 0; min-width: 0; }
.rkt > .rkt-n { margin: 0 auto; }
.rkt .rkd-nd { padding: 5px 9px; font-size: 13.5px; line-height: 1.25; text-align: center; max-width: 100%;
  overflow-wrap: anywhere; }
.rkt-g { margin-top: 4px; padding: 2px 7px; border-radius: 6px; box-shadow: inset 0 0 0 1px var(--tl);
  font: 600 10.5px/1.2 Geist, Inter, system-ui, sans-serif; color: var(--accent2); letter-spacing: .03em; }
.rkt-e { margin-bottom: 3px; font: italic 400 12px/1.2 Literata, "Source Serif 4", Georgia, serif; color: var(--dim2); }
.rkt-kids { position: relative; display: flex; justify-content: center; gap: 6px; width: 100%; padding-top: 18px; }
.rkt-kids::before { content: ""; position: absolute; top: 0; left: 50%; height: 9px; border-left: 1px solid var(--tl); }
.rkt-kids > .rkt-n { padding-top: 9px; }
.rkt-kids > .rkt-n::before { content: ""; position: absolute; top: -9px; left: 0; right: 0; border-top: 1px solid var(--tl); }
.rkt-kids > .rkt-n:first-child::before { left: 50%; }
.rkt-kids > .rkt-n:last-child::before { right: 50%; }
.rkt-kids > .rkt-n:only-child::before { display: none; }
.rkt-kids > .rkt-n::after { content: ""; position: absolute; top: -9px; left: 50%; height: 18px; border-left: 1px solid var(--tl); }
.rkt .rkt-kids .rkt-kids .rkd-nd { font-size: 12.5px; padding: 4px 6px; overflow-wrap: normal; hyphens: auto; }
.rkt .rkd-nd { overflow-wrap: normal; hyphens: auto; }
/* the joins bridge the 6px gap between siblings */
.rkt-kids > .rkt-n::before { left: -3px; right: -3px; }
.rkt-kids > .rkt-n:first-child::before { left: 50%; right: -3px; }
.rkt-kids > .rkt-n:last-child::before { left: -3px; right: 50%; }
/* in an exam (a paper, its review, a multiple choice card) code never
   folds: a folded line reads as a line of its own, and in Python the
   indentation is the meaning. Lines stay whole and the block scrolls */
.mccard .qcode, .ppq .qcode, .ppr .qcode { overflow-x: auto; overscroll-behavior-x: contain; }
.mccard .qcode code, .ppq .qcode code, .ppr .qcode code {
  white-space: pre; overflow-wrap: normal; width: max-content; min-width: 100%; }
.mccard .qcode .ln, .ppq .qcode .ln, .ppr .qcode .ln { padding-left: 0; text-indent: 0; }
/* an exam's result: what cost points, worst first, each with Train */
.pptrain { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 18px; }
.pptrain .llabel { margin: 0 2px 2px; }
.pptrow { display: flex; align-items: center; gap: 12px; padding: 12px 12px 12px 14px; border-radius: 14px;
  background: var(--panel); border: 1px solid var(--border); }
.pptrow .tt { flex: 1; min-width: 0; display: grid; gap: 3px; }
.pptrow .t { font: 600 14.5px/1.25 Geist, Inter, system-ui, sans-serif; color: var(--text); }
.pptrow .s { font: 400 12.5px/1.5 Geist, Inter, system-ui, sans-serif; color: var(--dim2); }
.pptrow .lpgo { flex: none; min-height: 38px; padding: 0 16px; }
/* ---- Read cards, v3 (2026-10-16): calm and clear. A sentence reads in
   the question's serif with its key words softly lilac; a term stands in
   the UI face over its meaning; lists are quiet rows (a sequence numbered
   on a thin rail); two sides stand apart on a hairline; figures draw what
   the slides draw, in hairlines and faint lilac fills; icons are dim line
   drawings. Blocks rise in one after another, lines draw once ---- */
.rkdiag { gap: 26px; }
.rc { --rc-ink: var(--lstem); --rc-dim: var(--dim2); --rc-line: color-mix(in srgb, var(--accent) 42%, transparent);
  --rc-fill: color-mix(in srgb, var(--accent) 7%, transparent); --rc-bg: var(--chatbg);
  display: flex; flex-direction: column; gap: 10px; min-width: 0; color: var(--rc-ink); }
.labread .rc, .rkpeek .rc { --rc-bg: var(--lsurf); }
.rc-lead { font: 500 12.5px/1.3 Geist, Inter, system-ui, sans-serif; color: var(--dim); letter-spacing: .01em; }
.rc-cue { font-weight: 600; color: color-mix(in srgb, var(--accent2) 70%, var(--lstem)); }
.rc .link { cursor: pointer; text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent);
  text-decoration-thickness: 1px; text-underline-offset: 3px; }
.rc-ic { flex-shrink: 0; width: 18px; height: 18px; fill: none; stroke: color-mix(in srgb, var(--accent2) 60%, var(--dim));
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.rc-k { font: 600 15.5px/1.35 Geist, Inter, system-ui, sans-serif; color: var(--rc-ink); }
.rc-g { font: 400 15px/1.5 Literata, "Source Serif 4", Georgia, serif; color: var(--rc-dim); }
.rc-lb { font: 500 13px/1.25 Geist, Inter, system-ui, sans-serif; color: var(--rc-ink); }
/* a sentence */
.rc-line { margin: 0; font: 400 17px/1.6 Literata, "Source Serif 4", Georgia, serif; color: var(--rc-ink); text-wrap: pretty; }
/* a set: quiet rows, a dot or an icon */
.rc-set, .rc-flow { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.rc-set li { display: flex; align-items: flex-start; gap: 12px; }
.rc-set .rc-dot { flex-shrink: 0; width: 5px; height: 5px; margin: 9px 6px 0 7px; border-radius: 50%; background: var(--rc-line); }
.rc-set .rc-ic { margin-top: 1px; }
.rc-tx2 { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* a sequence: numbers on a thin rail */
.rc-flow { gap: 0; }
.rc-flow li { position: relative; display: flex; gap: 14px; padding-bottom: 14px; }
.rc-flow li:last-child { padding-bottom: 0; }
.rc-flow li:not(:last-child)::before { content: ""; position: absolute; left: 11px; top: 24px; bottom: 2px; width: 1px; background: var(--rc-line); }
.rc-n { flex-shrink: 0; width: 23px; height: 23px; border-radius: 50%; display: grid; place-items: center;
  box-shadow: inset 0 0 0 1px var(--rc-line); font: 600 11.5px/1 Geist, Inter, system-ui, sans-serif; font-style: normal; color: var(--accent2); }
.rc-flow .rc-tx2 { padding-top: 1px; }
/* terms over their meanings */
.rc-pairs { margin: 0; display: flex; flex-direction: column; }
.rc-pr { display: grid; grid-template-columns: auto 1fr; column-gap: 12px; padding: 11px 0; border-top: 1px solid var(--lhair); }
.rc-pr:first-child { border-top: 0; padding-top: 0; }
.rc-pr:last-child { padding-bottom: 0; }
.rc-pr > dt, .rc-pr > dd { grid-column: 2; margin: 0; }
.rc-pr:not(:has(> .rc-ic)) { grid-template-columns: 1fr; }
.rc-pr:not(:has(> .rc-ic)) > dt, .rc-pr:not(:has(> .rc-ic)) > dd { grid-column: 1; }
.rc-pr > .rc-ic { grid-row: 1 / span 2; margin-top: 1px; }
.rc-pr > dd { margin-top: 3px; font: 400 15px/1.55 Literata, "Source Serif 4", Georgia, serif; color: var(--rc-dim); text-wrap: pretty; }
.rc-pr > dd .rc-cue { color: color-mix(in srgb, var(--accent2) 55%, var(--lstem)); font-weight: 500; }
/* two sides */
.rc-vs { display: grid; grid-template-columns: 1fr 1px 1fr; gap: 16px; }
.rc-vsl { background: var(--rc-line); opacity: .6; }
.rc-side { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.rc-side p { margin: 0; font: 400 15px/1.55 Literata, "Source Serif 4", Georgia, serif; color: var(--rc-dim); text-wrap: pretty; }
.rc-side .rc-cue { font-weight: 500; }
/* figures: shared */
.rc-svg { display: block; width: 100%; max-width: 420px; height: auto; overflow: visible; }
.rc-svg .rc-tx { font: 500 11.5px Geist, Inter, system-ui, sans-serif; fill: var(--rc-ink); }
.rc-svg .rc-dim { fill: var(--rc-dim); font-weight: 400; }
.rc-svg .rc-key { fill: var(--accent2); font-weight: 600; }
.rc-svg .rc-ax { fill: var(--dim); font-weight: 500; }
.rc-draw, .rc-axis, .rc-ringc { fill: none; stroke: var(--rc-line); stroke-width: 1.2; vector-effect: non-scaling-stroke; }
.rc-acc { fill: none; stroke: color-mix(in srgb, var(--accent) 80%, transparent); stroke-width: 1.6; vector-effect: non-scaling-stroke; }
.rc-tip { fill: none; stroke: color-mix(in srgb, var(--accent) 80%, transparent); stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.rc-axis { stroke: rgba(255,255,255,.18); }
.rc-ringc { stroke: rgba(255,255,255,.07); }
/* bow tie: causes, the knot, effects; two soft wings */
.rc-bow { position: relative; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 8px; min-height: 120px; padding: 6px 0; }
.rc-bowbg { position: absolute; inset: 0; width: 100%; height: 100%; }
.rc-wingf { fill: var(--rc-fill); stroke: none; }
.rc-wing { position: relative; display: flex; flex-direction: column; gap: 8px; }
.rc-wing.l { align-items: flex-start; } .rc-wing.r { align-items: flex-end; text-align: right; }
.rc-wing .rc-lb { max-width: 9.5em; padding: 3px 7px; border-radius: 7px; background: var(--rc-bg); }
.rc-knot { position: relative; display: grid; place-items: center; width: 72px; height: 72px; border-radius: 50%; text-align: center;
  background: var(--rc-bg); box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--accent) 70%, transparent); }
.rc-knot .rc-lb { font-weight: 600; color: var(--accent2); padding: 0 6px; }
.rc-bowl { display: flex; justify-content: space-between; margin-top: -2px; font: italic 400 13px/1.3 Literata, "Source Serif 4", Georgia, serif; color: var(--rc-dim); }
/* balance: the chart */
.rc-zone { fill: var(--rc-fill); stroke: none; }
/* stack: layers, the top one a shade stronger */
.rc-stack { display: flex; flex-direction: column; gap: 4px; }
.rc-layer { display: flex; flex-direction: column; gap: 2px; padding: 10px 14px; border-radius: 10px;
  background: color-mix(in srgb, var(--accent) calc(10% - var(--r) * 1.5%), transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) calc(30% - var(--r) * 4%), transparent); }
.rc-layer .rc-g { font-size: 14px; }
/* Swiss cheese */
.rc-slab { fill: var(--rc-fill); stroke: var(--rc-line); stroke-width: 1.2; }
.rc-hole { fill: var(--rc-bg); stroke: var(--rc-line); stroke-width: 1; }
.rc-note { margin: 0; font: 400 14.5px/1.5 Literata, "Source Serif 4", Georgia, serif; color: var(--rc-dim); }
/* cycle and hub: labels round a ring */
.rc-ring { position: relative; width: min(100%, 320px); aspect-ratio: 1; margin: 4px auto; }
.rc-ring > svg { inset: 0; width: 100%; height: 100%; }
.rc-node, .rc-ctr { position: absolute; transform: translate(-50%, -50%); max-width: 38%; text-align: center; }
.rc-node .rc-lb { display: inline-block; padding: 5px 9px; border-radius: 9px; background: var(--rc-bg);
  box-shadow: inset 0 0 0 1px var(--rc-line); font-size: 12.5px; }
.rc-ctr .rc-lb { display: inline-block; padding: 8px 12px; border-radius: 12px; background: var(--rc-bg);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--accent) 70%, transparent); font-weight: 600; color: var(--accent2); }
/* matrix */
.rc-mx { display: grid; grid-template-columns: auto 1fr 1fr; gap: 6px; align-items: stretch; }
.rc-mxyl { grid-column: 1 / -1; font: 500 12px/1.2 Geist, Inter, system-ui, sans-serif; color: var(--dim); }
.rc-mxxl { grid-column: 2 / -1; text-align: right; font: 500 12px/1.2 Geist, Inter, system-ui, sans-serif; color: var(--dim); }
.rc-mxy { writing-mode: initial; align-self: center; font: 500 11.5px/1.2 Geist, Inter, system-ui, sans-serif; color: var(--rc-dim); max-width: 4.5em; }
.rc-mxx { text-align: center; font: 500 11.5px/1.2 Geist, Inter, system-ui, sans-serif; color: var(--rc-dim); }
.rc-cell { padding: 10px 11px; border-radius: 10px; background: var(--rc-fill); box-shadow: inset 0 0 0 1px var(--lhair);
  font: 400 14px/1.45 Literata, "Source Serif 4", Georgia, serif; color: var(--rc-ink); min-height: 3.2em; }
/* spectrum */
.rc-spec { padding: 30px 6px 0; }
.rc-specline { position: relative; height: 34px; }
.rc-specline::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px;
  background: linear-gradient(to right, var(--rc-line), color-mix(in srgb, var(--accent) 80%, transparent)); }
.rc-pt { position: absolute; top: 50%; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; max-width: 34%; text-align: center; }
.rc-pt::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--rc-bg);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--accent) 75%, transparent); transform: translateY(-50%); }
.rc-pt.up { flex-direction: column-reverse; transform: translate(-50%, calc(-100% + 4.5px)); }
.rc-pt.up::before { transform: translateY(50%); }
.rc-pt .rc-lb { font-size: 12.5px; padding: 2px 0; }
.rc-specends { display: flex; justify-content: space-between; margin-top: 18px; font: italic 400 13px/1.3 Literata, "Source Serif 4", Georgia, serif; color: var(--rc-dim); }
/* venn */
.rc-venn circle.rc-vset { fill: var(--rc-fill); }
/* the one authored moment: blocks rise in turn, lines draw once */
.rkcard:not(.drawn) .rc { opacity: 0; }
.drawn .rc { animation: rcin .55s cubic-bezier(.16, 1, .3, 1) both; animation-delay: calc(90ms + var(--b, 0) * 110ms); }
@keyframes rcin { from { opacity: 0; transform: translateY(6px); } }
.rc-draw { stroke-dasharray: 1; stroke-dashoffset: 0; }
.drawn .rc-draw { animation: rcdraw 1s cubic-bezier(.3, .7, .3, 1) both; animation-delay: calc(250ms + var(--b, 0) * 110ms); }
@keyframes rcdraw { from { stroke-dashoffset: 1; } }
@media (prefers-reduced-motion: reduce) { .drawn .rc, .drawn .rc-draw { animation: none; } }
@media (max-width: 380px) { .rc-vs { grid-template-columns: 1fr; } .rc-vsl { height: 1px; } }
.rkdiag > .rc, .rkdiag { align-self: stretch; width: 100%; }
.rc-ring > svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.rc-ring.hub { width: min(100%, 300px); }
.rc-pt.lo { align-items: flex-start; transform: translateX(-6px); }
.rc-pt.lo.up { transform: translate(-6px, calc(-100% + 4.5px)); }
.rc-pt.hi { align-items: flex-end; transform: translateX(calc(-100% + 6px)); }
.rc-pt.hi.up { transform: translate(calc(-100% + 6px), calc(-100% + 4.5px)); }
.rc-pt.lo .rc-lb, .rc-pt.hi .rc-lb { text-align: inherit; }
.rc-pt.lo { text-align: left; } .rc-pt.hi { text-align: right; }
.rc-specends { margin-top: 34px; }
.rc-ring.hub .rc-draw { stroke: color-mix(in srgb, var(--accent) 30%, transparent); }
.rc-venn .rc-dotc { fill: color-mix(in srgb, var(--accent) 80%, transparent); }
