/* ═══════════════════════════════════════════════════════════════════════════
   outline.css — shared stylesheet for lecture outline pages (outline only)
   Linked from: outlines/[Subject]/[Lecture].html as ../assets/outline.css
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── RESET ──────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
b, strong { font-weight: 700 !important; }
/* The topnav and the side nav are both flush to the viewport edge, so the UA
   default body margin has to go or they float 8px off it. */
body { margin: 0; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* ── 8-CATEGORY COLOR SYSTEM — SINGLE SOURCE OF TRUTH ────────────────────────
   These eight categories drive three visual families that must always agree:
     .pill-*   inline pill badges in the outline body
     .hl-*     soft highlights inside the must-know box
     .l-*      swatches in the color key legend
   Change a color here and all three families follow.

   NOTE ON LEGAL: the source instructions listed both "Legal statutes" and
   "Clinical concepts" as amber/yellow, which made them indistinguishable.
   Legal is green here so all eight categories stay visually separable.
   ──────────────────────────────────────────────────────────────────────── */
:root {
  --cat-drug-bg:    #ffe0d0;  --cat-drug-br:    #e89070;  --cat-drug-fg:    #7a2800;
  --cat-rx-bg:      #d0f0ed;  --cat-rx-br:      #7ececa;  --cat-rx-fg:      #065550;
  --cat-warn-bg:    #fde8e8;  --cat-warn-br:    #f5b7b7;  --cat-warn-fg:    #9b1c1c;
  --cat-dx-bg:      #ede0f5;  --cat-dx-br:      #c4a0e8;  --cat-dx-fg:      #4a1a7a;
  --cat-anat-bg:    #dbeafe;  --cat-anat-br:    #93c5fd;  --cat-anat-fg:    #1e3a5f;
  --cat-concept-bg: #fef9c3;  --cat-concept-br: #fde047;  --cat-concept-fg: #713f12;
  --cat-law-bg:     #f0fdf4;  --cat-law-br:     #86efac;  --cat-law-fg:     #14532d;
  --cat-inst-bg:    #f1f5f9;  --cat-inst-br:    #cbd5e1;  --cat-inst-fg:    #334155;
}

/* ── TOP NAV ─────────────────────────────────────────────────────────────── */
.topnav {
  position: sticky; top: 0; z-index: 100;
  background: #fff; border-bottom: 1.5px solid #e8e8e8;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 16px; height: 48px; gap: 8px;
}
.topnav-left  { display: flex; align-items: center; gap: 5px; flex-shrink: 0; }
/* Last in the row, and the account chip lands here — site.js's findChipSlot()
   looks for exactly this class, which is what puts the signed-in name in the
   same top-right corner on outlines, the study plan and the cheat sheet as it
   occupies on the library. The chip carries its own `position: relative`, so
   the drop-down anchors to the name rather than to this box; nothing extra is
   needed here beyond letting it sit at the end. */
.topnav-right { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.topnav-title {
  flex: 1; min-width: 0;
  font-size: 14px; font-weight: 700; color: #0d2b5e;
  font-family: 'Georgia', serif; letter-spacing: 0.02em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-align: center; padding: 0 8px;
}

.hy-wrap { display: flex; align-items: center; gap: 6px; margin-right: 2px; }
.hy-label {
  font-size: 11.5px; font-weight: 700; color: #c45400;
  white-space: nowrap; user-select: none;
  font-family: 'Georgia', serif; letter-spacing: 0.03em;
}
.nav-sep { width: 1px; height: 20px; background: #e0e0e0; margin: 0 3px; }
#hy-toggle:checked + .toggle-slider { background: #c45400; }

.nav-btn {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 5px 10px; border-radius: 6px;
  border: 1.5px solid #ddd; background: #fff; color: #333;
  font-family: 'Georgia', serif; font-size: 12.5px;
  font-weight: 600; cursor: pointer; text-decoration: none;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
  white-space: nowrap; user-select: none;
}
.nav-btn:hover  { background: #f4f4f4; border-color: #bbb; color: #111; }
.nav-btn.home-btn       { border-color: #2563eb; color: #2563eb; }
.nav-btn.home-btn:hover { background: #eff6ff; }
/* The wordmark, and the way home. These values are index.html's .brand rule,
   copied deliberately: the identity has to read the SAME on both pages, and it
   is not a .nav-btn — no border, no fill, no padding box — because boxing it
   put the site's name in the same visual language as the ← → controls beside
   it. It sits first in the row, hard against the left edge. */
.nav-brand {
  display: flex; align-items: center; gap: 10px;
  flex-shrink: 0; color: inherit; text-decoration: none;
  margin-right: 6px;
}
.nav-brand:hover { text-decoration: none; }
.nav-brand img {
  width: 30px; height: 30px; border-radius: 8px;
  object-fit: cover; flex-shrink: 0;
  box-shadow: 0 1px 2px rgba(13, 43, 94, 0.04);
}
.nav-brand span {
  font-size: 1.12rem; font-weight: 800; letter-spacing: 0.055em;
  color: #0d2b5e; line-height: 1;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
}
/* Narrow bars drop the word and keep the mark, exactly as the library's topbar
   does — the icon alone still reads as the way home. */
@media (max-width: 700px) {
  .nav-brand span { display: none; }
  .nav-brand { margin-right: 2px; }
}
.nav-btn.disabled       { opacity: 0.3; pointer-events: none; }
.nav-btn.qbank-btn      { border-color: #6b21a8; color: #6b21a8; }
.nav-btn.qbank-btn:hover{ background: #f3e8ff; }
/* Anki — hidden by outline.js on a lecture with no matching cards. */
.nav-btn.anki-btn       { border-color: #1d4ed8; color: #1d4ed8; }
.nav-btn.anki-btn:hover { background: #e6edff; }
.nav-btn.anki-btn.copied      { border-color: #1a6e40; color: #1a6e40; background: #e8f6ee; }
.nav-btn.anki-btn.copy-failed { border-color: #9b2424; color: #9b2424; background: #fdecec; }
/* Settings → "Anki buttons" off. !important because outline.js drives this
   button's own display inline — it starts hidden and is shown only once a
   lecture turns out to have matching cards (§24.5), so an inline style always
   wins over a plain rule here. */
html[data-anki-ui="off"] .nav-btn.anki-btn { display: none !important; }

/* Completed — shaped like a .nav-btn so it sits in the row without inventing a
   second visual language, but it is a <label> wrapping a real checkbox: the tick
   is a statement about the lecture, not a mode switch like ⚡ HY beside it.
   Ticked, it goes green and stays green — the same colour the library list uses
   for a completed row, so the two surfaces read as one fact. */
.done-wrap {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 6px;
  border: 1.5px solid #ddd; background: #fff; color: #333;
  font-family: 'Georgia', serif; font-size: 12.5px;
  font-weight: 600; cursor: pointer;
  white-space: nowrap; user-select: none;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
  margin-right: 2px;
}
.done-wrap:hover { background: #f4f4f4; border-color: #bbb; color: #111; }
.done-wrap input { margin: 0; cursor: pointer; accent-color: #1a6e40; }
.done-wrap.done {
  border-color: #1a6e40; color: #1a6e40; background: #e8f6ee;
}
.done-wrap.done:hover { background: #ddf0e5; }

.toggle-switch { position: relative; width: 36px; height: 20px; cursor: pointer; }
.toggle-switch input { opacity: 0; width: 0; height: 0; }
.toggle-slider {
  position: absolute; inset: 0; background: #ddd;
  border-radius: 20px; transition: background 0.2s;
}
.toggle-slider::before {
  content: ''; position: absolute;
  width: 14px; height: 14px; left: 3px; top: 3px;
  background: #fff; border-radius: 50%; transition: transform 0.2s;
}
.toggle-switch input:checked + .toggle-slider::before { transform: translateX(16px); }

/* .lecture-title now lives inside the topnav — see .topnav-title below */

/* ── PAGE SHELL ───────────────────────────────────────────────────────────────
   outline.js wraps the generated content in .page-shell and prepends .sidenav.
   Generated outlines still ship nothing but <div id="outline-content">.       */
.page-shell {
  display: flex;
  align-items: flex-start;
}

/* ── SECTION SIDE NAV ─────────────────────────────────────────────────────────
   Built at runtime from the h2 headers. Sticks below the 48px topnav and
   scrolls independently once the section list outgrows the viewport.         */
.sidenav {
  flex: 0 0 250px;
  position: sticky; top: 48px;
  align-self: flex-start;
  /* Pinned to the viewport rather than sized to the list, so the right-hand
     border runs the full height instead of stopping under the last section. */
  height: calc(100vh - 48px);
  overflow-y: auto; overscroll-behavior: contain;
  padding: 26px 12px 40px 18px;
  background: #fbfbfa; border-right: 1px solid #e8e8e8;
  font-family: 'Georgia', serif;
}
.sidenav-title {
  font-size: 10px; font-weight: 700; color: #5F5E5A;
  text-transform: uppercase; letter-spacing: 0.12em;
  margin: 0 0 10px 9px;
}
.sidenav a {
  display: block;
  padding: 5px 9px; margin-bottom: 1px;
  border-left: 2px solid transparent; border-radius: 0 5px 5px 0;
  font-size: 12px; line-height: 1.4;
  color: #4a5568; text-decoration: none;
  transition: background 0.12s, color 0.12s;
}
.sidenav a:hover { background: #f0f0ee; color: #0d2b5e; }
.sidenav a.active {
  background: #eef2f8; color: #0d2b5e;
  font-weight: 700; border-left-color: #0d2b5e;
}
/* Section hidden by the ⚡ HY filter — its nav entry goes with it. */
.sidenav a.sidenav-hidden { display: none; }

/* Collapsed via the ☰ button. Taken out of the flow entirely rather than
   narrowed to a rail, so the outline gets the whole page width back. */
.page-shell.nav-collapsed .sidenav { display: none; }

.nav-btn.sidenav-toggle {
  font-size: 14px; line-height: 1;
  padding: 5px 9px;
}
.nav-btn.sidenav-toggle.active {
  background: #eef2f8; border-color: #9db4d4; color: #0d2b5e;
}

/* ── OUTLINE CONTENT ──────────────────────────────────────────────────────── */
.page-content {
  flex: 1; min-width: 0;
  padding: 32px 44px 64px;
  font-family: 'Georgia', serif;
  font-size: 14px; line-height: 1.57;
  color: #1a1a1a; background: #ffffff;
}

/* ── READING SIZE (Settings → "Outline text size") ───────────────────────────
   `zoom` rather than a font-size bump, because every measurement in this file
   is in px — headings, pills, tag badges, block borders, figure captions. A
   font-size on the container would enlarge the body text and leave all of that
   at its original size, which is worse than not offering the setting. zoom
   scales the whole column proportionally, including the px, and it is the one
   property that does.

   Scoped to .page-content, so the topnav, the section sidenav and the account
   chip stay exactly where the reader learned they are — only the prose grows.
   study.html and cheatsheet.html use the same class, so they follow for free. */
html[data-reading="large"]  .page-content { zoom: 1.12; }
html[data-reading="xlarge"] .page-content { zoom: 1.28; }
/* The QBank's Read More frame shows the same outline prose, so it takes the
   same size. .rm-outline is the wrapper qbank.js puts inside that frame's
   srcdoc body — see settingsAttrs() and outlineFrame() there. */
html[data-reading="large"]  .rm-outline { zoom: 1.12; }
html[data-reading="xlarge"] .rm-outline { zoom: 1.28; }

h2 {
  font-size: 13px; font-weight: 700; color: #0d2b5e;
  text-transform: uppercase; letter-spacing: 0.09em;
  /* Section spacing lives here and nowhere else — CLAUDE.md §7 forbids <hr> or
     any per-outline separator, so this one margin sets the gap between every
     section of every outline in the repo. */
  margin: 64px 0 9px; padding-bottom: 3px;
  border-bottom: 1px solid #d0d8e8;
  /* clears the sticky topnav when jumped to from the side nav */
  scroll-margin-top: 62px;
}
.page-content > h2:first-of-type { margin-top: 0; }

/* Slide-range badge that opens every section header: "Slides 4–9" */
.slide-badge {
  display: inline-block; background: #E5E4DC; color: #5F5E5A;
  border-radius: 20px; font-size: 10px; font-weight: 500;
  padding: 2px 8px; margin-right: 7px;
  text-transform: none; letter-spacing: 0.02em; vertical-align: middle;
}

ul { list-style: none; margin: 0; padding: 0; }
li.row {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: 8px; margin-bottom: 5px; padding-left: 2px;
}
/* The text span takes remaining width on the first row */
li.row > span:not(.dot) { flex: 1; min-width: 0; }
.dot {
  flex-shrink: 0; width: 7px; height: 7px;
  border-radius: 50%; margin-top: 5px;
}
/* All dots use navy — other color classes kept for backwards compatibility */
.dot-navy, .dot-teal, .dot-orange, .dot-purple,
.dot-red, .dot-green, .dot-gray, .dot-brown { background: #0d2b5e; }

/* Sub-bullets: always forced to a new full-width row beneath the parent text.
   flex-basis:100% pushes ul.sub onto its own line in the flex-wrap container.
   This works regardless of whether ul.sub is inside the text <span> or a
   direct child of li.row — both cases resolve correctly. */
ul.sub {
  flex-basis: 100%; width: 100%;
  margin: 2px 0 3px 0; padding-left: 22px;
  clear: both;
}
li.sub-row {
  display: flex; align-items: flex-start;
  gap: 7px; margin-bottom: 3px;
  font-size: 13.5px; color: #2d2d2d;
  width: 100%;
}
.subdot {
  flex-shrink: 0; width: 5px; height: 5px;
  border-radius: 50%; margin-top: 6px; opacity: 0.75;
}
.subdot.dot-navy, .subdot.dot-teal, .subdot.dot-orange, .subdot.dot-purple,
.subdot.dot-red, .subdot.dot-green, .subdot.dot-gray, .subdot.dot-brown { background: #0d2b5e; }

ol.num-list {
  margin: 4px 0 6px 0; padding-left: 26px;
  font-size: 14px; line-height: 1.57; color: #1a1a1a;
}
ol.num-list li { margin-bottom: 4px; padding-left: 4px; }

/* ── LECTURE HEADER (lecturer + institution) ──────────────────────────────── */
.lecturer-line {
  font-size: 13.5px; font-weight: 700; color: #1a1a1a;
  margin: 0 0 2px 0;
}
.institution-line {
  font-size: 11.5px; color: #7a7a7a;
  margin: 0 0 16px 0; letter-spacing: 0.01em;
}

/* ── COLOR KEY LEGEND ─────────────────────────────────────────────────────── */
.legend { margin: 0 0 22px 0; }
.legend-title {
  font-size: 10px; font-weight: 700; color: #5F5E5A;
  text-transform: uppercase; letter-spacing: 0.12em; margin-bottom: 6px;
}
.legend-item {
  display: inline-block;
  font-size: 10.5px; font-weight: 700;
  padding: 2px 8px; border-radius: 20px;
  margin: 0 4px 4px 0; line-height: 1.5;
}
.l-drug    { background: var(--cat-drug-bg);    color: var(--cat-drug-fg);    border: 1px solid var(--cat-drug-br); }
.l-tx      { background: var(--cat-rx-bg);      color: var(--cat-rx-fg);      border: 1px solid var(--cat-rx-br); }
.l-warn    { background: var(--cat-warn-bg);    color: var(--cat-warn-fg);    border: 1px solid var(--cat-warn-br); }
.l-diag    { background: var(--cat-dx-bg);      color: var(--cat-dx-fg);      border: 1px solid var(--cat-dx-br); }
.l-anat    { background: var(--cat-anat-bg);    color: var(--cat-anat-fg);    border: 1px solid var(--cat-anat-br); }
.l-concept { background: var(--cat-concept-bg); color: var(--cat-concept-fg); border: 1px solid var(--cat-concept-br); }
.l-legal   { background: var(--cat-law-bg);     color: var(--cat-law-fg);     border: 1px solid var(--cat-law-br); }
.l-inst    { background: var(--cat-inst-bg);    color: var(--cat-inst-fg);    border: 1px solid var(--cat-inst-br); }

/* ── PILLS ─────────────────────────────────────────────────────────────────── */
.pill-drug, .pill-rx, .pill-warn, .pill-dx,
.pill-anatomy, .pill-law, .pill-concept, .pill-inst, .pill-new {
  display: inline-block;
  font-size: 11px; font-weight: 700;
  padding: 1px 7px; border-radius: 20px;
  letter-spacing: 0.03em; vertical-align: middle;
  white-space: nowrap; line-height: 1.6; margin: 0 1px;
}
.pill-drug    { background: var(--cat-drug-bg);    color: var(--cat-drug-fg);    border: 1px solid var(--cat-drug-br); }
.pill-rx      { background: var(--cat-rx-bg);      color: var(--cat-rx-fg);      border: 1px solid var(--cat-rx-br); }
.pill-warn    { background: var(--cat-warn-bg);    color: var(--cat-warn-fg);    border: 1px solid var(--cat-warn-br); }
.pill-dx      { background: var(--cat-dx-bg);      color: var(--cat-dx-fg);      border: 1px solid var(--cat-dx-br); }
.pill-anatomy { background: var(--cat-anat-bg);    color: var(--cat-anat-fg);    border: 1px solid var(--cat-anat-br); }
.pill-concept { background: var(--cat-concept-bg); color: var(--cat-concept-fg); border: 1px solid var(--cat-concept-br); }
.pill-law     { background: var(--cat-law-bg);     color: var(--cat-law-fg);     border: 1px solid var(--cat-law-br); }
.pill-inst    { background: var(--cat-inst-bg);    color: var(--cat-inst-fg);    border: 1px solid var(--cat-inst-br); }
/* legacy — superseded by the .tag-new tag; kept so older outlines still render */
.pill-new     { background: #f3e8ff; color: #6b21a8; border: 1px solid #c084fc; }

/* ── PILL BOXES OFF (Settings → "Pill boxes in outlines") ────────────────────
   A pill WRAPS the term rather than labelling it, so this cannot hide them —
   hiding a pill would delete the drug name inside it. What it removes is the
   BOX: the fill, the border, the padding and the radius. The category colour
   stays on the text, so a section still says which terms are drugs and which
   are anatomy, at a whisper instead of as a row of badges. That is the whole
   complaint this answers — a densely tagged section reading as decoration
   rather than as prose.

   Set on <html> by PSTSettings in site.js, at parse time, so a reader who has
   turned boxes off never watches them appear and then flatten. */
html[data-pills="off"] :is(.pill-drug, .pill-rx, .pill-warn, .pill-dx,
  .pill-anatomy, .pill-law, .pill-concept, .pill-inst, .pill-new) {
  background: none; border-color: transparent;
  padding: 0; border-radius: 0;
  font-size: inherit; font-weight: 700; letter-spacing: inherit;
  line-height: inherit; margin: 0;
}

/* ── MUST-KNOW HIGHLIGHTS ─────────────────────────────────────────────────────
   Soft marker-pen fills used ONLY inside .must-know-box. Unlike pills these
   wrap across lines and stack on top of <b> rather than replacing it.        */
.hl-drug, .hl-tx, .hl-warn, .hl-diag,
.hl-anat, .hl-concept, .hl-legal, .hl-inst {
  border-radius: 3px; padding: 0 3px;
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
}
.hl-drug    { background: var(--cat-drug-bg);    color: var(--cat-drug-fg);    border: 1px solid var(--cat-drug-br); }
.hl-tx      { background: var(--cat-rx-bg);      color: var(--cat-rx-fg);      border: 1px solid var(--cat-rx-br); }
.hl-warn    { background: var(--cat-warn-bg);    color: var(--cat-warn-fg);    border: 1px solid var(--cat-warn-br); }
.hl-diag    { background: var(--cat-dx-bg);      color: var(--cat-dx-fg);      border: 1px solid var(--cat-dx-br); }
.hl-anat    { background: var(--cat-anat-bg);    color: var(--cat-anat-fg);    border: 1px solid var(--cat-anat-br); }
.hl-concept { background: var(--cat-concept-bg); color: var(--cat-concept-fg); border: 1px solid var(--cat-concept-br); }
.hl-legal   { background: var(--cat-law-bg);     color: var(--cat-law-fg);     border: 1px solid var(--cat-law-br); }
.hl-inst    { background: var(--cat-inst-bg);    color: var(--cat-inst-fg);    border: 1px solid var(--cat-inst-br); }

/* ── MUST-KNOW BOX ────────────────────────────────────────────────────────── */
.must-know-box {
  border: 2px solid #c9a227; background: #fffbea;
  border-radius: 8px; padding: 14px 18px; margin: 0 0 28px 0;
}
.must-know-box .mk-title {
  font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.12em;
  color: #7a5c00; margin-bottom: 10px;
}
.must-know-box ul { margin: 0; padding: 0; list-style: none; }

/* ── COLLAPSING THE MUST-KNOW BOX ──────────────────────────────────────────
   `mk-collapsible` is added by outline.js, never by the generated HTML, and
   that is what makes these rules safe: with JavaScript off the class never
   lands, nothing is hidden, and the five points read exactly as before. A bare
   `display: none` here would hide them permanently for anyone without JS, with
   no control on the page able to bring them back. */
.must-know-box.mk-collapsible .mk-title {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 0; text-align: left;
  background: none; border: none; cursor: pointer;
  font-family: inherit; font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.12em; color: #7a5c00;
}
.must-know-box.mk-collapsible .mk-title:hover { color: #5c4500; }
.must-know-box.mk-collapsible .mk-chev {
  margin-left: auto; font-size: 11px;
  transition: transform 0.15s ease;
}
.must-know-box.mk-collapsible.open .mk-chev { transform: rotate(90deg); }
.must-know-box.mk-collapsible ul { display: none; }
.must-know-box.mk-collapsible.open ul { display: block; }
/* No trailing gap under a header that is standing alone. */
.must-know-box.mk-collapsible:not(.open) .mk-title { margin-bottom: 0; }

/* On paper there is nothing to click, so the points always print. */
@media print {
  .must-know-box.mk-collapsible ul { display: block !important; }
  .must-know-box.mk-collapsible .mk-title { margin-bottom: 10px !important; }
  .must-know-box.mk-collapsible .mk-chev { display: none; }
}
.must-know-box li {
  display: flex; align-items: flex-start;
  gap: 9px; margin-bottom: 7px;
  font-size: 13.5px; color: #1a1a1a; line-height: 1.5;
}
.must-know-box li:last-child { margin-bottom: 0; }
.mk-dot {
  flex-shrink: 0; width: 7px; height: 7px;
  border-radius: 50%; background: #c9a227; margin-top: 5px;
}

/* ── BLOCK CALLOUTS ───────────────────────────────────────────────────────── */
.block-critical {
  border-left: 4px solid #c0392b; background: #fff5f5;
  padding: 9px 13px; margin: 10px 0; border-radius: 0 4px 4px 0;
}
.block-critical .lbl {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.12em; color: #c0392b; margin-bottom: 4px;
}
.block-mnem {
  border-left: 4px solid #2e7d32; background: #f1f8f1;
  padding: 9px 13px; margin: 10px 0; border-radius: 0 4px 4px 0;
}
.block-mnem .lbl {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.12em; color: #2e7d32; margin-bottom: 4px;
}
/* .block-mcq is retired: questions the lecturer posed, and questions supplied
   by an instructor handout, now live in the companion .json as in-house
   questions instead of in the outline. See validate_outline.py RETIRED_BLOCKS. */
.block-keypoint {
  border-left: 4px solid #c9a227; background: #fffbea;
  padding: 9px 13px; margin: 12px 0 0 0; border-radius: 0 4px 4px 0;
}
.block-keypoint .lbl {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.12em; color: #7a5c00; margin-bottom: 4px;
}
.block-miscon {
  border-left: 4px solid #6b7280; background: #f6f7f8;
  padding: 9px 13px; margin: 10px 0; border-radius: 0 4px 4px 0;
}
.block-miscon .lbl {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.12em; color: #4b5563; margin-bottom: 4px;
}

/* ── DE-EMPHASIZED CONTENT (DON'T HAVE TO KNOW / NOT DISCUSSED) ───────────────
   Applied to li.row / li.sub-row alongside a .tag-skip or .tag-nd tag. The
   content is preserved but visually recedes; the ⚡ HY filter hides it. */
li.row.muted, li.sub-row.muted {
  font-size: 12.5px; color: #8a8a8a;
}
li.row.muted b, li.row.muted strong,
li.sub-row.muted b, li.sub-row.muted strong { font-weight: 600 !important; }
li.row.muted .dot, li.sub-row.muted .subdot { background: #b8b8b8; }

/* ── 7-TIER TAGS ──────────────────────────────────────────────────────────────
   .tag-will      🔴 WILL TEST            explicit verbal test promise only
   .tag-flag      🟠 LECTURER FLAGGED     verbal emphasis trigger phrase
   .tag-mem       🟠 MEMORIZE             the verb "memorize" specifically
   .tag-question  ❓ LECTURE QUESTION     the lecturer put a question to the room
   .tag-new       🟣 NEW / UPDATED        descriptive only, not a priority
   .tag-skip      ⬜ DON'T HAVE TO KNOW   lecturer excused it from testing
   .tag-nd        ⬜ NOT DISCUSSED        on a slide, never spoken to
   The first four survive the ⚡ HY filter — see outline.js HY_TAG_SELECTOR, and
   they are §15's priority order in the same sequence: FLAGGED, MEMORIZE, then
   LECTURE QUESTION.

   There is deliberately no editorial tier. .tag-hy (⭐ HIGH YIELD) was removed:
   it was applied on inference rather than on anything the lecturer said, it
   outnumbered every real tag several to one, and it never survived the ⚡
   filter anyway. Important-but-unflagged content is now simply untagged. The
   class is gone rather than hidden, so any outline still carrying it fails
   validate_outline.py instead of rendering a tag that means nothing. */
.tag-will, .tag-flag, .tag-mem, .tag-question,
.tag-new, .tag-skip, .tag-nd, .tag-nofa,
.exam-tag, .likely-tag {
  display: inline-block; color: #fff;
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.08em; padding: 2px 7px; border-radius: 4px;
  vertical-align: middle; margin-left: 6px; white-space: nowrap;
}
.tag-will { background: #dc2626; }
.tag-flag { background: #ea7317; }
.tag-mem  { background: #b45309; }
.tag-question { background: #ca8a04; }
.tag-new  { background: #7c3aed; }
.tag-skip { background: #9ca3af; }
.tag-nd   { background: #9ca3af; }
/* ── COVERAGE TAG — orthogonal to the six above ───────────────────────────────
   .tag-nofa  📕 NOT IN FIRST AID   no topic of its own in reference/index.md

   The six tiers describe what the LECTURER said; this one describes what an
   outside resource covers, so it is not a seventh tier and it does not compete
   with them. It stacks: a 🔴 WILL TEST bullet that also carries 📕 is the most
   valuable line in the document — promised on the exam and available nowhere
   else. It survives the ⚡ HY filter alongside the three flag tags, because
   content no third-party resource carries is exactly what a student cannot
   afford to filter away. Also legal on an h2, where it means the whole section
   has no First Aid home. */
.tag-nofa { background: #0f766e; }
/* legacy aliases — the old two-tag system, kept so older outlines still render */
.exam-tag   { background: #dc2626; }
.likely-tag { background: #db2777; }

.step1-tag {
  display: inline-block; background: #e6a817; color: #fff;
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.07em; padding: 2px 6px; border-radius: 3px;
  vertical-align: middle; margin-left: 4px;
}

/* hr.divider is no longer generated — sections separated by h2 margin only */

/* ── COMPARISON TABLE ─────────────────────────────────────────────────────── */
.cmp-table { width: 100%; border-collapse: collapse; font-size: 13px; margin: 8px 0 4px; }
.cmp-table th {
  background: #eef2f8; color: #0d2b5e;
  padding: 5px 10px; text-align: left;
  font-weight: 700; border: 1px solid #d0d8e8;
}
.cmp-table td { padding: 5px 10px; border: 1px solid #e4e8f0; vertical-align: top; }
.cmp-table tr:nth-child(even) td { background: #f8fafc; }

/* A table row carrying !skip or !nd — same treatment as li.row.muted above. */
.cmp-table tr.muted td { font-size: 12.5px; color: #8a8a8a; }
.cmp-table tr.muted td b, .cmp-table tr.muted td strong { font-weight: 600 !important; }

/* ── QBANK SESSION MODAL ──────────────────────────────────────────────────────
   Built by outline.js when the QBank button is clicked. Deliberately the same
   visual language as the "Build a QBank Session" panel on the home page — same
   purple family, same pill shapes, same launch bar — so the two read as one
   feature seen from two places. The lecture picker is the only thing missing,
   because the lecture you are reading is the only one on offer.              */
.qb-modal-overlay {
  display: none;
  position: fixed; inset: 0; z-index: 200;
  background: rgba(13, 43, 94, 0.32);
  padding: 20px;
  overflow-y: auto;
  align-items: flex-start; justify-content: center;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
}
.qb-modal-overlay.visible { display: flex; }

.qb-modal {
  width: 100%; max-width: 560px; margin: auto;
  background: #fdfbff;
  border: 1.5px solid #d4bbf5; border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 14px 40px rgba(13, 43, 94, 0.22);
}
.qb-modal-hdr {
  display: flex; align-items: center; gap: 10px;
  padding: 13px 16px;
  background: #f5eeff; border-bottom: 1.5px solid #d4bbf5;
}
.qb-modal-icon  { font-size: 1rem; flex-shrink: 0; }
.qb-modal-title { font-weight: 700; font-size: 0.95rem; color: #5b1fa8; }
.qb-modal-close {
  margin-left: auto; border: none; background: none;
  font-size: 0.9rem; color: #9b7ec8; cursor: pointer;
  padding: 2px 4px; line-height: 1;
}
.qb-modal-close:hover { color: #4a1a8a; }
.qb-modal-lecture {
  padding: 10px 16px 0;
  font-size: 0.85rem; font-weight: 700; color: #3d1a75;
}
.qb-modal-body { padding: 10px 16px 16px; }

.qb-modal .qb-filter-section {
  margin: 10px 0 14px;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.qb-modal .qb-filter-lbl { font-size: 0.82rem; font-weight: 600; color: #555; flex-shrink: 0; }
.qb-modal .qb-filters    { display: flex; gap: 5px; flex-wrap: wrap; }
.qb-modal .qbf {
  font-size: 0.8rem; font-weight: 600; padding: 4px 11px;
  border-radius: 20px; border: 1.5px solid #d8cff0;
  background: #fff; color: #6b5a8a; cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.qb-modal .qbf:hover  { border-color: #9b7ec8; color: #4a1a8a; }
.qb-modal .qbf.active { background: #6b21a8; border-color: #6b21a8; color: #fff; }
.qb-modal .qbf.f-incomplete.active { background: #b45309; border-color: #b45309; }
.qb-modal .qbf.f-wrong.active      { background: #9b2424; border-color: #9b2424; }
.qb-modal .qbf.f-correct.active    { background: #1a6e40; border-color: #1a6e40; }
.qb-modal .qbf.f-marked.active     { background: #c99700; border-color: #c99700; }
.qb-modal .qbf.f-willtest.active   { background: #dc2626; border-color: #dc2626; }
.qb-modal .qbf.f-nofa.active       { background: #0f766e; border-color: #0f766e; }
.qb-modal .qbf.f-inhouse.active    { background: #0d2b5e; border-color: #0d2b5e; }
.qb-modal .qbf.f-generated.active  { background: #6b21a8; border-color: #6b21a8; }

.qb-modal .qb-launch {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 11px 14px;
  background: #f2edfb; border-radius: 7px;
  border: 1.5px solid #d4bbf5; flex-wrap: wrap;
}
.qb-modal .qb-avail        { font-size: 0.82rem; color: #6b5a8a; flex: 1; min-width: 120px; }
.qb-modal .qb-avail strong { color: #3d1a75; }
.qb-modal .qb-avail em     { color: #9b7ec8; font-style: normal; }
.qb-modal .qb-n-wrap  { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.qb-modal .qb-n-label { font-size: 0.82rem; color: #6b5a8a; white-space: nowrap; }
.qb-modal .qb-n-wrap input {
  width: 58px; padding: 4px 7px; text-align: center;
  border: 1.5px solid #d4bbf5; border-radius: 6px;
  font-size: 0.85rem; font-weight: 700; color: #3d1a75;
  background: #fff; outline: none; -moz-appearance: textfield;
}
.qb-modal .qb-n-wrap input::-webkit-outer-spin-button,
.qb-modal .qb-n-wrap input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.qb-modal .qb-n-wrap input:focus    { border-color: #6b21a8; }
.qb-modal .qb-n-wrap input:disabled { opacity: 0.35; background: #f5f0ff; }
.qb-modal .qb-start {
  padding: 7px 18px; border-radius: 7px;
  border: none; background: #6b21a8; color: #fff;
  font-size: 0.88rem; font-weight: 700; cursor: pointer;
  transition: background 0.12s, opacity 0.12s; white-space: nowrap;
}
.qb-modal .qb-start:hover:not(:disabled) { background: #5b1a92; }
.qb-modal .qb-start:disabled { opacity: 0.4; cursor: not-allowed; }

@media (max-width: 640px) {
  .qb-modal-overlay { padding: 12px; }
  .qb-modal .qb-launch { justify-content: flex-end; }
}

/* ── PRINT ────────────────────────────────────────────────────────────────────
   Goal: a clean PDF at full page width with backgrounds intact and nothing
   split across a page break mid-thought.                                     */
@media print {
  body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }

  .topnav  { display: none !important; }
  .sidenav { display: none !important; }
  .qb-modal-overlay { display: none !important; }
  /* whatever the collapse state was on screen, print is always the full page */

  /* The flex shell would otherwise leave the content in a single column box */
  .page-shell { display: block; }

  .page-content {
    max-width: 100%; width: 100%;
    padding: 0.4in 0.5in; margin: 0;
  }

  /* Never split a unit of meaning across pages */
  li.row, li.sub-row, ol.num-list li,
  .must-know-box, .must-know-box li,
  .block-critical, .block-mnem, .block-keypoint, .block-miscon,
  .cmp-table, .cmp-table tr, .no-break, .legend {
    break-inside: avoid; page-break-inside: avoid;
  }

  /* A header must never strand at the bottom of a page without its content */
  h2 {
    break-inside: avoid;  page-break-inside: avoid;
    break-after: avoid;   page-break-after: avoid;
  }

  li.row, li.sub-row { orphans: 3; widows: 3; }

  /* Wrap any table in <div class="no-break"> to keep it whole */
  .no-break { break-inside: avoid; page-break-inside: avoid; }
}

/* ── RESPONSIVE ───────────────────────────────────────────────────────────── */
/* Below this the sidebar costs more reading width than the navigation is worth,
   so the outline goes back to a single full-width column. */
@media (max-width: 1000px) {
  .sidenav              { display: none; }
  .nav-btn.sidenav-toggle { display: none; } /* controls nothing at this width */
  .page-content         { padding: 28px 30px 56px; }
}

@media (max-width: 640px) {
  .nav-btn      { padding: 5px 9px; font-size: 13px; }
  .topnav-title { display: none; } /* too narrow for title on mobile */
  /* The box survives, its caption does not — a checkbox that turns green still
     reads as "done" once you have met it on a wider screen. */
  .done-label   { display: none; }
  .done-wrap    { padding: 5px 8px; }
  .page-content  { padding: 20px 16px 48px; }
  .lecture-title { padding: 16px 16px 10px; font-size: 17px; }
  .topnav        { padding: 0 10px; gap: 6px; }
  .cmp-table     { font-size: 12px; }
  .cmp-table th,
  .cmp-table td  { padding: 4px 7px; }
  .must-know-box { padding: 12px 14px; }
}


/* ── FIGURES (INSTRUCTIONS §9.5) ──────────────────────────────────── v1 ─────
   peterstesia:figures:css:v1

   Appended to outlines/assets/outline.css by tools/setup.py. The sentinel on
   the line above is how setup.py knows this block is already applied, so a
   second run is a no-op. Do not remove it.

   Claude writes a SRCLESS placeholder and tools/inject_figures.py fills the
   src later:

     <figure class="fig" data-fig="F01" data-slide="14">
       <img class="fig-img" alt="…">
       <figcaption class="fig-cap"><span class="fig-label">Figure 1 · Slide 14</span>
         Caption. <span class="tag-flag">🟠 LECTURER FLAGGED</span></figcaption>
     </figure>

   A figure whose src was never filled is hidden rather than rendered as a
   broken image — so an un-injected outline degrades to a text-only page
   instead of a page full of torn-icon placeholders.
   ──────────────────────────────────────────────────────────────────────── */

/* A figure occupies the right half of its section and the bullets flow down the
   left half beside it, so the diagram sits next to the prose that explains it
   rather than interrupting it. Implemented as a float because sections are a
   flat run of siblings under #outline-content (§9.5) — there is no per-section
   wrapper to make a grid column out of, and a float is the one mechanism that
   shortens the line boxes of following bullets without any wrapper at all.

   The counterpart to this is the `clear` rule further down: anything that is a
   block with its own edges — a table, a block-*, the next h2 — must drop below
   the figure instead of sliding under it. */
/* Base state is the narrow-screen one: a figure on its own full-width row. The
   float system below is layered on for wide screens and for print. */
figure.fig {
  margin: 14px 0 18px;
  padding: 0;
  break-inside: avoid; page-break-inside: avoid;
}

/* ── HOW A SECTION'S FIGURES LAY OUT ─────────────────────────────────────────
   Two goals in tension: leave no dead space, and keep each figure near the
   bullets it belongs to. A pair fills the width exactly, and a figure that
   would otherwise sit alone in a full-width row floats instead, so the bullets
   fill the space beside it.

     1 figure    [ bullets ][ F1 ]
     2 figures   [ F1 ][ F2 ]          bullets below
     3 figures   [ bullets ][ F1 ]
                 [ F2 ][ F3 ]
     4 figures   [ F1 ][ F2 ]          two pairs, bullets below
                 [ F3 ][ F4 ]
     5 figures   [ bullets ][ F1 ] then two pairs

   So an ODD run leads with a right-floated figure and pairs the rest; an EVEN
   run is all pairs. The odd one out leads rather than trails because the figure
   that sits beside prose should be the one that prose is about — a trailing
   leftover would end up next to the section's opening bullets, which are about
   something else.

   CSS cannot count siblings, so the "first figure of an odd-length run" cases
   are spelled out. §9.5 caps an outline at 6 figures, so 1, 3 and 5 are the only
   odd run lengths that can occur.

   Matching on the siblings themselves rather than a wrapper div keeps generated
   outlines free of layout markup. ":not(figure.fig + figure.fig)" reads as "is
   the first figure of its run".

   WIDTHS ARE EXACT ON PURPOSE. A pair is 50% + 50%, with the gutter taken as
   padding INSIDE each box rather than as a margin between them (box-sizing is
   border-box globally, so the padding is included in the 50%). An earlier
   version used 47.5% + 2% margin, which came to 99% and left a 1% sliver at the
   right edge — and a sliver is worse than nothing, because the bullets that
   follow put their line boxes in it and dribble down the right-hand side one or
   two characters wide instead of clearing to below the figures. Consuming the
   row exactly leaves no line box to fall into.

   The leader's 5% left margin is load-bearing for the same class of reason:
   48 + 5 + 50 = 103% means a pair figure can never squeeze in beside the leader
   at any column width, which is what forces the pair onto the row below without
   needing a clear on an element CSS cannot select. */
@media screen and (min-width: 861px), print {
  figure.fig {
    float: left;
    clear: none;
    width: 50%;
    padding-right: 26px;
    margin: 6px 0 16px;
  }

  figure.fig:not(figure.fig + figure.fig):not(:has(+ figure.fig)),
  figure.fig:not(figure.fig + figure.fig):has(+ figure.fig + figure.fig):not(:has(+ figure.fig + figure.fig + figure.fig)),
  figure.fig:not(figure.fig + figure.fig):has(+ figure.fig + figure.fig + figure.fig + figure.fig):not(:has(+ figure.fig + figure.fig + figure.fig + figure.fig + figure.fig)) {
    float: right;
    clear: right;
    width: 48%;
    padding-right: 0;
    margin: 6px 0 16px 5%;
  }
}

figure.fig .fig-img {
  display: block;
  /* Two caps, not one. Width fills the half-column; the rasters stay full size
     (inject_figures.py writes up to 1100px) so surplus pixels become sharpness
     on hi-DPI screens. Height is capped because a PORTRAIT slide crop — some run
     880x1492 — would otherwise stand 700px+ tall at half-column width and push
     its own caption off the screen. A normal 3:2 diagram never reaches this cap;
     it exists only to tame the tall ones. */
  max-width: 100%;
  max-height: min(620px, 68vh);
  width: auto;
  height: auto;
  margin: 0 auto;
  background: #fff;
  border: 1px solid #dfe3ea;
  border-radius: 6px;
}

/* Full-width by contract: a comparison table is a reading unit of its own and a
   half-width one would wrap unreadably, and the bordered blocks would render
   half-covered by a figure they have nothing to do with. h2 clears so a section
   can never start beside the previous section's figure. */
h2,
.cmp-table,
.block-critical, .block-mnem, .block-miscon, .block-keypoint,
.must-know-box, .legend {
  clear: both;
}

figure.fig .fig-cap {
  margin-top: 8px;
  font-size: 12.5px;
  line-height: 1.55;
  color: #3f4a5a;
}

/* Same visual family as the .slide-badge on an h2 — this is a source label,
   not content, so it reads as chrome rather than as part of the caption. */
.fig-label {
  display: inline-block;
  font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.1em;
  color: #0d2b5e; background: #eef2f8;
  border: 1px solid #d0d8e8; border-radius: 4px;
  padding: 1px 6px; margin-right: 7px;
  vertical-align: middle; white-space: nowrap;
}

/* Placeholder never injected. .fig-empty is set by outline.js; the :has()
   rule covers the no-JS case in browsers that support it. */
figure.fig.fig-empty            { display: none !important; }
figure.fig:has(.fig-img:not([src])) { display: none; }

@media print {
  /* The float layout carries over to paper — same reading relationship — but the
     height cap becomes a page fraction so one diagram cannot claim a whole sheet. */
  figure.fig .fig-img { max-height: 4.2in; }
  figure.fig .fig-cap { font-size: 11px; }
}

/* Below 861px the layout above simply never applies: half a phone column cannot
   hold a bullet without shredding it into two-word lines, so figures keep the
   unfloated full-width base state and only the height cap needs tightening. */
@media screen and (max-width: 860px) {
  figure.fig .fig-img { max-height: min(520px, 60vh); }
}

@media (max-width: 640px) {
  figure.fig          { margin: 12px 0 14px; }
  figure.fig .fig-cap { font-size: 12px; }
}

/* ── DARK MODE (the Appearance setting) ─────────────────────────────────────────
   site.js writes data-theme on <html>: absent means follow the OS, "dark"
   and "light" force it. One mechanism rather than a second palette: the
   whole page is inverted with hue preserved, then images are inverted back
   so figures, slides and the icon stay as authored. The filter sits on the
   ROOT element on purpose — the filter spec exempts the root from creating
   a containing block, so position:fixed overlays (settings, pause screen,
   notices) keep working. Scoped to screen so printing never inverts. */
@media screen and (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) {
    filter: invert(0.925) hue-rotate(180deg);
    background: #fff;   /* inverts to the page's dark canvas */
  }
  html:not([data-theme="light"]) img,
  html:not([data-theme="light"]) video {
    filter: invert(1) hue-rotate(180deg);
  }
}
@media screen {
  html[data-theme="dark"] {
    filter: invert(0.925) hue-rotate(180deg);
    background: #fff;
  }
  html[data-theme="dark"] img,
  html[data-theme="dark"] video {
    filter: invert(1) hue-rotate(180deg);
  }
}

/* ── SECTION NOTES (outline.js initSectionNotes) ───────────────────────────
   The 📝 button rides on each <h2>; the note itself is a sticky-yellow box
   under the heading. Hidden until it holds text or is opened. */
.sec-note-btn {
  border: none; background: none; cursor: pointer;
  font-size: 13px; line-height: 1; padding: 2px 4px; margin-left: 8px;
  vertical-align: middle; opacity: 0.35; transition: opacity 0.15s;
}
.sec-note-btn:hover { opacity: 1; }
/* A filled note reads as a filled control: full strength on a sticky-yellow
   chip, so a scan down the page shows exactly which sections carry notes. */
.sec-note-btn.has-note {
  opacity: 1; background: #ffe990; border-radius: 6px;
}

.section-note { display: none; margin: 8px 0 14px; }
.section-note.open, .section-note.has-note { display: block; }
.section-note-lbl {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: #8a6d1a; margin-bottom: 4px;
}
.section-note-area {
  display: block; width: 100%; min-height: 64px; resize: vertical;
  box-sizing: border-box; padding: 10px 12px;
  background: #fff9d6; border: 1.5px solid #e8d48a; border-radius: 8px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
  font-size: 13px; line-height: 1.55; color: #3a3115; outline: none;
}
.section-note-area:focus { border-color: #c9a227; }
.section-note-hint {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
  font-size: 10.5px; color: #a08c4a; margin-top: 3px;
}
