/* engine/styles.css — the seminar engine's visual language.

   Colour and type come from the family token block, brand.css, whose
   canonical copy lives in rae60/law-hub; the block below is pasted
   verbatim, so this app matches its siblings (the hub, /miller2/, the
   constitution pages). Unlike the hub and Miller (which load fonts from
   Google's CDN), every font here is self-hosted from engine/fonts/ — no
   request in this app ever leaves its own origin except the one YouTube
   embed (youtube-nocookie.com), and only once a youtube block is actually
   present and its iframe loads.

   Desktop-first: this is read at a desk, seminar prep, not scrolled
   one-handed. Reading column ~76ch; one phone fallback breakpoint at
   the bottom stacks everything for the iPhone case. */

/* ── Self-hosted fonts ─────────────────────────────────────────────── */

@font-face {
  font-family: 'Libre Baskerville';
  src: url('fonts/libre-baskerville-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Libre Baskerville';
  src: url('fonts/libre-baskerville-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Libre Baskerville';
  src: url('fonts/libre-baskerville-400italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: 'DM Sans';
  src: url('fonts/dm-sans-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'DM Sans';
  src: url('fonts/dm-sans-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'DM Sans';
  src: url('fonts/dm-sans-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'DM Sans';
  src: url('fonts/dm-sans-400italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('fonts/jetbrains-mono-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('fonts/jetbrains-mono-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('fonts/jetbrains-mono-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* ── Tokens ────────────────────────────────────────────────────────── */

/* ---- brand.css pasted verbatim from rae60/law-hub — begins ---- */
:root {
  /* the green ramp */
  --accent-night: #102e23;   /* footer */
  --accent-deep:  #123f2f;   /* masthead gradient start */
  --accent-dark:  #174f3a;   /* headings, table heads, theme-color */
  --accent:       #256b50;   /* links, controls, card rules (6.4:1 on white) */
  --accent-line:  #8db79e;   /* hover borders, soft rules */
  --accent-pale:  #d7eee0;   /* pills, targeted-row highlight */
  --accent-wash:  #f0fff0;   /* soft fills */
  --accent-tint:  rgba(37, 107, 80, 0.10);  /* selection, hover fills */
  --accent-ring:  rgba(37, 107, 80, 0.16);  /* box-shadow focus halo */

  /* text on green */
  --on-accent:       #ffffff;
  --on-accent-soft:  #dff4e7;   /* eyebrows on the masthead */
  --on-accent-muted: #c9dfd2;   /* dates, straplines on the masthead */

  /* neutrals (the seminars set) */
  --ink:          #1c2733;
  --ink-soft:     #55636f;
  --ink-faint:    #8b95a0;
  --parchment:    #fdfcfa;
  --paper:        var(--parchment);   /* alias: Miller and the constitution pages say --paper */
  --paper-raised: #ffffff;
  --surface-soft: #f5f8f6;
  --line:         #e1ded4;

  /* semantics — unchanged in meaning across the family */
  --amber-bg:     #fff4e5;   /* caution, uncurated, methodological warning */
  --amber-border: #d98c2b;
  --success:      #2d6a4f;   /* committed / saved states */
  --danger:       #a3312a;

  --font-display: 'Libre Baskerville', Georgia, serif;
  --font-body:    'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
}
/* ---- brand.css ends ---- */

:root {
  --column: 76ch;
  --rail-width: 200px;
}

/* ── Reduced motion — present from the start, even though little in
   this task animates yet ───────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Reset / base ──────────────────────────────────────────────────── */

* {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--parchment);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.25;
  color: var(--ink);
  margin: 0 0 1rem;
}

p {
  margin: 0 0 1rem;
}

a {
  color: var(--accent-dark);
}

ul, ol {
  padding-left: 1.4rem;
}

strong {
  font-weight: 700;
}

.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 0.35rem;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--accent);
  color: #fff;
  padding: 0.75rem 1rem;
  z-index: 100;
}
.skip-link:focus {
  left: 0.5rem;
  top: 0.5rem;
}

.loading,
.view-missing,
.view-error,
.thinking-empty {
  color: var(--ink-soft);
  font-style: italic;
  max-width: var(--column);
  margin: 0 auto;
}
.view-error {
  color: var(--danger);
  font-style: normal;
}

/* ── Masthead & nav ──────────────────────────────────────────────────
   Module/seminar title populate live once the routed seminar loads
   (see engine/app.js updateMasthead); the draft badge is hidden unless
   the loaded seminar's frontmatter carried draft: true. */

.masthead {
  color: var(--on-accent);
  background:
    radial-gradient(circle at 86% 16%, rgba(217, 140, 43, 0.16), transparent 22rem),
    linear-gradient(135deg, var(--accent-deep) 0%, var(--accent-dark) 60%, var(--accent) 100%);
  padding: 2rem 1.5rem 1.75rem;
}

.masthead .eyebrow {
  color: var(--on-accent-soft);
  margin-bottom: 0.5rem;
}

.masthead-title {
  margin: 0;
  font-size: 1.6rem;
  color: #fff;
}

.draft-badge {
  display: inline-block;
  margin-top: 0.85rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #1c2733;
  background: #f2b705;
  padding: 0.25rem 0.6rem;
  border-radius: 3px;
}
.draft-badge[hidden] {
  display: none;
}

/* The footage view is a landing for paper readers, not a place — the
   primary nav hides there so a workbook reader is never led into the
   app's machinery (pdf-edition spec, amended 15 September). The body
   class is toggled centrally in app.js's render(). */
body.footage-mode .site-nav { display: none; }

.site-nav {
  display: flex;
  overflow-x: auto;
  background: var(--paper-raised);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 10;
}

.nav-link {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  letter-spacing: 0.03em;
  text-decoration: none;
  color: var(--ink-soft);
  padding: 1rem 1.25rem;
  border-bottom: 3px solid transparent;
  white-space: nowrap;
}

.nav-link--active {
  color: var(--accent-dark);
  border-bottom-color: var(--accent);
  font-weight: 500;
}

/* ── Main content ──────────────────────────────────────────────────── */

main#view {
  padding: 2.5rem 1.5rem 5rem;
}

/* Each block carries its own max-width rather than main#view, so a
   full-width block (currently just setpiece — see .block--full-width)
   can widen without a special-cased parent layout. "Full width" means
   the width available inside main#view's own padding, not an edge-to-
   edge viewport bleed — this stays a desktop reading app, not a slide
   deck. */
.block {
  max-width: var(--column);
  margin: 0 auto 1.85rem;
  width: 100%;
}
.block--full-width {
  max-width: none;
}

/* A generic two-column utility, ready for the set-piece task to use
   inside a full-width block — not applied by anything in this task. */
.two-col-region {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2rem;
}

/* ── Front door: orientation block ────────────────────────────────────
   The shell supplies structure only. Copy is whatever prose the
   seminar's own author wrote as their opening lines (the leading run
   of "prose" blocks, before the first heading or directive) — see
   App.view('seminar', ...) in app.js, which is the only thing that
   decides which blocks land here. */

.orientation {
  /* Boxed in the source-card chrome (Richard's ruling, 2026-08-29):
     the front door was the one screen of bare display-serif prose,
     and next to A1's all-card page it read oversized and unrelated.
     The box converts the welcome into apparatus, so the text drops
     to the body register the cards use — the section pages keep
     their two-register contrast (book-voice prose between cards)
     untouched, because this styles .orientation only. */
  max-width: var(--column);
  margin: 0 auto 2.75rem;
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 1.3rem 1.5rem;
}
.orientation .prose p:last-child {
  margin-bottom: 0;
}
.orientation-privacy {
  margin: 1.1rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ink-soft);
}

/* The paper edition's own quiet line (2026-09-04-pdf-edition-design.md)
   — same quiet mono-small register as .orientation-privacy, just
   above, but a SIBLING of .orientation rather than a line inside it:
   renderFrontDoor appends it to the outer container after the box, not
   into the orientation div itself, so it needs its own centring rather
   than inheriting .orientation's. */
.front-door-paper {
  max-width: var(--column);
  margin: 1.1rem auto 0;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ink-soft);
}

/* ── The page turn — an invitation, never a meter ─────────────────────── */
.place-turn {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin: 3rem auto 0;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
  max-width: var(--column);
}
.place-turn a { text-decoration: none; max-width: 48%; }
.place-turn-next { margin-left: auto; text-align: right; font-weight: 600; }
.place-notice { font-style: italic; margin: 0 auto 1.5rem; max-width: var(--column); }

/* The "whole seminar" view's own back link, above its rendered blocks. */
.whole-back {
  display: inline-block;
  margin: 1rem 0 1.5rem;
  text-decoration: none;
}
.whole-back:hover { text-decoration: underline; }

/* ── Footage view (the paper edition's landing for a video signpost,
   2026-09-04-pdf-edition-design.md "The footage pages") ────────────────
   The honour gate is a QUIET box: same source-card/check-card chrome
   as every other bordered card that carries no accent border of its
   own (the card taxonomy comment, below) — it is not a student-action
   box, there is nothing to submit here, the workbook already holds the
   writing — and deliberately does not reach for --amber-bg/
   --amber-border either: not a caution, not an uncurated flag, simply
   the prompt, reproduced in full. */
.footage-honour-gate {
  max-width: var(--column);
  margin: 0 auto 1.85rem;
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 1.3rem 1.5rem;
}
.footage-honour-rubric {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--ink-soft);
  margin: 0 0 1rem;
}
/* Echoes .commit-prompt's own italic-display register (see "Commit",
   below) — this IS that same prompt text, reproduced, not a fresh
   voice speaking over it. */
.footage-honour-prompt {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.1rem;
  color: var(--ink);
}
.footage-honour-reassurance {
  font-style: italic;
  color: var(--ink-soft);
  margin: 0.9rem 0 0;
}
/* The closing line — mono and centred, a colophon rather than a page
   turn: footage renders no .place-turn of its own to close with. */
.footage-close {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--ink-soft);
  text-align: center;
  max-width: var(--column);
  margin: 2.5rem auto 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}

/* ── Plain prose & headings ────────────────────────────────────────── */

.prose :last-child {
  margin-bottom: 0;
}

.block h2, .block h3, .block h4 {
  margin-top: 0;
}

/* ── Card taxonomy ─────────────────────────────────────────────────────
   Three shapes, so fourteen-odd block kinds don't blur into one
   another:
     1. source cards      — bordered, serif/mono content (reading,
                             further_reading, legal_platform,
                             seminar_questions, casebook_entry, link,
                             file)
     2. student-action boxes — accent LEFT BORDER only; solid accent
                             fill is reserved exclusively for Commit
                             buttons (.commit-button — first rendered by
                             Task 4's Commit.box/Commit.methodBox)
     3. media figures      — figure + caption, minimal chrome (image,
                             video, youtube)
   Plain prose and headings are neither — unboxed flowing type. */

.source-card {
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 1.3rem 1.5rem;
}
.source-card-eyebrow {
  margin-bottom: 0.65rem;
}
.source-card-body :last-child {
  margin-bottom: 0;
}
/* Currently a no-op: renderStatute gives its eyebrow BOTH
   source-card-eyebrow and the shared .eyebrow class (line ~170 above),
   which already sets this same 0.08em. Kept explicit anyway, scoped to
   --statute, as the hook a future statute-specific tweak would reach
   for first rather than touching the shared .eyebrow rule every other
   source card also uses. */
.source-card--statute .source-card-eyebrow {
  letter-spacing: 0.08em;
}
/* A statute's line structure IS content: subsections on their own
   lines, lettered paragraphs indented as the Act prints them. Markdown
   treats single newlines as soft and swallows leading spaces — the
   author's line-faithful HRA ss 3–4 rendered as prose soup
   (2026-08-31). markdown2 preserves the raw newlines and indent spaces
   inside its <p> source, so pre-wrap resurrects the enacted shape;
   long single-line provisions (the ECA card) still soft-wrap exactly
   as before. Type statute bodies as the Act prints them —
   authoring.md's statute row says so in the same commit. */
.source-card--statute .source-card-body {
  white-space: pre-wrap;
}

.questions-invitation {
  margin: 1rem 0 0;
  padding-top: 0.85rem;
  border-top: 1px dashed var(--line);
  color: var(--ink-soft);
}

.casebook-shortname {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.2rem;
  margin: 0 0 0.15rem;
}
.casebook-citation {
  margin-bottom: 1.1rem;
}
.casebook-extract {
  border-left: 3px solid var(--line);
  padding: 0.2rem 0 0.2rem 1.1rem;
  margin: 0 0 1.1rem;
}
.casebook-extract:last-of-type {
  margin-bottom: 0.5rem;
}
.casebook-extract-heading {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin: 0 0 0.5rem;
}
.casebook-extract-body {
  font-family: var(--font-display);
}
.casebook-extract-body :last-child {
  margin-bottom: 0;
}
.casebook-provenance {
  margin: 0.5rem 0 0;
}

.link-card-anchor,
.file-card-link {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.92rem;
  color: var(--ink);
  text-decoration: none;
  background: var(--parchment);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 0.65rem 1.1rem;
}
.link-card-anchor:hover,
.file-card-link:hover {
  border-color: var(--accent);
  color: var(--accent-dark);
}
.link-card-desc {
  margin-top: 0.9rem;
}
.link-card-warning {
  margin-top: 0.6rem;
  color: var(--danger);
  font-size: 0.88rem;
}
.file-card-missing {
  /* Inert fallback for missing/refused file sources. Must not look
     clickable — matching the plain-text treatment of .link-card-warning
     (muted text, no border/background/hover). */
  margin-top: 0.6rem;
  color: var(--danger);
  font-size: 0.88rem;
}

/* ── The authority (:::authority, engine/app.js renderAuthority) ──────
   docs/authority-design.md §3: "compact house chrome, quieter than an
   extract card." Like .check-card further down this file, .authority-
   card duplicates .source-card's own box chrome at TIGHTER padding
   rather than sharing its selector — same reasoning as that rule's own
   comment: the two stay free to diverge. Not pen territory (renderer's
   own comment): no .pen-mark/.pen-print machinery ever touches this
   card, so no rule here needs to make room for either. */
.authority-card {
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 1rem 1.3rem;
}
.authority-card-eyebrow {
  margin-bottom: 0.5rem;
}
/* The identity line — prominent, one line, both name and citation(s)
   in the display (serif) face; only .authority-name adds the italic
   OSCOLA gives a case name, so the citation(s) read roman simply by
   NOT inheriting it (no separate "roman" rule needed). */
.authority-identity {
  font-family: var(--font-display);
  font-size: 1.15rem;
  margin: 0 0 0.7rem;
}
.authority-name {
  font-style: italic;
}
.authority-body {
  margin-bottom: 0.9rem;
}
.authority-body :last-child {
  margin-bottom: 0;
}
/* The single action: house link voice — same mono/underline/accent
   register as .quiet-continue (an inline invitation, not a boxed
   button like .link-card-anchor's own stand-alone-card treatment,
   which this card, sitting quieter than a source card, doesn't reach
   for) — plus the same visible :focus-visible ring .quiet-continue
   already carries. target/rel are never set in CSS; they arrive from
   engine/app.js's externaliseLinks pass, same as any other departing
   anchor on the page. */
.authority-action {
  display: inline-block;
  color: var(--accent-dark);
  font-family: var(--font-mono);
  font-size: 0.92rem;
  letter-spacing: 0.02em;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.authority-action:hover {
  color: var(--accent);
}
.authority-action:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* ── The brief (:::brief, engine/brief.js) ─────────────────────────
   The case-brief notebook (2026-09-02-brief-directive-design.md).
   Head chrome borrows the authority identity classes wholesale (one
   builder, one look); the scaffold below is a quiet form — labels
   carry the prompts, fields are plain textareas. Tokens below are the
   file's own :root set (checked above, at the top of this file) —
   --card-bg does not exist here, so .brief-card and its form controls
   reuse --paper-raised, the token .authority-card already uses for
   the same "card surface" role, just above. */
.brief-card {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1.1rem 1.25rem 1.25rem;
  background: var(--paper-raised);
}
.brief-form { margin-top: 1rem; }
.brief-field { margin: 0 0 1rem; }
.brief-field-label { display: block; margin-bottom: 0.3rem; }
.brief-field-title {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.brief-field-prompt {
  display: block;
  font-size: 0.82rem;
  color: var(--ink-soft);
}
.brief-field-input, .brief-judge-points {
  width: 100%;
  box-sizing: border-box;
  font: inherit;
  font-size: 0.92rem;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper-raised);
  resize: vertical;
}
.brief-judge-row {
  border-left: 2px solid var(--line);
  padding-left: 0.75rem;
  margin: 0 0 0.75rem;
}
.brief-judge-name {
  width: 100%;
  box-sizing: border-box;
  font: inherit;
  font-size: 0.92rem;
  font-weight: 600;
  padding: 0.35rem 0.6rem;
  margin-bottom: 0.4rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper-raised);
}
.brief-judge-remove {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  padding: 0.15rem 0.5rem;
  margin-top: 0.3rem;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 4px;
  color: var(--ink-soft);
  cursor: pointer;
}
.brief-save-status {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--ink-soft);
  min-height: 1em;
  margin: 0.25rem 0 0;
}
.brief-save-notice {
  font-size: 0.82rem;
  color: var(--danger);
  margin: 0.5rem 0 0;
}

/* ── The brief's controls (Task 4) — exports and print left, Delete
   alone far right (the butter-fingers doctrine: a destructive action
   needs its own distance from the workaday ones beside it). .btn-small
   (Export Markdown, Export RTF, Print this brief) carries the
   ghost-outline look for the three left-hand buttons; only Delete gets
   a look of its own, in --danger, below. */
.brief-controls {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  margin-top: 1rem;
}
.btn-small {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  padding: 0.25rem 0.6rem;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 4px;
  color: var(--ink-soft);
  cursor: pointer;
}
.btn-small:hover {
  border-color: var(--accent);
  color: var(--accent-dark);
}
.btn-small:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.brief-delete {
  margin-left: auto;             /* alone, far right */
  font-family: var(--font-mono);
  font-size: 0.7rem;
  padding: 0.25rem 0.6rem;
  background: transparent;
  border: 1px solid var(--danger);
  border-radius: 4px;
  color: var(--danger);
  cursor: pointer;
}

/* The print-only rendering _preparePrintView (engine/brief.js) builds
   from the STORED value: invisible on screen unconditionally (same
   split as .pen-print-notes, above the "Check your thinking" section
   — declared here, revealed only under body.pen-printing inside the
   existing @media print block, at the bottom of this file). The
   student's line breaks in facts/held/etc. are plain text, never
   markdown — pre-line is what makes them survive as breaks on paper. */
.brief-print-view { display: none; }
.brief-print-view p { white-space: pre-line; }
.brief-print-cite {
  font-size: 0.85em;
  color: var(--ink-soft);
  margin: 0.3rem 0 0;
}

/* ── The sources (:::book/:::article/:::web/:::report/:::newspaper/
   :::hansard, engine/sources.js) ──────────────────────────────────
   Six OSCOLA cards, one look — the authority card's quiet chrome
   (2026-09-02-sources-directives-design.md). Identity in the display
   face; only .source-cite-italic adds the italic OSCOLA gives titles
   and site/paper names. Duplicates .authority-card's box chrome
   (background/border/radius/padding) and .authority-action's link
   treatment rather than sharing their selectors — the same house
   convention .check-card/.work-room/.brief-card already follow above,
   keeping the families free to diverge later. */
.source-cite-card {
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 1rem 1.3rem;
}
.source-cite-eyebrow {
  margin-bottom: 0.5rem;
}
.source-cite-identity {
  font-family: var(--font-display);
  font-size: 1.15rem;
  margin: 0 0 0.7rem;
}
.source-cite-italic { font-style: italic; }
.source-cite-body {
  margin-bottom: 0.9rem;
}
.source-cite-body :last-child {
  margin-bottom: 0;
}
.source-cite-action {
  display: inline-block;
  color: var(--accent-dark);
  font-family: var(--font-mono);
  font-size: 0.92rem;
  letter-spacing: 0.02em;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.source-cite-action:hover {
  color: var(--accent);
}
.source-cite-action:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* ── The student's pen (engine/pen.js — Task 1: anchors, resolution,
   painting) ────────────────────────────────────────────────────────
   docs/pen-design.md. .pen-mark wraps a RESOLVED highlight's text —
   one family of spans per stored mark, sharing a data-pen-id, so a
   mark crossing an inline <em>/<strong> boundary inside
   .casebook-extract-body/.source-card-body (the .pen-source regions,
   set by Pen.attach) still erases as one unit. No custom property for
   the highlight yellow exists yet (checked :root, above) — #fef08a is
   the workbench's own soft highlight, used literally here exactly as
   every other one-off card colour already is in this file (e.g. the
   masthead's #f2b705, the method tab's #10161e) — --amber-bg/
   --amber-border are the exception, reused across several rules; this
   one colour is not, at least not yet (spec §3: a palette is future
   work, deliberately deferred). The print-a-single-card flow is Task
   4's — this rule only carries the print WASH colour Task 4 will
   render onto, per spec §7 ("a mono laser says what the screen
   says"). */
.pen-mark {
  background: #fef08a;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.pen-mark:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ── The pencil's noted face (docs/pencil-design.md §5) ────────────────
   A small dot marks a mark that carries a note — enough to find your
   own annotations at a glance, quiet enough to count nothing (spec's
   own kindness line: no counts anywhere). Decorative only: a
   pseudo-element is never exposed to the accessibility tree at all (no
   aria-hidden needed — there is nothing there for it to hide), so the
   ACCESSIBLE fact lives entirely in the family's own aria-label
   instead ("Highlight with note: …", set by pen.js's _wireEraser).
   Screen only, deliberately unscoped by any @media query: print
   numbers noted marks instead (Task 3's own print-time
   data-pen-print-n attribute and ::after rule, added later, override
   this ::after's `content` entirely under @media print — the two are
   never both visible at once because Task 3's rule targets the
   attribute this screen rule never sets). */
.pen-mark--noted::after {
  /* A star, not a dot — the dot was too easily missed (the author's
     beta verdict, 2026-08-31), and the star is the house's own pin
     language: his research workbench marks pinned paragraphs ☆/★.
     Decoration only; the aria-label carries the "with note" fact. */
  content: '★';
  color: var(--accent);
  font-size: 0.7em;
  margin-left: 0.2em;
  vertical-align: super;
}

/* ── The pen: selection pill + eraser popover (Task 2, engine/pen.js)
   ────────────────────────────────────────────────────────────────────
   One shared instance of each — created once at module init, kept in
   document.body, repositioned per use, never re-created (Pen's own
   _positionNear). Chrome, not content: reuses the method card's own
   register (.method-card-tab/-panel, above) rather than inventing a
   new one — a floating ink pill for the offer, a bordered white panel
   with the same shadow for the popover. Both are position:absolute
   (not fixed): Pen._positionNear converts a getBoundingClientRect()
   viewport rect into PAGE coordinates via +window.scrollX/Y, which is
   what lets an absolutely-positioned document.body child scroll WITH
   the text it's anchored to, with no scroll listener needed. */
.pen-pill-group,
.pen-popover {
  position: absolute;
  /* Above the mobile "Places" overlay (60, ~line 1150) and the method
     card (50) — a floating pen control must win over either. Only
     .skip-link's 100 is higher, and it only ever occupies the
     top-left corner on keyboard focus; it never actually overlaps
     either of these. */
  z-index: 70;
}
.pen-pill-group[hidden],
.pen-popover[hidden] {
  display: none;
}

/* The pill pair (docs/pencil-design.md §3 decision c): ONE positioned
   box holding both buttons — pen.js shows/hides/positions this group
   as a single unit, never either button separately, so "Highlight"
   and "+ note" always appear and disappear together. */
.pen-pill-group {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.pen-pill {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  background: var(--ink);
  color: #fff;
  border: none;
  border-radius: 999px;
  padding: 0.6rem 1.3rem;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22);
  cursor: pointer;
}
.pen-pill:hover {
  background: #10161e;
}
.pen-pill:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* "+ note" (pencil, spec §3) — shares .pen-pill's shape/sizing/type
   scale wholesale (same base class on the element; nothing above this
   rule is duplicated), a quieter fill only: the house's bordered-
   parchment register (.pen-popover-remove/.pen-print/.link-card-anchor
   below and above) rather than the primary pill's solid ink fill, so
   "+ note" reads as offered beside Highlight, never above it. Own
   :hover needed (not just :focus-visible, already inherited from
   .pen-pill above) because .pen-pill:hover's #10161e fill would
   otherwise darken this button to look like the ink pill on hover,
   undoing the quieter register on the one interaction that matters
   most. */
.pen-pill--note {
  background: var(--parchment);
  color: var(--ink);
  border: 1px solid var(--line);
  box-shadow: none;
}
.pen-pill--note:hover {
  background: var(--parchment);
  border-color: var(--accent);
  color: var(--accent-dark);
}

.pen-popover {
  /* 26rem, up from the original 19 — "a bit bigger - wider. It feels a
     little constrained" (the author, first pencil beta). Still clamped
     to the viewport on phones by the max-width below. */
  width: 26rem;
  max-width: calc(100vw - 2.5rem);
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1.1rem 1.25rem;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.2);
}
.pen-popover-quote {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 0.98rem;
  color: var(--ink);
  margin: 0 0 0.9rem;
}
/* The note field (pencil, spec §4) — house form register, matching
   Commit.methodBox's own labelled-field pair
   (.commit-method-label/.commit-method-textarea) rather than inventing
   a new one. 16px font-size (not the file's usual rem sizing) matches
   .commit-textarea/.commit-method-textarea's own deliberate choice:
   below 16px, iOS Safari zooms the viewport on focus. */
.pen-note-label {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  color: var(--ink);
  margin: 0 0 0.4rem;
}
.pen-note-field {
  display: block;
  width: 100%;
  min-height: 6.5rem;
  font-family: var(--font-body);
  font-size: 16px;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 4px;
  resize: vertical;
  background: var(--parchment);
  color: var(--ink);
  margin: 0 0 0.9rem;
}
.pen-note-field:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-tint);
}
/* Save note — prominent, but never a solid accent fill (that's
   reserved for .commit-button — see its own comment above: "the ONE
   place in this app a solid accent fill appears"). The same outlined-
   mono register as .thinking-export/.thinking-install-button, scaled
   to the popover's own compact size instead of that page's larger one,
   so Save note reads as the popover's primary action without
   competing with the house's one reserved solid fill. Sits inline
   before Remove (both inline-flex, wrapping naturally if the popover
   is too narrow to hold both on one line) — the right margin is this
   button's own gap to Remove, since inline flow has no `gap`. */
.pen-popover-save-note {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--font-mono);
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--accent-dark);
  background: transparent;
  border: 2px solid var(--accent);
  border-radius: 4px;
  padding: 0.55rem 1rem;
  margin: 0 0.6rem 0 0;
  cursor: pointer;
}
.pen-popover-save-note:hover {
  background: var(--accent-tint);
}
.pen-popover-save-note:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* Bordered mono box, accent on hover/focus — the same quiet, small-
   button-with-a-border register as .link-card-anchor/.file-card-link
   (above), not --danger: removing a highlight is deliberately low-
   stakes (spec §6 — "No confirm dialog — re-marking is trivial"), so
   Remove reads as an ordinary action, not an alarm. */
.pen-popover-remove {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--font-mono);
  font-size: 0.88rem;
  color: var(--ink);
  background: var(--parchment);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 0.55rem 1rem;
  cursor: pointer;
}
.pen-popover-remove:hover {
  border-color: var(--accent);
  color: var(--accent-dark);
}
.pen-popover-remove:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ── The pen: print this case (Task 4, Pen.printCard) ─────────────────
   Quiet card furniture on screen: the same bordered-mono-box register
   as .pen-popover-remove/.link-card-anchor/.file-card-link just above —
   border + parchment fill, accent only on hover/focus, no fill of its
   own — printing is as low-stakes an action as erasing, spec §6's
   "ordinary action, not an alarm" reasoning applies here too. Block-
   level with an auto LEFT margin (not position:absolute) so it lives in
   ordinary document flow, on its own row, pushed right: app.js inserts
   it FIRST in the card, before the name/citation/eyebrow, because a
   real citation can run the card's full width (see app.js's own
   comment on this) — a corner badge floated OVER that text at the top
   of the card would overlap it, where a plain flow row never can.
   display:flex (not inline-flex) keeps its OUTER box block-level, so
   margin-left:auto still pushes it right the way it would for a plain
   block — the flex is only for centring "Print" inside the fixed
   min-height. Hidden unconditionally in @media print, below: a "Print"
   button has no business on paper, one card or the whole page. */
.pen-print {
  display: flex;
  align-items: center;
  justify-content: center;
  width: fit-content;
  min-height: 44px;
  margin: 0 0 0.9rem auto;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-soft);
  background: var(--parchment);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 0 0.9rem;
  cursor: pointer;
}
.pen-print:hover {
  border-color: var(--accent);
  color: var(--accent-dark);
}
.pen-print:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ── The pencil's printed notes (docs/pencil-design.md §7) ────────────
   The "Your notes" aside pen.js's printCard appends inside the printed
   card, and the superscript numbers it stamps onto each noted mark's
   own ::after (data-pen-print-n — see the noted-face rule above for how
   the two ::after rules divide the work) are BOTH print-only:
   assembled by JS right before window.print() and swept away again by
   the same _clearPrintFlags every clear route already shares
   (afterprint, the defensive re-clear at the top of every printCard
   call, and hashchange). This screen half of the split hides the aside
   unconditionally, deliberately unscoped by any @media query — the
   node is appended to the LIVE document a moment before window.print()
   actually engages the print stylesheet, so without a screen-scoped
   rule here it would flash visible on an ordinary screen render for
   that brief window ("even mid-flow the screen never shows it," this
   task's own brief). The print half — where it is actually shown, and
   how it is typeset — lives inside the existing @media print block,
   below, scoped to body.pen-printing to match .pen-print-target's own
   convention there. */
.pen-print-notes {
  display: none;
}

/* ── Check your thinking (engine/app.js renderCheck) ──────────────────
   Bordered like a source card — .check-card duplicates .source-card's
   box chrome below rather than sharing its selector, so the two stay
   free to diverge — not a student-action box: the card itself never
   takes the accent LEFT BORDER that shape reserves (see the taxonomy
   comment above). Only an individual OPTION ROW earns a quiet left
   accent, and only once chosen — the student's own pick, never a
   verdict on it. No ticks, no green/red, no counts anywhere in this
   family; "the strongest answer" (.check-best) is the one comparative
   label the card ever shows, and only after the full reveal. */

.check-card {
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 1.3rem 1.5rem;
}
.check-stem :last-child {
  margin-bottom: 0;
}

.check-options {
  border: none;
  margin: 1rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.check-option {
  padding: 0.15rem 0 0.15rem 0.7rem;
  border-left: 3px solid transparent;
}
/* The chosen marker: accent, because it marks the student's own pick —
   never --success/--danger, which would turn a single-best-answer
   question into a scored quiz. */
.check-option--chosen {
  border-left-color: var(--accent);
}

.check-option-label {
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  cursor: pointer;
}
.check-option-label input[type="radio"] {
  flex: 0 0 auto;
  margin: 0.3rem 0 0;
  accent-color: var(--accent);
}
.check-option-text {
  flex: 1 1 auto;
}

/* Indented under its option — same bordered-quote shape .casebook-extract
   uses elsewhere in this file, at the same 3px/--line weight, so a
   check's feedback reads as "quoted material under this option" rather
   than borrowing the chosen row's own accent for a different purpose. */
.check-feedback {
  margin: 0.6rem 0 0 1.75rem;
  padding: 0.15rem 0 0.15rem 1rem;
  border-left: 3px solid var(--line);
}
.check-feedback :last-child {
  margin-bottom: 0;
}

.check-best {
  margin: 0 0 0.4rem;
}

.check-show-others {
  margin-top: 0.5rem;
}

/* Student-action boxes: commit/reflect/setpiece placeholders in this
   task (Tasks 4/5 give commit/reflect real behaviour; setpiece gains
   its registered renderers, still inside this same shape). */
.action-box {
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-left: 4px solid var(--accent);
  border-radius: 6px;
  padding: 1.3rem 1.5rem;
}
.action-box-eyebrow {
  margin-bottom: 0.5rem;
}
.action-box-body :last-child {
  margin-bottom: 0;
}
.action-box-placeholder-note {
  margin: 0.9rem 0 0;
  padding-top: 0.8rem;
  border-top: 1px dashed var(--line);
  color: var(--ink-soft);
  font-size: 0.92rem;
}

/* ── Commit (Commit.box, kept for compatibility, and Commit.methodBox —
   Task 4) ─────────────────────────────────────────────────────────────
   Both share the .action-box shape above. .commit-button is the ONE
   place in this app a solid accent fill appears — everywhere else in
   the student-action-box shape stays accent-LEFT-BORDER-only. */

.commit-prompt {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.1rem;
  color: var(--ink);
}

.commit-privacy,
.reflect-privacy {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ink-soft);
  margin: 0.5rem 0 1.1rem;
}

.commit-reassurance {
  font-style: italic;
  color: var(--ink-soft);
  margin: 0 0 1.1rem;
}

.commit-lead {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--ink-soft);
  margin: 0 0 0.6rem;
}

.commit-textarea {
  display: block;
  width: 100%;
  min-height: 7rem;
  font-family: var(--font-body);
  font-size: 16px;
  padding: 0.75rem;
  border: 1px solid var(--line);
  border-radius: 4px;
  resize: vertical;
  background: var(--parchment);
  color: var(--ink);
}
.commit-textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-tint);
}

.commit-error {
  color: var(--danger);
  font-size: 0.9rem;
  margin: 0.9rem 0 0;
}

.commit-button {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 4px;
  padding: 0.75rem 1.35rem;
  margin-top: 1rem;
  cursor: pointer;
}
.commit-button:hover {
  background: var(--accent-dark);
}
.commit-button:active {
  transform: translateY(1px);
}

.commit-box--committed {
  border-left-color: var(--success);
}
.commit-committed-label {
  color: var(--success);
}
.commit-committed-text {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.05rem;
  white-space: pre-wrap;
}
.commit-timestamp {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ink-soft);
  margin: 0.9rem 0 0;
}

/* ── Commit.methodBox — the five labelled fields ─────────────────────── */

.commit-method-fields {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  margin: 0 0 0.5rem;
}

.commit-method-field {
  display: flex;
  flex-direction: column;
}

.commit-method-label {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  color: var(--ink);
  margin-bottom: 0.4rem;
}

.commit-method-textarea {
  display: block;
  width: 100%;
  min-height: 3.4rem;
  font-family: var(--font-body);
  font-size: 16px;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 4px;
  resize: vertical;
  background: var(--parchment);
  color: var(--ink);
}
.commit-method-textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-tint);
}

.commit-method-rows {
  margin: 0.25rem 0 0;
}
.commit-method-row {
  display: flex;
  gap: 0.85rem;
  padding: 0.4rem 0;
  border-top: 1px dashed var(--line);
}
.commit-method-row:first-child {
  border-top: none;
  padding-top: 0;
}
.commit-method-row-label {
  flex: 0 0 auto;
  min-width: 9.5rem;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.commit-method-row-value {
  font-family: var(--font-display);
  font-style: italic;
  white-space: pre-wrap;
}

/* ── Reflect ───────────────────────────────────────────────────────────
   Same .action-box shape as Commit, but its Continue is deliberately
   quiet (.quiet-continue, below) — never accent-filled, never shaped
   like a Commit button. */

.reflect-prompt {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.1rem;
  color: var(--ink);
  margin-bottom: 0.5rem;
}

/* ── Quiet Continue — shared by Reflect and Reveal ─────────────────────
   A link-button: no fill, no border box, underlined mono text. The
   deliberate visual opposite of .commit-button in this app. */

.quiet-continue {
  display: inline-block;
  background: transparent;
  border: none;
  color: var(--accent-dark);
  font-family: var(--font-mono);
  font-size: 0.92rem;
  letter-spacing: 0.02em;
  text-decoration: underline;
  text-underline-offset: 0.2em;
  padding: 0.5rem 0;
  margin-top: 0.25rem;
  cursor: pointer;
}
.quiet-continue:hover {
  color: var(--accent);
}
.quiet-continue:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
.quiet-continue:disabled {
  opacity: 0.55;
  cursor: default;
  text-decoration: none;
}

/* ── Reveal ────────────────────────────────────────────────────────────
   Layers are plain content wrappers with no shape of their own beyond
   spacing — layer content (casebook cards, transcripts, prose) is
   already styled by App.renderBlock's own renderers or a set-piece's
   own markup. tabindex="-1" is set programmatically (reveal.js); it
   never shows a focus ring beyond the browser's normal outline. */

.reveal-layer {
  margin-top: 1.75rem;
}
.reveal-layer:first-child {
  margin-top: 0;
}
.reveal-layer:focus {
  outline: none;
}
.reveal-continue {
  margin-bottom: 1.75rem;
}

/* ── Gate (Task 4) ─────────────────────────────────────────────────────
   A Continue-gate's button (engine/app.js's armGate) — quiet-continue
   again (see above: same Reflect-style link-button, reused not
   reinvented), extended only with what's specific to standing ALONE
   between blocks rather than inside a padded .action-box (Reflect) or a
   stack of .reveal-layers (Reveal): its own block-level centring. A
   commit-gate renders no button at all — nothing to style here. */
.gate-continue {
  display: block;
  max-width: var(--column);
  margin: 2rem auto;
}

/* Visually hidden but still present and readable by assistive tech —
   Reveal's own live region, and available generally. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ── Method card — persistent corner tab ──────────────────────────────
   Fixed bottom-right, never a backdrop, never blocking content. Uses
   --ink (not --accent) for its own fill deliberately: solid accent fill
   is reserved for the Commit button alone, and this is chrome, not a
   call to action. */

.method-card {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 50;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.75rem;
  max-width: calc(100vw - 2.5rem);
}
.method-card[hidden] {
  display: none;
}
.method-card--input-focused {
  visibility: hidden;
}

.method-card-tab {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  background: var(--ink);
  color: #fff;
  border: none;
  border-radius: 999px;
  padding: 0.7rem 1.3rem;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22);
  cursor: pointer;
}
.method-card-tab:hover {
  background: #10161e;
}
.method-card-tab:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.method-card-panel {
  width: 22rem;
  max-width: calc(100vw - 2.5rem);
  max-height: 65vh;
  overflow-y: auto;
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1.25rem 1.4rem;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.2);
}
.method-card-panel[hidden] {
  display: none;
}

.method-card-heading {
  font-size: 1.05rem;
  margin: 0 0 0.9rem;
}

.method-card-list {
  margin: 0;
}
.method-card-item {
  padding: 0.55rem 0;
  border-top: 1px dashed var(--line);
}
.method-card-item:first-child {
  border-top: none;
  padding-top: 0;
}
.method-card-question {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--ink-soft);
  margin: 0 0 0.25rem;
}
.method-card-gloss,
.method-card-quote {
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 0.98rem;
  color: var(--ink);
}

.method-card-filled {
  border: 1px solid var(--line);
  border-left: 4px solid var(--ink);
  border-radius: 6px;
  background: var(--paper-raised);
  padding: 1.3rem 1.5rem;
}

/* ── The wayfinding rail — a map of the places, never a meter ──────────
   Chrome, like the method card: quiet, marginal, and carrying no
   judgement. It lists the seminar's WHOLE territory — every named place
   (see engine/rail.js's constitution) — and draws exactly one
   distinction — the place you are in. Visited and not-yet-visited
   entries are styled IDENTICALLY: nothing here counts, ticks, fills,
   shades-as-done, or hints at how much is left.

   The fixed rail is present only where it genuinely fits beside the
   reading measure. Below that breakpoint it is display:none, but it is
   not simply absent: a "Places" button (also styled below) opens the
   same list as a full-screen overlay instead. */

.section-rail {
  display: none;
}

@media (min-width: 1180px) {
  /* Reserve the rail's lane out of main#view's own right padding, so
     neither the centred prose column nor a full-width set-piece can run
     underneath it: 1.5rem gutter + the rail + the 1.5rem edge inset
     main#view already uses. 1180px is the width at which the content
     area left over is still wider than --column, so the reading measure
     never shrinks to pay for the rail — desktop and iPad-landscape sit
     above that line, anything narrower does not. */
  /* `has-section-rail` is set by Rail.update() and removed by
     Rail.clear() (engine/rail.js, engine/app.js), so a view with no map
     — "Your thinking", or any future view, or a seminar with no places
     — keeps its column centred instead of sitting 112px left of a large
     unexplained void. Both calls run synchronously inside App.render()
     before the new view's DOM is even appended, so a view swap never
     shows a stale offset for even one frame. */
  body.has-section-rail main#view {
    padding-right: calc(1.5rem + var(--rail-width) + 1.5rem);
  }

  /* Vestigial: scroll-margin only matters to something that scrolls a
     target into view, and nothing does that for these two selectors any
     more — the rail now navigates between PLACES (a route change, a
     fresh page) rather than scrolling to a heading within one growing
     page. Left in place as harmless headroom in case in-page scroll-to-
     heading returns; safe to delete otherwise. */
  body.has-section-rail #view > .block > h2,
  body.has-section-rail #view > .block--setpiece {
    scroll-margin-top: 5rem;
  }

  .section-rail {
    position: fixed;
    right: 1.5rem;
    /* A band that clears the masthead at the top of the document and the
       method-card tab's bottom-right zone; the entries sit centred
       within it via the auto margins below (auto margins rather than
       justify-content, so an over-long list scrolls instead of having
       its first entries clipped out of reach). */
    top: 15rem;
    bottom: 6rem;
    width: var(--rail-width);
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    z-index: 5; /* beneath the sticky nav (10) and the method card (50) */
    pointer-events: none; /* the empty band is not a click target */
  }
  .section-rail[hidden] {
    display: none;
  }

  .section-rail-caption {
    margin: auto 0 0.55rem;
    font-size: 0.65rem;
    color: var(--ink-faint);
  }

  .section-rail-list {
    list-style: none;
    margin: 0 auto 0 0;
    padding: 0;
    width: 100%;
    border-left: 1px solid var(--line);
    pointer-events: auto;
  }

  .section-rail-item {
    /* Inter-row spacing lives HERE, not as bottom padding on the
       clamped link below: Safari paints a line-clamped element's
       clipped third line through its own padding-bottom (the classic
       -webkit-line-clamp + padding bleed), which squashed sliver-high
       text fragments between rail rows. Margin is outside the clip
       box, so nothing can bleed into it. 0.35rem here + the link's
       remaining 0.35rem top padding keeps the old 0.7rem rhythm. */
    margin: 0 0 0.35rem;
  }

  .section-rail-link {
    /* Two lines, then ellipsis. Mono register, NORMAL case — Richard's
       ruling (2026-08-13): entries are full section headings, sentence-
       length strings, and sustained capitals tax dyslexic readers (the
       same A6 principle that de-capitalised the transcript speakers).
       Uppercase survives only on true chips (.draft-badge, row labels).
       Case is free either way in a true monospace — advance width does
       not change — so the clamp arithmetic below is unaffected. The
       line count is the lever that moves fit (23 characters to 46), and
       the band above already scrolls when a list outgrows it.
       -webkit-box is the clamp idiom; it supplies its own ellipsis, so
       text-overflow is not repeated here. */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    width: 100%;
    background: transparent;
    border: none;
    border-left: 2px solid transparent;
    margin-left: -1px; /* the marker sits on the list's own hairline */
    padding: 0.35rem 0 0 0.75rem; /* no padding-bottom — see .section-rail-item */
    text-align: left;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    line-height: 1.4;
    letter-spacing: 0.06em;
    color: var(--ink-soft);
    text-decoration: none;
    cursor: pointer;
    overflow: hidden;
  }
  .section-rail-link:hover {
    color: var(--ink);
  }
  .section-rail-link:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
  }

  /* The foot link is a direct child of .section-rail, outside
     .section-rail-list — the rail itself is pointer-events:none (the
     empty band must not be a click target), and only the list re-enables
     it above. Without this, the link renders and reads fine but every
     click falls through to whatever is behind it. */
  .rail-whole-link {
    pointer-events: auto;
  }
}

/* The address chip inside a rail row ("B4" before "The Dog Act") — same
   mono family as the row it sits in, just bolder, so the citation reads
   as a citation without becoming a second visual language. */
.rail-address {
  font-family: inherit;
  font-weight: 700;
  margin-right: 0.35rem;
}

/* The one and only state a row can carry: the place you are in right
   now. Set via `aria-current="true"` (rail.js), never via a class that
   visited-but-not-current rows could accidentally also pick up — the
   attribute IS the semantics, sighted and assistive alike. */
.section-rail-link[aria-current="true"] {
  font-weight: 700;
  border-left: 3px solid var(--accent);
  padding-left: 0.5rem;
}

/* The foot of the map: an invitation to read straight through, not a
   ranked alternative to any row above it. */
.rail-whole-link {
  display: block;
  margin-top: 1rem;
  font-size: 0.85rem;
}

/* The mobile stand-in for the fixed rail: a button that opens the same
   list as a full-screen overlay. Hidden above the rail's own breakpoint
   (the fixed rail already does the job there); shown below it only once
   rail.js has something to show (`[hidden]` wins on specificity over the
   plain display rule below, whichever order they run in). */
.places-button {
  display: none;
  font: inherit;
}
.section-rail-close { display: none; }
@media (max-width: 1179.98px) {
  .places-button[hidden] { display: none; }
  .places-button {
    display: inline-block;
    margin-left: auto;
  }
  .section-rail { display: none; }
  .section-rail--open {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 60;
    background: var(--paper-raised);
    overflow-y: auto;
    padding: 2rem 1.5rem;
    width: auto;
  }
  .section-rail--open .section-rail-close {
    display: inline-block;
    margin: 0 0 1rem;
    font: inherit;
  }
  .section-rail--open .section-rail-list { list-style: none; margin: 0; padding: 0; }
  .section-rail--open .section-rail-link {
    display: block;
    padding: 0.65rem 0.25rem;
    text-decoration: none;
    color: inherit;
  }
  .section-rail--open .section-rail-link[aria-current="true"] {
    font-weight: 700;
    border-left: 3px solid var(--accent);
    padding-left: 0.5rem;
  }
}

/* Media figures: image, video, youtube. The renderers add .media-figure
   to the SAME element the walker classes .block — so this family must
   never set its own margin: an outer `.media-figure { margin: 0 }`
   (written to reset figure defaults, which the child rule below already
   does) silently overrode .block's `margin: 0 auto` and sent every
   video flush-left on wide screens (the author's B4 report,
   2026-08-31). The block's own margin governs; only the child figure
   is reset here. */
.media-figure figure {
  margin: 0;
}
.media-figure img,
.media-figure video {
  width: 100%;
  height: auto;
  border-radius: 4px;
  display: block;
  background: var(--line);
}
.media-figure figcaption {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--ink-soft);
  margin-top: 0.65rem;
}
.youtube-embed {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: 4px;
  overflow: hidden;
  background: var(--ink);
}
.youtube-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* Unknown block kind: loud, not silent — visually distinct (danger)
   from the "known, just not built yet" placeholder styling above. */
.error-card {
  background: #fdf2f1;
  border: 1px solid var(--danger);
  border-left: 4px solid var(--danger);
  border-radius: 6px;
  padding: 1.3rem 1.5rem;
}
.error-card-eyebrow {
  color: var(--danger);
  margin-bottom: 0.4rem;
}
.error-card-message {
  color: var(--danger);
  margin: 0;
  font-weight: 500;
}

/* ── Transcript ────────────────────────────────────────────────────────
   A dramatis personae strip (case/hearing/source + one row per named
   speaker and their role) followed by turns as speaker chips. Bench
   and counsel are distinguished by SHAPE as well as colour — a filled
   pill vs. an outlined rectangular tag — so the distinction survives
   grayscale printing or colour-blindness, not just a colour swap. A
   turn with no speaker and role "other" is a stage direction: no chip
   at all, a centred italic line with generous whitespace around it. */

.transcript {
  background: transparent;
}

.personae-strip {
  border: 1px solid var(--line);
  border-left: 4px solid var(--ink);
  border-radius: 6px;
  background: var(--paper-raised);
  padding: 1.2rem 1.4rem;
  margin-bottom: 1.75rem;
}
.personae-meta {
  margin: 0 0 0.85rem;
}
.personae-list {
  margin: 0;
}
.personae-row {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.4rem 0;
  margin: 0;
  border-top: 1px dashed var(--line);
}
.personae-row:first-child {
  border-top: none;
  padding-top: 0;
}
.personae-name {
  font-weight: 600;
  margin: 0;
  min-width: 13rem;
}
.personae-role {
  /* Normal case by ruling (2026-08-13): these are full sentences since
     the roles became "why" explanations, and sustained capitals tax
     dyslexic readers (A6). Chips keep their caps; sentences do not. */
  margin: 0;
  color: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: 0.82rem;
  letter-spacing: 0.03em;
}

.turns {
  display: flex;
  flex-direction: column;
}
.turn {
  display: flex;
  gap: 1.1rem;
  align-items: baseline;
  padding: 0.9rem 0;
  border-top: 1px solid var(--line);
}
.turn:first-child {
  border-top: none;
}
.turn-chip {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  white-space: nowrap;
  padding: 0.32rem 0.8rem;
  min-width: 8rem;
  text-align: center;
}
.turn-chip--bench {
  /* Bench: a filled, fully-rounded pill. */
  background: var(--ink);
  color: var(--parchment);
  border-radius: 999px;
  font-weight: 500;
}
.turn-chip--counsel {
  /* Counsel: an outlined rectangular tag — different shape, different
     colour, never colour alone. */
  background: transparent;
  color: var(--accent-dark);
  border: 1.5px solid var(--accent);
  border-radius: 3px;
}
.turn-chip--other {
  /* A named speaker absent from the roles map — neither bench nor
     counsel: a third, quieter shape (dashed, neutral). */
  background: transparent;
  color: var(--ink-soft);
  border: 1.5px dashed var(--ink-faint);
  border-radius: 3px;
}
.turn-content {
  flex: 1 1 auto;
  min-width: 0;
}
.turn-content :last-child {
  margin-bottom: 0;
}

.scene-break {
  text-align: center;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.05rem;
  color: var(--ink-soft);
  margin: 2.75rem 0;
}
.scene-break p {
  margin: 0;
}

/* ── Your thinking ─────────────────────────────────────────────────── */

.thinking-view {
  max-width: var(--column);
  margin: 0 auto;
}

.thinking-heading {
  margin-bottom: 1.25rem;
}

.thinking-item {
  border-top: 1px solid var(--line);
  padding: 1.1rem 0;
}
.thinking-item:first-of-type {
  border-top: none;
}

.thinking-id {
  margin-bottom: 0.5rem;
}

.thinking-row {
  display: flex;
  gap: 0.85rem;
  padding: 0.3rem 0;
  border-top: 1px dashed var(--line);
}
.thinking-item .thinking-row:first-of-type {
  border-top: none;
}
.thinking-row-label {
  flex: 0 0 auto;
  min-width: 9.5rem;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.thinking-row-value {
  font-family: var(--font-display);
  font-style: italic;
}

.thinking-line {
  font-family: var(--font-display);
  font-style: italic;
  white-space: pre-wrap;
  margin: 0.35rem 0;
}

/* The pencil's gathered note (docs/pencil-design.md §6) — the student's
   own words in upright body text, the quote above keeping
   .pen-popover-quote's display italic: the SAME quote-italic /
   note-roman split the printed edition already draws
   (.pen-print-note-quote / .pen-print-note-text, in @media print).
   Targets the hook class buildNotesGroup (engine/notes.js) plants for
   exactly this purpose; committed thinking elsewhere on the page keeps
   .thinking-line's own register. */
.thinking-notes-text {
  font-family: var(--font-body);
  font-style: normal;
}

.thinking-timestamp {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--ink-soft);
  margin: 0.6rem 0 0;
}

/* ── Forget my answers (Task 7) ───────────────────────────────────────
   Each seminar's entries plus its own control form one visual unit, so
   several seminars read as separate blocks rather than one
   undifferentiated list. Only the boundary BETWEEN groups needs a rule
   — a group's own items keep using .thinking-item's border-top exactly
   as before (:first-of-type is scoped per parent, so each group's own
   first item is still borderless against the group's top edge). The
   margin+padding+border-top combination mirrors .thinking-privacy
   below, the one other place this file separates a block this way. */
.thinking-seminar-group + .thinking-seminar-group {
  margin-top: 1.75rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--line);
}

/* The control: .quiet-continue again (Reflect/Reveal/Gate's link-button
   — see the Reflect and Gate rules above, reused here rather than
   reinvented) for all three buttons, ask and both confirm halves alike.
   Only the destructive half of the confirm gets its own colour,
   borrowed from the same --danger token .commit-error already uses;
   nothing here gets a solid fill, which stays reserved for
   .commit-button alone. The colour is repeated at :hover/:focus-visible
   because .quiet-continue's own hover/focus rules (same specificity,
   earlier in the file) would otherwise win the cascade and flip it back
   to accent blue on interaction. */
.thinking-forget {
  margin-top: 1.1rem;
}
/* .quiet-continue sets its own display: inline-block (same specificity
   as the UA [hidden] rule, but author origin always outranks user-agent
   origin at equal specificity) — without this override the ask button
   would stay visible even once .hidden is set, exactly the bug
   .draft-badge[hidden]/.method-card[hidden]/.places-button[hidden]
   above each exist to prevent for their own elements. */
.thinking-forget-ask[hidden] {
  display: none;
}
.thinking-forget-copy {
  font-size: 0.92rem;
  color: var(--ink-soft);
  margin: 0 0 0.75rem;
}
.thinking-forget-actions {
  display: flex;
  gap: 1.5rem;
}
.thinking-forget-forget,
.thinking-forget-forget:hover,
.thinking-forget-forget:focus-visible {
  color: var(--danger);
}
.thinking-forget-error {
  color: var(--danger);
  font-size: 0.88rem;
  margin: 0.75rem 0 0;
}

/* Prominent, but never a solid accent fill (that's reserved for Commit
   buttons, which this task doesn't render) — an outlined mono button
   made prominent by size and border weight instead. */
.thinking-export,
.thinking-install-button {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.88rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  background: transparent;
  color: var(--accent-dark);
  border: 2px solid var(--accent);
  border-radius: 4px;
  padding: 0.75rem 1.5rem;
  margin-top: 1.75rem;
  cursor: pointer;
}
.thinking-export:hover,
.thinking-install-button:hover {
  background: var(--accent-tint);
}
.thinking-export:active,
.thinking-install-button:active {
  transform: translateY(1px);
}

.thinking-install {
  margin-top: 1.25rem;
  font-size: 0.92rem;
  color: var(--ink-soft);
}
/* The separate-storage footnote under the invitation: quieter than the
   invitation itself, so it reads as a clarification rather than a
   warning. */
.thinking-install-note {
  margin-top: 0.5rem;
  font-size: 0.84rem;
  color: var(--ink-soft);
}
.thinking-install-button {
  margin-top: 0;
  margin-left: 0.6rem;
  padding: 0.4rem 0.9rem;
  font-size: 0.8rem;
}

.thinking-privacy {
  margin-top: 2.75rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--ink-soft);
  text-align: center;
}

/* ── Your work: the rooms (Task 2, docs/your-work-design.md §5) ───────
   .work-room / .work-room--app / .work-mark / .work-mark-star /
   .work-address are minted by engine/notes.js (Task 1) — this section
   is their only styling. Each room duplicates .source-card's own box
   chrome (background/border/radius/padding) rather than sharing its
   selector — the same house convention .check-card/.action-box/
   .statute-card/.rhyme-card already follow above, keeping the families
   free to diverge later. */

.work-room {
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 1.3rem 1.5rem;
}

/* Generous inter-room margin (design §5) — not a leading margin on the
   very first room: .thinking-view has no page-level heading of its own
   above the rooms (main#view's 2.5rem top padding is the only thing
   above Room 1 — see engine/app.js's App.view('thinking', ...), which
   renders nothing before calling Notes.renderThinking), so a margin-top
   on .work-room unconditionally would just pad the top of the page for
   no reason. Two clauses, because the two gaps that actually need
   filling arise differently:
     - Room 1 -> Room 2, when both exist: true adjacent siblings, so the
       same `+` adjacent-sibling technique .thinking-seminar-group
       already uses (above) reaches it without touching Room 1's own
       leading edge.
     - the export button -> "This app": .thinking-export (always
       rendered) sits between them unconditionally (renderThinking
       appends it before the app room in every case), so "This app" is
       NEVER a .work-room's next sibling — it needs its own,
       unconditional margin-top instead.
   2.75rem matches this file's own established "generous top-level
   break" value (.thinking-privacy just above, .orientation, .scene-break). */
.work-room + .work-room,
.work-room--app {
  margin-top: 2.75rem;
}

/* "This app" (design §2: "gathered into its own quiet card") gets no
   typographic override of its own: its content — .thinking-install /
   .thinking-install-note / .thinking-privacy, all above — is already
   smaller and ink-soft-coloured than ordinary body text, so shrinking
   the room itself on top of that would double-shrink it. The shared box
   above is the whole of its "quiet card" treatment: the same border,
   radius and padding as the two work rooms, undecorated further, is
   what reads as quiet furniture rather than a third work room. */

/* The notes list (design §5: "unbulleted"). Source-to-source separation
   inside it still comes from .thinking-seminar-group +
   .thinking-seminar-group (above) — .thinking-notes-group carries that
   class too (engine/notes.js's buildMarkGroup), so the existing
   hairline rule already reaches every source group here with no change
   of its own needed. */
.thinking-notes-marks {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* One mark. Structural successor to .thinking-item (see notes.js's own
   comment on buildMarkGroup: "only the per-mark wrapper itself changes
   shape, from a .thinking-item div to an li.work-mark") — same hairline
   and vertical rhythm .thinking-item already uses for a thoughts-room
   entry, carried over so a list of several marks under one source reads
   the same way a list of several commitments already does. */
.work-mark {
  border-top: 1px solid var(--line);
  padding: 1.1rem 0;
}
.work-mark:first-child {
  border-top: none;
  padding-top: 0;
}

/* The noted-mark star (design §2: "the same language the cards speak")
   — same colour and size as the pencil's own .pen-mark--noted::after
   star, above, not redeclared as a shared custom property, just the
   same two values. A real element here, not a pseudo-element (this is
   fresh-built DOM, not text inside an existing highlight), and it
   precedes a block-level quote paragraph rather than sitting mid-line
   after inline text, so it takes its own line rather than the ::after
   rule's vertical-align: super — `super` has no block-level equivalent,
   and floating it beside the quote risks the note paragraph beneath
   wrapping around it too for a very short quote. Block plus a small
   bottom margin is the plain, predictable option; flagged in the Task 2
   report for Task 3's walk to confirm it reads well against an inline
   placement. */
.work-mark-star {
  /* Floated beside the quote's first words, not block-above-it — the
     Task 3 walk saw the block form orphan the star on its own line
     (2026-08-31) and ruled for inline. Float keeps the markup order
     (star span, then the block quote element) while the eye reads
     "★ quoted words…" as one line. */
  float: left;
  color: var(--accent);
  font-size: 0.7em;
  margin-right: 0.35em;
  line-height: 2.4; /* optically centres the small glyph on the quote's first line */
}

/* The address link (design §3): the citation register, echoing
   .rail-address's "bolder mono" voice (above) but as a full standalone
   link rather than a label prefix inside an already-styled row, so it
   carries its own complete type/colour/hover treatment. No underline
   until hover or keyboard focus — an address is a citation, not a call
   to action (Global Constraints: "address-links are citations, not
   progress"). Several may be appended back to back with no separator
   (engine/notes.js's _appendAddressLinks) — margin-left (rather than
   .rail-address's own margin-right, which suits ITS "address before a
   label" position) gives each one, the first included, breathing room
   from whatever precedes it, address or label text alike. The
   :focus-visible outline matches this file's own dominant convention
   (2px solid accent, 2px offset — .pen-mark, .pen-pill,
   .method-card-tab, .section-rail-link, among others), not
   .quiet-continue's own 3px variant, which answers to that button's own
   padding rather than anything about this one. */
.work-address {
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--accent-dark);
  text-decoration: none;
  margin-left: 0.5rem;
}
.work-address:hover,
.work-address:focus-visible {
  text-decoration: underline;
}
.work-address:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The "Your briefs" room (Task 5, spec §Your briefs) — .brief-shelf-*
   are minted by engine/notes.js's renderThinking, a shelf row per
   stored brief. Deliberately its OWN family, not a reuse of
   .work-address above: a shelf row shows the brief's own name/citation
   as its primary text, so its place link reads as a plain in-context
   link (default `a` colour, ordinary underline) rather than the
   citation-register mono treatment .work-address earns for standing
   alone as an address. */
.brief-shelf-row { margin: 0 0 1rem; }
.brief-shelf-title { margin: 0 0 0.15rem; }
.brief-shelf-name { font-style: italic; }
.brief-shelf-meta {
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  font-size: 0.7rem;
  color: var(--ink-soft, #6b6558);
  margin: 0 0 0.3rem;
}
.brief-shelf-place { display: inline-block; margin-right: 0.6rem; font-size: 0.82rem; }
.brief-shelf-actions { display: flex; gap: 0.5rem; margin-top: 0.25rem; }

/* ── Notes (free-text scratchpad — Notes.attach; not wired to any
   renderer in this task, ready for the reflect primitive) ──────────── */

.notes-box {
  margin: 1.25rem 0;
}
.notes-textarea {
  width: 100%;
  min-height: 5rem;
  font-family: var(--font-body);
  font-size: 0.95rem;
  padding: 0.65rem;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--paper-raised);
  color: var(--ink);
  resize: vertical;
}
.notes-textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-tint);
}
.notes-status {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--success);
  min-height: 1.1em;
  margin-top: 0.35rem;
}
.notes-status--error {
  color: var(--danger);
}

/* ── AI-draft convention (not used by this task's own content, but
   part of the fixed visual language this app's ecosystem shares) ──── */

.ai-draft {
  background: var(--amber-bg);
  border: 1px solid var(--amber-border);
  border-radius: 4px;
  position: relative;
}
.ai-draft-badge {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--amber-border);
  position: absolute;
  top: 0.4rem;
  right: 0.6rem;
}

/* ── Dog-act set-piece (setpieces/dog-act.js) ─────────────────────────
   Beats 1-4 keep the ordinary reading column even though the setpiece
   block itself is full-width (app.js's renderSetpiece sets
   .block--full-width on the container it hands to Setpieces.get(name))
   — only the exhibit layer (the annotated transcript + its rail)
   actually needs the extra width; everything else re-imposes --column
   itself, exactly as .block does for ordinary blocks. */

.dogact-beat {
  max-width: var(--column);
  margin: 0 auto 1.85rem;
}
.dogact-beat3 {
  margin-bottom: 0;
}
.dogact-commit,
.dogact-transcript,
.dogact-youtube {
  margin-top: 1.5rem;
}
.dogact-bridge {
  margin-top: 1.25rem;
}

/* Statute card: serif, formal — a double top rule reads as a primary
   legislative source, distinct from .source-card's plain single border. */
.statute-card {
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-top: 3px double var(--ink);
  border-radius: 0 0 6px 6px;
  padding: 1.5rem 1.75rem;
}
.statute-card-eyebrow {
  margin-bottom: 1rem;
}
.statute-card-body {
  font-family: var(--font-display);
  line-height: 1.75;
}
.statute-card-body p {
  margin: 0 0 1rem;
}
.statute-card-body p:last-child {
  margin-bottom: 0;
}

/* ── The marked exhibit (Reveal layer i) ──────────────────────────────
   Desktop: transcript column + a right-hand rail of notes, connected by
   JS-measured, CSS-drawn leader lines (see layoutLeaders in
   setpieces/dog-act.js). Phone fallback (below, in the existing
   breakpoint): the rail and leaders are hidden; notes stack beneath
   each turn instead (.exhibit-turn-notes, built regardless of
   breakpoint and toggled purely by this stylesheet — display:none
   content is excluded from the accessibility tree, so this never
   double-exposes a note to assistive tech). */

.exhibit-layer {
  max-width: none;
}
.rhyme-layer,
.close-layer {
  max-width: var(--column);
  margin: 0 auto;
}

.dogact-layer-heading {
  margin-bottom: 1.25rem;
}

.exhibit {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  column-gap: 2.5rem;
  align-items: start;
}

.exhibit-rail {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.exhibit-note {
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 6px;
  padding: 0.9rem 1.1rem;
}
.exhibit-note--unanchored {
  border-left-style: dashed;
  border-left-color: var(--ink-faint);
}
.exhibit-note-badge {
  margin-bottom: 0.3rem;
}
.exhibit-note--unanchored .exhibit-note-badge {
  color: var(--ink-faint);
}
.exhibit-note-label {
  font-family: var(--font-display);
  font-weight: 700;
  margin: 0 0 0.35rem;
}
.exhibit-note-text {
  margin: 0;
  font-size: 0.95rem;
}

.exhibit-highlight {
  background: var(--accent-tint);
  border-radius: 2px;
  padding: 0.05em 0.15em;
}
.exhibit-highlight-badge {
  font-family: var(--font-mono);
  font-size: 0.68em;
  font-weight: 600;
  color: var(--accent-dark);
  margin-left: 0.2em;
}

.exhibit-leaders {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.exhibit-leader {
  position: absolute;
  height: 0;
  border-top: 1.5px dashed var(--accent);
  transform-origin: 0 0;
}

.exhibit-turn-notes {
  display: none;
}
.exhibit-unplaced-notes {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px dashed var(--line);
}

.exhibit-error {
  color: var(--danger);
}

/* ── The century rhyme (Reveal layer ii) ──────────────────────────────
   .two-col-region (declared above, "ready for the set-piece task to
   use") supplies the grid + its own phone stacking rule already —
   .rhyme-cards only adds card-specific styling. */

.rhyme-cards {
  align-items: stretch;
}
.rhyme-card {
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 1.3rem 1.5rem;
}
.rhyme-card-year {
  font-size: 1.1rem;
  color: var(--accent-dark);
  margin-bottom: 0.6rem;
}
.rhyme-card-source {
  margin: 0 0 0.9rem;
  font-size: 0.92rem;
  color: var(--ink-soft);
}
.rhyme-card-quote {
  margin: 0;
  padding-left: 1rem;
  border-left: 3px solid var(--line);
  font-family: var(--font-display);
  font-style: italic;
}
.rhyme-card-quote p:last-child {
  margin-bottom: 0;
}

/* ── The close (Reveal layer iii): judgment + close copy + the model/
   student method comparison. Spatial juxtaposition only — no
   evaluative styling (no colour-coding right/wrong, no ticks/crosses)
   — see setpieces/dog-act.js's renderStudentDogAct2. Again built on
   .two-col-region for the responsive 2-up/1-up split. ─────────────── */

.close-comparison {
  margin-top: 1.75rem;
  align-items: start;
}
.close-model .method-card-filled {
  height: 100%;
}
.close-student {
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 1.3rem 1.5rem;
  height: 100%;
}
.close-student-heading {
  font-size: 1.05rem;
  margin: 0 0 0.9rem;
}
.close-student-empty {
  color: var(--ink-soft);
  font-style: italic;
  margin: 0;
}
.close-student-rows {
  margin: 0;
}
.close-student-row {
  display: flex;
  gap: 0.85rem;
  padding: 0.4rem 0;
  border-top: 1px dashed var(--line);
}
.close-student-row:first-child {
  border-top: none;
  padding-top: 0;
}
.close-student-row-label {
  flex: 0 0 auto;
  min-width: 9.5rem;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.close-student-row-value {
  font-family: var(--font-display);
  font-style: italic;
}
.close-student-timestamp {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--ink-soft);
  margin: 0.9rem 0 0;
}

/* ── Phone fallback — the one breakpoint, stacks everything ─────────── */

@media (max-width: 700px) {
  main#view {
    padding: 1.5rem 1.1rem 3.5rem;
  }
  .masthead {
    padding: 1.5rem 1.25rem 1.25rem;
  }
  .masthead-title {
    font-size: 1.35rem;
  }
  .orientation .prose {
    font-size: 1.15rem;
  }
  .source-card,
  .action-box,
  .error-card,
  .personae-strip,
  .work-room {
    padding: 1.05rem 1.15rem;
  }
  .personae-row {
    flex-direction: column;
    gap: 0.1rem;
  }
  .personae-name {
    min-width: 0;
  }
  .turn {
    flex-direction: column;
    gap: 0.5rem;
  }
  .turn-chip {
    min-width: 0;
    align-self: flex-start;
  }
  .thinking-row {
    flex-direction: column;
    gap: 0.15rem;
  }
  .thinking-row-label {
    min-width: 0;
  }
  .commit-method-row {
    flex-direction: column;
    gap: 0.15rem;
  }
  .commit-method-row-label {
    min-width: 0;
  }
  .method-card {
    right: 1rem;
    bottom: 1rem;
  }
  .method-card-panel {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    max-width: none;
    max-height: 60vh;
    border-radius: 12px 12px 0 0;
  }
  .two-col-region {
    grid-template-columns: 1fr;
  }
  .statute-card {
    padding: 1.05rem 1.15rem;
  }
  .exhibit {
    display: block;
  }
  .exhibit-rail,
  .exhibit-leaders {
    display: none;
  }
  .exhibit-turn-notes {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-top: 0.85rem;
  }
  .close-student-row {
    flex-direction: column;
    gap: 0.15rem;
  }
  .close-student-row-label {
    min-width: 0;
  }
}

/* ── Print — the whole page on paper; the PDF edition comes later ─────── */
.media-print-title { display: none; }
@media print {
  .site-nav, .section-rail, .places-button, .skip-link, .place-turn,
  .whole-back, .method-card, .loading, .youtube-embed,
  /* The pen's own floating/corner chrome (Task 2's pill and popover,
     Task 4's own Print button): none of the three has any business on
     paper, one card isolated or the whole page — unconditional, not
     scoped to body.pen-printing below. Closes the gap the Task 2
     review carried forward as C1 ("the pill and popover are not yet
     hidden under @media print"). .pen-pill-group (pencil, spec §3) is
     listed alongside .pen-pill defensively, not because it is reachable
     any other way: both its children already carry .pen-pill and are
     hidden by that selector alone, which leaves the wrapping group an
     empty, unstyled box — this closes it explicitly rather than relying
     on that emergent zero-size collapse. */
  .pen-print, .pen-pill, .pen-pill-group, .pen-popover { display: none !important; }
  .draft-badge:not([hidden]) {
    display: inline-block;
    border: 2px solid #000;
    padding: 0.1rem 0.5rem;
  }
  .source-card, blockquote, .commit-box, .turn,
  .casebook-extract, .reflect-box, .check-card,
  .work-room, .authority-card, .source-cite-card,
  .footage-honour-gate { break-inside: avoid; }
  iframe { display: none !important; }
  .media-print-title { display: block; font-weight: 700; }
  body { background: #fff; }
  main#view { padding: 0 !important; }
  /* Your work (design §5, "rooms print as cards"): the rooms already
     get the same break-inside: avoid as the other card families, just
     above. The one thing genuinely specific to this page is the address
     link itself — a citation, not a call to action, so on paper it
     reads as plain ink text: no accent colour, no underline, matching
     how .link-card-anchor (a visible, unhidden link elsewhere in this
     same print pass) already carries no colour/underline treatment of
     its own to override. Element+class, not the screen rule's bare
     class, so this wins on specificity regardless of source order. */
  a.work-address {
    text-decoration: none;
    color: inherit;
  }
  /* The authority's one action, on paper: an instruction, not a live
     link — "Read it on <source> →" prints as plain ink text (same
     no-colour/no-underline treatment as a.work-address, just above),
     and — the deliberate choice, stated here rather than left implicit
     — WITHOUT the raw href anywhere on the page. Many print
     stylesheets add a generic `a[href]::after { content: " ("
     attr(href) ")" }` rule precisely so a reader holding paper can
     still see where a link pointed; this file does not, anywhere, and
     .authority-action is exactly the place a reader would expect that
     URL to surface if such a rule existed. It doesn't, on purpose: the
     action's own text already names the source, a permalink is not
     something paper can click, and printing one under a formal OSCOLA
     citation would read as clutter, not information (spec: "paper
     cannot click"). */
  a.authority-action {
    text-decoration: none;
    color: inherit;
  }
  /* The source card's one action, on paper: same treatment as
     a.authority-action, just above — an instruction, not a live link,
     for the same reason (spec: "paper cannot click"). */
  a.source-cite-action {
    text-decoration: none;
    color: inherit;
  }
  /* Printing ONE card (Print this case): the whole-view break guards
     above make .source-card and .casebook-extract unbreakable — right
     for short cards amid a full page, wrong for a single-card handout
     whose card is TALLER than a page: the browser defers the whole
     unbreakable block to a fresh sheet (a blank page 1 under the
     citation — Richard's Thoburn print, 2026-08-30) and then breaks
     it anyway. A handout flows from the first page. Scoped to
     body.pen-printing so the whole-view print keeps its guards. */
  body.pen-printing .pen-print-target,
  body.pen-printing .pen-print-target .casebook-extract {
    break-inside: auto;
  }
  /* The pen (engine/pen.js): on paper the highlight yellow becomes a
     light grey wash — spec §7, "a mono laser says what the screen
     says." Confirmed here in Task 1; still holds unchanged in Task 4. */
  .pen-mark {
    background: #ddd;
    /* Browsers drop background colours in print by default (Chrome's
       "Background graphics", Safari/Firefox's "Print backgrounds" all
       ship unchecked) — without this per-element override the wash
       vanishes and a marked-up case prints as if clean, silently
       breaking spec §7's "a mono laser says what the screen says" on
       the DEFAULT path. print-color-adjust: exact is the documented
       remedy: print THIS element's colours regardless of the toggle.
       Both spellings — Chrome/Safari read -webkit-, Firefox the
       unprefixed form. Print-scope only; the screen never sees it. */
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  /* A mark focused at print time — tap the mark, Escape, print is a
     mainline path; the Task 5 walk captured the ring on paper — must
     not print its screen focus ring. Same specificity as the screen
     .pen-mark:focus-visible rule; later in source order, so it wins
     here, and only under print. */
  .pen-mark:focus-visible { outline: none; }

  /* ── Print this case (Task 4) — one card, isolated ───────────────────
     Pen.printCard (engine/pen.js) tags document.body .pen-printing, the
     chosen card .pen-print-target, and every REAL ancestor between that
     card and #view (exclusive) .pen-print-ancestor — walked in JS, not
     guessed here, because #view never puts a card straight under itself
     (see printCard's own comment for the full trace): a fresh load
     nests it one level (.place-body in the per-place seminar view,
     .whole-place — one per place — in the "whole seminar" view), and a
     gate opened LIVE this session nests it one level deeper again
     inside a .reveal-layer, arbitrarily many times over for further
     gates opened live inside an already-live-opened one in the same
     place. The two rules below hide any child of #view, or of a tagged
     ancestor, that is neither the target nor itself tagged — which
     walks the chain however deep it turns out to be, for either view,
     without hard-coding either wrapper's name, and correctly does
     nothing extra when the card sits straight under #view (the legacy
     no-places fallback: zero ancestors get tagged, and the base rule
     alone already leaves it unhidden). Nothing INSIDE .pen-print-target
     is touched by either rule, so the card's own extracts and the
     student's marks print exactly as they stand — the target needs no
     separate "reveal" rule, because neither rule ever hides it to begin
     with. The masthead sits OUTSIDE #view entirely (a sibling under
     body — see index.html) and needs its own rule for exactly that
     reason; .site-nav/.section-rail/etc. are already unconditionally
     hidden above, print-one-card or not, so nothing further is needed
     for them here. */
  body.pen-printing .masthead { display: none !important; }
  body.pen-printing #view > *:not(.pen-print-target):not(.pen-print-ancestor),
  body.pen-printing .pen-print-ancestor > *:not(.pen-print-target):not(.pen-print-ancestor) {
    display: none !important;
  }

  /* ── The pencil: numbered notes on paper (docs/pencil-design.md §7)
     ────────────────────────────────────────────────────────────────
     Two artifacts, both print-only and both built by pen.js's
     _numberNotesForPrint (called from printCard) right before
     window.print() — never stored, never shown on screen, spec §7's
     own words: a superscript number stamped onto each noted mark's own
     ::after, and the "Your notes" aside appended inside the printed
     card, numbered to match purely via the <ol>'s own native decimal
     numbering (list-style is never touched here — the ul, ol rule near
     the top of this file sets only padding-left) — so the aside's Nth
     <li> lines up with data-pen-print-n="N" because pen.js assigns
     both in the SAME walk, over the SAME document-order list of noted
     families, in the SAME iteration; nothing in this stylesheet
     re-derives or re-checks that pairing. */
  .pen-mark--noted[data-pen-print-n]::after {
    /* Same selector shape as the screen dot rule (.pen-mark--noted
       ::after, near the top of this file), plus the attribute:
       (0,2,1) beats that rule's (0,1,1) on specificity alone, so this
       wins whenever the attribute is present — it only ever MATTERS
       under print because data-pen-print-n is never set outside the
       printCard -> window.print() window (pen.js's own
       _numberNotesForPrint/_clearPrintFlags pair). The cascade
       resolves each property independently, though, not rule-by-rule:
       the screen rule (now the STAR: content/color/font-size/
       margin-left/vertical-align) sets properties this rule must own
       under print, and every one is reset below — the dot-era box
       resets (display/width/height/border-radius/background) stay as
       harmless defence — even where a value ends up unchanged
       (vertical-align stays `super`)
       or close to it (margin-left) — because a property left unset
       here would still fall through to the screen rule's own value for
       THAT property alone, specificity notwithstanding, and the number
       would render inside a dot-styled circle instead of replacing it.
       Verified property-by-property against the screen rule, not
       assumed — see this task's own report for the full trace. */
    content: attr(data-pen-print-n);
    display: inline;
    width: auto;
    height: auto;
    margin-left: 0.15em;
    border-radius: 0;
    background: none;
    vertical-align: super;
    font-size: 0.65em;
    /* Ink, not accent — paper is mono, no verdict colours (this task's
       own brief). Not inherited by accident: .pen-mark itself already
       sets color: inherit, and neither the noted-face rule nor this one
       sets a color of its own, tracing all the way up to body's own
       `color: var(--ink)` — stated explicitly anyway so a future edit
       to any rule in that chain can't silently recolour the printed
       number without touching a line that says, in as many words, that
       it must not. */
    color: inherit;
  }

  /* The "Your notes" aside — appended INSIDE the printed card, i.e.
     inside .pen-print-target's own subtree, so the ancestor-walk hiding
     rules above (which only ever hide a SIBLING of the target chain,
     never anything inside the target itself) already leave it unhidden
     with no carve-out of its own needed. The screen half of this split
     — an unconditional, unscoped `.pen-print-notes { display: none; }`
     — lives with the rest of this file's screen rules (with the pen's
     other print-only chrome, above the "Check your thinking" section);
     this is only the print-time reveal, scoped to body.pen-printing to
     match .pen-print-target/.pen-print-ancestor's own convention just
     above, even though (belt and braces, not a live gap) the node is
     never in the DOM at all outside a printCard() call in the first
     place. House print register: a dashed-in-spirit top rule to read as
     an appendix to the card rather than more of its own prose (compare
     .questions-invitation's identical border-top move, elsewhere in
     this file), a small mono-uppercase heading matching
     .casebook-extract-heading's own "section label" treatment rather
     than the large serif h1–h4 display style, and the SAME italic-quote
     / plain-note-body split the popover and the Your-thinking gathering
     already use elsewhere (engine/notes.js's own buildNotesGroup) —
     declared fresh here rather than reused across files, because
     everything this block styles only ever exists print-side, inside
     this one block. */
  body.pen-printing .pen-print-notes {
    display: block;
    margin-top: 1.4rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--line);
  }
  .pen-print-notes h3 {
    font-family: var(--font-mono);
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--ink-soft);
    margin: 0 0 0.6rem;
  }
  .pen-print-notes ol {
    margin: 0;
  }
  .pen-print-notes li {
    margin: 0 0 0.7rem;
  }
  .pen-print-notes li:last-child {
    margin-bottom: 0;
  }
  .pen-print-note-quote {
    font-family: var(--font-display);
    font-style: italic;
    color: var(--ink);
    margin: 0 0 0.2rem;
  }
  .pen-print-note-text {
    font-family: var(--font-body);
    color: var(--ink);
    white-space: pre-wrap;
    margin: 0;
  }

  /* ── The brief's own print rendering (Task 4, engine/brief.js) ───────
     "Print this brief" is Pen.printCard's mechanism (body.pen-printing,
     .pen-print-target on the card, the ancestor walk above) plus one
     extra swap this card alone needs: students never print clipped
     textareas, so _preparePrintView builds a read-only .brief-print-view
     from the STORED value and this pair of rules substitutes it for the
     live form. Both sides are scoped to .pen-print-target (the tagged
     .brief-card itself, per printCard's own doc comment) rather than
     left unscoped, so a WHOLE-SEMINAR print with several brief cards on
     one page — none of them the single printed target — never blanks
     any of their forms; the ancestor-walk rules above only hide a
     SIBLING of the target chain, never touch inside a target's own
     subtree, which is exactly why this card's own swap needs its own
     rule rather than a free ride off theirs. */
  body.pen-printing .brief-print-view { display: block; }
  body.pen-printing .pen-print-target .brief-form,
  body.pen-printing .pen-print-target .brief-controls,
  body.pen-printing .pen-print-target .brief-save-status,
  body.pen-printing .pen-print-target .brief-save-notice,
  body.pen-printing .pen-print-target .authority-card-eyebrow,
  body.pen-printing .pen-print-target .authority-identity,
  body.pen-printing .pen-print-target .authority-body,
  body.pen-printing .pen-print-target .authority-action {
    display: none;
  }
}
