/* Chapter (long-form) view styles. Loaded in both modes; CSS toggles
   hide/show via body.mode-chapter / body.mode-slides classes. */

:root {
  --fg: #1c1c1c;
  --muted: #5a5a5a;
  --accent: #2e5f6a;
  --bg: #ffffff;
  --rule: #e3e3e3;
  --code-bg: #f7f7f5;
  --width: 720px;
}

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: "Charter", "Iowan Old Style", Georgia, "Times New Roman", serif;
  font-size: 18px;
  line-height: 1.55;
}

/* Safety net: any stray wide element (a markdown image with a
   pixel width, a long inline pre tag, a third-party embed) should
   never punch a horizontal scrollbar through the whole page.
   [overflow-x: clip] is preferred over [hidden] because it does
   not establish a new scroll container and so does not break the
   sticky positioning of the page header. Scoped to chapter mode
   because reveal.js manages its own viewport in slide mode. */
body.mode-chapter {
  overflow-x: clip;
}

:root {
  --sidebar-width: 260px;
}

/* Toggle visibility by mode. */
body.mode-chapter .reveal { display: none; }
body.mode-slides  .chapter { display: none; }
body.mode-slides  .lecture-meta-footer { display: none; }

/* Opening title slides are slide-mode only. In chapter mode the
   page-header bar and the lecture's own H1 already carry the
   title, so the inline title slide is redundant. Authored as a
   `:::slide` block wrapping `<div class="title-slide-inner">`. */
body.mode-chapter section:has(.title-slide-inner) { display: none; }

.page-header {
  position: sticky;
  top: 0;
  background: var(--bg);
  border-bottom: 1px solid var(--rule);
  padding: 0.6rem 1rem;
  /* [box-sizing: border-box] so the header's padding stays inside
     its declared width. Without this, on narrow viewports the
     padding adds 2rem to the content width and pushes the header
     past 100vw. */
  box-sizing: border-box;
  max-width: 100%;
  display: flex;
  /* Vertically centre items by box, not by text baseline. The ⌂
     glyph in the home link extends well below the normal text
     baseline; baseline alignment lets the button box hang below
     the header rule and get visually clipped. */
  align-items: center;
  /* Allow the header to wrap onto a second row on narrow viewports
     so the right-side cell-controls cluster does not overflow the
     viewport horizontally. */
  flex-wrap: wrap;
  /* Uniform spacing between all header items: the same 0.4rem used
     by the inner cell-controls. The lecture-title has [flex: 1] so
     it absorbs the wide gap between the left cluster (sidebar
     toggle + home + meta) and the right cluster (cell controls +
     mode toggle); other adjacent items stay at 0.4rem. */
  gap: 0.4rem;
  /* Sits above x-ocaml's shadow-DOM Run button (z-index 999), so
     a cell scrolling under the sticky header is hidden by it
     instead of painting its Run over the banner. */
  z-index: 1000;
}
.lecture-meta {
  color: var(--muted);
  font-size: 0.85rem;
  font-family: ui-sans-serif, system-ui, -apple-system, sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.lecture-title {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 600;
  flex: 1 1 0;
  /* Without [min-width: 0], a flex item's minimum size defaults to
     its content's intrinsic width, which prevents the title from
     shrinking and pushes the rightmost header buttons off-screen
     on narrower viewports. Allow shrinking with an ellipsis when
     space gets tight. */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* [overflow: hidden] clips at the content box. Without an
     explicit line-height + small padding-bottom the box height
     equals the typographic line, and descenders (g, p, y, ?
     tail) get clipped at the bottom edge. */
  line-height: 1.4;
  padding-bottom: 0.1rem;
}
.mode-toggle,
.cell-controls button {
  border: 1px solid var(--rule);
  background: transparent;
  padding: 0.35rem 0.8rem;
  border-radius: 4px;
  cursor: pointer;
  color: var(--accent);
  font-family: ui-sans-serif, system-ui, -apple-system, sans-serif;
  font-size: 0.85rem;
}
.mode-toggle:hover,
.cell-controls button:hover { background: var(--code-bg); }
.cell-controls {
  display: flex;
  gap: 0.4rem;
  /* Let buttons wrap to a second row on narrow viewports instead
     of overflowing the header (and the page) horizontally. */
  flex-wrap: wrap;
}
body.mode-chapter .when-slides  { display: none; }
body.mode-slides  .when-chapter { display: none; }

.chapter {
  max-width: var(--width);
  margin: 2rem auto;
  padding: 0 1rem 4rem;
  /* A bare URL written as link text (e.g. autolink
     [<https://example.com/very/long/path>]) is one unbreakable token;
     on narrow viewports it forces the line to extend past the
     viewport edge. [overflow-wrap: anywhere] lets the browser
     break it after any character if needed, but leaves normal
     prose alone. */
  overflow-wrap: anywhere;
}

/* ---- GitBook-style sidebar ---- */

.sidebar {
  position: fixed;
  top: 3.4rem;
  bottom: 0;
  left: 0;
  width: var(--sidebar-width);
  overflow-y: auto;
  border-right: 1px solid var(--rule);
  background: #fcfcfb;
  padding: 1rem 0.75rem 2rem;
  font-family: ui-sans-serif, system-ui, -apple-system, sans-serif;
  font-size: 0.9rem;
  z-index: 5;
}
.sidebar-title {
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0 0.5rem 0.4rem;
}
.sidebar-nav details {
  margin: 0.2rem 0;
}
.sidebar-nav summary {
  cursor: pointer;
  list-style: none;
  padding: 0.25rem 0.5rem;
  border-radius: 3px;
  color: var(--fg);
  font-weight: 600;
}
.sidebar-nav summary::marker,
.sidebar-nav summary::-webkit-details-marker {
  display: none;
}
.sidebar-nav summary::before {
  content: "▸";
  font-size: 0.7em;
  margin-right: 0.5em;
  color: var(--muted);
}
.sidebar-nav details[open] > summary::before {
  content: "▾";
}
.sidebar-nav summary:hover { background: var(--code-bg); }
.sidebar-nav .week-no {
  display: inline-block;
  font-size: 0.78em;
  color: var(--muted);
  margin-right: 0.3em;
}
.sidebar-lectures {
  list-style: none;
  padding: 0;
  margin: 0.2rem 0 0.4rem 1.4rem;
}
.sidebar-lectures li a {
  display: block;
  padding: 0.2rem 0.5rem;
  border-radius: 3px;
  text-decoration: none;
  color: var(--fg);
  font-weight: 400;
}
.sidebar-lectures li a:hover { background: var(--code-bg); }
.sidebar-lectures li.current > a {
  background: #e8f0e6;
  color: var(--accent);
  font-weight: 600;
}
.sidebar-lectures .lec-no {
  display: inline-block;
  width: 2.4em;
  color: var(--muted);
  font-size: 0.85em;
}

/* Shift the article right when the sidebar is visible. The sidebar
   is var(--sidebar-width) wide; we leave 2.5rem of breathing room
   between the sidebar's right edge and the start of the chapter
   prose so the text is not flush against the rule. */
@media (min-width: 900px) {
  body.mode-chapter:not(.sidebar-hidden) .chapter,
  body.mode-chapter:not(.sidebar-hidden) .prev-next,
  body.mode-chapter:not(.sidebar-hidden) .lecture-meta-footer {
    margin-left: calc(var(--sidebar-width) + 2.5rem);
    margin-right: 1.5rem;
  }
}
body.sidebar-hidden .sidebar { display: none; }

/* The toggle lives in the header bar; hide it in slide mode. */
.sidebar-collapse {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 1px solid var(--rule);
  background: transparent;
  border-radius: 4px;
  cursor: pointer;
  color: var(--accent);
  font-family: ui-sans-serif, system-ui, -apple-system, sans-serif;
  font-size: 1.1rem;
  line-height: 1;
  box-sizing: border-box;
}
.sidebar-collapse:hover { background: var(--code-bg); }

/* Home / landing-page link in the header. Sits next to the sidebar
   toggle so the reader can always escape back to the course index. */
.home-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  color: var(--accent);
  font-family: ui-sans-serif, system-ui, -apple-system, sans-serif;
  font-size: 1.1rem;
  line-height: 1;
  text-decoration: none;
  box-sizing: border-box;
}
.home-link:hover { background: var(--code-bg); }
body.mode-slides .home-link { opacity: 0.6; }

/* ---- Prev / Next ---- */

.prev-next {
  display: flex;
  gap: 1rem;
  max-width: var(--width);
  margin: 2rem auto 4rem;
  padding: 0 1rem;
  font-family: ui-sans-serif, system-ui, -apple-system, sans-serif;
}
.prev-next a,
.prev-next .disabled {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 0.7rem 1rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  text-decoration: none;
  color: var(--fg);
  background: #fafafa;
}
.prev-next a:hover { background: var(--code-bg); }
.prev-next .next { text-align: right; }
.prev-next .label {
  font-size: 0.75rem;
  text-transform: uppercase;
  color: var(--muted);
  letter-spacing: 0.04em;
}
.prev-next .sub { font-weight: 600; margin-top: 0.15rem; }
.prev-next .disabled { visibility: hidden; }

/* On narrow screens, sidebar is hidden by default. The user can open
   it via the header button (toggles .sidebar-hidden on body). */
@media (max-width: 899px) {
  body.mode-chapter:not(.sidebar-hidden) .sidebar {
    box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.2);
  }
}

/* ---- Mobile / touch refinements ----
   Three issues the smaller-viewport pass found:

   1. Touch targets. The header buttons are ~32x34 px on desktop;
      that is under the Apple HIG 44 px and Material 48 px
      minimums, so on touch devices the buttons are hard to hit.
   2. The lecture title ellipses aggressively to "Course..." once
      the cell-controls cluster wraps; at narrow widths the title
      should drop to its own row.
   3. The privacy banner sits flush against the right edge at
      ~390 px viewport. Span it full-width with safe margins
      instead, so it has dismiss buttons inside the viewport.

   Scoped to (a) coarse pointers (phones, tablets), and (b) narrow
   viewports (<= 600 px) so desktop browsers at narrow widths also
   get the bigger targets if a mouse user is squinting. */

@media (pointer: coarse), (max-width: 600px) {
  .mode-toggle,
  .cell-controls button,
  .sidebar-collapse,
  .home-link {
    min-height: 44px;
    min-width: 44px;
    padding-left: 0.7rem;
    padding-right: 0.7rem;
  }
  .privacy-banner button {
    min-height: 44px;
    min-width: 64px;
    padding: 0.5rem 1rem;
  }
}

@media (max-width: 600px) {
  /* Hide page-level cell controls and the slide-mode toggle on
     phones. Each button is forced to 44px (touch-target rule above)
     and they wrap onto 3 extra rows, eating ~1/3 of the viewport.
     The per-cell Run button in x-ocaml's shadow DOM still works, so
     mobile readers do not lose execution; they only lose the
     page-level shortcuts (Run all / Clear / Reset), which are
     clumsy to invoke on a phone anyway. Slide mode is not usable on
     mobile, so the toggle would lead to a broken view. */
  .cell-controls,
  .mode-toggle { display: none; }

  /* Stack: lecture title gets its own row below the button cluster.
     The page-header flex-wrap (set in the earlier mobile pass) lets
     this happen; we just force the title to take the full row. */
  .lecture-title {
    flex-basis: 100%;
    order: 99;            /* push title below the button cluster */
    text-overflow: clip;  /* no need to ellipsis once it has the row */
    white-space: normal;
    font-size: 1rem;
  }

  /* Privacy banner: span the bottom of the viewport with comfortable
     left/right margins. Drops the fixed 360 px max-width that
     pushed it flush against narrow screens' right edges. */
  .privacy-banner {
    left: 0.75rem;
    right: 0.75rem;
    max-width: none;
  }
}

.chapter h1, .chapter h2, .chapter h3 {
  font-family: ui-sans-serif, system-ui, -apple-system, sans-serif;
  line-height: 1.25;
  margin-top: 2.2rem;
}
.chapter h2 { font-size: 1.4rem; }
.chapter h3 { font-size: 1.15rem; color: var(--accent); }

/* Heading permalinks. The [¶] anchor sits to the right of the
   heading, fades in on hover. Click to update the URL hash so the
   reader can copy a link to the specific section. */
.chapter h2,
.chapter h3,
.chapter h4 { position: relative; }
.chapter .permalink {
  display: inline-block;
  margin-left: 0.4rem;
  color: var(--muted);
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.12s ease-out;
  font-size: 0.85em;
  font-weight: 400;
  vertical-align: 0.05em;
}
.chapter h2:hover .permalink,
.chapter h3:hover .permalink,
.chapter h4:hover .permalink,
.chapter .permalink:focus { opacity: 1; }
.chapter .permalink:hover { color: var(--accent); }

/* ---- Privacy banner (first-visit notice) ---- */

.privacy-banner {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  max-width: 360px;
  padding: 0.8rem 1rem;
  background: #fff;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
  font-family: ui-sans-serif, system-ui, -apple-system, sans-serif;
  font-size: 0.88rem;
  line-height: 1.45;
  z-index: 1500;
}
.privacy-banner p {
  margin: 0 0 0.6rem;
  color: var(--fg);
}
.privacy-banner a {
  color: var(--accent);
}
.privacy-banner .privacy-actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}
.privacy-banner button {
  padding: 0.35rem 0.9rem;
  border-radius: 4px;
  cursor: pointer;
  font: inherit;
}
.privacy-banner .privacy-allow {
  border: 1px solid var(--accent);
  background: var(--accent);
  color: #fff;
}
.privacy-banner .privacy-allow:hover { filter: brightness(1.1); }
.privacy-banner .privacy-decline {
  border: 1px solid var(--rule);
  background: transparent;
  color: var(--fg);
}
.privacy-banner .privacy-decline:hover { background: var(--code-bg); }
body.mode-slides .privacy-banner { display: none; }

.chapter p { margin: 0.9rem 0; }
.chapter pre, .chapter code { font-family: "JetBrains Mono", "Fira Code", Menlo, ui-monospace, monospace; }
.chapter pre { background: var(--code-bg); padding: 0.8rem 1rem; border-radius: 4px; overflow-x: auto; }
.chapter code { background: var(--code-bg); padding: 0.1rem 0.3rem; border-radius: 3px; font-size: 0.9em; }
.chapter pre code { background: transparent; padding: 0; }
/* Images and wide block elements must not exceed the chapter
   column width: without [max-width: 100%] a roadmap SVG of intrinsic
   width 800 punches a horizontal scrollbar through the page on
   mobile. */
.chapter img,
.chapter svg,
.chapter video {
  max-width: 100%;
  height: auto;
}
/* Tables can be arbitrarily wide; wrap them in a horizontally
   scrollable region rather than letting them push the page. */
.chapter table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
}

/* Slide sections inline in chapter mode: render as soft callouts. */
.chapter section.slide {
  border-left: 3px solid var(--accent);
  padding: 0.4rem 1rem 0.4rem 1rem;
  margin: 1.4rem 0;
  background: #fafafa;
}
.chapter section.slide.subslide {
  border-left-color: #8aa9ad;
  margin-left: 1.2rem;
}
.chapter span.fragment {
  /* In chapter mode fragments are visible inline. */
  display: inline;
}

/* Speaker notes are slide-mode only. */
.chapter aside.notes,
body.mode-chapter aside.notes {
  display: none;
}

.lecture-meta-footer {
  max-width: var(--width);
  margin: 3rem auto 2rem;
  padding: 1rem;
  border-top: 1px solid var(--rule);
  font-size: 0.9rem;
  color: var(--muted);
}
.meta-line { margin: 0.3rem 0; }
.meta-label { font-weight: 600; color: var(--fg); margin-right: 0.4rem; }
.lecture-meta-footer ul { margin: 0.3rem 0 0 1.5rem; padding: 0; }

/* x-ocaml cells fit the chapter width and look like code. */
x-ocaml {
  display: block;
  margin: 1rem 0;
  font-size: 0.92em;
}

/* Each x-ocaml cell is wrapped in a [.cell-wrap] (injected by JS).
   The Run button lives in the cell's shadow DOM at its top-right;
   the reset (↺) sits just to its left, positioned absolutely
   inside the wrapper so it follows the cell's bounding box in
   both chapter and slide modes. */
.cell-wrap {
  position: relative;
  margin: 1rem 0;
}
.cell-wrap x-ocaml {
  display: block;
  margin: 0;
}
.reset-cell {
  /* Shape, size, and alignment mirror x-ocaml's shadow-DOM Run
     button (which is a UA-default <button>: 26px tall, square
     corners, #f5f5f5 background, 1px #6d6d6d border, 13px Arial).
     We can't style the shadow button itself, so we match its
     appearance here. Sits immediately to its left at the cell's
     top-right. */
  position: absolute;
  top: 0;
  right: 3.6rem;
  z-index: 2;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid #6d6d6d;
  border-radius: 0;
  background: #f5f5f5;
  color: #6d6d6d;
  cursor: pointer;
  font-family: Arial, sans-serif;
  font-size: 18px;
  line-height: 22px;
  font-weight: 400;
  box-sizing: border-box;
}
.reset-cell:hover { background: #ececec; }
/* Flag cells with persisted edits: the reset button gets a coloured ring. */
.reset-cell.dirty {
  border-color: var(--accent);
  color: var(--accent);
  background: #fff8e1;
}

/* ---- Inline quizzes ---- */

.quiz {
  margin: 1.4rem 0;
  padding: 0.9rem 1rem;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  background: #fafaf7;
}
.quiz > p:first-child {
  margin-top: 0;
  font-weight: 600;
}
.quiz.answered.quiz-correct {
  border-left-color: #3a7a3a;
  background: #f3faf3;
}
.quiz.answered:not(.quiz-correct) {
  border-left-color: #b35858;
}

/* MCQ */
.quiz-choices {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin: 0.6rem 0;
  padding: 0;
  border: 0;
}
.quiz-choice {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  padding: 0.35rem 0.55rem;
  border: 1px solid transparent;
  border-radius: 4px;
  cursor: pointer;
  background: #ffffff;
}
.quiz-choice:hover { background: var(--code-bg); }
.quiz-choice input[type="radio"] {
  margin-top: 0.35em;
  cursor: pointer;
}
.quiz-choice-text { flex: 1; }
.quiz-choice-text p { display: inline; margin: 0; }
.quiz-mcq.answered .quiz-choice.correct {
  background: #e8f4e6;
  border-color: #6ea66c;
}
.quiz-mcq.answered .quiz-choice.wrong {
  background: #f8e2e2;
  border-color: #c98a8a;
}
.quiz-mcq:not(.answered) .quiz-explanation {
  display: none;
}
.quiz-explanation {
  margin-top: 0.7rem;
  padding-top: 0.6rem;
  border-top: 1px dashed var(--rule);
  font-size: 0.95em;
}
.quiz-explanation p:first-child { margin-top: 0; }
.quiz-explanation p:last-child { margin-bottom: 0; }

/* Reference-solution disclosure: collapsed by default. Authored with
   :::solution. Used right after a :::quiz code so self-readers do not
   see the answer immediately below the question. */
.chapter details.solution {
  margin: 0.8rem 0;
  padding: 0.4rem 0.8rem;
  background: #fafafa;
  border-left: 3px solid var(--accent, #6e8acc);
  border-radius: 2px;
}
.chapter details.solution > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--accent, #4a6da1);
  user-select: none;
  padding: 0.2rem 0;
}
.chapter details.solution > summary::marker { color: var(--muted, #888); }
.chapter details.solution[open] > summary {
  margin-bottom: 0.4rem;
}
.chapter details.solution > *:not(summary):first-child { margin-top: 0; }
.chapter details.solution > *:last-child { margin-bottom: 0; }

/* Code quiz */
.quiz-code .quiz-controls {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0.4rem 0 0.2rem;
}
.quiz-check {
  padding: 0.3rem 0.9rem;
  border: 1px solid #6d6d6d;
  background: #f5f5f5;
  color: #2e5f6a;
  font: 600 13px Arial, sans-serif;
  cursor: pointer;
}
.quiz-check:hover { background: #ececec; }
.quiz-show-tests {
  padding: 0.2rem 0.5rem;
  border: 0;
  background: transparent;
  color: var(--muted);
  font: 13px ui-sans-serif, system-ui, sans-serif;
  cursor: pointer;
}
.quiz-show-tests:hover { color: var(--accent); }
.quiz-status {
  font: 0.92em ui-sans-serif, system-ui, sans-serif;
}
.quiz-status.running { color: var(--muted); }
.quiz-status.pass    { color: #3a7a3a; font-weight: 600; }
.quiz-status.fail    { color: #b35858; font-weight: 600; }

/* Hide the test cell unless [show-tests] is toggled. Overrides the
   [hidden] HTML attribute that parse.ml adds for [ocaml test] cells. */
.quiz-code x-ocaml[data-quiz-test] { display: none !important; }
.quiz-code.show-tests x-ocaml[data-quiz-test] { display: block !important; }

/* ---- On-this-page TOC (right-hand, chapter mode only) ----
   Built client-side from the prose section headings (see buildToc in
   the runtime script). Complements the left course-outline sidebar:
   left answers "which lecture", this answers "where in this lecture".
   Shown only on wide screens; never in slide mode or print/PDF. */

.toc {
  position: fixed;
  top: 3.6rem;
  right: 1rem;
  width: 220px;
  max-height: calc(100vh - 5rem);
  overflow-y: auto;
  padding: 0.6rem 0.75rem 0.8rem;
  background: #fcfcfb;
  border: 1px solid var(--rule);
  border-radius: 4px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
  font-family: ui-sans-serif, system-ui, -apple-system, sans-serif;
  font-size: 0.82rem;
  line-height: 1.4;
  z-index: 5;
}
.toc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.4rem;
}
.toc-title {
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}
.toc-collapse {
  border: 0;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font: 1rem/1 ui-sans-serif, system-ui, sans-serif;
  padding: 0 0.2rem;
}
.toc-collapse:hover { color: var(--accent); }
/* Glyph flips with state: visible list shows a "minimise" mark,
   collapsed shows a "contents" mark. */
.toc-collapse::before { content: "\2013"; }            /* en dash */
.toc.collapsed .toc-collapse::before { content: "\2261"; } /* triple bar */
.toc.collapsed { width: auto; }
.toc.collapsed .toc-head { margin-bottom: 0; }
.toc.collapsed .toc-title { display: none; }
.toc.collapsed .toc-body { display: none; }

.toc-body {
  list-style: none;
  margin: 0;
  padding: 0;
}
.toc-body li { margin: 0; }
.toc-body a {
  display: block;
  padding: 0.18rem 0.4rem;
  color: var(--muted);
  text-decoration: none;
  border-left: 2px solid transparent;
  border-radius: 0 3px 3px 0;
  overflow-wrap: anywhere;
}
.toc-body a:hover { color: var(--fg); background: var(--code-bg); }
.toc-body a.active {
  color: var(--accent);
  font-weight: 600;
  border-left-color: var(--accent);
  background: var(--code-bg);
}
.toc-h3 a { padding-left: 1.3rem; font-size: 0.95em; }

/* Visibility: chapter-mode, wide screens, screen (not print) only. */
body.mode-slides .toc { display: none; }
@media print { .toc { display: none; } }
@media (max-width: 1279px) { .toc { display: none; } }
