/* print.css — the printed form of a practice sheet.

   Before this file, `@media print` appeared nowhere in the repo: printing any
   page produced the app chrome, the nav, and a key the learner could read
   while attempting the problems. A generated sheet is only useful on paper if
   the paper version is a worksheet rather than a screenshot of a web app.

   Two rules come from docs/research/printed-course-structure.md:
     - The key goes on its OWN pages at the back, never beside the problem.
       Feedback matters more under interleaving, not less (Rohrer and Hartwig
       2023: interleaved practice produces more failures, and "they cannot
       learn from such failures unless they receive feedback"), but feedback
       is only feedback after an attempt.
     - Numbering and running heads are signals, and signalling carries
       retention g+ = 0.53 across 103 studies. They are cheap; keep them.

   Everything here is scoped to @media print, so it cannot affect the screen. */

@media print {
  /* Chrome off. The sheet is the document. */
  /* .skip-link is index.html's accessibility jump target. It belongs to the
     app, not to the book, and it printed on the cover of every PDF this book
     ever produced because this list did not name it. */
  /* #erc-banner is the cookie-consent bar js/analytics.js appends to the
     body. It has no class, only an id, so the gate that checks this list
     never looked for it — and it printed on EVERY page of a 1,223-page
     book, between the notation entries. */
  .topbar, .mobnav, #mobnav, .crumb, .ws-noprint, .ws-controls, .skip-link,
  #erc-banner,
  footer, .site-footer, .fab, .toast, #modalRoot, .scrim { display: none !important; }

  html, body {
    background: #fff !important;
    color: #000 !important;
    font-size: 11pt;
    margin: 0;
    padding: 0;
  }
  #app, #view { margin: 0 !important; padding: 0 !important; max-width: none !important; }

  @page { margin: 18mm 16mm 20mm 16mm; }

  /* A running head on every page, so a loose sheet can be identified. */
  .ws-head h1 { font-size: 18pt; margin: 0 0 2mm; }
  .ws-head .lede, .ws-taught { font-size: 10pt; color: #333 !important; margin: 0 0 3mm; }
  .ws-taught a { color: #000 !important; text-decoration: none; }

  /* Worked examples: the sheet teaches before it asks. */
  .ws-examples {
    border: 1pt solid #999;
    padding: 4mm 5mm;
    margin: 0 0 6mm;
    break-inside: avoid;
  }
  .ws-examples h2 { font-size: 11pt; margin: 0 0 2mm; text-transform: uppercase; letter-spacing: .05em; }
  .ws-example { margin: 0 0 3mm; }
  .ws-example:last-child { margin-bottom: 0; }
  .ws-ex-prompt { font-weight: 600; margin: 0 0 1mm; }
  .ws-example ol { margin: 0; padding-left: 6mm; }

  /* Problems: two columns, each problem kept whole. */
  .ws-problems { columns: 2; column-gap: 8mm; }
  .ws-problems h2 { column-span: all; font-size: 11pt; margin: 0 0 3mm; text-transform: uppercase; letter-spacing: .05em; }
  .ws-problem {
    break-inside: avoid;
    page-break-inside: avoid;
    display: flex;
    gap: 3mm;
    margin: 0 0 7mm;
  }
  .ws-n { font-weight: 700; min-width: 7mm; }
  /* Room to work. A printed problem with no white space under it is a quiz,
     not a worksheet. */
  .ws-q { flex: 1; min-height: 18mm; }
  .ws-star { break-inside: avoid; }

  /* The answer controls are screen-only: on paper the learner writes. */
  .ws-q input, .ws-q button, .ws-q select, .ws-q math-field,
  .ws-q .quiz-actions, .ws-q .quiz-feedback, .ws-q .btn { display: none !important; }
  /* ...except the options of a multiple-choice problem, which ARE the problem. */
  .ws-q .quiz-options, .ws-q .quiz-options * { display: revert !important; }
  .ws-q .quiz-options { list-style: upper-alpha; padding-left: 6mm; }

  .ws-figure svg, .ws-figure img { max-width: 60mm; height: auto; }

  /* The key: forced onto its own page, at the back, never beside a problem. */
  .ws-key {
    break-before: page;
    page-break-before: always;
    columns: 2;
    column-gap: 8mm;
  }
  /* <details> is collapsed on screen; print it open regardless of the toggle. */
  .ws-key > summary { column-span: all; list-style: none; }
  .ws-key > summary::-webkit-details-marker { display: none; }
  .ws-key > summary h2 { font-size: 13pt; margin: 0 0 4mm; }
  .ws-key[open] > *, .ws-key > * { display: revert !important; }
  .ws-key-row { break-inside: avoid; display: flex; gap: 3mm; margin: 0 0 4mm; }
  .ws-key-a { font-weight: 700; margin: 0; }
  .ws-key-why { margin: 1mm 0 0; font-size: 10pt; color: #222 !important; }

  /* ── The test paper (js/exam.js) ────────────────────────────────────────
     It borrows .ws-problems, .ws-problem and .ws-key wholesale, so it inherits
     the two-column body, the unsplittable problem box and the key's own pages
     at the back. Only what a test has and a practice sheet does not is here. */
  .ex-paper-head { break-after: avoid; margin: 0 0 6mm; }
  .ex-paper-head h1 { font-size: 18pt; margin: 0 0 2mm; }
  .ex-covers, .ex-stamp, .ex-note { font-size: 9.5pt; color: #333 !important; margin: 0 0 1.5mm; }
  .ex-note { font-style: italic; }
  .ex-prompt { margin: 0 0 1.5mm; }
  /* Room to work in. The reason the paper exists is that the working happens on
     it, so the space is part of the question, not padding around it. */
  .ex-work {
    height: 22mm;
    border-bottom: 1pt dotted #bbb;
    margin: 1mm 0 0;
  }
  /* "Before you start": the pre-training page, scoped to one paper
     (printed-course-structure.md §1, 13 of 16 tests, median d = 0.75). It is
     kept whole and sits above the first question, because a reader who meets
     the symbol for the first time in question 4 has already lost the question. */
  .ex-pre {
    border: 1pt solid #999;
    padding: 4mm 5mm;
    margin: 0 0 6mm;
    break-inside: avoid;
    break-after: avoid;
  }
  .ex-pre h3 { font-size: 10pt; margin: 0 0 2mm; text-transform: uppercase; letter-spacing: .05em; }
  .ex-pre h3 + ul + h3 { margin-top: 4mm; }
  .ex-pre-list { list-style: none; margin: 0; padding: 0; font-size: 10pt; }
  .ex-pre-list li { margin: 0 0 2mm; break-inside: avoid; }
  .ex-sym { display: inline-block; min-width: 10mm; font-weight: 700; }
  .ex-where, .ex-unmet { display: block; font-size: 9pt; color: #444 !important; }
  .ex-unmet { font-style: italic; }
  .ex-choices, .ex-lines { list-style: none; margin: 1mm 0 0; padding: 0; }
  .ex-choices li, .ex-lines li { margin: 0 0 1mm; display: flex; gap: 2mm; align-items: baseline; }
  .ex-letter { font-weight: 700; min-width: 5mm; }
  /* A true/false item, which on screen is two buttons. On paper the reader has
     to be told it is a question and given something to circle. */
  .ex-ask { font-weight: 700; margin: 1.5mm 0 1mm; }
  .ex-tf { display: flex; gap: 6mm; margin: 0; }
  .ex-tf-o { border: 1pt solid #999; border-radius: 4mm; padding: 0.8mm 4mm; }

  a[href]::after { content: ""; }   /* no printed URLs: they are lesson links, not references */
}

/* Screen styles for the sheet. Kept in this file so the whole feature is one
   stylesheet to load, and deliberately light — the sheet should look like a
   sheet on screen too. */
.ws-index { list-style: none; padding: 0; display: grid; gap: .35rem; }
.ws-index li { display: flex; justify-content: space-between; gap: 1rem; padding: .45rem .6rem; border-radius: 8px; background: var(--surface-2, rgba(127, 127, 127, .06)); }
.ws-head { margin-bottom: 1rem; }
.ws-taught { font-size: .9rem; }
.ws-examples { border: 1px solid var(--line); border-radius: 10px; padding: .8rem 1rem; margin: 1rem 0; }
.ws-examples h2 { font-size: .95rem; margin: 0 0 .5rem; }
.ws-ex-prompt { font-weight: 600; margin: 0 0 .25rem; }
.ws-controls { display: flex; flex-wrap: wrap; gap: .75rem; align-items: center; margin: 1rem 0; }
.ws-check { display: inline-flex; gap: .35rem; align-items: center; }
.ws-problems { display: grid; gap: 1rem; margin-top: 1rem; }
.ws-problem { display: flex; gap: .75rem; padding: .75rem; border-radius: 10px; background: var(--surface-2, rgba(127, 127, 127, .05)); }
.ws-problem.ws-star { border: 1px solid var(--accent, #c8a24a); }
.ws-n { font-weight: 700; opacity: .7; min-width: 1.6rem; }
.ws-q { flex: 1; min-width: 0; }
.ws-key { margin-top: 1.5rem; }
.ws-key > summary { cursor: pointer; }
.ws-key > summary h2 { display: inline; font-size: 1.05rem; }
.ws-key-row { display: flex; gap: .75rem; padding: .5rem 0; border-top: 1px solid var(--line); }
.ws-key-a { font-weight: 700; margin: 0; }
.ws-key-why { margin: .2rem 0 0; font-size: .9rem; opacity: .85; }
.ws-meta { margin-top: 1rem; font-size: .85rem; }

/* Screen styles for the test paper. The paper is shown as it will print — the
   builder above it is the only part that is not on the page you hand over. */
.ex-controls { margin: 0 0 1.25rem; }
.ex-kinds { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .6rem; }
.ex-row { display: flex; flex-wrap: wrap; gap: .75rem; align-items: center; margin: .75rem 0; }
.ex-subjects { border: 1px solid var(--line); border-radius: 10px; padding: .5rem .75rem; }
.ex-subjects > summary { cursor: pointer; font-size: .9rem; }
.ex-ticks { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: .3rem .9rem; margin-top: .6rem; }
.ex-ticks label { display: flex; gap: .4rem; align-items: baseline; font-size: .9rem; }
.ex-tick-actions { display: flex; gap: .4rem; margin-top: .6rem; }
.ex-paper-head { margin: 1.5rem 0 1rem; }
.ex-covers, .ex-stamp, .ex-note { font-size: .88rem; opacity: .8; margin: .2rem 0; }
.ex-note { font-style: italic; }
.ex-prompt { margin: 0 0 .35rem; }
.ex-work { height: 3.5rem; border-bottom: 1px dashed var(--line-strong); margin-top: .35rem; }
.ex-pre { border: 1px solid var(--line); border-radius: 10px; padding: .8rem 1rem; margin: 1rem 0 1.25rem; }
.ex-pre h3 { font-size: .8rem; margin: 0 0 .5rem; text-transform: uppercase; letter-spacing: .05em; opacity: .75; }
.ex-pre h3 + ul + h3 { margin-top: .9rem; }
.ex-pre-list { list-style: none; margin: 0; padding: 0; font-size: .9rem; display: grid; gap: .4rem; }
.ex-sym { display: inline-block; min-width: 2rem; font-weight: 700; }
.ex-where, .ex-unmet { display: block; font-size: .8rem; opacity: .7; }
/* opacity:1 overrides the .7 of the rule above: --orange at full strength is 5.62:1
   on the paper surface and 6.22:1 on --surface-1; blended at .7 it is 3.11:1,
   under AA, and contrast-check reads tokens so it cannot see an opacity. */
.ex-unmet { font-style: italic; color: var(--orange); opacity: 1; }
.ex-choices, .ex-lines { list-style: none; margin: .35rem 0 0; padding: 0; }
.ex-choices li, .ex-lines li { display: flex; gap: .5rem; align-items: baseline; margin: 0 0 .2rem; }
.ex-letter { font-weight: 700; opacity: .7; }
.ex-ask { font-weight: 700; margin: .4rem 0 .25rem; }
.ex-tf { display: flex; gap: 1rem; margin: 0; }
.ex-tf-o { border: 1px solid var(--line-strong); border-radius: 999px; padding: .1rem .8rem; font-size: .9rem; }

/* ── The booklet (js/booklet.js): front matter, then sections, key at the back ──
   Same two rules as a sheet, applied to a hundred pages instead of three: the
   key never sits beside its problem, and the structure is signalled rather than
   implied (docs/research/printed-course-structure.md §3, §5). */
@media print {
  .bk-noprint { display: none !important; }

  .bk-cover { break-after: page; page-break-after: always; text-align: center; padding-top: 40mm; }
  .bk-cover h1 { font-size: 30pt; margin: 0 0 4mm; }
  .bk-cover .lede { font-size: 13pt; }
  .bk-count, .bk-personal { font-size: 10pt; color: #333 !important; }

  /* Front matter: the pre-training page and the contents, before any problem. */
  .bk-front { break-after: page; page-break-after: always; }
  .bk-front h3 { font-size: 12pt; margin: 6mm 0 2mm; text-transform: uppercase; letter-spacing: .05em; }
  .bk-pre, .bk-notation { list-style: none; padding: 0; }
  /* Screen styling must not follow the book onto paper. The list rules further
     down give these rows a tinted rounded card, which on screen separates them
     and on paper is a grey box that eats toner and prints muddy on a mono
     laser. Reset every screen decoration here rather than hunting for it later:
     print is the medium this document is FOR. */
  .bk-pre li, .bk-notation li, .bk-index li, .bk-contents li:nth-child(odd) {
    background: transparent !important;
    border-radius: 0 !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
  }
  .bk-pre li, .bk-notation li { break-inside: avoid; margin: 0 0 2.5mm; }

  /* A running head on every page. Chrome repeats a fixed-position element on
     each printed page, which is the only way to get one without a print engine.
     It carries the book's title so a loose page can be identified, and it is
     the answer to page numbers that may not line up: a reader navigates by the
     section number printed at the top of each section, which cannot drift. */
  .bk-runhead {
    position: fixed;
    top: 0; left: 0; right: 0;
    font-size: 8pt;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: #555 !important;
    border-bottom: .3pt solid #bbb;
    padding-bottom: 1mm;
  }
  .bk-where { display: block; font-size: 9pt; color: #444 !important; }
  .bk-sym { display: inline-block; min-width: 10mm; }
  .bk-nothing { font-style: italic; }

  .bk-contents { columns: 2; column-gap: 8mm; list-style: none; padding: 0; counter-reset: none; }
  .bk-contents li { break-inside: avoid; display: flex; gap: 2mm; align-items: baseline; margin: 0 0 1.5mm; }
  .bk-sec { font-weight: 700; min-width: 9mm; }
  .bk-uses { font-size: 9pt; color: #555 !important; }
  .bk-page { margin-left: auto; font-variant-numeric: tabular-nums; }

  .bk-section { break-before: page; page-break-before: always; }
  .bk-section h2 { font-size: 14pt; margin: 0 0 4mm; }
  .bk-problems { columns: 2; column-gap: 8mm; }
  .bk-problems li { break-inside: avoid; margin: 0 0 7mm; min-height: 16mm; }

  .bk-key { break-before: page; page-break-before: always; }
  .bk-key h2 { font-size: 14pt; }
  .bk-key h3 { font-size: 11pt; margin: 4mm 0 2mm; }
  .bk-key-list { columns: 2; column-gap: 8mm; }
  .bk-key-list li { break-inside: avoid; margin: 0 0 2mm; }
  .bk-key-why { font-size: 9pt; color: #222 !important; }
}

/* Screen styles for the booklet. */
.bk-cover h1 { margin-bottom: .25rem; }
.bk-count, .bk-personal, .bk-warn { font-size: .9rem; opacity: .8; }
.bk-personal { font-weight: 600; opacity: 1; }
.bk-front h3 { font-size: 1rem; margin: 1.25rem 0 .5rem; }
.bk-pre, .bk-notation, .bk-contents, .bk-index { list-style: none; padding: 0; }
.bk-pre li, .bk-notation li { padding: .4rem .6rem; margin-bottom: .3rem; border-radius: 8px; background: var(--surface-2, rgba(127,127,127,.06)); }
.bk-where { display: block; font-size: .82rem; opacity: .75; }
.bk-sym { display: inline-block; min-width: 2.2rem; }
/* How the symbol is READ, set apart from the mathematics it follows. Without
   this the two run together on the page — "17 ÷ 5 = 3 remainder 2seventeen
   divided by five" — because js/booklet.js emits this class and, until
   2026-09-08, nothing in the repo styled it. */
.bk-sym-reads { display: block; font-style: italic; opacity: .8; margin-top: .15rem; }
.bk-contents li { display: flex; gap: .5rem; align-items: baseline; padding: .3rem .5rem; border-radius: 6px; }
.bk-contents li:nth-child(odd) { background: var(--surface-2, rgba(127,127,127,.05)); }
.bk-sec { font-weight: 700; opacity: .65; min-width: 2.2rem; }
.bk-uses { font-size: .8rem; opacity: .7; }
.bk-page { margin-left: auto; opacity: .6; font-variant-numeric: tabular-nums; }
.bk-index li { display: flex; justify-content: space-between; gap: 1rem; padding: .45rem .6rem; border-radius: 8px; background: var(--surface-2, rgba(127,127,127,.06)); margin-bottom: .3rem; }
.bk-special li { background: var(--surface-3, rgba(127,127,127,.12)); }
.bk-section { margin-top: 2rem; }
.bk-problems li, .bk-key-list li { margin-bottom: .5rem; }
.bk-key { margin-top: 2rem; }
.bk-key-why { opacity: .8; font-size: .9rem; }

/* The problem STATEMENT, where the question is only its last line. It reads as
   one paragraph with the question, so it is inline rather than a block: an
   olympiad star is "An equilateral triangle has side 6. Area = ?", not a
   heading and a question. */
.bk-stem { display: inline; }
.ws-stem { margin: 0 0 .35rem; }

/* ── The measuring frame ───────────────────────────────────────────────────────
   Real page numbers need real measurement: the contents page used to print an
   estimate (sections x 4.5), which is worse than useless once a reader tries to
   turn to p.412 and finds something else there.

   The browser will not tell you where its page breaks fall, so the book is laid
   out once in a hidden container sized to the SAME page box the @page rule
   above uses, and js/booklet.js reads each section's offset against that box.
   The three numbers below are the single source of that box: print and
   measurement must agree or the count is fiction, so @page's margins are
   restated here as custom properties and nowhere else.

   A4 is 210 x 297mm. Content width = 210 - 16 - 16 = 178mm.
   Content height = 297 - 18 - 20 = 259mm. */
:root {
  --page-w: 178mm;
  --page-h: 259mm;
  --page-gap: 8mm;
}

/* Off-screen, but laid out for real: `visibility: hidden` inside a zero-clip
   wrapper keeps the browser computing geometry (display:none would not) while
   nothing reaches the screen or a screen reader. */
.bk-measure {
  position: absolute;
  left: -10000px;
  top: 0;
  width: var(--page-w);
  visibility: hidden;
  pointer-events: none;
  font-size: 11pt;
  line-height: 1.35;
}
.bk-measure[data-mode="print"] .bk-problems,
.bk-measure[data-mode="print"] .bk-key-list { columns: 2; column-gap: var(--page-gap); }
/* Reading mode is one column at a larger size, and measuring it as two columns
   of 11pt understated Volume I by half: the cover claimed 64 pages against the
   124 the print dialog produced. These mirror the @media print rules below. */
.bk-measure[data-mode="read"] { font-size: 12pt; line-height: 1.5; }
.bk-measure[data-mode="read"] .bk-problems,
.bk-measure[data-mode="read"] .bk-key-list { columns: auto; }
.bk-measure[data-mode="read"] .bk-problems li { min-height: 0; margin: 0 0 3.5mm; }
.bk-measure[data-mode="read"] .bk-key-list li { margin: 0 0 2.5mm; }
.bk-measure .bk-problems li,
.bk-measure .bk-key-list li { break-inside: avoid; margin: 0 0 7mm; min-height: 16mm; }
.bk-measure .bk-section { margin: 0 0 6mm; }

/* The running head belongs to paper only. */
.bk-runhead { display: none; }
@media print { .bk-runhead { display: block; } }

/* "This is an index, not the whole book." It used to be grey text after the
   twelfth section, where a reader who had already printed never saw it. It is
   a callout at the top now, and it prints, because the printed copy is exactly
   where the misunderstanding survives. */
.bk-more {
  border: 1px solid var(--line-strong, #999);
  border-left-width: 4px;
  padding: .7rem .9rem;
  margin: 0 0 1.2rem;
  font-size: .92rem;
}
.bk-pick { margin-right: .5rem; }
/* "Build my version": every chapter, each opening to its lessons. Two
   thousand rows at once would be the wall this feature exists to avoid. */
/* The parts of a personal book. On paper the reader holds one part, so the
   list of the others is screen-only. */
.bk-parts { margin: 1rem 0 0; padding: .7rem .9rem; border: 1px solid var(--line, #ddd); border-radius: 8px; }
.bk-partlist { margin: .5rem 0 0; padding-left: 1.3rem; display: flex; flex-direction: column; gap: .25rem; }
@media print { .bk-parts { display: none; } }
.bk-mine { margin: 1rem 0 0; }
.bk-mine > summary { cursor: pointer; }
.bk-minelist { max-height: 22rem; overflow-y: auto; margin: .6rem 0; border: 1px solid var(--line, #ddd); border-radius: 6px; padding: .4rem .6rem; }
.bk-minech > summary { cursor: pointer; padding: .15rem 0; }
.bk-minehead { display: inline; }
.bk-minelessons { padding: .2rem 0 .5rem 1.4rem; display: flex; flex-direction: column; gap: .15rem; }
.bk-minelesson { font-size: .9rem; }
@media print { .bk-mine { display: none; } }
.bk-buildsel { display: flex; flex-wrap: wrap; gap: .75rem; align-items: center; margin: 1rem 0 0; }
.bk-buildsel .muted { font-size: .82rem; max-width: 52ch; }
.bk-actions { display: flex; flex-wrap: wrap; gap: .75rem; align-items: center; margin: 0 0 1rem; }
.bk-printhint { font-size: .82rem; max-width: 46ch; }

/* ── Book typography ──────────────────────────────────────────────────────────
   The layout was correct and it still read as a printed web page. This is the
   difference, and it is CRAFT rather than evidence: docs/research/design.md §2
   gives line length as the critical variable (Grade B, and any specific number
   only Grade C) and dark-on-light polarity (Grade A, already true on paper).
   It says nothing about serif versus sans, chapter openings or justification,
   so nothing below is dressed up as research.

   Five things were making it look like a web page:
     a sans-serif body, ragged-right setting, uppercase letterspaced headings,
     bordered boxes, and section titles styled as <h2> rather than as the
     opening of a chapter.

   Fraunces is already vendored and self-hosted (css/fonts.css) with a true
   italic, so the book face costs nothing new. `lang="en"` is set on <html>,
   which is what makes `hyphens: auto` work — justified text without hyphenation
   opens rivers, and is worse than ragged-right.

   Loaded after the rules above so it wins on specificity ties. */
@media print {
  html, body {
    font-family: "Fraunces", Georgia, "Times New Roman", serif;
    font-size: 10.5pt;
    line-height: 1.45;
    font-variant-numeric: oldstyle-num;
  }

  /* Justified with hyphenation. Headings, lists of problems and anything with
     mathematics stay ragged — justifying a line containing a KaTeX box stretches
     the spaces around the maths, and design.md §3 makes spacing a correctness
     property, not a taste one. */
  .bk-body p, .bk-hook, .bk-teach p {
    text-align: justify;
    hyphens: auto;
    -webkit-hyphens: auto;
    orphans: 2;
    widows: 2;
  }
  .bk-problems li, .bk-key-list li, .bk-contents li, h1, h2, h3, h4 {
    text-align: left;
    hyphens: manual;
  }

  /* The prose measure. Problems stay in two columns; explanation does not —
     a paragraph of teaching in a 40-character column reads like a newspaper,
     and line length is the one variable design.md §2 will actually commit to. */
  .bk-teach { max-width: 118mm; }

  /* A section opens like a chapter: air above it, the number small and set
     apart, the title large and quiet. Not an <h2> with a bottom margin. */
  .bk-section > h2 {
    font-size: 17pt;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
    margin: 18mm 0 6mm;
    padding-bottom: 2mm;
    border-bottom: .4pt solid #000;
  }
  .bk-section:first-of-type > h2 { margin-top: 0; }

  /* Headings stop shouting. Uppercase + letterspacing is a UI convention and
     it is the loudest "this came from a website" signal on the page. */
  .bk-front h3, .bk-practice-h, .ws-examples h2, .ws-problems h2 {
    font-family: "Fraunces", Georgia, serif;
    font-size: 11pt;
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0;
    font-style: italic;
  }

  /* Callouts and worked examples: a rule and an indent, the way a printed book
     sets an aside. A bordered card is a screen idiom. */
  .bk-worked, .bk-callout, .ws-examples {
    border: 0;
    border-left: 1.2pt solid #000;
    border-radius: 0;
    padding: 0 0 0 5mm;
    margin: 4mm 0 4mm 4mm;
    background: transparent !important;
  }
  .bk-callout { border-left-style: double; }
  .bk-callout .bk-wrong { font-style: italic; }
  .bk-worked-h {
    font-style: italic;
    font-weight: 600;
    margin: 0 0 1mm;
  }

  /* The cover, given the room a title page expects. */
  .bk-cover { padding-top: 62mm; }
  .bk-cover h1 { font-size: 34pt; font-weight: 600; letter-spacing: -.01em; }
  .bk-cover .lede { font-size: 12pt; font-style: italic; }

  /* Running head in the book's own voice rather than a UI label. */
  .bk-runhead {
    font-family: "Fraunces", Georgia, serif;
    font-size: 8.5pt;
    font-style: italic;
    letter-spacing: 0;
    text-transform: none;
  }

  /* Mathematics keeps its own metrics — KaTeX sizes relative to the body, and
     design.md §3 warns that the smallest glyphs on the page are the sub- and
     superscripts. Nudged up so they stay inside the fluent range on paper. */
  .katex { font-size: 1.06em; }
}

/* ── The book does not inherit the website ────────────────────────────────────
   Owner, on seeing the first real PDF: "the book doesn't have to follow how the
   website is." Correct, and the first printed cover proved why — the title came
   out grey, sans-serif and left-aligned while everything under it was black,
   serif and centred, because `app.css` sets `h1 { font-family: var(--font-display);
   color: var(--ink-strong) }` and --font-display is Bricolage Grotesque, a sans.
   Setting the SIZE of a heading and not its family leaves the site's voice in
   the middle of the book.

   So this block overrides the design TOKENS themselves for print, rather than
   playing specificity whack-a-mole against every rule that consumes them. Only
   the book and the sheets are ever printed, so re-pointing the tokens at the
   book face is safe and says the intent once. */
@media print {
  :root {
    --font-display: "Fraunces", Georgia, "Times New Roman", serif;
    --font-body: "Fraunces", Georgia, "Times New Roman", serif;
    --ink: #000;
    --ink-strong: #000;
    --ink-soft: #333;
    --ink-faint: #555;
    --accent: #000;
    --line: #bbb;
  }
  h1, h2, h3, h4 {
    font-family: "Fraunces", Georgia, "Times New Roman", serif !important;
    color: #000 !important;
    letter-spacing: 0 !important;
  }

  /* The title page, set deliberately rather than inherited. Everything centred,
     the title given room, a rule to close it, and the whole block sitting on the
     upper third where a title sits — not floating in the middle of nowhere. */
  .bk-cover {
    text-align: center !important;
    padding-top: 55mm;
  }
  .bk-cover h1 {
    text-align: center !important;
    font-size: 32pt !important;
    font-weight: 600 !important;
    line-height: 1.1;
    margin: 0 auto 6mm;
    padding-bottom: 5mm;
    border-bottom: .5pt solid #000;
    max-width: 120mm;
  }
  .bk-cover .lede {
    text-align: center !important;
    font-size: 12.5pt;
    font-style: italic;
    color: #000 !important;
    margin: 0 0 3mm;
  }
  .bk-cover .bk-count,
  .bk-cover .bk-personal,
  .bk-cover .bk-warn {
    text-align: center !important;
    font-size: 9.5pt;
    color: #333 !important;
  }
  /* No running head on the title page: a cover carries its own name. */
  .bk-cover ~ * .bk-runhead { display: block; }
}

@media print {
  .bk-ahead { list-style: none; padding: 0; }
  .bk-ahead li { break-inside: avoid; margin: 0 0 2.5mm; }
  .bk-ahead-note { font-style: italic; font-size: 9.5pt; margin: 0 0 2mm; }
}
.bk-ahead { list-style: none; padding: 0; }
.bk-ahead li { padding: .4rem .6rem; margin-bottom: .3rem; border-radius: 8px; background: var(--surface-2, rgba(127,127,127,.06)); }
.bk-ahead-note { font-size: .85rem; opacity: .8; margin: 0 0 .4rem; }
.bk-vol { display: block; }
.bk-vol .muted { display: block; }
.bk-vol-note { display: block; font-size: .85rem; opacity: .72; margin-top: .2rem; }

/* ── Reading on a screen, which is what this book is actually for ─────────────
   Owner, on the first PDF: "im not trying to get this to be printed, im just
   doing this so i can use it on my tablet."

   A printed worksheet and a tablet book are different documents, and every
   choice above optimised for the wrong one:

     two columns          on a tablet you scroll to the bottom of column one and
                          back up to the top of column two, for every page
     16mm under a problem  room to write, on a surface you cannot write on
     A4 at 10.5pt          a page you must pinch-zoom to read

   So `[data-mode="read"]` is the DEFAULT and paper is the option. Both go
   through Save-as-PDF; they differ only in what the page is shaped for. */
@media print {
  .bk[data-mode="read"] { font-size: 12pt; line-height: 1.5; }

  /* One column, everywhere. */
  .bk[data-mode="read"] .bk-problems,
  .bk[data-mode="read"] .bk-key-list,
  .bk[data-mode="read"] .bk-contents,
  .bk[data-mode="read"] .bk-notation { columns: auto; }

  /* No writing space: on a screen it is just scrolling. */
  .bk[data-mode="read"] .bk-problems li { min-height: 0; margin: 0 0 3.5mm; }
  .bk[data-mode="read"] .bk-key-list li { margin: 0 0 2.5mm; }

  /* A comfortable measure without the two-column crutch, and the teaching no
     longer needs its own narrower clamp. */
  .bk[data-mode="read"] .bk-teach { max-width: none; }
  /* Measure and leading, both taken off Axler rather than guessed.
     Measured there: median 65 characters a line (p90 72), leading 1.38x the
     type size. 34em rendered at 74 characters in Fraunces, so 30em brings it
     onto his median; 1.40 leading is his, rounded. Line length is the one
     variable design.md §2 will commit to (Grade B), and 65 is a measurement
     from a book people like reading rather than a number off a style guide. */
  .bk[data-mode="read"] .bk-body p,
  .bk[data-mode="read"] .bk-hook { max-width: 30em; }
  .bk[data-mode="read"] { line-height: 1.40; }

  /* A section still starts a page — that is what makes the contents' page
     numbers meaningful and what a PDF reader treats as a chapter boundary. */
  .bk[data-mode="read"] .bk-section { break-before: page; page-break-before: always; }
}

/* On screen, the same distinction, so what you see is what you save. */
.bk[data-mode="read"] .bk-problems { display: block; }
.bk[data-mode="read"] .bk-body p, .bk[data-mode="read"] .bk-hook { max-width: 30em; }
.bk-mode { display: inline-flex; gap: .35rem; align-items: center; font-size: .85rem; }
.bk-contents a { text-decoration: none; }
.bk-contents a:hover { text-decoration: underline; }

/* ── Hints, index, difficulty marks, numbered subsections ─────────────────────
   The four things the reference books have and this book did not. */
@media print {
  /* Hints and the index each start their own page: hints must not be visible
     from the problem, and an index is a back-of-book object. */
  .bk-hints, .bk-indexpage { break-before: page; page-break-before: always; }
  .bk-hints h3, .bk-indexpage h2 { break-after: avoid; }
  .bk-hint-list { list-style: none; padding: 0; }
  .bk-hint-list li { break-inside: avoid; margin: 0 0 2mm; }

  /* Two columns for the index even in reading mode: index entries are short,
     and a single column of them is a page of whitespace. */
  .bk-ix { columns: 2; column-gap: 8mm; margin: 0; }
  .bk-ix dt.bk-ix-letter {
    column-span: none;
    font-weight: 700;
    font-size: 11pt;
    margin: 3mm 0 1mm;
    break-after: avoid;
  }
  .bk-ix dd { margin: 0 0 .6mm; display: flex; gap: 2mm; break-inside: avoid; font-size: 9.5pt; }
  .bk-ix-refs { margin-left: auto; font-variant-numeric: tabular-nums; }
  .bk-ix-refs a { color: #000 !important; text-decoration: none; }

  /* The difficulty mark sits in the margin, not in the sentence. */
  .bk-mark { font-size: 9pt; }
  .bk-subno { font-weight: 400; color: #555 !important; margin-right: 1.5mm; }
}

.bk-hints { margin-top: 2rem; }
.bk-hint-list { list-style: none; padding: 0; }
.bk-hint-list li { padding: .3rem 0; }
.bk-ix { margin: 0; columns: 2; column-gap: 2rem; }
.bk-ix dt.bk-ix-letter { font-weight: 700; margin: .8rem 0 .2rem; }
.bk-ix dd { margin: 0 0 .15rem; display: flex; gap: .5rem; font-size: .9rem; }
.bk-ix-refs { margin-left: auto; opacity: .7; font-variant-numeric: tabular-nums; }
.bk-mark { opacity: .75; }
.bk-subno { opacity: .55; font-weight: 400; margin-right: .35rem; }

/* Review pages — the chapter final and the cumulative checkpoint. They are
   real sections with real section numbers, because a review a reader can skip
   without noticing is a review nobody does. The rule above the heading marks
   them as a different kind of page without needing a colour. */
.bk-review { border-top: 3px double var(--line-strong, #999); padding-top: .6rem; }
.bk-review-note { font-size: .9rem; opacity: .85; margin: 0 0 .8rem; }

/* The part-range control on a personal book's cover. Screen only: on paper the
   reader is holding the job it produced. */
.bk-partrange { margin: .5rem 0 0; display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.bk-partrange input { width: 4.5rem; }
@media print { .bk-partrange { display: none; } }

/* Practice that sits between two read steps rather than at the end of the
   section. It needs less air above it than the section's own heading: it is a
   turn in the same conversation, not a new subject. */
.bk-practice-inline { margin-top: .7rem; }

/* THE BOOK'S VERTICAL RHYTHM. Every class below was emitted by js/booklet.js
   and styled by nothing, which gate B9 now catches. `.bk-read` is the wrapper
   around EVERY teaching step, so its absence is why a page arrived as one
   undifferentiated slab — the owner's "no gaps so it looks so overwhelming".
   These are spacing rules only: the book's type is set elsewhere, and what was
   missing was the air between one idea and the next. */
.bk-read { margin: 0 0 1.15rem; }
.bk-read:last-child { margin-bottom: 0; }
.bk-noteach { margin: .5rem 0 1rem; }
.bk-rolled-worked { margin: .9rem 0; }
.bk-why { margin: .3rem 0 0; }
/* One notation entry: the symbol and its name, the worked instance, the check. */
.bk-sym-head { margin: 0 0 .25rem; }
.bk-sym-ex { margin: .15rem 0 .4rem; }
.bk-sym-check { margin: .45rem 0 0; }

/* The one-line legend in the front matter. The worked treatment of the same
   symbols lives in .bk-notation in the appendix at the back; this is the scan
   sheet printed-course-structure.md §1 actually licenses. */
.bk-legend { list-style: none; padding: 0; margin: .4rem 0 1rem; }
.bk-legend li { margin: 0 0 .28rem; line-height: 1.35; break-inside: avoid; }
.bk-legend .bk-sym { display: inline-block; min-width: 2.6em; }

/* A symbol taught where it is first used, and a hard problem shown worked
   before the hard band. Both are teaching inside a section, so they sit apart
   from the prose without starting a page. */
.bk-notation-here { margin: .6rem 0 1rem; }
.bk-sym-teach { margin: 0 0 .8rem; break-inside: avoid; }
.bk-worked-hard { break-inside: avoid; }
.bk-worked-ans { margin: .3rem 0 0; font-weight: 600; }

/* Choices under a closed problem, and the per-distractor feedback in the key. */
.bk-ask { margin: .2rem 0 .1rem; font-style: italic; }
.bk-choices { list-style: none; margin: .25rem 0 0; padding: 0 0 0 .6rem; }
.bk-choices li { margin: 0 0 .12rem; min-height: 0; break-inside: avoid; }
.bk-choice-k { display: inline-block; min-width: 1.4em; font-weight: 600; }
.bk-key-distractors { list-style: none; margin: .15rem 0 0; padding: 0 0 0 .8rem; }
.bk-key-distractors li { margin: 0; }

/* The working a fix-mistake item asks the reader to check. */
.bk-lines { list-style: none; margin: .25rem 0 0; padding: 0 0 0 .6rem; }
.bk-lines li { margin: 0 0 .12rem; min-height: 0; break-inside: avoid; }

/* A widget probe, printed as a prediction with its answer under it. */
.bk-probe { margin: .5rem 0 .7rem; padding: 0 0 0 .7rem; border-left: 2px solid currentColor; break-inside: avoid; }
.bk-probe-note { margin: 0 0 .2rem; font-style: italic; }
.bk-probe-q { margin: 0 0 .15rem; }
.bk-probe-a { margin: .25rem 0 0; }
.bk-probe-only { margin: .3rem 0 .5rem; font-style: italic; }
