:root {
  color-scheme: light;
  --bg:#e2dbc2; --fg:#16140f; --dim:#463b28; --rule:#8c7f5e; --card:#ebe5d0;
  --board:#c4ae80; --on-board:#16140f; --block:#16140f; --on-block:#e2dbc2;
  --accent:#084a1c; --mark:#5a3e00; --pin:#5c3500; --warn:#801c0a; --info:#0a4a4a;
  --sea:#d3d5c4; --land:#d9d0b0; --water:#0c4468;
  --sel: #801c0a;
  --flora:#424500; --abstract:#6a1f66; --lex:#742b00; --basin:#6e2418;
  --hi:#c8200a;
  --print:multiply;
  --text:Charter,Georgia,"Times New Roman",serif; --ui:var(--text);
  /* The paper and the board: tiling PNGs of one colour under varying alpha,
     declared here alone so that the two dark blocks below name a tile rather than
     each holding a copy. ImageMagick 6, for each of light (seed 7, sigma .5, floor
     60, cap 4, black), dark (11, .5, 60, 12, #7d5fb0, the purple in the ink) and
     board (13, .55, 45, 6, black; text sits on this one too):
       convert -seed S -size 96x96 xc:gray +noise Random -colorspace Gray
         -virtual-pixel tile -blur 0xSIGMA -auto-level -level FLOOR%,95%
         -posterize 3 +level 0,CAP% mask.png
       convert -size 96x96 xc:INK mask.png -alpha off -compose CopyOpacity
         -composite -define png:color-type=6 -define png:compression-level=9
         -strip tile.png
     **Mottling, and faint, because a Tier-1 form is read off this.** A dark speck
     beside an `i` is a diacritic nobody printed. Weaken a tile before making it
     louder; cards stay flat for the same reason. */
  --grain-light:url(data:image/png;base64,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);
  --grain-dark:url(data:image/png;base64,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);
  --grain-board:url(data:image/png;base64,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);
  --grain:var(--grain-light);
}
/* **Three states, and the two dark blocks are the same tokens on purpose.**
   No `data-theme` means follow the system, which is what a reader who has never
   touched the toggle wants and the only thing that works with no JS at all.
   `data-theme="light"` and `="dark"` are an explicit choice and must win in
   *both* directions — the media query alone could force light on a dark system
   but never dark on a light one, so the toggle had nothing to set.
   CSS cannot union a media query with an attribute selector, so the block is
   written twice; the values are identical and belong to `:root` either way. */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) {
  --bg:#14111a; --fg:#f4eeda; --dim:#cfc09a; --rule:#5a5068; --card:#1f1a27;
  --board:#2a2234; --on-board:#f4eeda; --block:#b89f70; --on-block:#14111a;
  --accent:#6fe08a; --mark:#f2c23e; --pin:#eda75f; --warn:#ff8a6b; --info:#6fdcdc;
  --sea:#161722; --land:#2b2633; --water:#6cc6f7;
  --sel: #ff8a6b;
  --flora:#d6dc4e; --abstract:#e3a0e6; --lex:#ffa04d; --basin:#e09a88;
  --hi:#ff6a4d;
  --print:normal;
  --grain:var(--grain-dark);
  color-scheme: dark;
} }
:root[data-theme="dark"] {
  --bg:#14111a; --fg:#f4eeda; --dim:#cfc09a; --rule:#5a5068; --card:#1f1a27;
  --board:#2a2234; --on-board:#f4eeda; --block:#b89f70; --on-block:#14111a;
  --accent:#6fe08a; --mark:#f2c23e; --pin:#eda75f; --warn:#ff8a6b; --info:#6fdcdc;
  --sea:#161722; --land:#2b2633; --water:#6cc6f7;
  --sel: #ff8a6b;
  --flora:#d6dc4e; --abstract:#e3a0e6; --lex:#ffa04d; --basin:#e09a88;
  --hi:#ff6a4d;
  --print:normal;
  --grain:var(--grain-dark);
  color-scheme: dark;
}
/* `color-scheme` so the browser's own furniture follows — the search field, the
   scrollbars, the focus ring. Without it a dark page carries a white input. */
:root[data-theme="light"] { color-scheme: light }
* { box-sizing:border-box }
body { margin:0; background:var(--bg) var(--grain); color:var(--fg);
  font:16px/1.5 var(--text); }
a { color:var(--accent) }
/* **Small capitals on the site's own words only.** Capital against small capital
   is a distinction in the notation (`keying_spec.md`), so this class of rule must
   never reach an element that can hold the book's text: not `.location`, not the
   contents panel, not a card, a search hit or a tree row. */
#bar .site-title a:not(:first-of-type), #site-foot .refs a, .draft-tag, .run-tag,
.leaf-tag, .pill, .alpha-sorts .g-key, .outline .ol-part h4, .alpha-sorts th,
.run .page-no .opp, ul.tree code.cls {
  font-variant-caps:all-small-caps; letter-spacing:.05em }
/* The board: the two bands the cream page sits between. Green on kraft is about
   2.5:1, so nothing here wears a hue; `--on-board` is the whole of its colour. */
#bar, #site-foot { background:var(--board) var(--grain-board); color:var(--on-board) }
#bar a, #site-foot a, #bar .location { color:var(--on-board) }
#bar button { font-size:1rem; color:var(--on-board);
  border-color:var(--on-board); background:var(--card) }
#bar button:hover { background:var(--bg) }
/* The theme button shows where it goes: a moon in light, a sun in dark. Written
   against both dark conditions for the reason the token blocks are. */
#bar [data-theme-toggle] { font-size:1.35rem; font-weight:700; line-height:1.1;
  padding:.1rem .5rem }
[data-theme-toggle] .to-light { display:none }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) [data-theme-toggle] .to-light { display:inline }
  :root:not([data-theme="light"]) [data-theme-toggle] .to-dark { display:none }
}
:root[data-theme="dark"] [data-theme-toggle] .to-light { display:inline }
:root[data-theme="dark"] [data-theme-toggle] .to-dark { display:none }
#bar a:hover, #site-foot a:hover { text-decoration:underline }
#bar { z-index:9; display:flex; gap:.75rem;
  align-items:center; padding:.5rem .9rem;
  border-bottom:1px solid var(--on-board); font-family:var(--ui);
  font-size:1rem; }
/* Three zones: the site's name left, the controls centred, the page's identity
   hard right. The centre is the only one that grows, so it stays centred in the
   window rather than centred in whatever is left over — and the two ends are
   given the same basis so an unusually long identity cannot drag the middle off
   centre. */
#bar .site-title, #bar .bar-right { flex:1 1 0; min-width:0 }
#bar .site-title a:first-of-type { font-weight: bold; }
#bar .site-title a:not(:first-of-type) { margin-left:.9em; font-size:1.1em }
#bar .bar-right { display:flex; align-items:center; gap:.75rem;
  justify-content:flex-end }
#bar .bar-right input { min-width:0 }
#bar .location { white-space:nowrap }
#bar .page-specific-buttons {
    display: flex;
    flex: 0 0 auto;
    flex-direction: row;
    gap: 0.5em;
    justify-content: center;
}
/* --- the site's own apparatus, at the foot ---
   The other views, the search field and the theme control. Off the top of the
   window on purpose: none of it is wanted while reading, and the header is the
   one strip that is on screen the whole time. */
#site-foot { display:flex; flex-direction:column; align-items:center; gap:.6rem;
  margin:2rem 0 0; padding:1rem .9rem 2rem;
  border-top:1px solid var(--on-board);
  font-family:var(--ui); font-size:1rem }
#site-foot .refs a { font-size:1.1em }
#site-foot .refs { display:flex; gap:.9rem; flex-wrap:wrap;
  justify-content:center }
#site-foot a { text-decoration:none }
#bar a { text-decoration:none }
button, .btn { font:inherit; font-family:var(--ui); font-size:.8rem;
  padding:.25rem .6rem; border:1px solid var(--dim); border-bottom-width:2px;
  background:var(--bg); color:var(--fg); cursor:pointer; }
button:hover { border-color:var(--accent) }
/* Pressed: the heavier edge moves to the top, so the face seems to go in. */
button:active { border-bottom-width:1px; border-top-width:2px }
main.cols { display:flex; align-items:flex-start; flex-direction: row-reverse; }
.cols-reversed main.cols { flex-direction: row; }
#primary { flex:1 1 auto; padding: 0 1rem; min-width:0; max-width:44rem; margin: 1rem auto; }
/* **Idle** is the state that used to be `:empty`, and could not stay so: the
   column now always holds a `#stack` and a `#map-pane`, either of which may have
   nothing in it. Idle means both — no cards and the pane shut — and it is what
   collapses the column and re-centres the text.
   **And a third condition, since the tab bar arrived**: a bar is furniture, and
   furniture is not a reason to hold a column open across a book nobody has
   clicked anything in. The contents are asked for when `#toc-switch` is
   checked, or — before the script has set the box from the sitting's memory —
   when the head script has put `.side-contents` on `<html>` for first paint.
   It is written as an ancestor guard on the same rule rather than as a rule of
   its own, because a competing `.side-contents #secondary { display:block }`
   would lose: `:not(:has(#map-pane…))` carries an id, so the selector below is
   two ids to that one's one, and the override would be a no-op that reads like
   a fix — the failure this stylesheet already documents at `#bar`. */
#primary:first-child:last-child,
html:not(.side-contents):not(:has(#toc-switch:checked)):not(.side-open):not(:has(#side-on:checked)) #secondary:not([data-fixed]):not(:has(.card)):not(:has(#map-pane:not([hidden]))) + #primary
  { margin:1rem auto }
/* `--bar-gap` is how much of the header is still on screen. The header scrolls
   away and the column does not, so a fixed `top:3rem` left a strip of nothing
   above the column for the whole of the book once you were past its first
   screen. `edition.js` keeps it at the header's bottom edge, 3rem at the top of
   the page and 0 below it; 3rem is the answer without the script. */
:root { --bar-gap:3rem }
#secondary { flex: 1; padding: 0.8rem 0.5rem; position:sticky; top:var(--bar-gap);
  max-height:calc(100vh - var(--bar-gap) - 1rem); overflow-y:auto; }
html:not(.side-contents):not(:has(#toc-switch:checked)):not(.side-open):not(:has(#side-on:checked)) #secondary:not([data-fixed]):not(:has(.card)):not(:has(#map-pane:not([hidden])))
  { display: none; }

/* **Which panel shows is the stylesheet's**, off `#toc-switch`: no script
   between a reader and the contents. The contents when they are asked for, and
   when the column is empty — a column opened onto nothing opens onto the book's
   outline — and the entities otherwise. The `:has(#panel-contents)` guard is a
   view that sends no contents, whose column is the entities whatever happens. */
#panel-contents { display:none }
html:is(.side-contents, :has(#toc-switch:checked)) #panel-contents,
#secondary:not(:has(.card)):not(:has(#map-pane:not([hidden]))) #panel-contents
  { display:block }
html:is(.side-contents, :has(#toc-switch:checked)) #side-body:has(#panel-contents) #panel-entities,
#secondary:not(:has(.card)):not(:has(#map-pane:not([hidden]))):has(#panel-contents) #panel-entities
  { display:none }

/* --- the column's edges ---
   **The hide fringe on the inner edge, beside the text, and the scrollbar on the
   outer one**, whichever side the column is on. A scrollbar goes where the
   writing direction ends, and a grid starts where it begins, so the fringe —
   first in the source — and the scrollbar always land on opposite edges: on the
   right of the page the column runs left-to-right (fringe left, scrollbar
   right); swapped to the left (⇄) it runs right-to-left (fringe right,
   scrollbar left).
   **Partitioned vertically**: the column is a fixed height and does not scroll;
   inside it `#side-col` stacks the scrolling panels over the TOC switch, which
   has the bottom to itself and covers nothing. The scrollbar is therefore
   `#side-body`'s, and the direction that places it is set there; its children
   go back to left-to-right, since their text is. */
#secondary { direction:ltr; display:grid; grid-template-columns:auto 1fr;
  grid-template-rows:minmax(0,1fr); column-gap:.4rem; padding-inline-start:0;
  padding-bottom:0; height:calc(100dvh - var(--bar-gap)); overflow:hidden; max-width: 22rem; }
.cols-reversed #secondary { direction:rtl }
#side-col { display:flex; flex-direction:column; min-width:0; min-height:0;
  direction:ltr }
/* Padded on both sides because a scroller clips: the contents' "here" bar is a
   shadow drawn left of its row, and the page numbers would otherwise touch the
   scrollbar. */
#side-body { flex:1 1 auto; min-height:0; overflow-y:auto; padding:0 .4rem }
/* **The column's scrollbars are there when you are.** Thin, and transparent
   until the pointer or the focus is in the scroller: a full-weight bar down a
   narrow column, beside its fringe, was the loudest thing on the page and said
   nothing a reader was asking. The gutter is kept, so showing it moves nothing. */
#side-body, #secondary .ent-tree { scrollbar-width:thin; scrollbar-gutter:stable;
  scrollbar-color:transparent transparent }
#side-body:hover, #side-body:focus-within,
#secondary .ent-tree:hover, #secondary .ent-tree:focus-within {
  scrollbar-color:color-mix(in srgb,var(--dim) 55%,transparent) transparent }
.cols-reversed #side-body { direction:rtl }
.cols-reversed #side-body > * { direction:ltr }

/* The two fringes: a full-height strip with a rule and an arrow. The hide one
   points away from the text, the show one toward it — `›`/`‹` set by the side
   the column is on, in `content` so the arrow is never mirrored by an rtl
   column the way a character in the markup would be. */
#side-hide, #side-show { width:1.1rem; padding:0; border:0;
  background:transparent; color:var(--dim); font-size:1rem;
  cursor:pointer; direction:ltr;    /* an rtl column mirrors `content` too */
  /* Labels, not buttons, so nothing centres the arrow unless this does. */
  display:flex; align-items:center; justify-content:center }
#side-hide:hover, #side-show:hover { opacity:1; color:var(--fg);
  background:color-mix(in srgb,var(--rule) 30%,transparent) }
#side-hide { align-self:stretch; border-inline-end:1px solid var(--rule) }
#side-hide::before { content:"›" }
.cols-reversed #side-hide::before { content:"‹" }
/* The show fringe is fixed to the window's edge on the column's side, and is
   there exactly when the column is not: hidden by its fringe, or collapsed
   because nothing is in it — the idle rule's own condition, read off the
   sibling it stands before. */
#side-show { display:none; position:fixed; top:var(--bar-gap); bottom:0; right:0;
  z-index:4; border-left:1px solid var(--rule) }
#side-show::before { content:"‹" }
.cols-reversed #side-show { right:auto; left:0; border-left:0;
  border-right:1px solid var(--rule) }
.cols-reversed #side-show::before { content:"›" }
/* Two rules, not one list: `:has()` may not nest, so the idle condition is asked
   of `main` rather than of the aside, and a selector list with one invalid
   member drops the whole rule — which is how this first shipped, never shown. */
html:is(.side-dismissed, :has(#side-off:checked)) #side-show { display:flex }
html:not(.side-contents):not(:has(#toc-switch:checked)):not(.side-open):not(:has(#side-on:checked))
  main:not(:has(#secondary .card)):not(:has(#map-pane:not([hidden]))) #side-show
  { display:flex }

/* **Dismissed** is the hide fringe's state: the column gone and the text
   re-centred, until the show fringe, a card, a map or the contents ask for it. */
html:is(.side-dismissed, :has(#side-off:checked)) #secondary:not([data-fixed]) { display:none }
html:is(.side-dismissed, :has(#side-off:checked)) #secondary:not([data-fixed]) + #primary
  { margin:1rem auto }
/* **The fringes are labels; the radios behind them are the state.** Out of
   sight but in the tab order, their focus drawn on the fringe they stand
   before — the same arrangement as the TOC switch. **Fixed, not absolute**:
   clicking a label focuses its box, and the browser scrolls a focused control
   into view. An absolute box with no offsets sits where it would have been in
   flow, at the top of the page, so every click on a fringe jumped the reader
   there; a fixed one is always in view, so focusing it moves nothing. */
.side-state, #toc-switch { position:fixed; top:0; left:0; width:1px; height:1px;
  margin:0; opacity:0; pointer-events:none }
#side-on:focus-visible + #side-show, #side-off:focus-visible + #side-hide
  { outline:2px solid var(--accent); outline-offset:-2px; opacity:1 }

/* --- the TOC switch ---
   The full width of the column at its foot, square, below the scrolling part
   rather than over it. Solid while the contents are up, so the "cancel" reads
   as the state it undoes. */
#toc-toggle { flex:none; display:block; width:100%;
  margin:0; padding:.45rem 0; text-align:center;
  font-family:var(--ui); font-size:.75rem; letter-spacing:.04em;
  color:var(--dim); background:var(--card) }
html:is(.side-contents, :has(#toc-switch:checked)) #toc-toggle
  { background:var(--fg); color:var(--bg); border-color:var(--fg) }
/* The label says what pressing it will do, not what is showing. */
#toc-toggle .when-on { display:none }
html:is(.side-contents, :has(#toc-switch:checked)) #toc-toggle .when-off { display:none }
html:is(.side-contents, :has(#toc-switch:checked)) #toc-toggle .when-on { display:inline }
/* The box is the control and the label its face: out of sight but in the tab
   order (with the fringes' radios, above, and fixed for their reason), and its
   focus drawn on the label, which is what a reader sees. */
#toc-switch:focus-visible + #toc-toggle { outline:2px solid var(--accent);
  outline-offset:-2px }
/* **Only over something.** An empty column shows the contents and nothing
   else — the panel rule above asks the same condition — so a switch to a panel
   with nothing in it would be a control that does nothing. */
#secondary:not(:has(.card)):not(:has(#map-pane:not([hidden]))) :is(#toc-toggle, #toc-switch)
  { display:none }
/* Under the text on a narrow screen, the column is as tall as what it holds. */
@media (max-width:880px) {
  #side-hide, #side-show { display:none !important }
  #secondary { height:auto; overflow:visible }
  #side-body { overflow:visible }
}

/* --- the map pane ---
   One map per sitting, above the stack rather than in it: there is only ever one
   *here*, and a map that could be pushed out of sight by the next three cards
   was answering a question you had not stopped asking. */
#map-pane{position:relative;background:var(--card);border:1px solid var(--rule);
  padding:.6rem .75rem;margin-bottom:.6rem;
  font-family:var(--ui);font-size:.85rem;line-height:1.5}
#map-pane[hidden]{display:none}
#map-pane .dismiss{position:absolute;top:.4rem;right:.5rem;z-index:1;
  padding:.05rem .35rem;font-size:.7rem;line-height:1.4}
#map-pane h4{margin:0 0 .3rem;font-size:.9rem;font-family:inherit}
#map-pane .meta{color:var(--dim);font-size:.75rem;margin-bottom:.4rem}
@media (max-width:880px) {
  main.cols { display:block }
  #secondary { position:static; max-height:none; margin-top:2rem;
    border-top:1px solid var(--rule); padding-top:1rem }
}
/* **The bar sets the page's minimum width, which is why it stretched the whole
   page rather than merely looking cramped.** It is one flex row of eight things
   — title, location, buttons, three links and a search field — and a flex item
   does not shrink below its own content, `min-width` being `auto` on one. So the
   row establishes a floor wider than a phone, the body inherits it, and every
   column below is dragged out to match.
   Stacked here, and `min-width:0` on the field as well: columning alone leaves
   the input's default size holding the floor up. `.location` can be long — it
   carries the ref and the folio — so it wraps rather than pushing. */
@media (max-width:600px) {
  #bar { flex-wrap:wrap; gap:.4rem .75rem }
  #bar .site { flex:0 0 auto }
  #bar .site-title { flex:1 1 100% }
  /* Out of its wrapped row and into the corner, level with the title. */
  #bar { position:relative }
  #bar [data-theme-toggle] { position:absolute; top:.3rem; right:.9rem }
  #bar .bar-right { flex:1 1 0; flex-wrap:wrap; gap:.4rem .75rem;
    justify-content:flex-start }
  #bar .bar-right form { flex:1 1 6rem; display:flex }
  #bar .bar-right input { width:100% }
}
/* --- the text --- */
#primary p { margin:0 0 .35rem; text-align: justify; text-indent:1.4rem }
/* The paragraph that opens the leaf is the only one whose indent is not the
   default, and the class on it is what the page's own witnesses said — `@part`
   from an adjudicated seam, else the collator's `opens:`, else the keyed zone
   label (`tei_html.page_opens`). Flush where the paragraph carries over, and
   flush where nothing witnessed it: 305 of the 399 drafts say `zone-opens:
   continued`, so an unwitnessed indent would claim a break the print mostly does
   not have. (That measure is the first main zone's label, which
   `docs/open-questions.md` holds apart from the stricter one it quotes a rate
   for.) This was `p:first-of-type`, which asserted flush of *every* page — the
   92 that do open a paragraph were set as continuations of the page before. */
#primary p.opens-continued, #primary p.opens-unwitnessed { text-indent:0 }
/* **Unless it opens with a run-in head**, which is a break by definition — a
   section starts there, and the book indents the head with the paragraph it
   leads. Without this the exemption above swallowed it: a run-in head is very
   often the first thing on its page, so the heading sat flush and the ordinary
   paragraphs under it were the indented ones. */
#primary p:has(> .runin:first-child), .milestone + p { text-indent:1.4rem }
blockquote { margin:.8rem 0 .8rem 1.5rem; color:var(--dim) }
/* --- the four heading levels, as the book sets them ---------------------------
   The TEI says only which ToC entry opens here and how deep it is; everything
   below is this stylesheet reading `@unit`. The book's own four:

     chapter (1)     large, numbered, centred — the numeral on its own line
     section (2)     medium, unnumbered, centred
     subsection (3)  small caps, bold, run into the head of an indented paragraph
     subsubsection   semibold italic, title case, run in the same way

   The split between the first two and the last two is not this file's to make: a
   deep head is run-in *in the print*, so the words are on the page and the
   milestone renders as a bare anchor beside them (`.milestone.anchor`), while a
   head the printer set on its own line was a block the ToC join consumed, so its
   words come from `edition/toc.json`. Which happened is in the markup — see
   `tei_html._leads_a_block` — and this file styles whichever arrived. */
h2.milestone { font-weight:600; margin:1.6rem 0 .6rem }
/* **Centred at levels 1 and 2 only.** The book sets those on their own lines and
   centred; it runs 3 and 4 into a paragraph, which is what the comment above
   describes. So a deep head that arrives here as a block — because its page did
   not run one in, and the words came from the ToC — must still sit where its
   paragraph would start. Centring it invents a typographic level the print does
   not have, and does it on exactly the pages with the least evidence: the ones
   whose own head never read. */
h2.milestone.chapter, h2.milestone.section { text-align:center }
h2.milestone.chapter { font-size:1.35rem; letter-spacing:.08em;
  text-transform:uppercase; margin:2.6rem 0 1.2rem }
h2.milestone.chapter .milestone-n { display:block; font-size:.8em;
  letter-spacing:.16em; font-weight:500; margin-bottom:.3rem }
h2.milestone.section { font-size:1.05rem; letter-spacing:.06em;
  text-transform:uppercase; margin:2rem 0 .8rem }
/* Level 3 and 4 keep the ToC's numeral out of a run-in head, and the book prints
   none on either — but a milestone left as a block heading by a page that did not
   run its head in still sets in its own weight rather than the chapter's. */
h2.milestone.subsection { font-size:1rem; font-variant:small-caps;
  letter-spacing:.04em }
h2.milestone.subsubsection { font-size:1rem; font-style:italic; font-weight:500 }
/* The numeral, run into the title where a level ever sets it that way. Written as
   `::after` so the punctuation is presentation: the store holds `XI` and `Games`,
   and `. — ` is how this edition joins them. */
.milestone-n::after { content:". — " }
h2.milestone.chapter .milestone-n::after { content:"" }
/* The anchor is the boundary with the words left on the page: no box, no space,
   just something for a link to land on. */
span.milestone.anchor { display:inline; scroll-margin-top:4rem }
/* The toc id an old link names, set just before the heading it now reaches by
   its readable fragment. Empty and boxless, like the anchor. */
span.milestone.legacy { display:inline; scroll-margin-top:4rem }
/* --- the run-in head itself ---
   Styled by being run-in first and by depth second, because the page decides
   which it is: `chV.1` is a level-2 section and `1-128` prints its head run into
   the paragraph, so a rule that gave the run-in shape only to levels 3 and 4
   would leave that one bold and nothing else.

   **`all-small-caps` and not `small-caps`, and it is an approximation.** The book
   sets these heads with an initial capital and the rest in small capitals; the
   recognizer cannot tell a small capital from a capital, so `gt/ocr/` holds
   `SEAL-HUNTING.` and the initial is not recoverable from it — `edition/toc.json`
   has the casing but substituting the store's spelling for the page's is not
   something a stylesheet may do. `small-caps` would therefore be a no-op here,
   there being no lowercase for it to act on, and full capitals shout in a way the
   print does not. All-small-caps loses the initial and keeps the colour of the
   line, which is the better of the two errors. */
.runin { font-weight:700; font-variant-caps:all-small-caps; letter-spacing:.03em }
/* A minor head is the exception on both counts: the book sets it in italic title
   case, and the recognizer reads title case, so there is nothing to approximate.
   `tei_html._set_in_title_case` reads which it is off the case the page holds. */
.runin-title { font-style:italic; font-weight:600;
  font-variant-caps:normal; letter-spacing:0 }
h3 { font-size:1rem; margin:1.2rem 0 .4rem }
table { border-collapse:collapse; margin:.8rem 0 }
td,th { border:1px solid var(--rule); padding:.2rem .5rem; text-align:left }
/* In the page navigation now, not floated in the margin of the text. A float in
   the running prose is what it could not go on being: a figure floated to the
   head of a page tucked in beside it and shouldered it out of the corner. */
.folio { color:var(--dim); }
.neighbours .here { color:var(--dim); }
.tier1 { font-style:italic }
.unclear { border-bottom:1px dotted var(--mark) }
.supplied { color:var(--dim) }
.noteref { vertical-align:super; font-size:.7em; text-decoration:none;
  padding:0 .1em }
/* --- what a link points at -------------------------------------------------
 *
 * **The class is already on every link** — it is the prefix of `data-ref`, which
 * is the entity identity `class:slug` verbatim (`tei_html._referring`, and every
 * template that links a record). So nothing new is emitted; the stylesheet reads
 * what the corpus already carries.
 *
 * `--link` is the indirection that makes it one declaration per family instead
 * of one per rule: every link rule below is written in terms of it and defaults
 * it to `--accent`, and the family rules set nothing else.
 *
 * **Thirteen classes, five families.** Thirteen hues would be several pairs
 * nobody can tell apart, twice over for dark mode, and a fourteenth class would
 * need a colour that does not exist. A family is the coarsest grouping that
 * still answers the question a reader is asking — is this somewhere on land,
 * somewhere in the water, a creature, a person, or a record?
 *
 * **Land and water are two families and were one.** The old rule put `place:`
 * and `water:` in a single blue, on the reading that a sentence asks "place or
 * person" and nothing finer. That reading was thin even then and the four-class
 * split makes it wrong: `land:`/`place:` and `water:`/`river:` are the pair a
 * reader of this book separates constantly — the Anadyr is a river, a bay, a
 * town and a gulf within three pages — and the atlas beside the text has drawn
 * them apart since `geomap.css` took `data-kind`. `--pin` is the terrestrial
 * one because it is already what the map paints a settlement, so a village's
 * dot and its name in the sentence beside it are the same colour rather than
 * two unrelated conventions. Its near neighbour in light mode is `--flora`
 * (animal/taxon), which is the one pair here worth watching.
 *
 * The **point/region** cut inside each family carries no hue. Five families is
 * what the palette holds, the question "land or water" is the one a reader asks
 * mid-sentence, and "point or region" is a question about a map — so the atlas
 * answers it, on the node's own pill, and the prose does not try.
 *
 * `--abstract` is its own token and not `--mark`, which is the *apparatus*
 * colour: `.flag`, `.unclear`, `.unsettled` and `.pill.proposed` are all
 * `--mark`, and an event link drawn in it would read as an editorial mark on the
 * word rather than as a link. The two are the same hue family — the todo asks
 * for yellow and yellow is what it gets — so they are held apart by lightness
 * instead, and by the fact that a flag is a bordered box and a link is an
 * underline.
 *
 * `sky:` sits with `--abstract` because that family is *what the map does not
 * draw*, which is the one thing a star, an event, a work and a spirit have in
 * common. It is the least bad of five: the terrestrial and water hues would put
 * Orion on the same footing as a cape.
 *
 * `harness/entities.py`'s ENTITY_CLASSES is the authority and this is a copy of
 * it, so `test_edition.py` walks that dict and fails on any class with no rule
 * here, or with more than one — and, since a retired class leaves a selector
 * that is dead rather than wrong, on any rule here naming a class the store no
 * longer has. `language:` was one for as long as it took to notice.
 *
 * **The default is on `:root` and the selectors carry no element**, which is
 * what makes the family rules actually win. They used to be `a[data-ref^=…]` —
 * (0,1,1) — against consumers that each declared their own `--link:var(--accent)`
 * fallback at the same (0,1,1) and further down the file, so `a.node` in the
 * atlas beat every one of them and the whole tree came out accent-coloured.
 * A default that ties with the rule overriding it is not a default. Now nothing
 * but `:root` and these five lines declares `--link` at all: `--link` inherits,
 * an element's own declaration beats an inherited one whatever its specificity,
 * and a consumer can no longer take part in the contest by accident.
 *
 * Dropping the `a` is also what lets a non-link wear the colour: the atlas puts
 * the class on a `span.pill` beside each node, and it takes the family hue from
 * the same declaration rather than from a copy of the table.
 */
:root { --link:var(--accent) }
[data-ref^="place:"],  [data-ref^="land:"]         { --link:var(--pin) }
[data-ref^="water:"],  [data-ref^="river:"]        { --link:var(--water) }
[data-ref^="animal:"], [data-ref^="taxon:"]        { --link:var(--flora) }
[data-ref^="person:"], [data-ref^="people:"]       { --link:var(--accent) }
[data-ref^="event:"],  [data-ref^="source:"],
[data-ref^="institution:"], [data-ref^="being:"],
[data-ref^="sky:"]                                 { --link:var(--abstract) }
.ent { color:var(--link); text-decoration:none;
  border-bottom:1px solid color-mix(in srgb,var(--link) 70%,transparent) }
.ent:hover { border-bottom-color:var(--link);
  background:color-mix(in srgb,var(--link) 8%,transparent) }
/* A figure sets as its own block, and floats only when the box it was cut from
   left room beside it for a line of type. `[data-float]` is written into the
   served markup by `edition/_figure.html`, off the box's own `side` — it was set
   by the script once, which meant the picture, its placement and its wrap all
   arrived a frame late or not at all. */
/* **`flow-root` contains the floats**, and it is the fix rather than a tidy-up.
   Without a block formatting context here, a floated figure taller than the
   prose beside it hangs out of the bottom of the article and lands on whatever
   follows — the footnotes, and the prev/next row. `clear` on those would not do
   it: clearing moves a block below a float, and these are floats escaping their
   own container. */
article { display:flow-root }
.figure { margin:1rem 0; cursor:pointer }
.figure[data-float=left]  { float:left;  margin:.3rem 1.2rem .6rem 0; clear:both }
.figure[data-float=right] { float:right; margin:.3rem 0 .6rem 1.2rem; clear:both }
.figure-plates { display:flex; flex-direction:column; gap:.5rem; align-items:center }
.figure-plates img { max-width:100%; height:auto; display:block }
.figure figcaption { font-size:.85rem; color:var(--dim); margin-top:.4rem;
  text-align:center }
/* An unresolved figure says so where the picture would be. It must look like a
   gap rather than a caption, or it reads as part of the book. */
.figure-missing { font-size:.8rem; color:var(--dim); font-style:italic;
  border:1px dashed var(--rule); padding:.6rem; text-align:center }
/* A paragraph after a float must not tuck under it unless it is wrapping. The
   page's own <p> flow does the wrapping; the foot and the headings clear. */
/* A heading must not sit in a float's gutter — it reads as a caption for the
   picture rather than as the head of what follows. `#foot` and `.neighbours`
   belong to the page rather than to the column of prose, and `article`'s
   `flow-root` already keeps floats off them; these clears are the second line of
   defence for a float that starts outside the article. */
#foot, .neighbours, .figure + h3, h3 { clear:both }
/* An exempt page: figures one under the other, or the whole leaf. Both are
   images the reader is meant to look at rather than read past, so they get the
   column's full width and a click through to the file. */
.plates .plate { margin:0 0 2.5rem; cursor:default }
.whole-scan img, .plates img { max-width:100%; height:auto; display:block;
  margin:0 auto; border:1px solid var(--rule) }
/* A leaf a human ruled blank. Still served — the ruling is a claim, and a reader
   who wants to check it against the paper can, at a click, through the same
   lightbox as any other image. What it is not given is the full measure: a blank
   verso rendered at plate size is a screenful of empty paper between two pictures
   somebody was paging through, which reads as the page having failed to load. */
.whole-scan.blank-leaf img { max-width:16rem }
/* A leaf delivered as a Mixed Raster pair: the colour layer sized normally and
   the linework laid exactly over it. The linework is the master's full size and
   the colour a third of it, so the browser upscales the colour — which is the
   whole reason it may be small, smooth colour surviving what lettering would
   not. Only the second image is in flow; the first is positioned onto it, so
   the pair cannot drift apart at any width. */
.leaf-mrc { position:relative; line-height:0 }
/* The linework stays in flow and sizes the block — it is the master's own
   dimensions. The colour layer is positioned onto it and **must be given an
   explicit z-index below it**: a positioned element paints above in-flow
   content by default, so without this the background covers the lines and the
   map renders as a colour smear with no coastlines and no names. */
.leaf-mrc img { position:relative; z-index:1 }
/* `fill` and an explicit box: the linework in flow decides how big the block is,
   and the colour layer takes exactly that box. It is a third the linework's
   pixel size but the same aspect, so filling is exact — anything that sized it
   from its own intrinsic width would put the two layers at different scales. */
.leaf-mrc img:first-child { position:absolute; inset:0; width:100%; height:100%;
  max-width:none; object-fit:fill; z-index:0; border-color:transparent }
/* Every picture's anchor to its original. `contents`, so wrapping a picture in
   one changes no layout: the flex column, the percentage widths and the MRC
   pair's positioning all still see the image as their own child. */
a.pic { display:contents }
/* **A scan prints onto the paper** rather than sitting on it as a white rectangle.
   `--print` is `multiply` in light and `normal` in dark, where multiplying would
   black the leaf out. A Mixed Raster pair blends as one, from its container, so
   its two layers go on composing with each other as above. The lightbox is out of
   this on purpose: it is where a reader goes to see the leaf as it is. */
.figure-plates img, .whole-scan:not(.leaf-mrc) img, .leaf-mrc,
.outline .ol-thumb img, .crop img, .card .crop-fig img {
  mix-blend-mode:var(--print) }
a.pic img { cursor:pointer }
.figure-anchor { color:var(--dim); font-size:.85em; cursor:pointer }
#foot { margin-top:2rem; padding-top:.8rem; border-top:1px solid var(--rule);
  font-size:.85rem; color:var(--dim) }
#foot li { margin-bottom:.3rem; padding: 5px }
/* **The list draws no counter of its own.** Each `<li>` already opens with the
   note's `@n` — the marker the printer actually set — and an `<ol>`'s counter
   printed beside it gave every note its number twice ("1. ¹ Dyachkoff, p. 101.").
   Suppressing `@n` instead would have been the wrong half to drop: the counter is
   this list's position, `@n` is the page's own mark, and the two part company the
   moment a marker does not read or a note's text runs on from the page before. */
#foot li:target { background-color:color-mix(in srgb,var(--sel) 20%,transparent) }
#foot ol { list-style:none; padding-left:0; margin:0 }
/* --- apparatus, hidden in reader view --- */
.flag { font-family:var(--ui); font-size:.7rem; color:var(--mark);
  border:1px solid var(--mark); padding:0 .25em;
  cursor:help; margin:0 .15em; vertical-align:super }
.flag.question { background:color-mix(in srgb,var(--mark) 15%,transparent) }
.unsettled { background:color-mix(in srgb,var(--mark) 12%,transparent);
  border-bottom:1px dashed var(--mark) }
html.reader .flag { display:none }
html.reader .unsettled { background:none; border-bottom-style:solid }
/* --- a page not yet collated ---
   `--sel`, the red line, and deliberately not `--mark`: an inventory flag and an
   unsettled span are marks *within* a collated page, and this says the whole page
   has not had that review. It has to not read as one more of those.
   Reader view keeps it, unlike `.flag` and `.unsettled` above. Those hide because
   reader view is for reading a settled page without the apparatus; this one is
   the statement that the page is not settled at all, and a reader who has hidden
   the apparatus needs it more, not less. */
.draft-tag { font-family:var(--ui); font-size:.85rem; color:var(--sel);
  white-space:nowrap }
.draft-note { font-family:var(--ui); font-size:.9rem; color:var(--dim);
  border-top:1px solid var(--rule); border-bottom:1px solid var(--rule);
  margin:0 0 1rem; padding:.4rem 0 }
#primary p.draft-note { text-indent:0; text-align:left }
/* One pair of rules around two notes in a row, as on a leaf an editor has worked. */
#primary p.draft-note:has(+ p.draft-note) { border-bottom:0; margin-bottom:0 }
.draft-note code { font-size:.9em }
/* --- the stack --- */
.card { background:var(--card); border:1px solid var(--rule);
  padding:.6rem .75rem; margin-bottom:.6rem;
  font-family:var(--ui); font-size:.85rem; line-height:1.5 }
.card.pinned { border-color:var(--pin) }
.card h4 { margin:0 0 .3rem; font-size:.9rem; font-family:inherit }
.card h5 { margin:0 0 .3rem; font-size:.9rem; font-family:inherit }
.card .meta { color:var(--dim); font-size:.75rem; margin-bottom:.4rem }
.card .tools { float:right; display:flex; gap:.25rem }
.card .tools button { padding:.05rem .35rem; font-size:.7rem; line-height:1.4 }
/* No `white-space:pre-wrap`. It was right when the gloss went in as raw text and
   is wrong now that it arrives as paragraphs: the records are hard-wrapped at 79
   columns for editing, and pre-wrap reproduced that wrapping in a panel of a
   completely different width. */
.card table { font-size:.75rem; margin:.4rem 0 0 }
.crop { position:relative; overflow:hidden; width:100%;
  border:1px solid var(--rule); margin-top:.4rem;
  background:var(--card) }
.crop img { position:absolute; max-width:none }
/* An entity's picture. Floated so the gloss wraps it rather than waiting below
   it; the width attribute is the thumbnail's own, capped here, and height:auto
   keeps the ratio the attributes declare. */
.entity-img { float:left; max-width:40%; margin:0 .6rem .4rem 0 }
.entity-img img { display:block; max-width:100%; height:auto }
.entity-img figcaption { font-size:.65rem; line-height:1.3; color:var(--dim);
  margin-top:.2rem }
.card .gloss p { margin:0 0 .4rem }
.card .gloss p:last-child { margin-bottom:0 }
.card .meta a.out { display:inline-flex; align-items:center; gap:.3em;
  text-decoration:none }
.card .meta a.out:hover { text-decoration:underline }
/* Scaled by height with the width left free: the Wikidata mark is 1050x590 and
   a square box would squash it. */
.site { height:1em; width:auto; opacity:.8; flex:none }
/* Something that points at nothing: a wikilink to an absent entity, or an
   authority key `edition/authorities.json` does not hold. The bare class carries
   the span case in `_props.html`; the anchor case needs `a.ent.dangling`
   specifically, because a family rule is `a[data-ref^=…]` and would otherwise
   outrank a lone class and repaint a broken link as a sound one. "This goes
   nowhere" has to beat "this is a place". */
.dangling { color:var(--mark); border-bottom-style:dotted }
a.ent.dangling { --link:var(--mark) }
/* A Tier-1 form. In dark mode `--lex` and `--accent` are both warm and the
   colour alone is thin; the italic and the dotted rule are what actually tell a
   keyed form from an entity link, and they are why that is tolerable. */
a.lex { --link:var(--lex); color:var(--link); text-decoration:none;
  border-bottom:1px dotted var(--link); font-style:italic }
a.lex:hover { border-bottom-style:solid;
  background:color-mix(in srgb,var(--link) 8%,transparent) }
/* `data-ref` here is the entity's *own* id, so "map" takes the colour of the
   thing it maps. That is the point rather than an accident: the control sits on
   the record's own card and reads as part of it. */
a.mapref { --link:var(--accent); color:var(--link); text-decoration:none;
  border-bottom:1px dotted var(--link) }
table.props { font-size:.75rem; margin:.4rem 0; border-collapse:collapse }
table.props th { text-align:right; color:var(--dim); font-weight:400;
  padding:.1rem .5rem .1rem 0; border:none; vertical-align:top;
  white-space:nowrap }
table.props td { border:none; padding:.1rem 0 }
/* The bibliography block a human keyed off the page, on a `source:` card. Set
   apart from the parsed fields around it because `printed` is the record and
   the two are meant to be read against each other, not taken for one thing. */
table.props .printed { font-style:italic }
/* A rank on a value, and it is never quiet. The whole reason the field is on
   the card is that a link a model found and nobody opened must not render like
   one somebody checked. */
.resp { font-size:.7rem; color:var(--mark); font-family:ui-monospace,monospace }
.dim { color:var(--dim) }
/* Opening a `geo:` point on somebody else's map. Set quiet and after the
   coordinate, because the number is the record and these are only ways of
   looking at it — a reader checking whether a point lands on the right headland
   should read the value first and leave second. */
a.maplink { font-size:.7rem; margin-left:.4rem; color:var(--dim);
  text-decoration:none; border-bottom:1px dotted var(--rule) }
a.maplink:hover { color:var(--accent); border-bottom-color:var(--accent) }
h4.tier1 { font-style:italic; font-size:1.1rem }
#empty { color:var(--dim); font-size:.85rem; font-family:var(--ui) }
/* **A label recedes from what it labels, by more than hue.** Beside a name a type
   is smaller, lighter in weight and in neutral ink, while the name is heavier and
   in its family's full colour, so the two part at a glance. A status is the
   exception, since it is news about the entry: it keeps a colour and takes weight. */
.pill { display:inline-block; font-size:.78rem; font-weight:400; color:var(--dim);
  margin-left:.45rem }
.pill.proposed { color:var(--mark); font-weight:700 }
.pill.imputed { font-style:italic }
/* One form read as two languages on two collated pages. `--mark` is the
   apparatus colour and this is apparatus: it says the corpus disagrees with
   itself, which is a finding and not a defect in the card. */
.pill.unsettled { color:var(--mark); font-weight:700 }
/* The lines a Tier-1 form was printed on, from gt/ocr/. `lexicon lookup`'s
   reasoning: a form alone is a string, a form in its line is a sense. Kept
   small and unbulleted — it is evidence under a headword, not a list a reader
   works through. */
ul.lines { list-style:none; margin:.2rem 0 .4rem; padding-left:0;
  font-size:.85rem }
ul.lines li { margin:.1rem 0 }
ul.lines a { font-family:ui-monospace,monospace; font-size:.8rem;
  margin-right:.4rem }
ul.lines mark { margin: 0 .4rem; }
.ipa { display:flex; align-items:center; gap:.45rem; margin:.5rem 0 .3rem }
ul.tree, ul.tree ul { list-style:none; margin:0; padding-left:1.1rem }
ul.tree { padding-left:0; font-family:var(--ui); font-size:1rem }
/* Not `a.lex`: a Tier-1 form stays at its own weight, where its marks read cleanest. */
ul.tree a.ent, .ent-tree a.node { font-weight:600 }
ul.tree li { margin:.15rem 0; border-left:1px solid var(--rule);
  padding-left:.6rem }
ul.tree > li { border-left:none; padding-left:0 }
/* --- a tree of records ---
 *
 * The shape both drawn trees share: the map's legend under the picture
 * (`.map-tree`, whose controls are geomap.css's) and an entry's place in its own
 * class on its card (`.kin-tree`). **One block because they must look like one
 * thing** — they are two hierarchies and a reader is told so by what they say,
 * not by being made to learn two ways of reading a nested list.
 *
 * The node the tree is *about* is the one in full colour; the chain that holds
 * it is dimmed, so what was asked for and what merely contains it read apart at
 * a glance. */
.ent-tree { font-size:.82rem; margin:.4rem 0 .1rem }
/* In the sidebar a tree scrolls in a box of its own, so a long one does not
   push the next card, or the stack under the map, out of reach. */
#secondary .ent-tree { max-height:20ch; overflow-y:auto }
.ent-tree ul { list-style:none; margin:0; padding:0 0 0 .85rem }
.ent-tree > ul { padding-left:0 }
/* The rail is what makes a three-deep chain readable in a narrow pane, where
   indentation alone is a couple of characters. */
.ent-tree ul ul { border-left:1px solid var(--rule) }
.ent-tree li { padding:.08rem 0; line-height:1.5 }
.ent-tree a.node:not([data-ref]) { color:var(--dim); text-decoration:none }
.ent-tree a.node:hover { color:var(--fg); text-decoration:underline }
.ent-tree li.sel > a.node { color:var(--fg); font-weight:bold }
/* The atlas's own tree, marked from the sitting's selection by `map.js`. */
.atlas-tree a.node.sel { color:var(--fg); font-weight:bold }
.ent-tree .dim { font-size:.72rem; margin-left:.25rem }
/* The fold. A count and nothing else — "9 more" says what opening it costs,
   where a bare ▸ makes a reader open it to find out. */
.ent-tree li.more > details > summary { color:var(--dim); cursor:pointer;
  font-size:.76rem; list-style:none }
.ent-tree li.more > details > summary::-webkit-details-marker { display:none }
.ent-tree li.more > details > summary::before { content:'▸ ' }
.ent-tree li.more > details[open] > summary::before { content:'▾ ' }
.ent-tree li.more > details > summary:hover { color:var(--fg) }
.ent-tree li.more > details > ul { padding-left:0; border:0 }
/* The card's tree sits between the fields and the forms, so it needs the rule a
   pane's tree gets from the picture above it. */
.kin-tree { border-top:1px solid var(--rule); padding-top:.35rem;
  margin:.55rem 0 .5rem; clear:both }
/* `clear`, because the card's picture floats: a tree beside a float keeps its
   rule and its rails on boxes that run *under* the picture while its names are
   pushed clear of it, and the two stop lining up. Below the picture it is one
   tree again. */
/* A class heading in the encyclopedia tree. Not a link — there is no page for a
   class, and making one would be a filter pretending to be a place. A class
   nothing is filed under is dimmed rather than dropped. */
ul.tree code.cls { font-family:var(--ui); font-size:1.1rem; font-weight:700; color:var(--fg) }
ul.tree code.cls.empty { color:var(--dim) }
/* The atlas tree's node link. It carries `data-ref` like every other link to a
   record, so it takes its family colour the same way — the tree is the one place
   a reader sees a hundred entity names at once, and the classes are exactly what
   is worth telling apart there.
   **`.node`, not `a.node`, and that was the whole of why the tree was one
   colour.** A family rule is `a[data-ref^="…"]` — an element and an attribute,
   specificity (0,1,1). `a.node` is an element and a class, the same (0,1,1), and
   it sits two hundred lines further down the file, so its `--link` default won
   every tie and every node in the atlas came out in the accent whatever it was.
   It declares no `--link` of its own: the default lives on `:root` now, for the
   reason written out at the family table above. */
.node { color:var(--link); text-decoration:none;
  border-bottom:1px solid transparent }
a.node:hover { border-bottom-color:var(--link) }
.ipa .val { font-family:"Charis SIL","Doulos SIL","Gentium Plus",serif;
  font-size:1.05rem; color:var(--dim) }
button.speak { padding:.1rem .4rem; line-height:1.2 }
button.speak:disabled { opacity:.4; cursor:not-allowed }

/* --- what used to be `style="…"` attributes ----------------------------------
 *
 * Every rule below replaces an inline style that was interpolated into a Python
 * f-string. They are named for what they are rather than what they do, so a
 * second page wanting the same treatment asks for it by name instead of copying
 * a declaration list.
 */
#bar form input{font:inherit;padding:.2rem .4rem;border:1px solid var(--on-board);
                background:var(--card);color:var(--fg)}
/* The scan/reader controls above the card stack. */
#bar2{display:flex;gap:.4rem;margin-bottom:.6rem}
/* Previous/next among *collated* pages — what the reader can actually reach.
   Rendered at both ends of the text; the second copy is the last thing in
   `#primary`, and wants its rule above rather than below. */
.neighbours{display:flex;justify-content:space-between;
            font-family:var(--ui);font-size:.8rem;margin-bottom:1rem}
#primary > .neighbours:last-child{margin:1.5rem 0 0}
.ratify-row{margin-top:.5rem}
/* An exempt page is a picture, not prose — see `exempt.html`. */
#primary.leaf-width{max-width:72rem}
/* Search results carry a line of context either side of the hit and want the room. */
#primary.search-width{max-width:70rem}
.wide{width:100%}
.hits{font-size:.85rem}
.hits td.before{text-align:right}
.note-small{font-family:var(--ui);font-size:.8rem}
/* --- the hover preview ---
 *
 * The same fragment the stack would show, floated for a moment beside the link.
 * It reuses `.card` for its skin and has to undo three things `.card` gets from
 * living in `#secondary`: it takes its width from that column and has none of
 * its own, its `.tools` have nothing to float against, and its pinned/selected
 * borders mean nothing here. A fixed width rather than shrink-to-fit, so a long
 * gloss and a one-line one float the same shape and the preview does not jump
 * about as the pointer crosses a paragraph.
 *
 * It takes the pointer, because its own links are what a reader reaches for;
 * `edition.js` keeps it open across the gap and opens no preview from inside one.
 * It scrolls rather than clipping, for the same reason.
 *
 * Above `#lightbox`, which is `z-index:10` — a preview under an open lightbox
 * would be a card you can see the edge of and nothing else.
 */
.card.preview{position:fixed;z-index:12;width:24rem;max-width:calc(100vw - 2rem);
  max-height:60vh;overflow-y:auto;border-color:var(--fg)}
.card.preview .tools{display:none}
.card.preview.pinned{border-color:var(--fg);
  border-width:1px}
/* A figure's preview is the picture, and a picture that scrolls inside its box
   is a picture you cannot see. So this one drops the 60vh cap and the stack
   card's 24rem crop limit: the box takes whatever room `place` found, and the
   crops scale into what the heading leaves of it, a plate's several sharing it.
   Flex columns down to the image, with `min-height:0` at each step, is what lets
   the crop shrink below its natural height; `object-fit:contain` keeps its
   shape while it does. A picture that fits is at its natural size, since a
   column grows no larger than its content. */
.card.preview.figure{max-height:none;overflow:hidden;display:flex;flex-direction:column}
.card.preview.figure .body{display:flex;flex-direction:column;min-height:0}
.card.preview.figure .crop-fig{flex:1 1 auto;min-height:0;display:flex}
.card.preview.figure .crop-fig img{max-height:none;min-height:0;width:100%}
/* --- the footnote popup ---
 *
 * `.card` for its skin, like the preview, and the same three things undone: no
 * width from `#secondary`, no `.tools` to float, no pinned/selected border.
 * A kept note routinely holds an entity link of its own, so this is a place,
 * and `edition.js` carries the outside-click guard that costs.
 *
 * Narrower than the preview (18rem against 24) because a note is prose set at
 * the text's own size, not a card of labelled rows, and shrink-to-fit up to that
 * width because notes here run from four words to a paragraph — the preview is
 * fixed-width to stop it jumping about as the pointer crosses a line of names,
 * and this one is summoned deliberately at one marker.
 *
 * `z-index` above the preview's 11: the two can be on screen together, since a
 * note holds entity links, and the note is the one that was asked for. */
.card.notepop{position:fixed;z-index:11;width:max-content;max-width:min(26rem,calc(100vw - 2rem));
  max-height:60vh;overflow-y:auto;border-color:var(--fg);
  font-size:.92rem}
.card.notepop .tools{display:none}
.card.notepop .body{padding:.1rem .2rem}
/* The numeral that was the backlink in the foot. Superscript, as the marker in
   the text is, so the popup opens with the same character the sentence carried. */
.card.notepop .note-n{vertical-align:super;font-size:.7em;color:var(--dim);
  margin-right:.25em}
/* **The jump, at the note's own foot under a rule.** The marker above is a
   switch now — it opens the note and closes it — so what it stopped doing has to
   be on offer somewhere, and the place for it is the bottom of the thing you
   have just finished reading. Dashed, because a solid rule here would read as
   part of the note's text; this is the popup's own furniture.

   **Left, with the note's own text.** The popup is `width:max-content`, so its
   right edge moves with the length of the longest line in the note — a row set
   against that edge lands somewhere different for every note, and the reader has
   to look for it each time. The left margin is the one edge every note shares. */
.card.notepop .note-jump{display:block;margin-top:.5rem;padding-top:.4rem;
  border-top:1px dashed var(--rule);font-family:var(--ui);
  font-size:.72rem;text-decoration:none;color:var(--dim)}
.card.notepop .note-jump:hover{color:var(--accent)}
/* The marker while its note is up. Not a colour change — a `.noteref` is seven
   pixels of superscript numeral and a recoloured one is invisible — so the
   ground moves instead. */
.noteref.open{background:var(--accent);color:var(--bg);
  padding:0 .15em}
/* A column: the picture's box takes whatever the bar leaves, so the picture
   centres in the space it can actually be seen in and the bar never covers it. */
#lightbox {width: 100%;height: 100%;background-color: rgba(1, 1, 1, 0.4);position: fixed;z-index: 10;top: 0;
  display:flex; flex-direction:column}
/* Centred, which only started to matter once figures went in here. A page
   raster fills the viewport so left-aligned and centred look the same; a figure
   crop is often a third of the measure wide and sat against the left edge.
   `margin:auto` as well as the flex centring is the standard overflow fix — a
   flex-centred child that is larger than its container cannot be scrolled back
   to its own top-left, and a figure zoomed past the viewport is exactly that. */
/* `hidden`, where this was `auto`. Scrolling *was* the only way to see past the
   edge of a figure larger than the viewport; now the transform is, and a
   scrollbar moving the picture while a drag also moves it doubles every gesture
   and fights the pan. */
#lightbox-image {max-height: 100%;max-width: 100%;overflow: hidden;padding: 2em;
  flex:1; min-height:0; container-type:size;
  display: flex;align-items: center;justify-content: center;}
/* `contain`, never `cover`: cover crops to fill, and a lightbox that quietly
   trims the edges off a figure is showing the reader a different picture. */
#lightbox img {max-height: 100%;max-width: 100%;object-fit: contain;margin: auto;}
/* The zoom transform is on the *wrapper*, so one scale carries both layers of a
   Mixed Raster leaf and they cannot drift apart. */
#lightbox-stack { position:relative; margin:auto; line-height:0;
  transform-origin:50% 50%; will-change:transform }
#lightbox-stack.zoomed { cursor:grab }
#lightbox-image.panning, #lightbox-image.panning #lightbox-stack {
  cursor:grabbing }

/* **The top layer is sized against `#lightbox-image` and not against its
   parent**, and that is the whole of the fix for a pair that would not line up.
   The wrapper shrink-wraps its content, so an image constrained to
   `max-width:100%` *of the wrapper* is asking the parent how big it is while the
   parent is asking the child — circular, and browsers resolve it to the image's
   intrinsic size. Both layers then rendered at their own true widths, 3666 px of
   linework over 1222 px of colour, and the map came apart. Bounding the top
   layer in `cq` units breaks the cycle: the box is a size container, sized by
   the column and not by its content, so the layer gets a real size, the wrapper
   takes it, and the layer below fills that box exactly. The `4em` is the box's
   padding, both sides. */
#lightbox-stack img.top { display:block; margin:0; width:auto; height:auto;
  max-width:calc(100cqw - 4em); max-height:calc(100cqh - 4em);
  object-fit:contain; position:relative; z-index:1 }
/* `fill`, not `contain`: this box was measured from the layer above and the two
   share an aspect ratio, so filling is exact and letterboxing could only
   introduce the offset this is here to prevent. Same stacking rule as the page's
   copy — a positioned element paints above in-flow content, so without the
   explicit order the colour covers the linework. */
#lightbox-stack img.under { position:absolute; inset:0; width:100%; height:100%;
  max-width:none; max-height:none; object-fit:fill; z-index:0; margin:0 }
/* The pointer belongs to the wrapper. A browser's native image-drag starts a
   ghost-drag on `pointerdown` and eats the move events, which is what made
   panning feel like it was fighting back. */
#lightbox-stack img { -webkit-user-drag:none; user-select:none;
  pointer-events:none }

/* --- runs: an apparatus list served whole --- */
/* One list across the span's leaves, set the way the book sets it: title left,
   page number hard right. **No dot leaders.** They are typesetting rather than
   text — the printer's way of carrying the eye across a gap this layout does
   not have — and reproducing them would put marks on the page that are in no
   store. The right edge does the same work. */
.run ul { list-style:none; padding:0; margin:0 }
.run li { display:flex; align-items:baseline; gap:.5rem;
  padding:.1rem 0 .1rem 3.2rem; position:relative }
.run .page-no { margin-left:auto; font-variant-numeric:tabular-nums;
  white-space:nowrap; color:var(--dim) }
.run a.page-no { color:inherit; text-decoration:none;
  border-bottom:1px dotted var(--rule) }
.run a.page-no:hover { border-bottom-color:currentColor }

/* The leaf mark: where the printed page turned, out in the left margin so it
   never interrupts the list. Grey, small, and a **self-link** — a permalink to
   this point in the run, which is what a reader wants from a page break. Its scan
   sits beside it, because a reader consulting a run is at one leaf of it. */
.run .leaf-at { position:absolute; left:0; width:2.6rem; text-align:right;
  font-family:var(--ui); font-size:.75rem; color:var(--dim) }
.run .leaf-mark, .run .leaf-scan { color:inherit; text-decoration:none }
.run .leaf-mark:hover, .run .leaf-scan:hover { color:var(--fg) }
.run .leaf-scan { margin-left:.25em; font-size:.9em }
.run .leaf-at .run-tag { margin-left:.2em; font-size:.95em; color:var(--sel); display: block; }
/* **A selection runs straight through the marks**, so a passage copied across a
   page turn comes out as the sentence, with no `[338] uncollated` inside it. They
   stay links. The same for an inventory flag, which is apparatus and not text. */
.leaf-at, .flag { user-select:none; -webkit-user-select:none }
/* For the instant `edition.js` reads a selection, so a mark leaves no line break. */
html.copying .leaf-at { display:none }
/* --- a chapter: its leaves as one text --- */
/* The page number, Project Gutenberg's way: the mark sits inline exactly where
   the leaf turns, often mid-sentence, and is drawn in the right margin. Absolute
   with no `top`, so it keeps the vertical position of the line it is on — the
   reader sees which line the page turned at without the text being broken. */
.run-chapter { position:relative }
/* The margin the marks hang in is the column's to reserve: with the sidebar open
   beside it, a mark past `#primary`'s own padding is drawn over the sidebar. */
#primary:has(.run-chapter) { padding-right:3rem }
.run-chapter .leaf-at { position:absolute; left:auto; right:-4.2rem;
  width:3.6rem; text-align:left; text-indent:0; font-style:normal;
  font-weight:normal; letter-spacing:0; font-variant:normal }
/* On a phone that reserve was a fifth of the screen and more, for a mark a few
   characters wide. The mark is `[732]` over `uncollated` at most, and that is all
   the margin needs to hold. */
@media (max-width:600px) {
  #primary:has(.run-chapter) { padding-right:2.9rem }
  .run-chapter .leaf-at { right:-2.6rem; width:2.3rem }
  .run-chapter .leaf-scan { display:block }
  /* Set up the margin here, since across it the word is wider than the reserve. */
  .run-chapter .leaf-at .run-tag { writing-mode:vertical-rl; margin:.2em 0 0 }
}
.leaf-exempt { margin:1rem 0 }
.leaf-gap { font-family:var(--ui); font-size:.85rem; color:var(--dim) }
/* The pooled foot: a chapter's notes grouped under the page each was printed
   on, numbered as printed. The page is the group's head and a link back to it. */
#foot .foot-leaf + .foot-leaf { margin-top:.5rem }
#foot .foot-page { font-family:var(--ui); font-size:.75rem;
  color:var(--dim); text-decoration:none }
/* The neighbouring chapter's part of a shared leaf: present, so the page is
   whole, and visibly not this chapter's text. */
.other-chapter { margin:.4rem 0 }
.other-chapter .other-text { opacity:.6 }
.other-chapter:hover .other-text { opacity:.8 }
.other-chapter .other-label { display:block; font-family:var(--ui);
  font-size:.75rem; color:var(--dim) }
/* A leaf the store records nothing on still gets its row, because the anchor
   has to exist for the redirect to land on. It holds the mark and nothing. */
.run li.leaf-only { min-height:1rem }

/* The heading is a link and is drawn as if it were not: a contents page whose
   316 rows are all coloured is a wall, and the number beside each is already
   the visible affordance. The underline on hover is what says it is live. */
.run a.plain { color:inherit; text-decoration:none }
.run a.plain:hover { text-decoration:underline }
/* **The numeral hangs, so the titles line up.** Set inline it pushed each title
   over by its own width — `I.` and `XXIII.` are four characters apart — so the
   one column a contents page is made of was ragged down its whole length. Out in
   a gutter of its own, right-aligned against the text, every title starts at the
   same place whether it is numbered or not. The `li` is already `position:
   relative` for the leaf mark, and this is the next gutter in from it. */
.run .toc li { padding-left:6.9rem }
.run .toc-num { position:absolute; left:2.9rem; width:3.6rem; text-align:right;
  color:var(--dim); font-variant-numeric:tabular-nums }
/* The depths, each a step in from the last. Relative to the title column, not to
   the numeral's, so nesting reads as nesting and the numerals stay one rule.
   **Qualified by `li`**, because the rule above it is: `.run .toc li` carries a
   type selector and outranks a bare `.run .toc-l2`, which flattened all four
   depths to the base indent — the class named the level and the cascade ignored
   it. */
.run .toc li.toc-l2 { padding-left:7.1rem }
.run .toc li.toc-l3 { padding-left:8.3rem }
.run .toc li.toc-l4 { padding-left:9.7rem }

/* **Depth reads as scale, and not as the text's own dress.** Borrowing the page's
   four levels wholesale — the caps, the small caps, the italic — put four
   typefaces in one narrow column and made a contents page look like a ransom
   note. What a reader needs here is only to see which rows are the big divisions,
   and size and weight carry that on their own; the indent is already saying the
   rest. */
.run .toc-l0 { margin-top:.8rem; font-weight:600 }
.run .toc-l1 { margin-top:.9rem; font-size:1.05rem; font-weight:600 }
.run .toc-l2 { margin-top:.35rem }
.run .toc-l3 { font-size:.92rem }
.run .toc-l4 { font-size:.88rem; color:var(--dim); font-style: italic; }

/* --- the Contents in the sidebar ---
   The same class vocabulary over a different question. `.run .toc` sets a
   contents *page*: a numeral gutter at 2.9rem, titles at 6.9rem, four indents
   out to 9.7rem. None of that survives a 20rem column — so this is its own
   scope, not an override, and the two never meet in one document except on the
   Contents run itself, where the page keeps the gutters and the panel does not.
   Small, flush, and quiet: what a locator needs is to be scannable at a glance
   and to stay out of the way of the text it sits beside.

   **The depth is in the nesting, not in a per-level rule.** The panel renders
   the outline as the tree its levels describe, so one indent on `details > ul`
   compounds four times on its own; `.run .toc` needs four hand-set gutters
   because it renders one flat list and has to say in a class what the markup is
   not saying. `.toc-d{n}` is the depth a row is *at*, not the indent it takes —
   the classes are here for weight and colour, and level 0 shares depth 1 with
   the chapters because front matter is a top-level division too. */
#panel-contents { font-family:var(--ui); font-size:.78rem;
  line-height:1.45 }
#panel-contents ul { list-style:none; padding:0; margin:0 }
#panel-contents li { display:block; padding:.05rem 0 }
#panel-contents summary { display:flex; align-items:baseline; gap:.35rem;
  cursor:pointer; padding:.15rem 0 }
#panel-contents summary::marker { color:var(--dim); font-size:.8em }
#panel-contents .toc-d1 > details > summary,
#panel-contents .toc-d1.shut { font-weight:600 }
/* Each rung indented under the triangle of the one above, and once: the markup
   nests, so the step compounds without four rules to say so. */
#panel-contents details > ul { padding-left:1.1rem }
/* A row with no children is a plain `<li>` — a disclosure triangle over nothing
   is a control that does nothing, and the deepest rung is most of the rows. It
   takes the row shape a summary has, plus the indent the missing triangle would
   have given it. */
#panel-contents li:not(:has(> details)) { display:flex; align-items:baseline;
  gap:.35rem; padding-left:1.1rem }
/* **Depth reads as scale**, `.run .toc`'s rule and for its reason: borrowing the
   printed page's caps and small caps would put four typefaces in one narrow
   column. Here it is colour alone, the indent saying the rest. */
#panel-contents .toc-d2 { color:var(--dim) }
#panel-contents .toc-d3, #panel-contents .toc-d4 { color:var(--dim);
  font-size:.95em }
#panel-contents .toc-num { color:var(--dim); font-variant-numeric:tabular-nums }
#panel-contents .toc-title { flex-grow: 1; }
#panel-contents .page-no { margin-left:auto; font-variant-numeric:tabular-nums;
  white-space:nowrap; color:var(--dim); font-size:.9em }
#panel-contents a.plain, #panel-contents a.page-no { color: var(--dim); text-decoration:none; }
#panel-contents .here a.plain, #panel-contents .here a.page-no { color: inherit; }
#panel-contents a.plain:hover, #panel-contents a.page-no:hover
  { text-decoration:underline }
/* **Where you are.** The rule in the margin rather than a fill, so a marked
   chapter reads as a mark and not as a selected row: this panel is not a list
   you are choosing from. `--accent` is the link colour, which is what the rest
   of the edition already uses to mean "the thing you are following".

   **Several rows can carry it at once, and that is the point.** A page that
   prints two section heads is in both of them — 1-249 sets "Animal Food" and
   "Methods of Cooking" — and the containing chain names only the second, because
   a chain holds one entry per level by construction.

   **The rule is the division's alone.** Marks nest, so on every row they stacked a
   fringe per level and pushed each one further in. Below the division, colour and
   weight say it. */
#panel-contents .here { color:var(--fg) }
#panel-contents .toc-d1.here { box-shadow:-.3rem 0 0 -.15rem var(--accent); padding-left:.5em }
#panel-contents .here > details > summary, #panel-contents .here > .toc-title
  { font-weight:600 }
/* A mention count. Beside the title and before the folio, because it belongs to
   the heading and not to the page the heading starts on. */
#panel-contents .hits { font-size:.85em;  background-color: var(--rule); color:var(--fg);
                        font-variant-numeric:tabular-nums; padding: 1px 3px; }
#panel-contents .panel-note { margin:.6rem 0 0; font-size:.95em }

/* The illustration numbers hang the same way, but as an indent rather than a
   fixed gutter: `Fig. 12.` and `Figs. 214, 215, 216.` are three times apart, so a
   column wide enough for the longest would strand the 300 that are not. The
   caption block is flush and wraps flush; a long number pushes its own first line
   and nothing else. */
.run .loi-title { padding-left:5.4rem; text-indent:-5.4rem }
.run .loi-n { color:var(--dim) }
.run .loi-plate .loi-n { font-variant:small-caps; letter-spacing:.02em }
.run .authority { align-items:flex-start; padding-top:.5rem }
.run .authority-body { flex:1 }
/* Printed first and parsed under it, in that order and at that weight: the
   printed block is the record and the parsed fields are a reading of it. */
.run .printed { margin:0 }
.run .parsed { margin:.1rem 0 0; font-size:.8rem; color:var(--dim) }
.run-tag, .leaf-tag { font-family:var(--ui); font-size:.85rem; color:var(--dim) }

/* --- the outline, on the index ---
   The Contents' vocabulary (`.toc-title`, `.toc-num`, `.page-no`) over a third
   question: what is in the book, in the binding's order. A division's row is
   the weight `.run .toc-l1` gives a chapter; its sections nest under it and
   indent once per rung, the panel's way, since the markup nests. The leaves
   between chapters are pictures, since a store that only says `cover` has nothing
   else to show: the covers small and wrapping, the map larger. */
.index-head { text-align:center; margin:1rem 0 1.5rem }
.index-head h1 { margin:0; font-size:2.75rem; line-height:1.1; font-weight:normal }
#primary .index-head p { margin:.5rem 0 0; text-indent:0; text-align:center; color:var(--dim) }
.outline { list-style:none; margin:0; padding:0 }
.outline > li { margin:.3rem 0; line-height:1.5; display:flow-root }
.outline .ol-part { margin-top:1.6rem }
.outline .ol-part:first-child { margin-top:.4rem }
.outline .ol-part h4 { margin:0 0 .3rem; font-size:1rem; letter-spacing:.08em;
  color:var(--dim); border-bottom:1px solid var(--rule);
  padding-bottom:.15rem }
.outline .ol-toc { margin-top:.9rem }
.outline .ol-run > .toc-title, .outline .ol-toc > .toc-title,
.outline .ol-page > .toc-title, .outline .ol-leaf > .toc-title {
  font-size:1.05rem; font-weight:600; text-decoration:none; color:inherit }
.outline > li > a.toc-title:hover { text-decoration:underline }
.outline .toc-num { color:var(--dim); font-variant-numeric:tabular-nums }
.outline .ref { font-family:var(--ui); font-size:.75rem;
  color:var(--dim); text-decoration:none; margin-left:.4rem;
  font-variant-numeric:tabular-nums }
.outline .ref:hover { color:var(--fg); text-decoration:underline }
.outline .ol-leaf, .outline .ol-page { margin:.1rem 0 }
/* The scan and any folio float as one, so a row reads title, tags, number; a row
   of two pages stacks two of them. */
.outline .ol-at { float:right; clear:right; margin-left:.6rem; white-space:nowrap }
.outline .ol-at .page-no { float:none; display:inline-block; min-width:2em;
  margin-left:.4rem; text-align:right }
.outline .ol-covers { display:flex; flex-wrap:wrap; align-items:flex-end;
  gap:.4rem; margin:.5rem 0 }
.outline .ol-thumb { display:block; position:relative; text-decoration:none }
.outline .ol-thumb img { display:block; border:1px solid var(--rule) }
.outline .ol-thumb-cover { width:fit-content }
.outline .ol-thumb-cover img { width:50px; height:auto }
.outline .ol-thumb-map { width:min(22rem,100%); margin:.4rem auto .8rem; clear:both }
.outline .ol-thumb-map img { width:100%; height:auto }
/* The scan number sits on the picture: a strip of the page's own background, so it
   reads over a printed title as over a blank. */
.outline .ol-covers .ref { position:absolute; top:1px; left:1px; margin:0;
  padding:0 .15em; font-size:.6rem; line-height:1.3; color:var(--fg);
  background:var(--bg) }
/* --- the modal: whatever a `data-modal` link names --- */
#modal { width:min(60rem, calc(100vw - 2rem)); max-height:calc(100dvh - 3rem);
  padding:0; border:1px solid var(--fg); background:var(--bg);
  color:var(--fg) }
#modal::backdrop { background:rgba(1,1,1,.4) }
#modal .modal-close { position:sticky; top:.5rem; float:right; margin:.5rem .5rem 0 0;
  font-size:1.1rem; line-height:1; padding:.2rem .45rem; cursor:pointer }
#modal .modal-body { padding:.8rem 1.2rem 1.2rem }
#modal .modal-body h3 { margin-top:0 }
.outline .draft-tag { margin-left:.4rem }
.outline .leaf-tag { margin-left:.4rem }
.outline .ol-leaf > .leaf-tag:first-child { margin-left:0 }
/* **The folio floats right, on every row that has one**, set as the Contents
   run sets it: dim, tabular, a dotted rule under the live ones. A row is a
   block and not a flex line so the float works the same at every depth and
   the nested list under a section row can follow it in the flow. */
.outline .page-no { float:right; clear:right; margin-left:.6rem; color:var(--dim);
  font-variant-numeric:tabular-nums; white-space:nowrap; font-size:.9em;
  text-decoration:none }
.outline a.page-no { border-bottom:1px dotted var(--rule) }
.outline a.page-no:hover { color:var(--fg); border-bottom-color:currentColor }
.outline .sections { list-style:none; margin:.15rem 0 0; padding-left:1.4rem;
  font-size:.92rem; clear:right }
.outline .sections .sections { padding-left:1.1rem }
.outline .sections li { padding:.05rem 0 }
.outline .sections .sections li { font-size:.95em }
.outline .sections .toc-d3, .outline .sections .toc-d4 { color:var(--dim) }
.outline .sections .toc-d4 { font-style:italic }
.outline .sections a.plain { color:inherit; text-decoration:none }
.outline .sections a.plain:hover { text-decoration:underline }
.tier1-note { font-family:var(--ui); font-size:.7rem;
  color:var(--dim); border-bottom:1px dotted currentColor; cursor:help }

/* --- the alphabet chart --- */
/* The grids keep the print's own geometry: fixed columns, empty cells left
   empty. **The columns are unlabelled in the source and stay unlabelled here** —
   naming them stop/affricate/fricative/nasal would put an analysis on the page
   that Bogoras did not write. */
.run-alphabet .alpha-leaf { position:relative; height:1.2rem }
.alpha-grid { border-collapse:collapse; margin:.4rem 0 .6rem;
  table-layout:fixed }
.alpha-grid th { text-align:right; font-weight:400; color:var(--dim);
  font-family:var(--ui); font-size:.8rem; padding-right:.6rem;
  white-space:nowrap }
.alpha-grid td { padding:.15rem .5rem; text-align:center; min-width:2.6rem }
.alpha-grid .sort { font-size:1.15rem; text-decoration:none; color:inherit }
.alpha-grid .sort:hover { text-decoration:underline }
/* The imputed value under each glyph, small: the grid is for finding a sort,
   and the value is what you came for once you have. */
.alpha-grid .cell-ipa { display:block; font-size:.7rem; color:var(--dim) }
.grid-note { font-size:.85rem; color:var(--dim); margin:.2rem 0 1.2rem;
  max-width:46rem }

.alpha-sorts { border-collapse:collapse; width:100%; font-size:.9rem }
.alpha-sorts th { text-align:left; font-weight:400; color:var(--dim);
  font-family:var(--ui); font-size:.9rem;
  border-bottom:1px solid var(--rule); padding:.2rem .5rem }
.alpha-sorts td { padding:.3rem .5rem; vertical-align:top;
  border-bottom:1px solid var(--rule) }
/* Sort over codepoint: one identity, read as one, and the codepoint one line
   per part — `c + U+030C + U+02D9` is a base and two marks, and the sorts that
   look alike are exactly the ones differing by one of them. */
.alpha-sorts .sort-cell { text-align:center; white-space:nowrap; width:7rem }
.alpha-sorts .sort-cell .sort { font-size:1.4rem; display:block;
  line-height:1.3 }
.alpha-sorts .code { color:var(--dim); font-size:.7rem; white-space:nowrap;
  font-family:ui-monospace,monospace; display:block; line-height:1.35 }
/* Imputed over modern: one question, two witnesses, stacked so the
   disagreement is where the reader meets it rather than a column away. The
   brackets carry the difference — `[…]` is Bogoras's account of his own
   notation, `/…/` a current description of the language.
   **No `nowrap` on the cell**: the modern note is a sentence, and holding the
   whole cell on one line made this the widest column on the page. */
.alpha-sorts .value { text-align:center; width:11rem }
.alpha-sorts .v-imputed, .alpha-sorts .v-modern { display:block;
  white-space:nowrap; font-size:1.1rem; line-height:1.35 }
.alpha-sorts .v-modern { color:var(--dim) }
.alpha-sorts .m-note { display:block; white-space:normal; text-align:left;
  font-size:.72rem; line-height:1.3; margin-top:.2rem }
.alpha-sorts .num { text-align:center; font-variant-numeric:tabular-nums;
  color:var(--dim); width:4rem }
.alpha-sorts th.c { text-align:center }
.alpha-sorts .g { display:block }
/* Which printed key a gloss comes from, on every gloss. The two accounts are
   not one notation — p. 10 has nine sorts Mythology lacks — so an unattributed
   gloss would be a claim about both. */
.alpha-sorts .g-key { font-family:var(--ui); font-size:.8rem; color:var(--dim);
  margin-right:.3em }
.alpha-sorts .g-shared, .alpha-sorts .g-note, .alpha-sorts .m-note {
  color:var(--dim); font-size:.8em }
.alpha-sorts .g-note, .alpha-sorts .m-note { display:block }
.alpha-sorts .ipa-val { font-size:1.05em }
/* A hedge and an absence are different states and are drawn differently: `~ x`
   is a second value the source offered, `—` is no value at all. Collapsing
   them would let "unsettled" read as "settled on the first". */
.alpha-sorts .hedge { color:var(--dim); margin-left:.4em; font-size:.85em }
.alpha-sorts .none { color:var(--dim); cursor:help }
.alpha-notes { max-width:46rem; font-size:.9rem; padding-left:0;
  list-style:none }
.alpha-notes li { margin:.4rem 0 }

.run .loi-title { flex:1 }

/* A figure inside a stack card. `contain` and a height cap so a tall plate and
   a wide one both fit the column without the card growing past the viewport. */
.card .crop-fig { margin:.3rem 0 }
.card .crop-fig img { width:100%; max-height:24rem; object-fit:contain;
  background:var(--card) }
/* "Opp." on a plate's page number: the print's own word for it, and the whole
   difference between the page a plate is on and the page it faces. */
.run .page-no .opp { font-family:var(--ui) }
/* The lightbox's own foot: what this picture is, a way to the file itself, and
   the arrows when there is more than one. **In the column, under the picture,
   never over it**: laid over the backdrop it cost no height but sat on the
   foot of every picture tall enough to reach it.
   Two lines: what the picture is, then how to move between them. The caption is
   the thing being read and the controls are furniture, so they do not share a
   line and compete for the middle of it. */
#lightbox-bar { flex:none; position:relative; z-index:11;
  display:flex; flex-direction:column; gap:.35rem; align-items:center;
  padding:.5rem .9rem; font-family:var(--ui); font-size:.85rem;
  background:color-mix(in srgb, #000 55%, transparent); color:#f2efe9 }
#lightbox-bar .nav { display:flex; gap:.6rem; align-items:center }
#lightbox-bar a { color:inherit; text-decoration:none;
  border-bottom:1px dotted currentColor; max-width:60vw;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
#lightbox-bar a:hover { border-bottom-style:solid }
#lightbox-bar .count { font-variant-numeric:tabular-nums; opacity:.75 }
#lightbox-bar button { background:transparent; color:inherit;
  border-color:color-mix(in srgb, #fff 35%, transparent);
  font-size:1.1rem; line-height:1; padding:.1rem .5rem }
#lightbox-bar button:hover { border-color:#f2efe9 }

/* A cross-reference in the prose: `(Plate XXVII, Fig. 3)`, `Fig. 87`.

   **Only the numeral is the link**, never the `Fig.` in front of it — the word
   is the printer's furniture and one run can name three pictures, so `Figs.
   214, 215, 216` is three targets and underlining the phrase would make it look
   like one. Quiet by default: a page of prose carries a dozen of these and
   colouring them all turns a paragraph into a link farm, so they read as text
   until the cursor is on one.

   An unresolved reference is not a link at all and is left as plain text. It
   still carries its reason as a title, which is how a reader finds out that a
   plate's figure has no box in `gt/fig/` rather than assuming the edition
   simply does not link. */
a.figref { color:inherit; text-decoration:none;
  border-bottom:1px dotted var(--dim); cursor:pointer }
a.figref:hover, a.figref:focus { color:var(--link); border-bottom-color:var(--link) }
a.figref.unresolved { border-bottom-style:none; cursor:help; color:inherit }
.reader a.figref.unresolved { cursor:default }

/* A page or chapter cross-reference — `See p. 15.`, `See Chapter XII.` — set like
   a figure reference, because it is the same act: the book pointing at itself,
   over the numeral or the roman the printer set and nothing more. Two classes
   and one rule: they are drawn identically and a reader has no use for the
   difference, but the markup still says which kind it is rather than calling a
   chapter a page.

   Neither carries an `unresolved` state, and that is a real difference from
   `a.figref` rather than an omission: a figure handle is a join over `gt/fig/`
   that can come back empty, and a folio is an address that always leads
   somewhere — to the leaf, or to the route's own page saying which folios have a
   witness yet. */
a.pageref, a.chapref { color:inherit; text-decoration:none;
  border-bottom:1px dotted var(--dim); cursor:pointer }
a.pageref:hover, a.pageref:focus,
a.chapref:hover, a.chapref:focus { color:var(--link); border-bottom-color:var(--link) }

/* The editor's own blocks. Two classes, and they are deliberately not
   symmetrical: a notice interrupts and a supplement offers. Both are set between
   rules, a heavy one above and a hairline below, in their own colour with the
   heading to match: enough to read as *not* the text without a filled box
   competing with the page.

   `.unplaced` is the refusal, not an annotation — dashed rather than solid,
   because what it says is that something is *missing* from this page. */
aside.ann { margin:1.2rem 0; padding:.6rem 0;
  font-size:.94em }
aside.ann h5 { margin:0 0 .35rem; font-size:1.4em; font-weight:bold; text-align: center }
aside.ann h5 a { color: var(--fg); text-decoration:none; border-bottom:1px solid var(--dim) }
aside.ann h5 a:hover { border-bottom-color:var(--link); color:var(--link) }
aside.ann .summary p:first-child { margin-top:0 }
aside.ann .summary p:last-child { margin-bottom:0 }
aside.ann.notice { border-top:3px solid var(--warn); border-bottom:1px solid var(--warn) }
aside.ann.notice h5, aside.ann.notice h5 a { color:var(--warn) }
aside.ann.supplement { border-top:3px solid var(--info); border-bottom:1px solid var(--info) }
aside.ann.supplement h5, aside.ann.supplement h5 a { color:var(--info) }
aside.ann ul.shelf { margin:.5rem 0 0; padding-left:1.1rem }
aside.ann ul.shelf .note { color:var(--dim) }
aside.ann p.more { margin:.45rem 0 0; font-size:.92em }
aside.ann.unplaced { border-left:3px dashed var(--dim); padding-left:.9rem;
  color:var(--dim); font-style:italic }

/* A YouTube link, and the card it opens. Marked like an outbound link because
   that is what it is by `href` — the difference is only where it lands, and a
   reader who middle-clicks still leaves for YouTube. */
a.yt { color:var(--link); text-decoration:none;
  border-bottom:1px dotted var(--link); cursor:pointer }
a.yt::after { content:' ▸'; font-size:.85em; opacity:.7 }
a.yt:hover, a.yt:focus { border-bottom-style:solid }
/* 16:9, held by the padding trick so the player sizes to the card's width
   whatever the stack is set to. */
.card .embed { position:relative; width:100%; padding-bottom:56.25%;
  margin:.4rem 0 0; background:#000; overflow:hidden }
.card .embed iframe { position:absolute; inset:0; width:100%; height:100%;
  border:0 }
