/* ===========================================================================
   NOCTES BINANIANAE — online edition
   ===========================================================================

   The single stylesheet for the whole edition. Both builds load this same
   file: build_site.py copies it into dist-site/, build_wordpress.py into
   dist-wp/ for a WordPress theme to enqueue. Edit it HERE, in assets/ — the
   copies in both build directories are generated and are overwritten on every
   run, so an edit made there is lost the next time anyone builds.

   ---------------------------------------------------------------------------
   WHERE THE NUMBERS COME FROM
   ---------------------------------------------------------------------------
   Donald's InDesign setting is the source of truth. Measured by
   pdf_profile.py, tabulated in ENCODING_SCHEME.md:

       verse         11.5 / 15 pt     alternate-line indent   6 mm
       notes          9.5 / 11.5 pt   alternate-line indent   5 mm
       stanza space   4 mm            space between notes     2 mm

   6 mm and 5 mm look like two different indents. Measured against their own
   type size they are the same one — 6mm @ 11.5pt ≈ 5mm @ 9.5pt ≈ 1.48 em — so
   what looked like a millimetre grid is a single em step. The whole ladder
   collapses to one token: --step.

   ---------------------------------------------------------------------------
   THE CONTRACT — three things not to change
   ---------------------------------------------------------------------------
   1. NOT px, mm or pt for anything structural. Indents, stanza gaps and the
      line-number gutter are all multiples of --step, expressed in em, so they
      scale with the type and with a reader's own font-size setting. Convert
      any of them to a fixed unit and the verse stops holding its shape when
      the type scales.

   2. NOT %. A percentage resolves against container width, and .poem-body is
      width:fit-content — sized by its own longest line, which differs per
      poem. There is no single correct percentage for any indent here.

   3. NO entity spacing. No &nbsp;, no tab spans, no empty elements. Every
      space in the edition is a real space or a CSS box. (The superseded DOCX
      pipeline used 109 &nbsp; and 41 empty .tab spans; none survive here.)

   ---------------------------------------------------------------------------
   THE VOCABULARY
   ---------------------------------------------------------------------------
   Class names are TEI-derived: they say what a thing IS, not how it looks
   (ROADMAP.md § C2). Nothing is named for its appearance, so restyling never
   requires renaming — and the markup stays meaningful if this file is thrown
   away and replaced.

     STRUCTURE
       .noctes-chapter  one chapter — the unit a WordPress page holds
       .sheet           the centred page column
       .poem-body       the verse block: fit-content, centred as a block

     VERSE                                          TEI equivalent
       .lg              a stanza                    <lg type="stanza">
       .l               a verse line                <l>
       .ind-1 … .ind-6  indent level, in --step multiples   rend="ind-NN"
       .l.tc            a centred display line
       .l[data-n]       carries its own line number, drawn in the margin
       .sp / .speaker   a speech and its label (Fable XIV's duet)

     PROSE
       .pr              a paragraph inside a poem (the intro, Poema Latina)
       .prose           a prose chapter's body
       .extract         a block quotation
       .movement        a section head inside a poem — LARGO, PRESTO
       .subtitle  .dedication  .sig  .attribution
       .sig.closer      the signature closing the introduction   <closer><signed>
       .sig.tc          a signature centred under its letter     rend="center"
       table.ledger     the Whale & Elephant weighing table

     NOTES
       .notes           the endnote section (a <details> disclosure)
       .enref           an in-text note reference
       .en-back         the note's link back to the text
       .source          a quotation's source line (an epigraph's; set right in a note)

     NAVIGATION — dist-site/ only; a WordPress theme supplies its own
       .bar  .bar-home  .bar-nav  .bar-btn
       .bar-picker      the chapter menu — a <details>, never a <select>
       .masthead  .toc  the contents page

   ---------------------------------------------------------------------------
   RESTYLING
   ---------------------------------------------------------------------------
   Almost everything worth changing is a token in :root, immediately below.
   Type face, reading size, colour and the indent step each have exactly one
   definition in this file. Change the token, not the rules.
   =========================================================================== */

/* ============================================================ TYPEFACES ==
   Fraunces for the text, Courier Prime for the furniture: the faces of the
   site design (2026-11). Both are SIL Open Font License and self-hosted from
   fonts/ beside this file -- no request leaves the site. The woff2 files are
   subset to Latin, Latin Extended and Latin Extended Additional (the edition
   has Ḥ, ḥ and ẓ), general punctuation and ≠.

   Fraunces is a variable face with four axes. Weight and optical size are
   driven by the browser; the two odd ones, SOFT and WONK, are pinned on body
   below to the values the design uses.

   Fraunces has no small capitals and no oldstyle figures. .sc and the body's
   oldstyle request therefore fall back to what the browser synthesises, which
   is also what the design shows. */

@font-face {
  font-family: "Fraunces";
  src: url("fonts/fraunces-roman.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Fraunces";
  src: url("fonts/fraunces-italic.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Courier Prime";
  src: url("fonts/courier-prime-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Courier Prime";
  src: url("fonts/courier-prime-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Courier Prime";
  src: url("fonts/courier-prime-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* =============================================================== TOKENS ==
   The whole design surface. Every rule below consumes these; none of them
   hard-codes a face, a colour or a distance.
   ======================================================================== */

:root {

  /* ---- the indent step ------------------------------------------------
     One step. EVERYTHING indented in this edition is a multiple of it:
     the verse ladder (.ind-1 … .ind-6), hanging note numbers, block quotes,
     wrapped-line turnovers. Derived in the header above. Changing this one
     value re-proportions the entire edition coherently. */
  --step: 1.48em;

  /* ---- the line-number gutter -----------------------------------------
     The margin the line numbers stand in. .poem-body reserves it as its own
     padding-right, and the number is placed at the far edge of it — so this
     one value IS the space between the verse and its numbers.

     Two and a half steps. The gutter is measured from the right edge of the
     poem's LONGEST line, so for the poem whose longest line is itself a
     numbered one — Abschied zur Bina's line 15, and four others — it is the
     entire distance between the two. One step left them touching.

     Two would do if the gutter were only space, but the number is hung inside
     it, right-aligned, so the visible gap is the gutter LESS the number's own
     width — and that width is not fixed: Frognal runs to 120, and three
     figures take about 1.25 em where two take 0.84. At two steps the widest
     number would close the gap to 1.71 em, under the 2.17 em that is the
     tightest clearance in the setting itself. At two and a half, the worst
     case is 2.45 em and the ordinary one 2.87 em, both clear of it.

     The half step also buys margin against the browsers that size a hanging
     indent (.l's padding-left plus negative text-indent) about a step narrower
     than Chromium does.

     --num-size is the number's size as a plain fraction rather than a
     length, because the leading below has to be divided by it: an em inside
     the ::after resolves against the number's own smaller size, so a value
     meant in verse ems must be scaled back out.

     0.625 is the site design's 15px number against its 24px verse. Courier
     Prime's figures are wider than the old sans's, so three of them still take
     about 1.13 em: the clearance argument above holds unchanged. */
  --gutter: calc(var(--step) * 2.5);
  --num-size: 0.625;

  /* ---- type size ------------------------------------------------------
     Fluid: the reading size grows with the viewport between a comfortable
     minimum and a maximum that keeps the measure sane. Because every indent
     is in em, the whole verse structure scales with it automatically — the
     poem does not need a single breakpoint of its own.

     The rem/vw form (rather than raw vw) is deliberate: it keeps the size
     tied to the reader's browser font-size setting, so someone who has set
     a large default still gets it honoured.

     Raised 10% over the setting this was first derived at (17px -> 20px), on
     the client's reading of the proof. It is one edit because it is one token:
     the notes are an em of it, and every indent is an em multiple of --step,
     so the whole structure grew with it and no measurement below changed.

     Raised again for the site design (2026-11), which sets the verse at 24px
     on a desktop and 19px on a phone. The ramp runs between those two, from a
     375px screen to a 1000px one. Same single token, same consequence: nothing
     below was re-measured. */
  --size-body: clamp(1.1875rem, 1rem + 0.8vw, 1.5rem);

  /* Notes run smaller than the text they annotate, as in the source. Tracks
     --size-body rather than drifting away from it.

     A plain fraction as well as a length, for the same reason --num-size is
     one: --measure-note is in ch, so it resolves to a different width in the
     notes than it does anywhere else, and .chapter-head has to scale it back
     to the notes' own size to end up genuinely as wide as they are. */
  /* 17/24 in the site design (it was 0.8). */
  --note-scale: 0.71;
  --size-note: calc(var(--note-scale) * 1em);

  /* Leading. The two marked values are the source's own ratios; --leading-
     prose is a web choice, since InDesign prose leading was set for a much
     narrower column than a browser gives us. The site design (2026-11) left
     all three as they were: it changes the faces and the type size, never the
     spacing of the text. */
  --leading-verse: 1.3;    /* 15/11.5 in the source */
  --leading-prose: 1.62;
  --leading-note: 1.42;    /* 11.5/9.5 in the source */

  /* ---- the reading column ---------------------------------------------
     The site design's column, 700px wide at its 24px verse: 29.17 of the
     verse's em. The notes and the introduction's essay are set on it. The
     verse is NOT: a poem keeps its own width and centring (.poem-body), which
     the proofing round settled and the design does not touch. Built from
     --size-body, not from a bare em, so it is the same width in the notes as
     in the verse even though their ems differ. */
  --column: calc(var(--size-body) * 29.1667);

  /* ---- measure --------------------------------------------------------
     Verse takes its width from its own longest line and must never be capped
     — a wrapped line of verse is a typographic failure, not a reflow. So
     these apply to PROSE only, and they are in ch: a measure is judged in
     characters per line, and ch tracks whatever face is loaded. */
  --measure-prose: 66ch;
  --measure-note: 74ch;

  /* ---- type faces -----------------------------------------------------
     Chosen with the site design (2026-11): Fraunces and Courier Prime, loaded
     by the @font-face rules above from fonts/ beside this file. No third-party
     request is made.

     THIS IS THE ONLY PLACE A FACE IS NAMED. The old system stacks stay behind
     the new faces as the fallback, and a real generic stays last: a face that
     fails to load must still land on something of roughly the right
     proportions rather than on the browser's default.

     --serif carries the edition: verse, prose, notes — everything that is
             the text of the book.
     --sans  is used ONLY for furniture that must not be mistaken for the
             text: the reading bar, marginal line numbers, note numbers,
             contributor names in the contents. The name is kept from when
             that face was a sans, so that nothing which consumes it has to
             change; it now holds the design's typewriter face. */
  --serif: "Fraunces", Baskerville, "Baskerville Old Face", "Libre Baskerville",
           "Hoefler Text", Garamond, "Times New Roman", Times, serif;
  --sans: "Courier Prime", "Courier New", Courier, monospace;

  /* ---- colour ---------------------------------------------------------
     Five ROLES, not five colours. Everything visible resolves to one of
     them, which is what makes the dark theme below a short list of token
     overrides rather than a second stylesheet.

       --ink     body text
       --sheet   the page ground
       --rule    hairlines: the notes divider, contents rows, menu border
       --muted   subordinate text: line numbers, contributors, NOTES label
       --accent  note references and the current chapter — the only colour
                 in the edition, and it is only ever used to mean 'this is a
                 link into the apparatus'

     Neither end of the range is at the stop. The ground is a warm off-white,
     not #fff, and the ink a warm near-black, not #000: 15.1:1 where black on
     white would be 21:1. That is the reading-app convention — Instapaper,
     Pocket, iBooks all pull both ends in — because a page at full contrast
     glares under a lamp and greys out in sunlight, and neither is what paper
     does. The warmth is the same warmth throughout: every one of these is a
     yellow-red grey, so the page reads as stock rather than as a screen. */
  /* The site design's paper and ink (2026-11), and its hairline: the design
     draws rows at ink 38% over paper, which is this solid value. Its heavy
     rules -- under a title, above the notes -- are --ink itself, 2px. */
  --ink: #1a1b1f;
  --sheet: #f8f6f1;
  --rule: #a4a3a1;
  /* 4.8:1 on --sheet. The design's own grey, #7d7b76, measures 3.9:1 and so
     misses WCAG AA for body text -- and --muted is what the marginal line
     numbers are set in, the smallest type in the edition. This is the nearest
     darker grey of the same hue that passes. */
  --muted: #6f6d68;
  /* The design carries no colour at all: a link into the apparatus is marked
     by its underline (see .enref), so the accent is the ink. Kept as its own
     role so that a colour can come back in one place. */
  --accent: var(--ink);

  /* Tell the browser which way the page runs, so the scrollbar, the caret and
     any control it draws itself come out light too. Without this a reader on a
     dark OS gets a paper page in a dark frame. */
  color-scheme: light;

  /* Height of the fixed reading bar. .sheet derives its top padding from
     this, so a chapter's first line clears the bar however tall it becomes.
     Set to 0 and remove .bar if a host theme supplies its own navigation. */
  --bar-h: 3.5rem;
}

/* The edition is a day edition, and does NOT follow the system into dark.

   It used to. A reader whose OS was set to dark got the dark palette, which is
   the usual courtesy — but it is the wrong courtesy here. This is a facsimile
   of a privately printed book: the ground is meant to read as paper, and the
   whole palette above is built on that one idea, down to the warmth shared by
   all five tokens. Inverted, it stops being a book and becomes a terminal.

   So the dark palette stays, but only as an explicit choice — [data-theme]
   stamped on the root. Nothing in this edition stamps it: there is no
   JavaScript here and no toggle. It is kept for a host theme (WordPress, or
   tseliot.com) that offers its own dark mode and needs somewhere to point.
   Delete it if that never happens; it costs five lines and no rule below
   depends on it.

   Only tokens change. No rule past this point knows which theme it is in, and
   no colour anywhere below has its only definition inside a media query. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --ink: #e8e3da;
  --sheet: #1a1917;
  --rule: #3a3733;
  --muted: #928b83;
  --accent: #d08a6f;
}

*, *::before, *::after { box-sizing: border-box; }

/* The page ground is painted explicitly rather than left transparent: this
   markup is also served inside a WordPress theme, whose own background must
   not show through the edition.

   This rule, html's below and the box-sizing one above style the whole PAGE,
   by design: this file is the stylesheet of the edition's pages. On
   WordPress, enqueue it only on those pages (see design/README.md), never
   site-wide. */
body {
  margin: 0;
  background: var(--sheet);
  color: var(--ink);
  font-family: var(--serif);
  /* Fraunces's two character axes, as the design sets them: WONK on (the
     leaning n, m and h), SOFT off (sharp terminals). Faces without the axes
     ignore this. */
  font-variation-settings: "WONK" 1, "SOFT" 0;
  font-size: var(--size-body);
  line-height: var(--leading-prose);
  /* Oldstyle (non-lining) figures sit on the x-height and belong in running
     text — a date in a note should not shout. Anything that is a COUNTER
     rather than text opts back into lining figures locally: marginal line
     numbers, note numbers, the weighing ledger. */
  font-variant-numeric: oldstyle-figures proportional-nums;
  -webkit-text-size-adjust: 100%;
  text-rendering: optimizeLegibility;
  /* NEVER hyphenate, anywhere. The setting does not: ten lines in the whole
     edition end in a hyphen and every one is a real compound that happened to
     break there -- 'sitting-room', 'Anglo-Saxon', 'lieutenant-colonel'. Verse
     must never be broken, and the prose is set ragged right and unbroken, so
     the browser must not invent breaks either. Set once here and inherited;
     do not re-enable it on any element. */
  -webkit-hyphens: none;
  hyphens: none;
}

/* Paragraph margins are collapsed away and re-applied deliberately per role.
   Verse cannot tolerate an inherited paragraph margin: the gap between lines
   of a stanza must be zero, and the gap between stanzas belongs to .lg.

   Only inside the edition's own blocks (a chapter, the prototype's contents
   page), so a theme's paragraphs elsewhere on the same page keep their own
   margins. :where() adds no specificity: every rule below that sets a
   paragraph's margin still wins exactly as it did against a bare `p`. */
:where(.noctes-chapter, .masthead, .toc) p { margin: 0; }
/* ------------------------------------------------------------- the sheet --
   The page. Top padding clears the fixed bar. It runs the full width of the
   window, less a 1rem margin, because the design's heavy rules -- under the
   title, above the notes -- run edge to edge; the reading column inside it is
   --column, and each block centres itself on that. */

.sheet {
  padding: var(--bar-h) 1rem 6rem;
}
/* The bar is fixed, so it covers whatever an anchor jump scrolls to -- a note
   reference landed 55.8px up behind it, which is to say out of sight, in both
   directions of the note round trip. scroll-padding on the scroller fixes
   every jump at once; a scroll-margin on each target would have to be repeated
   on each, and missed on the next kind of target added. */
html { scroll-padding-top: calc(var(--bar-h) + 1.5em); }

/* --------------------------------------------------------------- headings */

/* THE POEM SIZES THE BLOCK; THE FRONT MATTER DOES NOT.
   .poem-body is width:fit-content, which means the widest child wins — and for
   six chapters the widest child is the title, not a line of verse.
   Expostulatory Epistle of a Coot's runs 50.8 em against a longest line of
   28.4 em. The block then stretched to the title, the verse stayed left-aligned
   inside it, and the title centred on a box the poem did not fill: 135.6 px off
   the verse's own centre on Thoughts of a Briton.

   width:0 takes these out of the parent's max-content sizing altogether;
   min-width:100% then fills whatever width the verse settled on, so a long
   title wraps over the poem instead of stretching it. (A percentage min-width
   resolves to zero while the parent is being sized, so there is no cycle here.)

   The rule is the one in the header: the poem block is sized by its own longest
   LINE. A title is not a line of the poem.

   And the title centres on the poem because the poem is centred — a deliberate
   departure from the setting, which centres the title on the page and leaves the
   verse left-aligned at a fixed margin beneath it, up to 60 pt away. See
   ENCODING_SCHEME.md; the two choices are one choice.

   Only the CENTRED front matter belongs here. .byline is not centred -- it
   carries a deliberate 4-step left indent -- and width:0 resolves that indent
   against an empty box before min-width expands it, which pushed the line a
   full 4 steps off the block and out the right-hand side.

   Scoped to .poem-body, because the title and the subtitles under it are no
   longer in it -- see .chapter-head below. What is left here is the subtitle
   that appears PART WAY DOWN a poem (Fragment of a Soliloquy has three), which
   is inside the block and still needs taking out of its sizing. */
.poem-body > :is(.head, .subtitle, .dedication) {
  width: 0;
  min-width: 100%;
}

/* The title and the subtitles under it.

   The site design (2026-11) gives the title a band of its own: display
   type, centred on the PAGE, closed by a heavy rule running edge to edge. So
   .chapter-head is a full-width container, and the title carries the band.

   The subtitles keep the setting they had. Each is held to the notes'
   measure and centred on the VERSE, as the whole header used to be: they
   used to sit inside .poem-body and so were held to the width of the poem's
   longest line, while the notes below them ran to --measure-note, and Fable
   XIV's subtitle broke after 'and The' and left 'Spider' alone on a line.

   The gutter is mirrored from .poem-body so a subtitle centres on the verse
   and not on the page. The poem block is centred with the marginal numbers'
   gutter inside it, which leaves the verse half a gutter left of the
   chapter's centre; a subtitle simply centred like the notes would sit half a
   gutter to the right of the verse it heads. The poems with no line numbers
   have no gutter to mirror, exactly as the block itself has none.

   --measure-note is in ch, and a ch is only as wide as the type it is measured
   in: the notes are set at --note-scale of this, so scaled by --note-scale it
   is the notes' own width here too. */
.chapter-head > .subtitle {
  --measure: calc(var(--measure-note) * var(--note-scale));
  max-width: calc(var(--measure) + var(--gutter));
  margin-inline: auto;
  padding-right: var(--gutter);
}
.noctes-chapter:not(:has(.poem-body .l[data-n])) .chapter-head > .subtitle {
  max-width: var(--measure);
  padding-right: 0;
}

/* The heading reset, likewise confined to the edition's blocks and weighing
   no more than a bare h1 did. */
.head, :where(.noctes-chapter, .masthead, .toc) :is(h1, h2, h3) {
  font-weight: 400;
  line-height: 1.2;
  text-wrap: balance;          /* no lonely last word in a title */
  margin: 0;
}
/* The design's title band: 110px of space above and below a 64px title, at
   most, and the rule under it. Sizes are in rem, not em, because the title
   is page furniture sized to the window, not a step on the text's scale. */
.head {
  font-size: clamp(2.4rem, 8vw, 4rem);
  line-height: 0.92;
  letter-spacing: -0.016em;
  text-transform: uppercase;
  text-align: center;
  padding-block: clamp(3.5rem, 7.6vw, 6.875rem);
  margin-block: 0 3rem;
  border-bottom: 2px solid var(--ink);
}
/* A note reference on a title is set tiny and high, as the design does:
   at the title's own 0.72em it would be a figure two-thirds the size of a
   line of verse. Its underline is what marks it, as everywhere. */
.head .enref { font-size: 0.24em; vertical-align: 2.9em; margin-left: 0.15em; }
/* A subtitle used to be pulled up under the title with a negative margin, so
   that it read as part of the heading. The site design puts the title's rule
   between them instead, so there is nothing to pull up into, and that one
   rule is gone. (It had to be scoped to that one position: Fragment of a
   Soliloquy has three subtitles interleaved with the centred lines they
   introduce, and an unscoped pull-up overprinted them.) Everything else about
   the subtitles is as it was set: centred, italic, 1.1em, and the spacing
   below. */
.subtitle {
  font-style: italic;
  text-align: center;
  font-size: 1.1em;
  margin-block: 0 1.5em;
}
/* A note number after an italic subtitle stays upright, where the proofreader
   asked for it. */
#the-whale-and-the-elephant .subtitle .enref,
#fable-xiv .subtitle .enref,
#vers-pour-la-foulque .subtitle .enref { font-style: normal; }
/* 'Note to the Reader' follows the essay's closing signature. The source
   starts it on a new page; here a gap twice the sub-sections' marks the end
   of the essay and the start of the back matter. */
.sig.closer + .subtitle { margin-top: 3em; }

/* The Introduction's back matter, as the site design sets it: 'Note To the
   Reader', 'Select Reading' and 'Abbreviations Used in Notes' are headings at
   the left of the column, upright, with rules around their lists. There is no
   class for these, because what picks them out is their place: everything after
   the closing signature.

   Each entry's .l lines run together as one paragraph, the space between them
   being the markup's own newline, and it is the entry that hangs. Italics in
   the entries are the source's and stay, as do the labels 'Sources' and
   'People': the one-word italic entries under the last heading, with no rule. */
#introduction .sig.closer ~ .subtitle {
  font-size: 1.25em;
  line-height: 1.1;
  letter-spacing: -0.01em;
  text-align: left;
  margin-bottom: 0.73em;
}
#introduction .sig.closer ~ .subtitle em { font-style: normal; }
#introduction .sig.closer ~ .pr {
  font-size: 0.79em;
  line-height: 1.55;
}
#introduction .sig.closer ~ :is(.pr, .lg) + .subtitle {
  margin-top: 2.93em;
  padding-top: 0.73em;
  border-top: 1px solid var(--rule);
}
#introduction .sig.closer ~ .lg {
  font-size: 0.71em;
  line-height: 1.45;
  margin-top: 0;
  padding-block: 0.76em;
  padding-left: calc(var(--step) * 0.875);
  text-indent: calc(var(--step) * -0.875);
  border-bottom: 1px solid var(--rule);
}
#introduction .sig.closer ~ .subtitle + .lg:has(~ .subtitle) { border-top: 1px solid var(--rule); }
#introduction .sig.closer ~ .lg > .l {
  display: inline;
  margin-left: 0;
  padding-left: 0;
  text-indent: 0;
}
#introduction .sig.closer ~ .lg ~ .subtitle ~ .lg:has(> .l:only-child > em:only-child) {
  padding-block: 1.76em 0.47em;
  border-bottom: 0;
}

/* A subtitle that introduces a single centred line is not finished with it: the
   two are one utterance, and the source sets them a plain 16.00 pt apart --
   one leading of their own 12 pt type, no space added. The 1.5 em below is for
   the other case, where the subtitle ends the front matter and the poem itself
   begins (23 to 33 pt in the setting).

   :only-child is what separates them. Album Leaflet No. 2's mock title-page is
   also centred lines after a subtitle, but nine of them in one block, and the
   source gives that 23 pt -- so it keeps the wider gap. An engine without
   :has() keeps the wider gap everywhere, which is the loose reading, never a
   collision. */
.subtitle:has(+ .lg > .l.tc:only-child) { margin-bottom: 0; }
/* The same pair split across the header and the poem: 'by the author of' ends
   the header and '"Cameron's Fall"' opens the poem body, so the rule above
   cannot see them. Closed up where the proofreader asked, as the source sets
   them; the Ode to a Roman Coot's 'By the author of' was not raised and keeps
   its space. */
#a-fig-for-a-foolish-one .chapter-head > .subtitle:last-child,
#fragment-of-a-soliloquy .chapter-head > .subtitle:last-child { margin-bottom: 0; }
/* Fragment of a Soliloquy's byline, 'by the author of the celebrated vocal
   refrain' (the poem body's second subtitle), stands a little apart from the
   title lines above it: 22.7pt below 'Alone in the Jungle' in the source,
   against 16pt between the other heading lines. */
#fragment-of-a-soliloquy .poem-body > .subtitle:nth-of-type(2) { margin-top: 0.6em; }
/* Poema Latina's sub-heading is a couplet from Churchill set as two subtitles;
   the source sets them on consecutive lines. */
#poema-latina .chapter-head > .subtitle:has(+ .subtitle) { margin-bottom: 0; }
/* Its source line, 'The Prophecy of Famine.', sits closer under the couplet
   than a subtitle's 1.5em, and a line clear of the verse below it: 13.5pt and
   18pt in the source. */
#poema-latina .chapter-head > .subtitle:last-child { margin-bottom: 0.6em; }
#poema-latina .poem-body > .sig:first-child { margin-top: 0; }
#poema-latina .poem-body > .sig + .lg { margin-top: 1em; }
/* Album Leaflet No. 2: a line clear of the mock title-page before the poem
   begins, 13.5pt in the source, where the proofreader asked for it. */
#album-leaflet-no-2 .poem-body > .lg + .pr { margin-top: 1.1em; }
.dedication {
  font-style: italic;
  text-align: center;
  margin-block: 0 1.6em;
}

/* ============================================================ VERSE =====
   The poem block is sized by its longest line and centred as a block, so the
   left edge of the verse stays where the poet put it. The block reserves its
   own line-number gutter as padding, so the numbers are part of what gets
   sized and centred rather than something hung off the outside of it.
   ======================================================================== */

.poem-body {
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
  /* The gutter is REAL SPACE inside the block, not an overhang. fit-content
     measures the border box, so the block comes out one gutter wider than its
     longest line and the numbers stand in space the block owns. Three things
     follow, and they are the whole reason for doing it this way:

       - max-width:100% now protects the gutter. Hung outside, it was the
         first thing a narrow container took away, and the numbers went over
         the verse. Inside, the container squeezes the block as a whole.
       - the numbers cannot be clipped by, or pushed out of, any ancestor.
       - verse and gutter centre as one unit, so the numbers cannot be
         squeezed against the edge of the window.

     The content box is unchanged — still exactly the longest line — so every
     indent, and .l.tc's centring, measure from where they always did. What
     does change is the measure: the block is a gutter wider, so it meets
     max-width:100% a gutter sooner. Hence the exemption below. */
  padding-right: var(--gutter);
  position: relative;
  font-size: 1em;
  line-height: var(--leading-verse);
  /* Verse is never hyphenated and never justified -- see body. */
}

/* Three chapters carry no line numbers at all — the introduction, Album
   Leaflet No. 2, Translation into English — and a gutter reserved for numbers
   that do not exist is a gutter taken off the measure for nothing. It costs
   the introduction five wrapped lines between roughly 740 and 900 px, its
   bibliography and mock title-page being the longest .l lines in the edition.
   So they get their full width back.

   Written as :not(:has()) rather than putting the padding on :has() deliberately.
   An engine too old for :has() discards this rule as unparseable and keeps the
   gutter everywhere — the safe reading, merely a wider block — where the other
   form would drop the gutter everywhere and put the numbers back on the verse. */
.poem-body:not(:has(.l[data-n])) { padding-right: 0; }

/* A stanza. The gap between stanzas belongs here, not on a line. */
.lg + .lg { margin-top: 1em; }

/* A verse line. The negative text-indent means that when a long line has to
   wrap on a narrow screen, its turnover hangs — so it reads as a continuation
   rather than as a new line of verse. This is the one thing a verse edition
   must not get wrong on a phone, and no percentage helps with it. */
.l {
  padding-left: var(--step);
  text-indent: calc(var(--step) * -1);
  text-wrap: pretty;
}

/* The indent ladder. One rule; the level is a multiple carried in --n. */
.l { margin-left: calc(var(--n, 0) * var(--step)); }
.ind-1 { --n: 1; }   /* the alternate line — by far the commonest */
.ind-2 { --n: 2; }
.ind-3 { --n: 3; }
.ind-4 { --n: 4; }
.ind-5 { --n: 5; }
.ind-6 { --n: 6; }

/* Marginal line numbers, every fifth line. Lining figures, since these are
   counters rather than text, and tabular so they align in the gutter. */
.l[data-n]::after {
  content: attr(data-n);
  position: absolute;
  /* Hung from the RIGHT edge of the gutter, which is how the setting does it:
     across Frognal's three pages of numbers the right edges agree to within
     0.01 pt while the left edges spread by up to 5 pt. They align on their
     right and grow leftwards as the digits accumulate.

     It also puts the number INSIDE the space .poem-body reserved for it. With
     left:100% it sat just past that space — outside the block — and depended on
     whatever margin the page happened to have beyond. On a phone that margin is
     about 20 px, and Frognal's three-digit numbers came within 2 px of the
     screen edge, clipping at 320 px. Here the block contains them. */
  right: 0;
  font-family: var(--sans);
  font-variant-numeric: lining-nums tabular-nums;
  font-size: calc(var(--num-size) * 1em);
  /* The number gets a line box exactly as tall as the verse line's, which is
     what puts the two baselines together. An absolutely positioned ::after
     takes the TOP of the line box as its static position, not the baseline;
     a box only as tall as its own smaller leading therefore hangs the digits
     near the top of the line and reads as a superscript. Matching the box
     heights leaves the half-leading to do the work, and the residue — the
     part that is only the difference in ascent between 1em and --num-size —
     is the nudge below. */
  line-height: calc(var(--leading-verse) / var(--num-size));
  transform: translateY(calc(0.1em / var(--num-size)));
  color: var(--muted);
  user-select: none;
}

/* A movement or section head inside a poem — LARGO, TRANSFORMATION SCENE, and
   Frognal's Roman numerals. It stands on the same ladder as the verse it heads
   and carries its own .ind-N, because the setting does not place them all
   alike: Frognal's numerals are 5 mm in from the verse base, Fable XIV's
   word-heads are flush on it. A fixed indent here would have to be wrong for
   one of them.

   It is spaced as A VERSE LINE WITH A STANZA SPACE BEFORE IT, and nothing
   after. Measured over all 16 heads in the edition: the baseline below a head
   is 15.00pt away, the verse leading exactly, so there is no space after it at
   all; the baseline above is 26.34pt, which is that same leading plus the 4 mm
   stanza space -- the 1em of .lg + .lg. Here that comes out as the head's own
   line box (1.3em) plus a 1em margin = 26.45pt, against 26.34 measured.

   (One head is set differently in the source: Fable XIV's ENSEMBLE WITH FULL
   CHORUS carries a stanza space after it as well. One of sixteen, and a class
   for it could only be named for how it looks, so it is not reproduced.) */
/* NOT italic here. Only 5 of the edition's 16 heads are set italic -- Fable
   XIV's INVOCATION, LARGO, PRESTO, NIGGER MINSTRELS and ENSEMBLE WITH FULL
   CHORUS, which the PDF gives in Baskerville-Italic -- and those 5 already
   carry an <em> from the parser. The other 11 are Baskerville: Frognal's and A
   Refutation's Roman numerals, and Fable XIV's own TRANSFORMATION SCENE, which
   stood italic beside its italic neighbours when the setting distinguishes
   them. Styling the class italic overrode the markup that already knew. */
.movement {
  /* 12 pt against the verse's 11.5 -- all 16 heads, in all three poems that
     have them. A plain fraction, like --num-size, so the leading below can be
     divided back out of it: the head has to stay ONE verse line tall however
     much larger its type is, or the line under it no longer lands a leading
     down. */
  --head: 1.043;
  font-size: calc(var(--head) * 1em);
  letter-spacing: 0.06em;
  /* The verse leading, NOT the 1.2 the titles take. A head that occupies a
     verse line has to be as tall as one, or the line below it comes up short
     -- it was landing 0.92 of a leading under the head instead of a whole
     one, which is the tighter heading line-height showing through. */
  line-height: calc(var(--leading-verse) / var(--head));
  /* The stanza space is the VERSE's em, so it is divided back out of the
     head's larger one too -- left as a plain 1em it grows with the head and
     the gap above opens to 1.80 leadings where the setting has 1.76. */
  margin-block: calc(1em / var(--head)) 0;
  margin-left: calc(var(--n, 0) * var(--step));
}

/* A centred display line (Album Leaflet's mock title-page). Centred lines are
   centred, never indented — their left edge is a function of their own width. */
.l.tc, .movement.tc {
  margin-left: 0; padding-left: 0; text-indent: 0; text-align: center;
}

/* Running prose set inside a poem (the Latin burlesque; the introduction).
   Joined back into real paragraphs so it reflows. */
.pr {
  max-width: var(--measure-prose);
  margin-block: 0 0.8em;
  text-wrap: pretty;
}

/* A signature or sign-off set to the right — 'John Haffenden', 'TP'. Roman:
   the source sets 'TP', 'Jean Aillevard' and 'The Prophecy of Famine.' upright,
   and the two that are italic carry their own <em>. */
.sig {
  margin-top: 1.2em;
  margin-left: calc(var(--step) * 4);
}
/* The author's name that closes the Introduction ('John Haffenden'), set
   flush right at the proofreader's request; the other signatures keep the
   rule above. */
.sig.closer { margin-left: 0; text-align: right; }
/* A signature centred under the letter it signs ('TP' in Whale note 3), at
   the proofreader's request. */
.sig.tc { margin-left: 0; text-align: center; }

/* Attribution — '[T. S. Eliot]' */
.attribution {
  margin-top: 1.6em;
  margin-left: calc(var(--step) * 5);
  font-style: normal;
}

/* --------------------------------------- speeches (Fable XIV's duet) ---
   A speaker label with a hanging indent, and the speech is an ordinary verse
   block. Replaces the tab + &nbsp; runs the DOCX carried. Grid keeps the
   label and the verse independent, so the verse indents still resolve
   against the speech block rather than against the label's width. */

/* The label column is a fixed 2.5 steps, not `auto`: each speech is its own
   grid, so an auto column was as wide as that speech's label and the verse of
   'Whale:', 'Elephant:' and 'Duet:' started at three different places. The
   source starts every speech's verse at the same point, just past the widest
   label ('Elephant:'). */
.sp {
  display: grid;
  grid-template-columns: calc(var(--step) * 2.5) 1fr;
  align-items: start;
}
.speaker {
  font-style: italic;
  white-space: nowrap;
}
.sp > .lg { grid-column: 2; }
.sp > .speaker + .lg { margin-top: 0; }
/* The first speech follows the scene's heading lines (the duet's 'Air: ...')
   after a stanza's space, as in the source. */
.lg + .sp { margin-top: 1em; }

/* On a narrow screen the label moves above its speech rather than stealing
   width from lines that are already tight. */
@media (max-width: 32rem) {
  .sp { grid-template-columns: 1fr; }
  .sp > .lg { grid-column: 1; margin-left: var(--step); }
}

/* =============================================================== PROSE == */

.prose p {
  max-width: var(--measure-prose);
  margin-inline: auto;
  text-wrap: pretty;          /* no orphans on the last line */
}
.prose p + p { text-indent: var(--step); }   /* continuing paragraphs indent */
.prose p.fp { text-indent: 0; }              /* ...but the first does not */

/* Quotations and quoted verse sit on the notes' own ladder. Against the notes'
   9.5pt the source sets a paragraph indent at 5mm, a block quotation at 8mm and
   quoted verse at 12mm -- 1.0, 1.6 and 2.4 steps. Taken to the nearest half
   step they stay on the ladder and keep the distinction the source draws
   between a quotation and verse quoted inside one.

   Left-aligned, not centred: `margin-inline: auto` on a block narrower than its
   column pushes it to the middle of the note, which is not where it sits on the
   page. */
blockquote.extract {
  margin-block: 0.6em;                          /* 2mm in the source */
  margin-inline: calc(var(--step) * 1.5) 0;
  font-size: 0.94em;
}
/* A quotation running to more than one paragraph marks the break with a
   first-line indent and no space, as the source does. Its own paragraphs
   only (>): verse lines quoted inside it are paragraphs too, and an indent on
   them would undo their hanging turnover. */
blockquote.extract > p + p { text-indent: var(--step); }
/* Inside a note the source does not reduce a quotation: all 27 are set at the
   note's own size, so the 0.94em above would shrink them a second time. */
.notes blockquote.extract { font-size: 1em; }
/* A letter's sign-off inside a quotation ('TP') sits on the line after the
   letter's last, as the source sets it: no gap above, and not the paragraph
   indent that the rule above gives every later paragraph of a quotation. */
blockquote.extract > .sig { margin-top: 0; text-indent: 0; }

/* ---------------------------------------------------- epigraphs ---------
   The introduction opens with quotations and their sources. The setting puts
   the quotation two steps in and the byline four. The gap between epigraphs
   is 6mm, which at the body's 11.5pt is one step exactly. The source line is
   set to the right, at the proofreader's request (the PDF sets it as a new
   paragraph, one 5mm indent in).

   A <blockquote>, not a stanza: the text is prose and must reflow. */

.epigraph {
  margin-left: calc(var(--step) * 2);
  max-width: var(--measure-prose);
  text-wrap: pretty;
}
.epigraph + .epigraph { margin-top: var(--step); }   /* 6mm in the source */
.epigraph .source { text-align: right; }

.byline {
  margin-left: calc(var(--step) * 4);
  margin-bottom: calc(var(--step) * 0.5);
}

/* ------------------------------------------- the introduction's opening --
   The site design opens the introduction as a spread -- the title on the
   left, the four opening epigraphs on the right -- then a heavy rule and the
   essay in the reading column.

   THE ESSAY STAYS IN NORMAL FLOW. Every quotation, verse indent, signature
   and sub-heading in it carries a proofed margin of its own, and those must
   add up exactly as they always have. So the essay is not laid out item by
   item (an earlier grid version centred each block, which halved every
   left margin); .poem-body keeps the ordinary block flow, its content box is
   narrowed to the column by padding on the right, and every child is moved
   right by the same inset. The whole essay moves as one, and the margins
   inside it are untouched.

   --inset is half of what the page has beyond the column: (page - column)/2.
   It is in cqi -- the width of #introduction, made a size container below --
   because a percentage would resolve against a different box for the
   padding (the chapter) and for the shift (the poem body).

   Only the title and the opening epigraphs are placed for the spread: the
   title floats left, the epigraphs stand at the right edge, and the rule
   under them clears both. The opening epigraphs are the ones before the
   essay's first paragraph or rule; the essay's later epigraph ('Jean
   Aillevard') is an ordinary part of the essay. This is done here, not in a
   page template, because the epigraphs are inside the chapter fragment. */
#introduction {
  container-type: inline-size;
  --inset: max(0px, (100cqi - var(--column)) / 2);
  --spread: 43rem;                     /* the epigraphs' column */
}
#introduction .chapter-head {
  float: left;
  width: calc(100cqi - var(--spread) - 3rem);
}
#introduction .head {
  text-align: left;
  border-bottom: 0;
  padding-block: 6.875rem 0;
  margin: 0;
}
#introduction .poem-body {
  width: auto;
  max-width: none;
  margin: 0;
  padding-right: calc(var(--inset) * 2);
}
#introduction .poem-body > * { position: relative; left: var(--inset); }

/* The opening epigraphs: at the right edge of the page, in their own column.
   The space between them is the setting's, one step, as before; the 2-step
   indent has nothing to be indented from there, so it goes. */
#introduction .poem-body > .epigraph:not(:is(.pr, .lg) ~ .epigraph) {
  left: 0;
  width: var(--spread);
  max-width: none;
  margin: 0 calc(var(--inset) * -2) 0 auto;
  font-size: 0.833em;                  /* the design's 20px */
}
#introduction .poem-body > .epigraph:not(:is(.pr, .lg) ~ .epigraph) + .epigraph {
  margin-top: var(--step);
}
#introduction .poem-body > .epigraph:first-child:not(:is(.pr, .lg) ~ *) {
  padding-top: 6.875rem;
}
#introduction .poem-body > .epigraph:not(:is(.pr, .lg) ~ .epigraph) .source {
  font-family: var(--sans);
  font-size: calc(0.625em / 0.833);
  max-width: 31rem;
}

/* The heavy rule under the spread, edge to edge, on the essay's first
   element (the '*' that opens it). */
#introduction .poem-body > .epigraph:not(:is(.pr, .lg) ~ .epigraph) + :not(.epigraph) {
  clear: both;
  left: 0;
  margin-right: calc(var(--inset) * -2);
  border-top: 2px solid var(--ink);
  margin-top: 4rem;
  padding-top: 3rem;
}
/* The essay's paragraphs fill the column; their leading and the space
   between them are as set. */
#introduction .pr { max-width: none; }
#introduction .notes { clear: both; }

/* Narrow: no spread. The title, then the epigraphs, then the essay, all in
   the column. */
@media (max-width: 62.5rem) {
  #introduction .chapter-head { float: none; width: auto; }
  #introduction .head { padding-block: 3.5rem 2rem; }
  #introduction .poem-body > .epigraph:not(:is(.pr, .lg) ~ .epigraph) {
    left: var(--inset);
    width: auto;
    margin: 0;
  }
  #introduction .poem-body > .epigraph:first-child:not(:is(.pr, .lg) ~ *) { width: auto; padding-top: 0; }
}

/* =============================================================== NOTES == */

/* Full width, so its heavy rule runs edge to edge like the title's; the
   heading and the list inside it are set on the reading column. */
.notes {
  margin-top: 5rem;
  padding-top: 2.5rem;
  border-top: 2px solid var(--ink);
  font-size: var(--size-note);
  line-height: var(--leading-note);
}
/* The Notes heading. This is a <details> summary — the apparatus collapses
   with no script, and the browser handles the keyboard and announces the
   expanded/collapsed state for free. The site design sets it as a heading,
   44px in the text face, with no disclosure triangle; the pointer and the
   focus ring are what say it can be pressed. --column is a length that does
   not depend on the local em, so the summary's larger type does not widen
   its column. */
.notes summary {
  display: block;
  max-width: var(--column);
  margin-inline: auto;
  font-size: clamp(2rem, 1.4rem + 1.5vw, 2.75rem);
  line-height: 1;
  cursor: pointer;
  list-style: none;
}
.notes summary::-webkit-details-marker { display: none; }
.notes ol {
  max-width: var(--column);
  margin: 1.75rem auto 0;
  padding: 0;
  list-style: none;
  counter-reset: note;
}
/* The note number hangs beside the note — the '1.' + em-space of the source
   becomes list structure, not a character.

   A two-column grid, not the usual hanging indent. padding-left with a negative
   text-indent only pulls the first INLINE box back into the margin, and a note's
   children are blocks: paragraphs, quotations, quoted verse. With no inline box
   to pull, the marker takes an anonymous line of its own and sits ABOVE the note
   instead of beside it. The grid puts it in the first column and every block in
   the second, which is the arrangement the speeches in Fable XIV already use.

   The marker column is a fixed width rather than sized by content so that it
   is the same in every note: Frognal runs to 45 notes, and a column that grew
   to fit its own number would step the note text right as the numbers reach
   two digits.

   1.5em is the width it always resolved to. It used to read max(step, 3ch),
   which in Baskerville came out at 1.5em; but a ch is the face's zero, and
   Fraunces's is wide enough that 3ch pushed every note's text nearly half an
   em right. So the proofed width is now written down rather than derived from
   the face, and the numbers are sized to fit it (below). */
.notes ol > li {
  counter-increment: note;
  display: grid;
  grid-template-columns: 1.5em 1fr;
  margin-bottom: 0.85em;      /* 2mm in the source */
}
.notes ol > li > * { grid-column: 2; }
/* The number in that first column IS the link back to the text -- see
   build_notes(). So it is real markup carrying the PDF's own number, not a CSS
   counter, which could not be a link and could drift from it besides.

   Stretched to fill its column and given the note's full line box, it clears
   the 24 x 24 px minimum target (WCAG 2.2 SC 2.5.8) that a bare '1.' does not:
   the old return arrow was 17.6 x 20.5. Underlined to match the superscript
   in the text, because it is the same link running the other way.

   In the furniture face, as the design sets it: a number is a counter, not
   text. Where it stands is unchanged. The leading is divided back out of its
   smaller size so its baseline stays on the note's first line. */
.notes ol > li > .en-back {
  grid-column: 1;
  align-self: start;
  font-family: var(--sans);
  /* Courier's figures are 0.6em apiece, so '45.' is 1.8 of its own em: at
     0.7 that is 1.26em of the note, leaving the quarter-em gap to the note's
     text that the old numbers had. */
  font-size: 0.7em;
  line-height: calc(var(--leading-note) / 0.7);
  font-variant-numeric: lining-nums tabular-nums;
  min-height: 1.5em;
}
/* A note running to more than one paragraph marks the break with a first-line
   indent and no space, exactly as the setting does -- the paragraphs sit on
   consecutive lines there, 5mm in. A vertical gap instead would be a different
   page from the one Donald set. */
/* A note's paragraph is indented when the setting indents it, and not
   otherwise. The class comes from the PDF, not from the paragraph's position in
   the note: 'every paragraph after the first' is nearly right but indents the
   19 paragraphs in the edition that are set flush. */
.notes li > p.ind { text-indent: var(--step); }
/* Verse quoted inside a note: 12mm in the source, deeper than a quotation. */
.notes .lg {
  margin-left: calc(var(--step) * 2.5);
  margin-block: 0.6em;
}
.notes .lg + .lg { margin-top: 0.6em; }         /* a stanza break, 2mm */
/* Verse quoted inside a quotation in a note (the couplets in Eliot's letter,
   Whale note 3): the quotation already stands in, so the verse goes one step
   further, the depth of the letter's own paragraph indent, as in the source. */
.notes blockquote.extract .lg { margin-left: var(--step); }
/* The source of a quotation in a note, on its own line and set to the right
   ('(cited in Poems II, 219)' under Private Willis's song). */
.notes li > p.source { text-align: right; }
/* The Tempest in Frognal's note 12: 'I wish' ends level with the longest line,
   where the proofreader asked for it. */
#frognal-n12 .lg { width: fit-content; }
#frognal-n12 .l:first-child { text-align: right; }

/* A note reference. vertical-align in em rather than `super` so the raise is
   proportional to the type; line-height:0 so a raised marker cannot push its
   own line apart — which in verse would open a visible gap mid-stanza. */
.enref { font-size: 0.72em; vertical-align: 0.42em; line-height: 0; }
/* Underlined at rest: the design marks a link into the apparatus by its
   underline, not by a colour. Hover thickens it. */
.enref a, .en-back {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
}
.enref a:hover, .en-back:hover { text-decoration-thickness: 2px; }

/* ------------------------------- the weighing ledger (Whale & Elephant) --
   Real tabular data, so a real table: it keeps its row/column semantics for a
   screen reader, and it reflows. No rules, per the source. */

table.ledger {
  border-collapse: collapse;
  margin: 1em 0 1em var(--step);
  font-variant-numeric: lining-nums tabular-nums;
  text-indent: 0;
}
table.ledger caption {
  text-align: left;
  margin-bottom: 0.5em;
}
/* EVERY column is centred, the names with the rest. That is measured, not a
   preference: the three names share a centre to within 0.02pt while their left
   edges scatter over 21pt, and the ditto mark shares 'stone's centre to within
   0.7pt where left-aligning the two would put the ditto at the far edge of its
   column. Padding is symmetric for the same reason -- it is the column that has
   to centre, not the box around it -- and the 0.55em between columns is
   unchanged by splitting it in two. */
table.ledger th,
table.ledger td {
  border: 0;
  padding: 0.1em 0.275em;
  text-align: center;
  font-weight: 400;
  white-space: nowrap;
}
/* Each heading is italic and sits in the single column it is centred over --
   which column is recovered from the setting's geometry in ledger_html(), not
   decided here. */
table.ledger thead th {
  font-style: italic;
  padding-bottom: 0.35em;
}

/* ------------------------------------------------------------ inline ---- */

/* Small capitals. The setting uses two mechanisms -- a dedicated small-caps
   font in the poems, an OpenType substitution in the notes -- and both arrive
   here as the same class. font-variant-caps rather than text-transform because
   the letters must stay lowercase in the markup: they are lowercase in the
   source, they should be lowercase when the text is copied out of the page, and
   a real capital inside a small-capped run (the F of 'Festschriftgeschenck')
   has to stay full size, which only font-variant-caps gets right. */
.sc { font-variant-caps: small-caps; }
em, .it { font-style: italic; }

/* ------------------------------------------------------- running head ----
   Contents / previous / chapter menu / next.

   No JavaScript: the menu is a native <details> disclosure. A <select> cannot
   navigate on its own -- it only fires 'change', which nothing in HTML turns
   into a page load -- whereas <details> needs no script, is keyboard-operable,
   and is announced as expanded/collapsed. Clicking off it closes it too -- see
   the dismiss layer below, which needs no script either.

   What <details> still will not do is close on Esc. That is native to <dialog>
   and to popover, and to nothing else; a disclosure has no such behaviour to
   inherit, focused or not. (Tested, because the note that used to stand here
   claimed it did.) The Popover API would give both dismissals for nothing, and
   is the way to go if Esc is wanted -- but it means a button and a popover in
   place of the summary and the details, so it is a change to the markup and to
   build_site.py, not to this file. */

.bar {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  height: var(--bar-h);
  display: flex;
  align-items: center;
  gap: 1rem;
  padding-inline: clamp(1.15rem, 6vw, 5rem);
  background: color-mix(in srgb, var(--sheet) 92%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
  font-family: var(--sans);
  font-size: 1rem;            /* everything in the bar and the menu inherits it */
  z-index: 10;
}
.bar a, .bar button, .bar select {
  color: inherit;
  background: none;
  border: 0;
  font: inherit;
  cursor: pointer;
  text-decoration: none;
}

/* Contents is taken out of the flow so the group in the middle is centred on
   the page, not on the space left over beside it. */
.bar-home { position: absolute; inset-inline-start: clamp(1.15rem, 6vw, 5rem); }
.bar-nav {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  margin-inline: auto;
  min-width: 0;
}

.bar-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.4rem;
  height: 2.4rem;
  border-radius: 999px;
  color: var(--muted);
  font-size: 1.2em;           /* the arrows and the contents glyph */
  line-height: 1;
}
.bar-btn:hover, .bar-btn:focus-visible {
  color: var(--ink);
  background: color-mix(in srgb, var(--rule) 55%, transparent);
}
/* At the first and last chapter the arrow stays put but goes dead, so the bar
   does not reflow as you read through. */
.bar-btn.is-off { opacity: 0.25; }

/* -------------------------------------------------- the chapter menu ----- */

.bar-picker { position: relative; min-width: 0; }
.bar-picker > summary {
  display: flex;              /* also blockifies the caret, so it can rotate */
  align-items: center;
  gap: 0.4rem;
  max-width: min(50vw, 24rem);
  padding: 0.4em 0.85em;
  border-radius: 999px;
  cursor: pointer;
  list-style: none;           /* Firefox's disclosure triangle */
}
.bar-picker > summary::-webkit-details-marker { display: none; }
/* Click off the menu to close it, with no script. A click on a pseudo-element
   hit-tests as a click on the element that owns it, so a full-viewport
   summary::before shown only while [open] is a dismiss layer that toggles the
   <details> shut by itself. It cannot fall out of step with the menu, because
   it IS the open state -- there is nothing to keep in sync, which is the part
   a scripted version has to get right and this cannot get wrong.

   It starts below the bar so the bar's own controls stay live, and it is not
   a scroll container, so a wheel or a swipe over it still scrolls the page.
   Esc and the summary close the menu as before.

   Positioned off the BAR, not off the viewport, though it is position:fixed.
   The bar carries a backdrop-filter, and a filter makes its element the
   containing block for the fixed descendants inside it -- so `inset: 56px 0 0`
   resolved against the bar's own 56px height and laid out a layer of no
   height at all, which swallowed nothing and closed nothing. 100% is the
   bar's height, which is where this has to start anyway. */
.bar-picker[open] > summary::before {
  content: "";
  position: fixed;
  inset-block-start: 100%;
  inset-inline: 0;
  height: 100vh;
  z-index: 0;
}
.bar-picker > summary:hover, .bar-picker > summary:focus-visible {
  background: color-mix(in srgb, var(--rule) 55%, transparent);
}
.bar-current { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-caret { color: var(--muted); font-size: 0.75em; }
.bar-picker[open] > summary .bar-caret { rotate: 180deg; }

.bar-menu {
  position: absolute;
  inset-block-start: calc(100% + 0.5rem);
  inset-inline-start: 50%;
  translate: -50% 0;
  width: max-content;
  max-width: min(92vw, 30rem);
  max-height: min(70vh, 34rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  z-index: 1;                 /* above the dismiss layer */
  margin: 0;
  padding: 0.35rem 0;
  list-style: none;
  /* The menu scrolls -- 21 chapters where about 15 fit -- and a list that
     stops flush on a border reads as a list that has ended. So each edge with
     more behind it carries a fade and a shadow, and loses them at the end of
     the travel: the two covers are background-attachment:local and so move
     with the content, the two shadows are scroll and stay with the box, and at
     either end of the scroll the cover is parked exactly over the shadow and
     cancels it. The hint appears and goes on its own, with nothing to sync.

     The shadow is mixed from --muted, not from black: --muted is darker than
     the sheet in the day palette and lighter than it in the night one, so the
     edge reads either way round. A black shadow would not exist at all on the
     dark panel, and no colour this far down the file may carry one fixed
     value -- see the palette note above. */
  --edge: color-mix(in srgb, var(--muted) 34%, transparent);
  background:
    linear-gradient(var(--sheet) 30%, transparent)    top    / 100% 2em,
    linear-gradient(transparent, var(--sheet) 70%)    bottom / 100% 2em,
    radial-gradient(farthest-side at 50% 0,
                    var(--edge), transparent)         top    / 100% 1.1em,
    radial-gradient(farthest-side at 50% 100%,
                    var(--edge), transparent)         bottom / 100% 1.1em,
    var(--sheet);
  background-repeat: no-repeat;
  background-attachment: local, local, scroll, scroll;
  border: 1px solid var(--rule);
  border-radius: 0.55rem;
  box-shadow: 0 0.7rem 2.2rem rgb(0 0 0 / 0.16);
}
/* A scrollbar that is ALWAYS THERE, which is the plainest way to say a list
   goes on. The platform's own is an OVERLAY scrollbar -- on a Mac it is
   invisible until you are already scrolling, so it can only confirm what you
   have found out for yourself. Styling ::-webkit-scrollbar gives the box a
   real one that holds its own width. The same prefixed route the summary's
   disclosure marker already takes.

   And NOT scrollbar-width / scrollbar-color beside it, tempting as the
   standard properties are: from Chrome 121 setting either one makes the
   browser ignore every ::-webkit-scrollbar rule, and `thin` on a Mac is still
   an overlay scrollbar. The pair together silently gave a 0px-wide bar. */
.bar-menu::-webkit-scrollbar { width: 0.6rem; }
.bar-menu::-webkit-scrollbar-track { background: transparent; }
.bar-menu::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--muted) 50%, transparent);
  border: 0.18rem solid transparent;   /* inset from the edge, via the clip */
  background-clip: padding-box;
  border-radius: 999px;
}
.bar-menu a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 0.5em 1.1rem;
  color: inherit;
}
.bar-menu a:hover, .bar-menu a:focus-visible {
  background: color-mix(in srgb, var(--rule) 45%, transparent);
}
.bar-menu [aria-current] { color: var(--accent); }
.bar-menu .author { color: var(--muted); white-space: nowrap; font-size: 0.9em; }

/* ------------------------------------------------------ contents page ---- */

.masthead { text-align: center; margin-bottom: 3.5rem; }
.masthead h1 {
  font-size: clamp(1.9rem, 1.3rem + 2.4vw, 3rem);
  font-variant-caps: small-caps;
  letter-spacing: 0.04em;
}
.masthead .byline {
  color: var(--muted);
  font-size: 0.95em;
  font-style: italic;
  margin-top: 0.7em;
}
.toc { max-width: 34rem; margin-inline: auto; }
.toc h2 {
  font-family: var(--sans);
  font-size: 0.72em;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.8em;
}
.toc ol { margin: 0; padding: 0; list-style: none; }
.toc a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 0.55em 0.2em;
  border-block-end: 1px solid var(--rule);
  color: inherit;
  text-decoration: none;
}
.toc a:hover .mt { text-decoration: underline; }
.toc .author {
  color: var(--muted);
  font-family: var(--sans);
  font-size: 0.82em;
  white-space: nowrap;
}

/* ------------------------------------------------------------ utility ---- */

/* Visually hidden, but still spoken. Used for the reading bar's arrow labels
   ("Previous: Introduction"), which are glyphs on screen. NOT display:none or
   visibility:hidden — both would remove the text from the accessibility tree,
   leaving a screen reader to announce a bare arrow character. */
.vh {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ------------------------------------------------------------ narrow ----- */

@media (max-width: 46rem) {
  /* The numbers stay in the right margin here as everywhere else. They used to
     move to the left of the line on the reasoning that a phone has no width to
     spare for a gutter — true, but the left margin has none either, and there
     the number hangs OUTSIDE the block with nothing to reserve its space. At
     390 px that put 113 of them partly off the screen. A line number that has
     left the viewport is worse than a narrow measure.

     The gutter is one step here rather than two. Two protect the case where
     .poem-body is sized by its own longest line and a browser measures that
     line's hanging indent a step short. At this width the block is not sized
     that way at all: it is clamped to the container, so the verse wraps to fit
     the content box and can never reach into the padding. The second step is
     guarding against something that cannot happen here, and it costs measure —
     it doubles the wrapped lines a phone has to show. */
  .poem-body { text-wrap: pretty; padding-right: calc(var(--step) * 1.5); }
  /* A subtitle mirrors the block's gutter so it keeps the verse's axis, so
     it has to mirror the narrowed one here too -- left at the full gutter it
     would both shift the subtitle off the verse and take a step and a half of
     measure off a phone for nothing. */
  .chapter-head > .subtitle { padding-right: calc(var(--step) * 1.5); }
  .noctes-chapter:not(:has(.poem-body .l[data-n])) .chapter-head > .subtitle { padding-right: 0; }
  /* The bar keeps all four controls; the menu gives up the contributor
     column rather than the chapter titles. */
  .bar { gap: 0.4rem; padding-inline: 0.9rem; }
  .bar-home { inset-inline-start: 0.6rem; }
  .bar-picker > summary { max-width: 46vw; }
  .bar-menu .author { display: none; }
}

/* Nothing here animates today; this is a standing guarantee so that anything
   added later cannot move for a reader who has asked it not to. */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ------------------------------------------------------------- print ----- */

/* Printing is a real use for a poetry edition, and it is nearly free here:
   because colour is five tokens, the whole thing goes to ink by overriding
   three of them. The rest is stopping stanzas from breaking across pages. */
@media print {
  :root { --ink: #000; --sheet: #fff; --muted: #555; }
  .bar { display: none; }
  .sheet { padding: 0; max-width: none; }
  .notes[open], .notes details { display: block; }
  .lg, .sp, table.ledger { break-inside: avoid; }
  .head { break-after: avoid; }
}

   /* No shiver in "Make mischief" (designer's request) */
   .nb-mischief-shiver { animation: none !important; }