/* cscd240.jdoner.me shared styles. Source file, edited by hand: build-site.py does not write it.
   Every page links it: the pages build-site.py writes, the pages rooms-api.py renders, and the header that
   rooms-api adds to /board. Page rules sit under body.site so a box's own board keeps its own look; only the
   tokens and the .site-header rules reach the board.

   The look (2026-10-15, her ask for a design that does not read as generated):
   - The subject is a Linux box and its terminal, so the dark ink of a terminal is the frame: the header, the
     command blocks and the primary buttons share 1 ink color; pages sit on a cool grey-green paper.
   - 1 accent, terminal amber: the cursor in the mark, XP, a chosen card, link underlines and the focus ring.
     Green means answered and nothing else; red means not yet and nothing else.
   - Type: DIN (DIN Alternate on a Mac, Bahnschrift on Windows) for headings and every number; Avenir Next or
     Segoe UI for controls; Charter for task prose and question text (students copy notes from it); the
     system monospace for commands. System fonts only: the CSP loads nothing from outside.
   - Spacing on 1 scale (4, 8, 12, 16, 24, 32, 48). Borders only where something opens, is chosen or is typed
     into; no shadows except the open menu. The progress bar has 1 cell per question.
   - The only motion is the 150 ms task collapse.
   Since 2026-10-17 (her order of 08:0x PDT: "confetti and some sort of pleasing sound ... dopamine"), motion answers
   the student's own action and nothing else: glyph confetti from the terminal's characters when an answer is right,
   amber XP orbs into the avatar, the room-complete card, the level ring. All of it is off under
   prefers-reduced-motion. The avatar's ring is the 1 place new colors appear: RuneScape's metal order, 1 metal per
   2 levels (the second level of a metal adds an outer band), so a level shows at a glance. */

:root {
  --bg: #f2f4f1; --fg: #1c2420; --muted: #56605a; --surface: #ffffff; --surface-2: #f5f7f4;
  --rule: #d6dcd6; --rule-soft: #e7ebe6; --control-border: #808a84; --input-border: #77817b; --input-bg: #ffffff;
  --link: #1c2420; --link-line: #c98a1c; --accent-text: #8a5000; --accent-soft: #fbf0dc;
  --code-bg: #e8ece7; --code-fg: #1c2420; --pre-bg: #1c2420; --pre-fg: #e6ece7; --pre-prompt: #f0b44c;
  --copy-bg: #2c3732; --copy-fg: #e6ece7;
  --bar-bg: #1c2420; --bar-fg: #f2f4f1; --bar-muted: #a8b3ac; --bar-rule: #2f3a35; --focus-bar: #f0b44c;
  --btn-bg: #1c2420; --btn-fg: #ffffff; --btn-hover: #36433c;
  --sel-bg: #fbf0dc; --sel-border: #8a5000; --track: #dde3dc;
  --ok: #1a6b3a; --ok-fill: #2b8a4e; --ok-soft: #e2f1e6; --on-ok: #ffffff; --no: #b3261e; --no-soft: #fbe9e7;
  --focus: #8a5000; --menu-hover: #eef1ed; --shadow-pop: 0 12px 32px rgba(28,36,32,.22);
  --display: "DIN Alternate", Bahnschrift, "DIN Next", "D-DIN", "Avenir Next Condensed", "Ubuntu", sans-serif;
  --ui: "Avenir Next", "Segoe UI Variable Text", "Segoe UI", Ubuntu, Roboto, "Helvetica Neue", sans-serif;
  --prose: Charter, "Bitstream Charter", "Sitka Text", Cambria, Georgia, serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Ubuntu Mono", monospace;
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px; --s7: 48px;
  --r-card: 6px; --r-control: 4px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #151b18; --fg: #e4eae5; --muted: #9ba69f; --surface: #1c2420; --surface-2: #222b26;
    --rule: #313b36; --rule-soft: #28312c; --control-border: #76837b; --input-border: #7c8981; --input-bg: #151b18;
    --link: #e4eae5; --link-line: #c98a1c; --accent-text: #f0b44c; --accent-soft: #3b2f16;
    --code-bg: #29332e; --code-fg: #e4eae5; --pre-bg: #0f1412; --pre-fg: #e4eae5; --pre-prompt: #f0b44c;
    --copy-bg: #222b26; --copy-fg: #e4eae5;
    --bar-bg: #0f1412; --bar-fg: #e4eae5; --bar-muted: #8f9a93; --bar-rule: #26302b; --focus-bar: #f0b44c;
    --btn-bg: #e4eae5; --btn-fg: #151b18; --btn-hover: #ffffff;
    --sel-bg: #3b2f16; --sel-border: #f0b44c; --track: #2c3631;
    --ok: #74d394; --ok-fill: #4fb873; --ok-soft: #1a3324; --on-ok: #0f1412; --no: #ff8f85; --no-soft: #3a1d1a;
    --focus: #f0b44c; --menu-hover: #26302b; --shadow-pop: 0 14px 36px rgba(0,0,0,.55);
  }
}
:root[data-theme="dark"] {
    --bg: #151b18; --fg: #e4eae5; --muted: #9ba69f; --surface: #1c2420; --surface-2: #222b26;
    --rule: #313b36; --rule-soft: #28312c; --control-border: #76837b; --input-border: #7c8981; --input-bg: #151b18;
    --link: #e4eae5; --link-line: #c98a1c; --accent-text: #f0b44c; --accent-soft: #3b2f16;
    --code-bg: #29332e; --code-fg: #e4eae5; --pre-bg: #0f1412; --pre-fg: #e4eae5; --pre-prompt: #f0b44c;
    --copy-bg: #222b26; --copy-fg: #e4eae5;
    --bar-bg: #0f1412; --bar-fg: #e4eae5; --bar-muted: #8f9a93; --bar-rule: #26302b; --focus-bar: #f0b44c;
    --btn-bg: #e4eae5; --btn-fg: #151b18; --btn-hover: #ffffff;
    --sel-bg: #3b2f16; --sel-border: #f0b44c; --track: #2c3631;
    --ok: #74d394; --ok-fill: #4fb873; --ok-soft: #1a3324; --on-ok: #0f1412; --no: #ff8f85; --no-soft: #3a1d1a;
    --focus: #f0b44c; --menu-hover: #26302b; --shadow-pop: 0 14px 36px rgba(0,0,0,.55);
}

/* ---- the page ---- */
html { -webkit-text-size-adjust: 100%; }
body.site { margin: 0; background: var(--bg); color: var(--fg); color-scheme: light;
  font: 16px/1.5 var(--ui); font-kerning: normal; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) body.site { color-scheme: dark; } }
:root[data-theme="dark"] body.site { color-scheme: dark; }
.site *, .site *::before, .site *::after { box-sizing: border-box; }
.site main { max-width: 768px; margin: 0 auto; padding: var(--s6) var(--s4) var(--s7); }
.site h1, .site h2, .site h3 { font-family: var(--display); font-weight: 700; line-height: 1.2; letter-spacing: .005em; }
.site h1 { font-size: 31px; margin: 0 0 var(--s2); }
.site h2 { font-size: 20px; margin: 0; }
.site main > h2 { margin: var(--s6) 0 var(--s3); }
.site h3 { font-size: 17px; margin: var(--s5) 0 var(--s2); }
.site p { margin: 0 0 var(--s3); }
.site a { color: var(--link); text-decoration: underline; text-decoration-color: var(--link-line);
  text-decoration-thickness: 2px; text-underline-offset: 3px; }
.site a:hover { text-decoration-color: currentColor; }
.site strong { font-weight: 700; }
.site code, .site pre, .site kbd { font-family: var(--mono); font-size: 14.5px; }
.site code { background: var(--code-bg); color: var(--code-fg); border-radius: 3px; padding: 1px 5px; overflow-wrap: anywhere; }
.site pre { background: var(--pre-bg); color: var(--pre-fg); padding: var(--s3) var(--s4); border-radius: var(--r-control);
  overflow-x: auto; margin: 0; line-height: 1.5; }
.site pre code { background: none; color: inherit; padding: 0; overflow-wrap: normal; }
.site table { border-collapse: collapse; width: 100%; display: block; overflow-x: auto; font-size: 15px; }
.site th, .site td { text-align: left; vertical-align: top; padding: var(--s2) var(--s3); border-bottom: 1px solid var(--rule-soft);
  overflow-wrap: anywhere; }
.site th { font-weight: 600; }
.site tbody tr:nth-child(even) { background: var(--surface-2); }
/* Tables, 2026-10-16 (her words 12:45 PDT): columns sized to content, a word never split, a command on one line.
   A table the build wraps in .table-wrap scrolls sideways inside it on a phone; the page itself never does. */
.site .table-wrap { overflow-x: auto; max-width: 100%; margin: var(--s3) 0; }
.site .table-wrap > table { display: table; table-layout: auto; width: 100%; overflow: visible; }
/* Her rule of 2026-10-17: nothing scrolls sideways on a phone. Under 640 px a table wraps its cells instead of
   scrolling inside .table-wrap: fixed layout shares the width, long words and commands break where they must
   (the cscd240 stylesheet's rule, taken into this copy 2026-10-24 when the render check found 14 glossary tables
   scrolling at 390). */
@media (max-width: 640px) {
  .site .table-wrap { overflow-x: visible; }
  .site .table-wrap > table { table-layout: fixed; }
  .site .table-wrap th, .site .table-wrap td { white-space: normal; overflow-wrap: anywhere; word-break: break-word; hyphens: auto; }
  .site .table-wrap code, .site .table-wrap pre { white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; }
}
.site td, .site th { overflow-wrap: normal; word-break: normal; hyphens: manual; }
.site td code, .site th code { white-space: nowrap; overflow-wrap: normal; }
.site table.labels td:first-child, .site table.labels th:first-child { white-space: nowrap; width: 1%; }
/* a short flag or file name in a label column never breaks, at any width, phones included (2026-10-18) */
.site .table-wrap table.labels td:first-child code { white-space: nowrap; overflow-wrap: normal; word-break: normal; }
@media (max-width: 640px) { .site .table-wrap > table.labels { table-layout: auto; } }
.site ul, .site ol { padding-left: var(--s5); }
.site li { margin: 0 0 var(--s1); }
.site .lede { color: var(--muted); margin: 0 0 var(--s4); }
.site .small { font-size: 14px; color: var(--muted); }
.site .muted { color: var(--muted); }
.site .empty { color: var(--muted); font-family: var(--prose); font-style: italic; }
.site .ok-text { color: var(--ok); font-weight: 700; }
.site .xp-text { color: var(--accent-text); font-weight: 700; font-family: var(--display); font-variant-numeric: tabular-nums; }
.site [hidden] { display: none !important; }

/* buttons: ink, not blue; the secondary is an outline in the same ink */
.site .button, .site button.check { display: inline-flex; align-items: center; justify-content: center; min-height: 44px;
  padding: var(--s2) 20px; border: 1px solid var(--btn-bg); border-radius: var(--r-control); background: var(--btn-bg);
  color: var(--btn-fg); font: 600 15px/1.2 var(--ui); text-decoration: none; cursor: pointer; }
.site .button:hover, .site button.check:hover { background: var(--btn-hover); border-color: var(--btn-hover); }
.site button.check:disabled { opacity: .6; cursor: default; }
.site .button.secondary { background: transparent; color: var(--fg); border-color: var(--control-border); }
.site .button.secondary:hover { background: var(--menu-hover); border-color: var(--fg); }

/* prose in the serif: task text, question text, the room's intro */
.site .task-inner, .site .q-text, .site .intro, .site .hero-summary, .site .module-summary {
  font-family: var(--prose); font-size: 17.5px; line-height: 1.62; }

/* facts under a title: plain words split by thin rules, not pills */
.site .meta { display: flex; flex-wrap: wrap; gap: var(--s1) 0; list-style: none; padding: 0; margin: var(--s3) 0 var(--s4); }
.site .chip { display: inline-flex; align-items: center; margin: 0; padding: 0 var(--s3); border-left: 1px solid var(--rule);
  color: var(--muted); font: 600 14px/1.4 var(--ui); }
.site .chip:first-child { padding-left: 0; border-left: 0; }
.site .chip-easy { color: var(--ok); }

/* the progress bar: 1 cell per question (the page sets --cells); with no --cells it is a plain bar */
.site .bar-track { position: relative; height: 10px; border-radius: 2px; background: var(--track); overflow: hidden;
  --gap: var(--bg); }
.site .bar-fill { height: 100%; width: 0; background: var(--ok-fill); }
.site .bar-track[style*="--cells"]::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(to right, transparent 0, transparent calc(100% / var(--cells) - 2px),
    var(--gap) calc(100% / var(--cells) - 2px), var(--gap) calc(100% / var(--cells))); }
.site .hero-stats { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--s1) var(--s4); margin: var(--s2) 0 0;
  font: 700 15px/1.3 var(--display); font-variant-numeric: tabular-nums; color: var(--fg); }
.site .hero-stats > :last-child { color: var(--accent-text); }

/* the room's top: on the page, not in a card, closed off by 1 rule */
.site .hero { padding: 0 0 var(--s5); margin: 0 0 var(--s5); border-bottom: 1px solid var(--rule); }
.site .hero h1 { font-size: 34px; }
.site .hero-summary { margin: 0; color: var(--fg); }
.site .hero-progress { margin: var(--s1) 0 var(--s5); }
.site .hero-actions { display: flex; flex-wrap: wrap; gap: var(--s3); margin-bottom: var(--s3); }
.site .save-note { margin: 0; color: var(--muted); font-size: 14px; }
.site .intro { margin: 0 0 var(--s5); color: var(--muted); }

/* task cards: the header row opens and closes the card */
.site .task { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r-card); margin: 0 0 var(--s3);
  overflow: hidden; }
.site .task-head { margin: 0; font-size: 16px; }
.site .task-toggle { display: flex; align-items: center; gap: var(--s3); width: 100%; min-height: 56px; padding: var(--s3) var(--s4);
  margin: 0; border: 0; background: transparent; color: var(--fg); text-align: left; cursor: default;
  font: 700 17px/1.3 var(--display); letter-spacing: .005em; }
body.site.js .task-toggle { cursor: pointer; }
body.site.js .task-toggle:hover { background: var(--surface-2); }
.site .task-num { flex: none; color: var(--muted); font: 600 14px/1.3 var(--ui); min-width: 3.4em; }
.site .task-title { flex: 1 1 auto; min-width: 0; }
.site .task-check { flex: none; width: 22px; height: 22px; border-radius: 50%; display: inline-flex; align-items: center;
  justify-content: center; font: 800 13px/1 var(--ui); color: var(--on-ok); border: 2px solid var(--control-border); }
.site .task.complete .task-check { background: var(--ok-fill); border-color: var(--ok-fill); }
.site .task.complete .task-title { color: var(--muted); }
/* the count: a number, not a bubble; green once the task is done */
.site .pill { flex: none; color: var(--muted); font: 700 15px/1 var(--display); font-variant-numeric: tabular-nums;
  white-space: nowrap; }
.site .task.complete .pill { color: var(--ok); }
.site .pill-plain { font: italic 400 15px/1 var(--prose); }
.site .chev { flex: none; width: 9px; height: 9px; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: rotate(45deg); margin: 0 var(--s1) var(--s1) 2px; display: none; }
body.site.js .chev { display: block; }
body.site.js .task.collapsed .chev { transform: rotate(-45deg); margin-bottom: 0; }
.site .task-body { display: grid; grid-template-rows: 1fr; border-top: 1px solid var(--rule-soft); }
.site .task-inner { min-height: 0; overflow: hidden; padding: var(--s4) 20px var(--s2); }
.site .task-inner > .lede:first-child { margin-bottom: var(--s4); }
.site .task.collapsed .task-body { grid-template-rows: 0fr; visibility: hidden; border-top-color: transparent;
  transition: grid-template-rows 150ms ease, visibility 0s linear 150ms, border-top-color 0s linear 150ms; }
.site .task.collapsed .task-inner { padding-top: 0; padding-bottom: 0; transition: padding 150ms ease; }
@media (prefers-reduced-motion: reduce) {
  .site .task.collapsed .task-body, .site .task.collapsed .task-inner { transition: none; } }
.site .task-inner > h3 { margin: var(--s5) 0 0; padding-top: var(--s4); border-top: 1px solid var(--rule);
  font: 700 17px/1.2 var(--display); }

/* questions: rows on a rule, not cards inside a card */
.site .qs { list-style: none; padding: 0; margin: 0; }
.site .q { margin: 0; padding: var(--s4) 0; border-bottom: 1px solid var(--rule-soft); scroll-margin-top: 72px;
  font: 16px/1.5 var(--ui); }
.site .q:last-child { border-bottom: 0; }
.site .q-head { display: flex; align-items: flex-start; gap: var(--s3); margin-bottom: var(--s3); }
.site .q-mark { flex: none; width: 22px; height: 22px; margin-top: 3px; border-radius: 50%; border: 2px solid var(--control-border);
  display: inline-flex; align-items: center; justify-content: center; color: var(--on-ok); font: 800 13px/1 var(--ui); }
.site .q.solved .q-mark { background: var(--ok-fill); border-color: var(--ok-fill); }
.site .q.solved .q-mark::before { content: "\2713"; }
.site .q-text { flex: 1 1 auto; min-width: 0; margin: 0; }
.site .q-num { font: 700 15px var(--display); font-variant-numeric: tabular-nums; color: var(--muted); margin-right: 2px; }
.site .xp-chip { flex: none; margin-top: 4px; color: var(--accent-text); font: 700 14px/20px var(--display);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.site .row { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; }
.site .row input { flex: 1 1 220px; min-width: 0; min-height: 44px; font: 16px var(--mono); padding: var(--s2) var(--s3);
  border: 1px solid var(--input-border); border-radius: var(--r-control); background: var(--input-bg); color: var(--fg); }
.site .row input::placeholder { color: var(--muted); opacity: 1; }
.site .q.solved input { border-color: var(--ok-fill); background: var(--ok-soft); color: var(--fg); }
.site .q.wrong input { border-color: var(--no); box-shadow: inset 0 0 0 1px var(--no); }
.site .cards { display: grid; gap: var(--s2); margin-bottom: var(--s2); }
.site .card { display: block; width: 100%; text-align: left; min-height: 44px; padding: 10px var(--s3);
  border: 1px solid var(--control-border); border-radius: var(--r-control); background: var(--surface);
  font: 16px/1.45 var(--prose); color: var(--fg); cursor: pointer; }
.site .card:hover { border-color: var(--fg); }
.site .card[aria-pressed="true"] { background: var(--sel-bg); border-color: var(--sel-border); box-shadow: inset 0 0 0 1px var(--sel-border); }
.site .q.wrong .card[aria-pressed="true"] { border-color: var(--no); box-shadow: inset 0 0 0 1px var(--no); }
.site .q.solved .card { cursor: default; opacity: .7; }
.site .q.solved .card:hover { border-color: var(--control-border); }
.site .q.solved .card[aria-pressed="true"] { opacity: 1; background: var(--ok-soft); border-color: var(--ok-fill);
  box-shadow: inset 0 0 0 1px var(--ok-fill); }
.site .correct-chip { display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--s2); color: var(--ok);
  font: 700 16px var(--display); }
.site .result { font: 600 14px/1.4 var(--ui); min-height: 1.2em; margin-top: var(--s2); color: var(--muted); }
.site .result:empty { display: none; }
.site .result.ok { color: var(--ok); } .site .result.no { color: var(--no); }
/* since 2026-10-15 18:xx (audit findings 1 to 3). The Check button is never swapped out, so focus stays on it:
   saved, it reads "Correct" in the old chip's look; busy, it is aria-disabled. A right answer no account saved
   is amber (the accent), with a dashed mark, and the field and Check stay live. */
.site button.check.is-correct, .site button.check.is-correct:hover { background: transparent; border-color: transparent;
  color: var(--ok); font: 700 16px var(--display); padding: 0 var(--s2); cursor: default; }
.site button.check[aria-disabled="true"]:not(.is-correct) { opacity: .6; cursor: progress; }
.site .q.unsaved .q-mark { border-color: var(--accent-text); border-style: dashed; }
.site .q.unsaved input { border-color: var(--sel-border); box-shadow: inset 0 0 0 1px var(--sel-border); }
.site .result.warn { color: var(--accent-text); }
.site .inline-form { display: inline; margin: 0; }
.site .linklike { display: inline; padding: 0; margin: 0; border: 0; background: none; font: inherit; color: var(--link);
  cursor: pointer; text-decoration: underline; text-decoration-color: var(--link-line); text-decoration-thickness: 2px;
  text-underline-offset: 3px; }
.site .visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.site details.hint { margin-top: var(--s2); }
.site summary { cursor: pointer; color: var(--fg); font: 600 14px/1.4 var(--ui); width: max-content; max-width: 100%;
  text-decoration: underline; text-decoration-color: var(--link-line); text-decoration-thickness: 2px; text-underline-offset: 3px; }
.site details.hint p { font-family: var(--prose); margin: var(--s2) 0 0; padding-left: var(--s3); border-left: 2px solid var(--rule); }

/* the front page */
.site .modules { list-style: none; padding: 0; margin: 0; }
.site .module { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r-card); padding: 20px var(--s5);
  margin: 0 0 var(--s3); }
.site .module .bar-track { --gap: var(--surface); }
.site .module-title { display: flex; align-items: center; gap: var(--s3); margin: 0 0 var(--s2); font-size: 22px; }
.site .module-title a { color: var(--fg); text-decoration: none; }
.site .module-title a:hover { text-decoration: underline; text-decoration-color: var(--link-line); }
.site .module-check:empty { display: none; }
.site .module-check { width: 24px; height: 24px; border-radius: 50%; background: var(--ok-fill); display: inline-flex;
  align-items: center; justify-content: center; font: 800 14px/1 var(--ui); color: var(--on-ok); }
.site .module-summary { margin: 0; }
.site .module .meta { margin-bottom: var(--s3); }

/* Your box and History */
.site .links { display: flex; flex-wrap: wrap; gap: var(--s3); margin: var(--s4) 0; padding: 0; list-style: none; }
.site .links li { margin: 0; }
.site .box-table { display: table; table-layout: fixed; margin: var(--s3) 0 var(--s4); border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule); }
/* Reset wipes the box, so it is never the loudest button on the page */
.site form[action="/claim/reset"] .button { background: transparent; color: var(--no); border-color: var(--no); }
.site form[action="/claim/reset"] .button:hover { background: var(--no-soft); border-color: var(--no); }
.site .box-table tbody tr:nth-child(even) { background: transparent; }
.site .box-table th { width: 7.5em; color: var(--muted); font: 600 14px/1.5 var(--ui); padding-left: 0; }
.site .box-table td { padding-right: 0; }
.site .box-table tr:last-child th, .site .box-table tr:last-child td { border-bottom: 0; }
.site .copy-line { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; }
.site .history-qs { list-style: none; padding: 0; margin: 0 0 var(--s2); border-top: 1px solid var(--rule); }
.site .history-qs li { margin: 0; padding: 10px 0; border-bottom: 1px solid var(--rule-soft); }
.site .history-qs .qid { font: 700 15px var(--display); font-variant-numeric: tabular-nums; color: var(--muted); margin-right: var(--s1); }
.site .count { font: 700 15px var(--display); font-variant-numeric: tabular-nums; color: var(--muted); margin-left: var(--s1); }
.site .badges { display: flex; flex-wrap: wrap; gap: var(--s3); margin: var(--s2) 0 var(--s4); }
.site .badge { display: flex; align-items: center; gap: var(--s3); padding: 10px var(--s4) 10px 10px; border-radius: var(--r-card);
  min-width: 220px; background: var(--surface); border: 1px solid var(--rule); }
.site .badge strong { display: block; font: 700 16px/1.25 var(--display); }
.site .badge span { display: block; font-size: 13px; color: var(--muted); }
/* not yet: an outline drawn in dashes; earned: filled green */
.site .badge .badge-shield { fill: none; stroke: var(--control-border); stroke-width: 2; stroke-dasharray: 4 3; }
.site .badge .badge-mark { stroke: var(--rule); }
.site .badge.earned { border-color: var(--ok-fill); }
.site .badge.earned .badge-shield { fill: var(--ok-fill); stroke: var(--ok-fill); stroke-dasharray: none; }
.site .badge.earned .badge-mark { stroke: var(--on-ok); }

/* copy buttons */
.site .copy-wrap { position: relative; margin: 0 0 var(--s3); }
.site .copy-wrap pre { padding-right: 84px; white-space: pre-wrap; overflow-wrap: anywhere; }
.site .copy-wrap pre code { overflow-wrap: anywhere; }
.site .copy-btn { min-height: 32px; min-width: 64px; padding: var(--s1) 10px; border-radius: var(--r-control); cursor: pointer;
  font: 600 13px var(--ui); background: transparent; color: var(--fg); border: 1px solid var(--control-border); }
.site .copy-btn:hover { border-color: var(--fg); }
.site .copy-wrap .copy-btn { position: absolute; top: 6px; right: 6px; background: var(--copy-bg); color: var(--copy-fg);
  border-color: #56635c; }
.site .copy-btn.copied { border-color: var(--ok-fill); color: var(--ok); }
.site .copy-wrap .copy-btn.copied { color: #8fe0aa; border-color: #4fb873; }

/* focus: every control shows where the keyboard is, in the accent */
.site a:focus-visible, .site button:focus-visible, .site input:focus-visible, .site summary:focus-visible,
.site-header a:focus-visible, .site-header button:focus-visible {
  outline: 3px solid var(--focus); outline-offset: 2px; border-radius: var(--r-control); }
.site .row input:focus-visible { outline-offset: 1px; }
.site .task-toggle:focus-visible { outline-offset: -3px; }
.site .copy-wrap .copy-btn:focus-visible { outline-color: var(--pre-prompt); }
.site-header a:focus-visible, .site-header .site-avatar-btn:focus-visible { outline-color: var(--focus-bar); }

@media (max-width: 560px) {
  .site main { padding: var(--s5) var(--s4) var(--s6); }
  .site h1, .site .hero h1 { font-size: 27px; }
  .site .task-toggle { padding: 10px var(--s3); gap: 10px; font-size: 16px; }
  .site .task-num { min-width: 0; }
  .site .task-inner { padding: var(--s3) var(--s3) var(--s1); }
  .site .module { padding: var(--s4); }
  .site .chip { padding: 0 10px; }
  .site .box-table th { width: 6.5em; }
  .site .task-inner, .site .q-text, .site .intro, .site .hero-summary, .site .module-summary { font-size: 16.5px; }
}

/* ---- the front page as a learning path, and the path's room pages (2026-10-15, her words: "the practice box
   one is at the top and very clearly emphasized in a subtle gold glow kind of way to get people to click it").
   The glow is the amber already used for link underlines (--link-line): a 1 px border and a soft shadow, the
   same in both themes, never animated. Units unlock in order only to the eye: a unit after the one you are in
   has a dashed marker and a dashed edge; every link works. ---- */
:root { --glow: rgba(201, 138, 28, .30); --glow-ring: rgba(201, 138, 28, .14); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --glow: rgba(240, 180, 76, .22); --glow-ring: rgba(240, 180, 76, .12); } }
:root[data-theme="dark"] { --glow: rgba(240, 180, 76, .22); --glow-ring: rgba(240, 180, 76, .12); }
.site .featured { background: var(--surface); border: 1px solid var(--link-line); border-radius: var(--r-card);
  padding: 20px var(--s5) var(--s5); margin: 0 0 var(--s6); box-shadow: 0 0 0 3px var(--glow-ring), 0 6px 28px var(--glow); }
.site .featured .bar-track { --gap: var(--surface); }
.site .featured-label { display: inline-block; margin: 0 0 var(--s2); padding: 2px 10px; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent-text); font: 700 13px/1.5 var(--ui); letter-spacing: .06em;
  text-transform: uppercase; }
.site main > .featured h2.featured-title, .site .featured-title { display: flex; align-items: center; gap: var(--s3);
  margin: 0 0 var(--s2); font-size: 26px; }
.site .featured-title a { color: var(--fg); text-decoration: none; }
.site .featured-title a:hover { text-decoration: underline; text-decoration-color: var(--link-line); }
.site .featured-note { font: 600 15px/1.45 var(--ui); margin: var(--s3) 0 0; }
.site .featured .hero-actions { margin: var(--s4) 0 0; }
.site .path-intro { color: var(--muted); margin: 0 0 var(--s5); }
.site .path { list-style: none; margin: 0; padding: 0; position: relative; }
.site .path::before { content: ""; position: absolute; left: 15px; top: 24px; bottom: 24px; width: 2px; background: var(--rule); }
.site .path-step { position: relative; margin: 0 0 var(--s4); padding-left: 48px; }
.site .path-marker { position: absolute; left: 0; top: 18px; width: 32px; height: 32px; border-radius: 50%; display: flex;
  align-items: center; justify-content: center; background: var(--bg); border: 2px solid var(--control-border);
  color: var(--fg); font: 700 15px/1 var(--display); font-variant-numeric: tabular-nums; }
.site .path-step.current .path-marker { background: var(--btn-bg); border-color: var(--btn-bg); color: var(--btn-fg); }
.site .path-step.done .path-marker { background: var(--ok-fill); border-color: var(--ok-fill); color: var(--on-ok); }
.site .path-step.later .path-marker { border-style: dashed; color: var(--muted); }
.site .path-card { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r-card); padding: var(--s4) 20px; }
.site .path-step.current .path-card { border-color: var(--control-border); }
.site .path-step.later .path-card { border-style: dashed; border-color: var(--control-border); }
.site .path-card .bar-track { --gap: var(--surface); }
.site .path-kicker { margin: 0 0 var(--s1); color: var(--muted); font: 700 13px/1.4 var(--ui); letter-spacing: .06em;
  text-transform: uppercase; }
.site .path-state { text-transform: none; letter-spacing: 0; }
.site .path-title { margin: 0 0 var(--s2); font-size: 22px; }
.site .path-rooms { list-style: none; margin: var(--s4) 0 0; padding: 0; border-top: 1px solid var(--rule-soft); }
.site .path-room { display: flex; align-items: center; gap: var(--s3); margin: 0; padding: 0; border-bottom: 1px solid var(--rule-soft); }
.site .path-room:last-child { border-bottom: 0; }
.site .path-room-link { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: var(--s3); min-height: 52px;
  padding: 10px 0; color: var(--fg); text-decoration: none; }
.site .path-room-link:hover .path-room-title { text-decoration: underline; text-decoration-color: var(--link-line);
  text-decoration-thickness: 2px; text-underline-offset: 3px; }
.site .path-room-num { flex: none; width: 26px; height: 26px; border-radius: 50%; display: flex; align-items: center;
  justify-content: center; background: var(--surface-2); border: 1px solid var(--control-border); color: var(--fg);
  font: 700 13px/1 var(--display); font-variant-numeric: tabular-nums; }
.site .path-room.complete .path-room-num { background: var(--ok-soft); border-color: var(--ok-fill); color: var(--ok); }
.site .path-room.next .path-room-num { background: var(--btn-bg); border-color: var(--btn-bg); color: var(--btn-fg); }
.site .path-room-name { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.site .path-room-title { font: 600 16px/1.35 var(--ui); overflow-wrap: anywhere; }
.site .path-room-meta { font-size: 13px; color: var(--muted); }
.site .continue-tag { flex: none; padding: 2px 10px; border-radius: 999px; background: var(--btn-bg); color: var(--btn-fg);
  font: 700 13px/1.6 var(--ui); }
.site .path-room-count { flex: none; display: flex; align-items: center; gap: 6px; color: var(--muted);
  font: 700 14px/1 var(--display); font-variant-numeric: tabular-nums; white-space: nowrap; }
.site .path-room.complete .path-room-count { color: var(--ok); }
.site .path-room-check { width: 20px; height: 20px; border-radius: 50%; display: inline-flex; align-items: center;
  justify-content: center; background: var(--ok-fill); color: var(--on-ok); font: 800 12px/1 var(--ui); }
.site .path-room-check:empty { display: none; }
.site .crumb { margin: 0 0 var(--s2); font: 600 14px/1.4 var(--ui); color: var(--muted); }
.site .chip-medium { color: var(--accent-text); }
.site .chip-hard { color: var(--no); }
.site .where { padding: var(--s3) var(--s4); background: var(--surface-2); border-left: 3px solid var(--link-line);
  border-radius: 0 var(--r-control) var(--r-control) 0; }
.site .room-nav { display: flex; flex-wrap: wrap; gap: var(--s3); margin: var(--s5) 0 0; }
.site .room-nav:empty { display: none; }
.site .room-nav a { display: flex; flex-direction: column; gap: 2px; flex: 1 1 240px; padding: var(--s3) var(--s4);
  border: 1px solid var(--rule); border-radius: var(--r-card); background: var(--surface); color: var(--fg);
  text-decoration: none; font: 600 16px/1.35 var(--ui); }
.site .room-nav a:hover { border-color: var(--control-border); }
.site .room-nav .small { font-weight: 500; }
.site .room-nav-next { text-align: right; margin-left: auto; }
@media (max-width: 560px) {
  .site .featured { padding: var(--s4); }
  .site main > .featured h2.featured-title, .site .featured-title { font-size: 23px; }
  .site .path::before { left: 11px; }
  .site .path-step { padding-left: 34px; }
  .site .path-marker { width: 24px; height: 24px; top: 16px; font-size: 13px; }
  .site .path-card { padding: var(--s3); }
  .site .path-room-link { flex-wrap: wrap; row-gap: var(--s1); }
  .site .path-room-name { flex-basis: calc(100% - 40px); }
  .site .continue-tag { margin-left: 38px; }
  .site .room-nav-next { text-align: left; }
}

/* ---- the header, on every page and on /board ---- */
.site-header { position: relative; display: flex; align-items: center; gap: var(--s3); min-height: 56px; padding: var(--s2) var(--s4);
  background: var(--bar-bg); color: var(--bar-fg); font: 16px/1.3 var(--ui); box-sizing: border-box; z-index: 20;
  text-align: left; border-bottom: 1px solid var(--bar-rule); }
.site-header * { box-sizing: border-box; }
.site-header.on-board { margin: -24px -24px 16px; }
.site-header a.site-brand { display: inline-flex; align-items: center; gap: 10px; color: var(--bar-fg); text-decoration: none;
  min-height: 40px; font: 700 18px/1 var(--display); letter-spacing: .01em; }
.site-header .site-brand img { width: 26px; height: 26px; display: block; }
.site-header .site-brand-sub { color: var(--bar-muted); font: 500 16px/1 var(--ui); letter-spacing: 0; }
.site-account { margin-left: auto; display: flex; align-items: center; min-height: 40px; }
.site-header a.site-signin { display: inline-flex; align-items: center; min-height: 40px; padding: 6px var(--s4);
  border-radius: var(--r-control); background: var(--bar-fg); color: var(--bar-bg); font: 600 15px var(--ui); text-decoration: none; }
.site-header a.site-signin:hover { background: #ffffff; }
.site-avatar-btn { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; padding: 0;
  margin: 0; border: 0; border-radius: 50%; background: transparent; cursor: pointer; }
.site-avatar-btn img, .site-avatar-btn .site-initial { width: 32px; height: 32px; border-radius: 50%; display: block;
  border: 2px solid var(--bar-muted); background: #3a4741; }
.site-avatar-btn .site-initial { color: #ffffff; font: 700 15px/28px var(--ui); text-align: center; }
.site-avatar-btn[aria-expanded="true"] img, .site-avatar-btn[aria-expanded="true"] .site-initial { border-color: var(--focus-bar); }
.site-menu { position: absolute; top: calc(100% - 4px); right: var(--s3); width: 288px; max-width: calc(100vw - 24px);
  background: var(--surface); color: var(--fg); border: 1px solid var(--rule); border-radius: var(--r-card);
  box-shadow: var(--shadow-pop); padding: 6px 0; font: 15px/1.4 var(--ui); }
.site-menu[hidden] { display: none; }
.site-menu-who { padding: 10px var(--s4) var(--s3); border-bottom: 1px solid var(--rule-soft); margin-bottom: var(--s1); }
.site-menu-who strong { display: block; font: 700 17px/1.3 var(--display); overflow-wrap: anywhere; }
.site-menu-who span { display: block; color: var(--muted); font-size: 14px; }
.site-menu-level { margin-top: 10px; font: 700 15px/1.3 var(--display); font-variant-numeric: tabular-nums; color: var(--accent-text); }
.site-menu-level .site-level-track { height: 6px; border-radius: 2px; background: var(--track); overflow: hidden; margin-top: 6px; }
.site-menu-level .site-level-fill { height: 100%; width: 0; background: var(--link-line); }
.site-menu-level small { display: block; color: var(--muted); font: 500 13px/1.4 var(--ui); margin-top: var(--s1); }
.site-menu-who .site-menu-badges { margin-top: 6px; font: 600 13px/1.4 var(--ui); }
.site-menu a.site-menu-item, .site-menu button.site-menu-item { display: flex; align-items: center; width: 100%; min-height: 44px;
  padding: var(--s2) var(--s4); border: 0; background: none; color: var(--fg); text-decoration: none; text-align: left;
  font: 15px var(--ui); cursor: pointer; }
.site-menu a.site-menu-item:hover, .site-menu button.site-menu-item:hover { background: var(--menu-hover); }
.site-menu-theme { padding: var(--s2) var(--s4) 10px; border-top: 1px solid var(--rule-soft); border-bottom: 1px solid var(--rule-soft);
  margin: var(--s1) 0; }
.site-menu-label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 6px; font-weight: 600; }
.site-theme-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.site-theme-cards button { min-height: 40px; padding: 6px var(--s1); border: 1px solid var(--control-border); border-radius: var(--r-control);
  background: var(--surface); color: var(--fg); font: 600 14px var(--ui); cursor: pointer; }
.site-theme-cards button[aria-pressed="true"] { background: var(--sel-bg); border-color: var(--sel-border);
  box-shadow: inset 0 0 0 1px var(--sel-border); }
.site-menu form { margin: 0; }
.site-menu a:focus-visible, .site-menu button:focus-visible { outline: 3px solid var(--focus); outline-offset: -3px; }
@media (max-width: 560px) { .site-header { padding: 6px var(--s3); } .site-header.on-board { margin: -24px -24px 16px; } }

/* ---- the midterm 1 review card (2026-10-15 19:xx): under the practice box card, before the path. Practice, not
   graded, so it takes the plain card edge and no amber glow; the practice box stays the 1 card that glows. ---- */
.site .featured.review-card { border-color: var(--control-border); box-shadow: none; margin-top: calc(-1 * var(--s3)); }
.site .review-card .featured-label { background: var(--surface-2); color: var(--muted); border: 1px solid var(--rule); }
.site .review-note { color: var(--muted); font: 500 14px/1.45 var(--ui); margin: var(--s2) 0 0; }
.site .review-card .module-summary { margin-bottom: 0; }

/* since 2026-10-17: C questions (a textarea, then what gcc said and what the program printed) and the staging line */
.site .code-row { display: grid; gap: var(--s2); }
.site .code-in { width: 100%; min-height: 44px; font: 15px/1.45 var(--mono); padding: var(--s2) var(--s3); tab-size: 4;
  border: 1px solid var(--input-border); border-radius: var(--r-control); background: var(--input-bg); color: var(--fg);
  resize: vertical; white-space: pre; overflow-x: auto; }
.site .q.solved .code-in { border-color: var(--ok-fill); background: var(--ok-soft); }
.site .q.wrong .code-in { border-color: var(--no); box-shadow: inset 0 0 0 1px var(--no); }
.site pre.run-out { margin-top: var(--s2); white-space: pre-wrap; overflow-wrap: anywhere; font-size: 14px; }
.site .staging-line { margin: 0; padding: var(--s2) var(--s4); background: var(--accent-soft); color: var(--accent-text);
  font: 600 14px var(--ui); text-align: center; border-bottom: 1px solid var(--rule); }

/* ---- rewards (since 2026-10-17; the script is the rewards part of site.js) ---- */
/* the header stays on screen so XP always has somewhere to land; anchors stop below it */
body.site > .site-header { position: sticky; top: 0; }
html { scroll-padding-top: 64px; }
.site .task { scroll-margin-top: 64px; }

/* reading tasks: Mark task complete, at the end of the task; only with the script, which sends it */
.site .mark-row { display: none; align-items: center; gap: var(--s3); flex-wrap: wrap; margin: var(--s5) 0 var(--s2);
  padding-top: var(--s4); border-top: 1px solid var(--rule); }
body.site.js .mark-row { display: flex; }
.site .mark-row .result { margin-top: 0; }
.site .button.mark-done.is-done, .site .button.mark-done.is-done:hover { background: transparent; border-color: transparent;
  color: var(--ok); font: 700 16px var(--display); padding: 0 var(--s2); cursor: default; }
.site .task.unsaved .task-check { background: transparent; border-color: var(--accent-text); border-style: dashed;
  color: var(--accent-text); }
.site .task.unsaved .button.mark-done.is-done { color: var(--accent-text); }
.site .task-check.popped { animation: site-pop 460ms cubic-bezier(.3,1.6,.5,1); }
@keyframes site-pop { 0% { transform: scale(.6); } 55% { transform: scale(1.45); } 100% { transform: scale(1); } }

/* the avatar: the XP count, the face in its level ring, the level number on the ring */
.site-avatar-btn { width: auto; min-width: 44px; gap: 10px; padding: 0 2px 0 12px; border-radius: 24px; }
.site-avatar-btn:hover { background: rgba(255,255,255,.07); }
.site-avatar-btn .site-xp { color: var(--focus-bar); font: 700 16px/1 var(--display); font-variant-numeric: tabular-nums;
  white-space: nowrap; letter-spacing: .01em; }
.site-avatar-btn .site-xp b { font-weight: 700; }
.site-face { position: relative; display: block; width: 40px; height: 40px; border-radius: 50%; padding: 2px;
  --ring: var(--bar-muted); background: var(--ring); }
.site-face img, .site-face .site-initial { width: 36px; height: 36px; border: 2px solid var(--bar-bg); }
.site-avatar-btn .site-face img, .site-avatar-btn .site-face .site-initial { width: 36px; height: 36px; border: 2px solid var(--bar-bg); }
.site-avatar-btn .site-face .site-initial { line-height: 32px; }
.site-avatar-btn[aria-expanded="true"] .site-face img, .site-avatar-btn[aria-expanded="true"] .site-face .site-initial { border-color: var(--bar-bg); }
.site-avatar-btn[aria-expanded="true"] .site-face { box-shadow: 0 0 0 2px var(--focus-bar); }
.site-face.ring-double { box-shadow: 0 0 0 2px var(--bar-bg), 0 0 0 3.5px var(--ring); }
.site-avatar-btn[aria-expanded="true"] .site-face.ring-double { box-shadow: 0 0 0 2px var(--bar-bg), 0 0 0 3.5px var(--focus-bar); }
.site-level-num { position: absolute; right: -5px; bottom: -4px; min-width: 18px; height: 18px; padding: 0 4px;
  border-radius: 9px; background: var(--ring); color: #14181a; border: 2px solid var(--bar-bg);
  font: 700 11px/14px var(--display); text-align: center; font-variant-numeric: tabular-nums; }
.ring-bronze { --ring: #c0814a; }   .ring-iron { --ring: #9aa1a8; }     .ring-steel { --ring: #c9d4de; }
.ring-mithril { --ring: #7b8cf0; }  .ring-adamant { --ring: #4fb873; }  .ring-rune { --ring: #45c6d6; }
.ring-dragon { --ring: #e0564b; }   .ring-gilded { --ring: #f0c95a; }
.ring-mithril .site-level-num, .ring-dragon .site-level-num { color: #ffffff; }
.site-face.got-xp { animation: site-got 320ms ease-out; }
.site-face.leveled { animation: site-leveled 900ms ease-out; }
@keyframes site-got { 0% { transform: scale(1); } 40% { transform: scale(1.14); } 100% { transform: scale(1); } }
@keyframes site-leveled { 0% { transform: scale(1); box-shadow: 0 0 0 0 var(--ring); }
  30% { transform: scale(1.22) rotate(-8deg); } 60% { transform: scale(1) rotate(4deg); box-shadow: 0 0 0 14px transparent; }
  100% { transform: none; } }

/* XP in flight: amber orbs and a +N XP tag that rises off the question */
.site-xp-orb { position: fixed; z-index: 70; width: 10px; height: 10px; border-radius: 50%; pointer-events: none;
  background: var(--focus-bar); box-shadow: 0 0 0 2px rgba(240,180,76,.25), 0 0 10px rgba(240,180,76,.7); }
.site-xp-float { position: fixed; z-index: 70; pointer-events: none; transform: translate(-50%, -50%);
  color: var(--accent-text); font: 700 18px/1 var(--display); font-variant-numeric: tabular-nums; white-space: nowrap;
  animation: site-float 900ms ease-out forwards; }
@keyframes site-float { 0% { opacity: 0; transform: translate(-50%, -30%); } 20% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -190%); } }
.site-confetti { position: fixed; inset: 0; width: 100vw; height: 100vh; z-index: 65; pointer-events: none; }

/* the card: room completed, or a new level. Terminal ink, an amber bar that runs down, then it flies to the avatar.
   Bottom right, so it never covers the task title that just took focus under the sticky header */
.site-card { position: fixed; right: var(--s4); z-index: 60; width: 320px; max-width: calc(100vw - 32px);
  padding: var(--s4) 20px var(--s5); border-radius: var(--r-card); background: var(--bar-bg); color: var(--bar-fg);
  border: 1px solid var(--focus-bar); box-shadow: var(--shadow-pop); overflow: hidden; cursor: pointer;
  animation: site-card-in 360ms cubic-bezier(.2,1.3,.4,1); }
.site-card-kicker { display: block; color: var(--focus-bar); font: 600 14px/1.3 var(--ui); }
.site-card-title { display: block; margin-top: 2px; font: 700 21px/1.25 var(--display); overflow-wrap: anywhere; }
.site-card-sub { display: block; margin-top: var(--s1); color: var(--bar-muted); font: 500 14px/1.4 var(--ui); }
.site-card-bar { position: absolute; left: 0; bottom: 0; height: 4px; width: 100%; background: var(--focus-bar);
  transform-origin: left; animation: site-card-bar linear forwards; }
@keyframes site-card-in { from { opacity: 0; transform: translateY(16px) scale(.96); } to { opacity: 1; transform: none; } }
@keyframes site-card-bar { from { transform: scaleX(1); } to { transform: scaleX(0); } }
.site-visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

@media (max-width: 560px) {
  .site-avatar-btn { padding-left: 8px; gap: 8px; }
  .site-avatar-btn .site-xp { font-size: 15px; }
  .site-card { right: var(--s3); left: var(--s3); width: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .site-face.got-xp, .site-face.leveled, .site-card, .site-xp-float { animation: none; }
  .site-card-bar { animation-name: site-card-bar; }
  .site .task-check.popped { animation: none; }
}

/* ---- ape.jdoner.me (2026-10-17): joined paths folded to a title row, the Continue card, All paths, search ---- */
.site .unit-fold > summary { list-style: none; cursor: pointer; display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: var(--s1) var(--s3); padding: 2px 0 var(--s2); }
.site .unit-fold > summary::-webkit-details-marker { display: none; }
.site .unit-fold > summary .path-title { margin: 0; font: 700 20px/1.3 var(--display); }
.site .unit-fold > summary .path-title::after { content: "Show rooms"; margin-left: var(--s3); font: 600 13px/1 var(--ui);
  color: var(--muted); text-decoration: underline; text-decoration-color: var(--link-line); text-underline-offset: 3px; }
.site .unit-fold[open] > summary .path-title::after { content: "Hide rooms"; }
.site .unit-fold > summary:focus-visible { outline: 2px solid var(--link-line); outline-offset: 4px; border-radius: 4px; }
.site .unit-row-meta { color: var(--muted); font: 600 14px/1.4 var(--ui); font-variant-numeric: tabular-nums; }
.site .unit-fold .module-summary { margin: var(--s2) 0 var(--s3); }
.site .ape-path-link { margin: var(--s3) 0 0; font-size: 14px; }
.site .ape-empty { margin: var(--s3) 0 0; color: var(--muted); font-style: italic; }
.site .ape-one .unit-fold > summary .path-title::after { content: none; }
.site .ape-continue { background: var(--surface); border: 1px solid var(--control-border); border-radius: var(--r-card);
  padding: var(--s4) 20px; margin: 0 0 var(--s5); }
.site .ape-continue-kicker { margin: 0 0 var(--s2); color: var(--muted); font: 700 13px/1.4 var(--ui); letter-spacing: .04em; }
.site .ape-continue-button { max-width: 100%; white-space: normal; text-align: left; }
.site .ape-browse { margin-top: var(--s6, 40px); }
.site .ape-browse-list { list-style: none; margin: 0 0 var(--s4); padding: 0; border-top: 1px solid var(--rule-soft); }
.site .ape-browse-item { display: flex; align-items: center; gap: var(--s3); border-bottom: 1px solid var(--rule-soft); }
.site .ape-browse-item a { flex: 1 1 auto; display: flex; align-items: center; gap: var(--s3); min-height: 56px;
  padding: var(--s3) 0; color: var(--fg); text-decoration: none; }
.site .ape-browse-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.site .ape-browse-count { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; color: var(--muted);
  font-size: 14px; font-variant-numeric: tabular-nums; }
.site .ape-chev { flex: none; font: 400 26px/1 var(--ui); color: var(--muted); }
.site .ape-browse-item a:hover .ape-chev { color: var(--fg); }
.site .ape-start { margin: 0 0 var(--s4); padding: var(--s3) var(--s4); background: var(--accent-soft); border-radius: var(--r-control);
  font-weight: 600; }
.site .unit-fold > summary, .site .unit-fold > summary * { text-decoration: none; }
.site .ape-browse-item a:hover .ape-browse-title { text-decoration: underline; text-decoration-color: var(--link-line); }
.site .ape-browse-title { font: 600 17px/1.35 var(--ui); }
.site .ape-browse-line { color: var(--muted); font-size: 14px; }
.site .ape-joined-tag { flex: none; font: 700 12px/1 var(--ui); color: var(--ok); background: var(--ok-soft);
  border-radius: 999px; padding: 4px 8px; }
.site .ape-search { max-width: 420px; }
.site .ape-search label { display: block; margin: 0 0 var(--s1); font: 600 14px/1.4 var(--ui); color: var(--muted); }
.site .ape-search input { width: 100%; box-sizing: border-box; font: 16px/1.4 var(--ui); padding: 8px 10px;
  border: 1px solid var(--control-border); border-radius: 8px; background: var(--surface); color: var(--fg); }
.site .ape-results { list-style: none; margin: var(--s2) 0 0; padding: 0; border: 1px solid var(--rule); border-radius: 8px;
  background: var(--surface); }
.site .ape-results li a { display: flex; justify-content: space-between; gap: var(--s3); padding: 10px 12px; color: var(--fg);
  text-decoration: none; border-bottom: 1px solid var(--rule-soft); }
.site .ape-results li:last-child a { border-bottom: 0; }
.site .ape-results li a:hover { background: var(--menu-hover); }
.site .ape-hit-kind { color: var(--muted); font-size: 13px; flex: none; }

/* ---- listings (2026-10-17, her words: like VS Code or a terminal, no sideways scrolling): ape-hl.js marks them.
   Source code: a light editor with line numbers drawn by CSS (Copy never copies them); long lines wrap with a
   hanging indent under the number, never a sideways scroll. Terminal and output: the dark block, prompt in amber,
   the command bright, the output dimmer. Colors pass 4.5:1 on their own background in both themes. ---- */
:root { --ed-bg: #fbfcfa; --ed-fg: #1f2328; --ed-gutter: #66706a; --ed-rule: #d9dfda; --ed-kw: #8b2fc9; --ed-type: #0b6b6b;
  --ed-str: #a23d12; --ed-num: #1750b0; --ed-com: #5f6b64; --ed-fn: #6a4a00; --ed-lit: #1750b0; --ed-meta: #8a5000;
  --term-out: #c4cec8; --term-cmd: #ffffff; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --ed-bg: #1b211e; --ed-fg: #e4eae5; --ed-gutter: #93a19a;
  --ed-rule: #2f3a34; --ed-kw: #d7a6ff; --ed-type: #7fd8d0; --ed-str: #f2a37f; --ed-num: #9cc4ff; --ed-com: #93a19a; --ed-fn: #f0d58a;
  --ed-lit: #9cc4ff; --ed-meta: #f0b44c; } }
:root[data-theme="dark"] { --ed-bg: #1b211e; --ed-fg: #e4eae5; --ed-gutter: #93a19a; --ed-rule: #2f3a34; --ed-kw: #d7a6ff;
  --ed-type: #7fd8d0; --ed-str: #f2a37f; --ed-num: #9cc4ff; --ed-com: #93a19a; --ed-fn: #f0d58a; --ed-lit: #9cc4ff; --ed-meta: #f0b44c; }
.site pre.hl-java, .site pre.hl-c { background: var(--ed-bg); color: var(--ed-fg); border: 1px solid var(--ed-rule);
  white-space: pre-wrap; overflow-wrap: anywhere; overflow-x: hidden; counter-reset: hl-line; padding-left: 0; }
.site pre.hl-java code, .site pre.hl-c code { white-space: pre-wrap; overflow-wrap: anywhere; }
.site pre.hl-java .hl-line, .site pre.hl-c .hl-line { display: block; box-sizing: border-box;
  position: relative; padding-left: 3.4em; text-indent: 0; counter-increment: hl-line; }
.site pre.hl-java .hl-line::before, .site pre.hl-c .hl-line::before { content: counter(hl-line); content: counter(hl-line) / "";
  position: absolute; left: 0;
  width: 2.4em; text-align: right; color: var(--ed-gutter); user-select: none; -webkit-user-select: none; }
.site .hl-kw { color: var(--ed-kw); font-weight: 600; }
.site .hl-type { color: var(--ed-type); }
.site .hl-str { color: var(--ed-str); }
.site .hl-num, .site .hl-lit { color: var(--ed-num); }
.site .hl-com { color: var(--ed-com); font-style: italic; }
.site .hl-fn { color: var(--ed-fn); }
.site .hl-meta { color: var(--ed-meta); }
.site pre.hl-terminal { white-space: pre-wrap; overflow-wrap: anywhere; overflow-x: hidden; }
.site pre.hl-terminal code { white-space: pre-wrap; overflow-wrap: anywhere; }
.site .hl-prompt { color: var(--pre-prompt); }
.site .hl-cmd { color: var(--term-cmd); font-weight: 600; }
.site .hl-out { color: var(--term-out); }
.site pre.hl-text { white-space: pre-wrap; overflow-wrap: anywhere; overflow-x: hidden; }
/* 2 listings side by side stack when the page is too narrow to hold both at full line width */
.site .listing-pair, .site .side-by-side { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 34em), 1fr)); gap: var(--s3); }
.site .listing-pair > *, .site .side-by-side > * { min-width: 0; }
@media (max-width: 600px) {
  .site pre.hl-java, .site pre.hl-c, .site pre.hl-terminal, .site pre.hl-text { font-size: 13px; }
  .site pre.hl-java .hl-line, .site pre.hl-c .hl-line { padding-left: 2.6em; }
  .site pre.hl-java .hl-line::before, .site pre.hl-c .hl-line::before { width: 1.9em; }
  .site .hl-ind { font-size: .5em; }
}
/* the per-choice why under a multiple-choice result (ape.jdoner.me, 2026-10-17) */
.site .result .why { margin: var(--s1) 0 0; font-weight: 400; color: var(--fg); }
/* the file tab on a Java listing (ape-hl.js sets data-file from its public class) */
.site pre.hl[data-file]::before { content: attr(data-file); display: block; margin: calc(-1 * var(--s3)) 0 var(--s2) 0;
  padding: 6px 12px; font: 600 12.5px/1.3 var(--ui); color: var(--ed-fg); background: var(--surface-2);
  border-bottom: 1px solid var(--ed-rule); border-radius: var(--r-control) var(--r-control) 0 0; }
/* figures (her ruling of 2026-10-17 09:02: diagrams are rendered figures, never text art): the light or the dark
   render follows the page's theme, the width of the text column at most, scaled down on a phone, never scrolled */
.site figure.fig { margin: var(--s4) 0; text-align: center; }
.site figure.fig img { max-width: 100%; height: auto; display: inline-block; }
.site figure.fig .fig-dark { display: none; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .site figure.fig .fig-light { display: none; }
  :root:not([data-theme="light"]) .site figure.fig .fig-dark { display: inline-block; } }
:root[data-theme="dark"] .site figure.fig .fig-light { display: none; }
:root[data-theme="dark"] .site figure.fig .fig-dark { display: inline-block; }
.site figure.fig figcaption { margin-top: var(--s2); font-size: 14px; color: var(--muted); }
.site .ape-signin-note { margin: 0 0 var(--s4); color: var(--muted); }
/* the setup box, only on a room that has the student clone a practice APE (spec field setup) */
.site .setup-box { margin: 0 0 var(--s4); padding: var(--s3) var(--s4); background: var(--accent-soft); border-radius: var(--r-control); }
.site .setup-box p { margin: 0; }
/* the code around a Java answer and its expected output, shown above the answer box (2026-10-17) */
.site .given { margin: var(--s2) 0 var(--s3); }
.site .given-label { margin: var(--s2) 0 var(--s1); font: 600 14px/1.4 var(--ui); color: var(--muted); }
.site .ape-exam-date { margin: 0 0 var(--s3); font-weight: 600; }
/* wrapping (2026-10-17 10:1x, the render check found "toSt / ring" at 390): a listing breaks inside a word only
   when that word cannot fit on a line of its own; the break points after . ( , that ape-hl.js adds come first */
.site .copy-wrap pre.hl, .site .copy-wrap pre.hl code, .site pre.hl, .site pre.hl code { overflow-wrap: break-word; word-break: normal; }
/* on a phone the Copy button sits under the listing, so the code gets the whole width */
@media (max-width: 600px) {
  .site .copy-wrap pre { padding-right: var(--s3); }
  .site .copy-wrap { display: flex; flex-direction: column; }
  .site .copy-wrap .copy-btn { position: static; align-self: flex-end; margin-top: 4px; order: 2; }
}
/* tables on a phone (agy eye review 2026-10-17 16:51: a right column cut off at 390): cells and the code in them may
   wrap, so a table fits the text width instead of scrolling sideways */
@media (max-width: 600px) {
  /* words in cells break only when a word alone cannot fit; code in cells may break anywhere (17:5x: "Answer / ed") */
  .site td, .site th { overflow-wrap: break-word; }
  .site td code, .site th code { white-space: normal; overflow-wrap: anywhere; }
  .site table.labels td:first-child, .site table.labels th:first-child { white-space: normal; width: auto; }
}
/* the Practice exams page (/exams/, 2026-10-17, decision d-2026-10-17-practice-exams-hub-on-ape-jdoner-me-with-live-scores):
   the path page's compact rows; on the right Accept, or the latest score as a bar with the pass line, its time and
   Feedback. On a phone the right side drops under the name */
.site .exam-hero { margin-bottom: var(--s4); }
.site .exam-hero .hero-summary { margin-bottom: var(--s2); }
.site .exam-how { margin: 0; }
.site .exam-note { min-height: 0; margin: 0 0 var(--s3); color: var(--muted); }
.site .exam-note:empty { display: none; }
.site .exam-card .path-rooms { margin-top: var(--s2); }
.site .exam-tally { margin: 0; font: 700 14px/1.4 var(--display); color: var(--muted); font-variant-numeric: tabular-nums; }
.site .exam-first { margin: var(--s3) 0 0; padding: var(--s3) var(--s4); background: var(--accent-soft);
  border-left: 3px solid var(--link-line); border-radius: 0 var(--r-control) var(--r-control) 0; }
.site .exam-first p { margin: 0; }
.site .exam-first[hidden], .site .exam-how[hidden] { display: none; }
.site .exam-next { margin: var(--s5) 0 0; }
.site nav.crumb { display: block; }
/* the exams path on the front page (once linked): its fold says exams, not rooms */
.site [data-path="exams"] .unit-fold > summary .path-title::after { content: "Show exams"; }
.site [data-path="exams"] .unit-fold[open] > summary .path-title::after { content: "Hide exams"; }
.site .exam-cmds { list-style: none; padding: 0; }
.site .exam-cmds li { margin: 0 0 var(--s2); }
.site .exam-cmds code { overflow-wrap: anywhere; }
/* View as (instructors only, 2026-10-17 18:4x): the form in the hero and the exams unit, and the banner over the rows */
.site .exam-viewas-form { margin: var(--s3) 0 0; }
.site .exam-viewas-form label { display: block; font: 600 14px/1.4 var(--ui); color: var(--muted); margin: 0 0 var(--s1); }
.site .exam-viewas-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); }
.site .exam-viewas-row input { min-height: 44px; padding: 0 12px; border: 1px solid var(--input-border); border-radius: var(--r-control);
  background: var(--input-bg); color: var(--fg); font: 500 16px/1 var(--ui); flex: 1 1 180px; min-width: 0; max-width: 260px; }
.site .exam-viewas-row a { display: inline-flex; align-items: center; min-height: 44px; }
.site .exam-viewas { margin: 0 0 var(--s3); padding: var(--s3) var(--s4); background: var(--sel-bg); border-left: 3px solid var(--sel-border);
  border-radius: 0 var(--r-control) var(--r-control) 0; }
.site .exam-viewas p { margin: 0; }
.site .exam-card.loading .exam-act { visibility: hidden; }
.site .exam-row { padding: 12px 0; flex-wrap: wrap; row-gap: var(--s2); scroll-margin-top: 80px; }
.site .exam-name { flex: 1 1 260px; min-width: 0; display: flex; align-items: center; gap: var(--s3); }
.site .exam-act { flex: 0 1 auto; display: flex; align-items: center; justify-content: flex-end; gap: var(--s3);
  margin-left: auto; }
.site .exam-act .button { min-height: 44px; padding: 0 18px; }
.site .exam-score { display: flex; flex-direction: column; gap: 4px; width: 216px; }
.site .exam-score[hidden], .site .exam-act [hidden] { display: none; }
.site .exam-bar { --gap: var(--surface); }
.site .exam-bar .bar-fill { background: var(--accent-text); }
.site .exam-bar.passing .bar-fill { background: var(--ok-fill); }
.site .exam-bar { overflow: visible; box-shadow: inset 0 0 0 1px var(--control-border); }
.site .exam-pass-line { position: absolute; top: -3px; bottom: -3px; left: 75%; width: 2px; background: var(--fg);
  box-shadow: 0 0 0 1px var(--surface); }
.site .exam-score-text { margin: 0; font: 500 13px/1.35 var(--ui); color: var(--muted); }
.site .exam-score-text [data-when] { display: block; }
.site .exam-score-text [data-when]:empty { display: none; }
.site .exam-score-text strong { font: 700 15px/1 var(--display); color: var(--fg); font-variant-numeric: tabular-nums; }
.site .exam-steps { padding-left: 1.4em; }
.site .exam-steps li { margin: 0 0 var(--s4); }
.site .exam-steps h2 { margin: 0 0 var(--s1); font-size: 19px; }
.site .exam-steps p { margin: 0; }
.site .exam-rules li { margin-bottom: var(--s2); }
@media (max-width: 600px) {
  .site .exam-name { flex: 1 1 0; }
  .site .exam-row.has-score .exam-name { flex: 1 1 100%; }
  .site .exam-row.has-score .exam-act { flex: 1 1 100%; justify-content: space-between; margin-left: 38px; }
  .site .exam-score { flex: 1 1 auto; width: auto; min-width: 0; }
}
/* wide column (her words of 2026-10-20 08:12, a 70-character Java line wrapping at desktop width, and 19:2x, "I dont like
   that the box is wider than the rest of it"). On a screen 900 px or wider the whole room column is 1040 px, so a
   listing stays inside the column and a line of about 100 characters still fits on one line. A listing with a file
   tab carries Copy in the tab bar, so it drops the right padding kept for the button. Below 900 px nothing changes:
   lines wrap and nothing scrolls sideways. */
.site .copy-wrap pre.hl[data-file] { padding-right: var(--s3); }
@media (min-width: 900px) {
  .site main { max-width: 1040px; }
}
}
/* the course as units of modules of rooms (her words of 2026-10-20 19:3x): on the front page each unit is a card that
   opens to its modules; the chevron turns when it is open; the whole row is the click target */
.site .course-units { display: flex; flex-direction: column; gap: var(--s3); margin: var(--s3) 0 var(--s4); }
.site .course-unit { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r-card); }
.site .course-unit > summary { list-style: none; cursor: pointer; display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: var(--s1) var(--s3); padding: var(--s3) var(--s4); min-height: 56px; }
.site .course-unit > summary::-webkit-details-marker { display: none; }
.site .course-unit > summary:hover { background: var(--surface-2); border-radius: var(--r-card); }
.site .course-unit > summary:focus-visible { outline: 2px solid var(--link-line); outline-offset: 2px; border-radius: var(--r-card); }
.site .course-unit-title { font: 700 19px/1.3 var(--display); }
.site .course-unit-title::before { content: ""; display: inline-block; width: 8px; height: 8px; margin: 0 12px 2px 2px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(-45deg); transition: transform 120ms ease; }
.site .course-unit[open] .course-unit-title::before { transform: rotate(45deg); }
.site .course-unit-meta { color: var(--muted); font: 600 14px/1.4 var(--ui); font-variant-numeric: tabular-nums; }
.site .course-unit-body { padding: 0 var(--s4) var(--s3); border-top: 1px solid var(--rule-soft); }
.site .course-unit-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s4); margin: var(--s3) 0; }
.site .course-unit .ape-browse-list { margin-bottom: 0; }
@media (prefers-reduced-motion: reduce) { .site .course-unit-title::before { transition: none; } }
@media (max-width: 600px) { .site .course-unit > summary, .site .course-unit-body { padding-left: var(--s3); padding-right: var(--s3); } }
.site .course-unit > summary, .site .course-unit > summary span { text-decoration: none; }

/* cybr101rooms.jdoner.me (2026-10-24): the one large button to the class CTF, first on the front page */
.site .ctf-call { margin: 0 0 var(--s5); padding: var(--s4); border: 1px solid var(--control-border); border-radius: var(--r-card); background: var(--surface); }
.site .ctf-button { width: 100%; min-height: 56px; font-size: 19px; white-space: normal; text-align: center; }
.site .ctf-note { margin: var(--s2) 0 0; text-align: center; }
