/* =========================================================================
   epistel — visual direction "Eckersberg"
   Golden Age light as the painters saw it: dusty Prussian blue, sea-green,
   warm plaster, a gilt frame-line. A modern museum presenting old letters.

   This is design/varianter/eckersberg/ as shipped. Every colour below was
   chosen against a measured contrast ratio, recorded in the comment beside
   it: change a value and the pair it belongs to has to be re-measured.

   FONTS
   -----
   Two OFL families, self-hosted as woff2 in assets/fonts -- no CDN, no
   external request at runtime (build brief, rule 2). Sources, versions and
   licences: static/fonts/README.md.
     · display  -> Playfair Display   (Didone; stands in for Didot / Bodoni 72)
     · body     -> Spectral           (warm transitional, generous x-height;
                                       stands in for Palatino / Hoefler Text)
     · labels   -> the reader's own sans. The museum-label micro-type is
                   small and sparse; a third webfont would cost more than it
                   would add.
   The system stacks stay in the font-family lists as real fallbacks behind
   the webfonts: the site must remain readable with zero webfonts loaded.

   DARK MODE  (sketched, not implemented -- a later slice owns it)
   ---------------------------------------------------------------
   The direction inverts rather than dims. Ground becomes a low-chroma
   Prussian night (--ground #141a1e, --paper #1b2226, --ink #e9e5d9); the two
   deep blocks stop being "dark on light" and become *raised* surfaces
   (--prussian #35566a, --seagreen #44604f) so the header band and the museum
   label still read as objects placed on a wall. Gilt lifts to #d8b869 for
   the frame lines (it must not sit at #b08d3e on a dark ground — it goes
   muddy). The pb chips keep the two-series split by hue but swap solid tints
   for 14% alpha washes with the text at #a8c6d6 / #dcbe83. Everything else
   is a token swap; no layout changes.
   ========================================================================= */

/* ---------------------------------------------------------------- fonts
   Subsetted to the "latin" range, which covers Danish (æ ø å Æ Ø Å) and the
   corpus' punctuation. Three characters in b1 -- ɔ (U+0254), Ψ (U+03A8) and
   ℳ (U+2133), eight occurrences in one letter -- fall outside it and are
   drawn by the reader's fallback serif; a whole extra subset for eight
   glyphs is not a trade the reader benefits from.

   Only the four faces the stylesheet actually asks for are vendored:
   Playfair 400 for the display line, Spectral 400 / 400 italic / 600 for
   reading text, editorial asides and the two emphasised runs.

   font-display: swap -- the text is the point, and it must never wait for
   the type to arrive.                                                     */

@font-face {
  font-family: "Playfair Display";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/playfair-display-latin-400-normal.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Spectral";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/spectral-latin-400-normal.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Spectral";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/spectral-latin-400-italic.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Spectral";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(fonts/spectral-latin-600-normal.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* --- surfaces ------------------------------------------------------- */
  --ground:      #f6f3ec;   /* warm plaster wall the whole site hangs on   */
  --paper:       #fdfcf9;   /* the letter's own quiet ground               */
  --plaster:     #ece6d9;   /* tinted field, warm                          */
  --sea-tint:    #e7ece7;   /* tinted field, cool                          */
  --hover:       #f7f4ec;

  /* --- deep blocks (the colour blocking) ------------------------------ */
  --prussian:    #2e4a5a;   /* site-header band; link colour on light      */
  --seagreen:    #3b4f45;   /* the museum-label card                       */

  /* --- ink ------------------------------------------------------------ */
  --ink:         #20211d;   /* 14.61:1 on ground, 15.79:1 on paper         */
  --ink-soft:    #454840;   /*  8.41:1 on ground                           */
  --muted:       #575a51;   /*  6.35:1 on ground, 5.65:1 on plaster        */

  /* --- gilt: two values, because gold does not pass AA as type --------- */
  --gilt:        #b08d3e;   /*  2.82:1 — RULES AND FRAMES ONLY, never text */
  --gilt-text:   #7a5b18;   /*  5.68:1 on ground — the same accent, as type*/
  --gilt-light:  #c9a856;   /*  4.11:1 on prussian, 3.86:1 on seagreen     */

  /* --- type on deep grounds ------------------------------------------- */
  --on-deep:     #f2efe4;   /*  8.29:1 on prussian, 7.63:1 on seagreen     */
  --on-blue-mut: #b7c8d0;   /*  5.43:1 on prussian                         */
  --on-deep-mut: #b7c6ba;   /*  4.94:1 on seagreen                         */
  --on-deep-acc: #e6dfcb;   /*  6.60:1 on seagreen                         */

  /* --- hairlines (decorative; carry no information on their own) ------- */
  --rule:        #ded7c6;
  --rule-warm:   #d8cdb4;
  --rule-cool:   #d3ddd4;
  --rule-faint:  #eae5d9;

  /* --- type ----------------------------------------------------------- */
  --display: "Playfair Display", "Didot", "Bodoni 72", "Hoefler Text", Georgia, serif;
  --body:    "Spectral", "Palatino", "Palatino Linotype", "Book Antiqua", "Hoefler Text", Georgia, serif;
  --label:   -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;

  /* --- measure -------------------------------------------------------- */
  --shell:   46rem;                          /* outer column, incl. gutter */
  --gutter:  clamp(1.15rem, 4vw, 2.5rem);
}

/* ---------------------------------------------------------------- base */

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

/* `hidden` has to win. Several rules below set `display` on elements the
   filter hides (a letter entry is a grid, a section is a block), and an
   author rule beats the browser's own [hidden] rule no matter what it says.
   Without this line the filter would hide nothing at all.               */
[hidden] { display: none !important; }

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--body);
  font-size: 1.0625rem;      /* 17px — Spectral, like Palatino, wants it   */
  line-height: 1.72;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

/* One shared column: header band, main and footer band all align on it.  */
.site-header > p,
.site-header > nav,
.site-footer > p,
main {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

main { padding-bottom: 4.5rem; }

a { color: var(--prussian); }

/* Focus: a Prussian ring on light ground (8.45:1), a bone ring on the deep
   blocks (8.07 / 7.63:1). Both far past the 3:1 floor for UI indicators.   */
a:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--prussian);
  outline-offset: 3px;
  border-radius: 1px;
}
.site-header a:focus-visible,
.letter > header .letter-meta a:focus-visible {
  outline-color: var(--on-deep);
}
a:focus { outline: 2px solid var(--prussian); outline-offset: 3px; }
a:focus:not(:focus-visible) { outline: none; }

.skip-link {
  position: absolute;
  left: -100vw;
  top: 0;
}
.skip-link:focus {
  position: static;
  display: block;
  padding: 0.7rem var(--gutter);
  background: var(--gilt-text);
  color: #fff;                          /* 6.05:1 */
  font-family: var(--label);
  font-size: 0.85rem;
  letter-spacing: 0.04em;
  text-decoration: none;
  outline: none;
}

/* -------------------------------------------------------- header band */

.site-header {
  background: var(--prussian);
  color: var(--on-deep);
  border-bottom: 2px solid var(--gilt-light);   /* the gallery frame edge */
  padding: 1.5rem 0 1.35rem;
}

.site-title {
  margin: 0;
  font-family: var(--display);
  font-size: 1.6rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  line-height: 1.1;
}
.site-title a {
  color: var(--on-deep);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.site-title a:hover { border-bottom-color: var(--gilt-light); }

.site-tagline {
  margin: 0.5rem 0 0;
  font-family: var(--label);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--on-blue-mut);
}

/* Two destinations, set as gallery-room labels under the wordmark. The
   current one is marked with a gilt rule as well as with aria-current, so it
   does not rely on the reader telling two shades of bone apart.
   on-deep 8.13:1 on prussian, on-blue-mut 5.43:1, gilt-light rule 4.11:1.  */
.site-nav {
  display: flex;
  gap: 1.6rem;
  margin: 0.9rem 0 0;
}
.site-nav a {
  padding-bottom: 0.2rem;
  border-bottom: 2px solid transparent;
  color: var(--on-blue-mut);
  font-family: var(--label);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
}
.site-nav a:hover { color: var(--on-deep); border-bottom-color: var(--gilt-light); }
.site-nav a[aria-current="page"] {
  color: var(--on-deep);
  border-bottom-color: var(--gilt-light);
}

/* -------------------------------------------------------- footer band */

.site-footer {
  margin-top: 4.5rem;
  background: var(--plaster);
  border-top: 1px solid var(--rule-warm);
  padding: 2rem 0 2.5rem;
}
.site-footer p {
  margin-block: 0;   /* not the shorthand: it would reset the shared
                        column's margin-inline: auto and pin the text
                        to the left edge (SharedColumnTest) */
  font-size: 0.84rem;
  line-height: 1.68;
  color: var(--muted);                  /* 5.65:1 on plaster */
}
.site-footer a { color: var(--gilt-text); }   /* 5.06:1 on plaster */

/* ------------------------------------------------------------ display */

h1 {
  position: relative;
  margin: 2.9rem 0 0;
  padding-top: 1.5rem;
  font-family: var(--display);
  font-size: clamp(2.5rem, 7vw, 3.7rem);
  font-weight: 400;
  line-height: 1.04;
  letter-spacing: -0.005em;
  color: var(--ink);
}
h1::before {                       /* the gilt tick: one accent, top left */
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 3.25rem;
  height: 3px;
  background: var(--gilt);
}

.lead {
  max-width: 34rem;
  margin: 1.35rem 0 0;
  font-size: 1.12rem;
  line-height: 1.66;
  color: var(--ink-soft);            /* 8.41:1 */
}
.lead strong { font-weight: 600; color: var(--ink); }

/* ================================================================ INDEX
   Two levels of order, both the edition's own: the volume a letter was
   printed in, and the correspondence it belongs to. A volume is a room —
   named on the wall by its own rule and label — and each correspondence
   inside it is hung as its own section of gallery wall: a tinted heading
   band above a clean run of entry rows.

   The band design is unchanged from the one-volume build; only its heading
   level moved (h2 -> h3) to make room for the volume above it.          */

/* --- the finder: filter and search ------------------------------------
   A plaster band under the intro, cut from the same cloth as the volume
   jump list below it — same tint, same gilt top rule, same micro-caps
   labels — so it reads as part of the wall and not as an app bolted on.

   It is in the markup with `hidden` on it and only appears when the
   script runs (see static/search.js). A reader without JavaScript gets
   the complete list, which is the page, and no control that lies.

   Contrast: labels --muted on --plaster 5.65:1; field text --ink on
   --paper 15.79:1; the status line --ink-soft on --plaster 7.49:1;
   the empty-state --gilt-text on --ground 5.68:1.                      */

.finder {
  margin: 2.6rem 0 0;
  padding: 1.3rem 1.5rem 1.15rem;
  background: var(--plaster);
  border-top: 2px solid var(--gilt);
  border-bottom: 1px solid var(--rule-warm);
}

.finder-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.9rem 1.4rem;
}
.finder-field--query { grid-column: 1 / -1; }

.finder-field label {
  display: block;
  margin-bottom: 0.3rem;
  font-family: var(--label);
  font-size: 0.61rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--muted);
}

.finder-field input,
.finder-field select {
  width: 100%;
  padding: 0.5rem 0.6rem;
  background: var(--paper);
  border: 1px solid var(--rule-warm);
  border-radius: 0;
  color: var(--ink);
  font-family: var(--body);
  font-size: 0.98rem;
  line-height: 1.4;
}
.finder-field input { font-size: 1.02rem; }
.finder-field input::placeholder {
  color: var(--muted);                /* 6.85:1 on paper */
  font-style: italic;
  opacity: 1;
}
.finder-field input:focus-visible,
.finder-field select:focus-visible {
  outline: 2px solid var(--prussian);
  outline-offset: 2px;
}

/* Preserve uncertainty, at the control this time: a year filter has to put
   every letter in exactly one year, and the edition does not always give
   one. The rule it was filed by is written here rather than left for the
   reader to trip over. Gilt italic, the site's editorial register.       */
.finder-note {
  grid-column: 1 / -1;
  margin: 0.4rem 0 0;
  font-size: 0.79rem;
  font-style: italic;
  line-height: 1.45;
  color: var(--gilt-text);            /* 5.06:1 on plaster */
}

.finder-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem 1.2rem;
  margin-top: 1rem;
}
.finder-status {
  margin: 0;
  font-family: var(--label);
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}
.finder-count { font-weight: 600; }
.finder-terms { color: var(--muted); }

.finder-reset {
  padding: 0.4rem 0.9rem;
  background: transparent;
  border: 1px solid var(--gilt);
  color: var(--gilt-text);            /* 5.06:1 on plaster */
  font-family: var(--label);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
}
.finder-reset:hover { background: rgba(176, 141, 62, 0.12); }
.finder-reset:focus-visible {
  outline: 2px solid var(--prussian);
  outline-offset: 2px;
}

.finder-empty {
  margin: 2.6rem 0 0;
  padding: 1.1rem 1.5rem;
  border: 1px dashed var(--gilt);
  font-style: italic;
  color: var(--gilt-text);
}

/* --- the volume: a room, announced ----------------------------------- */

.volume-nav {
  margin: 2.6rem 0 0;
  padding: 1.25rem 1.5rem 1.35rem;
  background: var(--plaster);
  border-top: 2px solid var(--gilt);
  border-bottom: 1px solid var(--rule-warm);
}
.volume-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr));
  gap: 0.15rem 1.5rem;
}
.volume-list li { line-height: 1.5; }
.volume-list a {
  display: block;
  padding: 0.18rem 0;
  font-size: 0.92rem;
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.volume-list a:hover { border-bottom-color: var(--gilt); }
.volume-list b {
  font-family: var(--label);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--gilt-text);            /* 5.06:1 on plaster */
}

.volume { margin-top: 4.2rem; }

.volume-head {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 0 1rem;
  padding-bottom: 0.7rem;
  border-bottom: 2px solid var(--gilt);
}
.volume-head h2 {
  grid-column: 1;
  margin: 0;
  font-family: var(--display);
  font-size: clamp(1.75rem, 4.5vw, 2.15rem);
  font-weight: 400;
  line-height: 1.12;
}
.volume-head h2 b {
  display: block;
  margin-bottom: 0.25rem;
  font-family: var(--label);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gilt-text);            /* 5.68:1 on ground */
}
.volume-head .volume-count {
  grid-column: 2;
  margin: 0;
  font-family: var(--label);
  font-size: 0.68rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

.correspondence {
  margin-top: 3rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--gilt);
}
/* Inside a volume the first correspondence sits close under the volume
   rule; the gap belongs between groups, not above the first one.       */
.volume-head + .correspondence { margin-top: 1.7rem; }

.group-head {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: start;
  gap: 0 1rem;
  padding: 1.15rem 1.5rem 1.1rem;
  background: var(--plaster);
  border-bottom: 1px solid var(--rule-warm);
}
/* Two tints, alternating, so eight sections read as rhythm and not repeat. */
.correspondence:nth-of-type(even) .group-head {
  background: var(--sea-tint);
  border-bottom-color: var(--rule-cool);
}

.group-head h3 {
  grid-column: 1;
  margin: 0;
  font-family: var(--display);
  font-size: 1.55rem;
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: 0.005em;
}
.group-head .group-note {
  grid-column: 1;
  margin: 0.3rem 0 0;
  font-size: 0.93rem;
  font-style: italic;
  color: var(--muted);               /* 5.65 / 5.88:1 on the two tints */
}
.group-head .group-count {
  grid-column: 2;
  grid-row: 1;
  justify-self: end;
  margin: 0.2rem 0 0;
  padding: 0.2rem 0.55rem;
  border: 1px solid rgba(176, 141, 62, 0.55);
  background: rgba(253, 252, 249, 0.55);
  font-family: var(--label);
  font-size: 0.66rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

/* One row style for every list on the site (Maria, 2026-07-28): the
   index's FRA/TIL/DATERET grid gave way to the shared .sibling-link
   rows -- title · date, the pair line, the resumé. The li keeps only
   the search's data attributes and the list its quiet padding.        */
.letter-list {
  list-style: none;
  margin: 0;
  padding: 0.75rem 0.85rem 1rem;
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.25rem;
}
.letter-entry { padding: 0; }

/* --- the presenter's resumé -------------------------------------------
   The only voice on the site that is neither the edition's nor the letter
   writer's, so it is marked as one and marked the same way every time: a
   gilt frame-line down its left side — the accent this design uses for
   everything editorial — and the body face in italic, which is how a
   person speaks in a room full of documents. No tint, no box, no label:
   at 333 repetitions anything heavier would take over the page.

   One rule for every list that carries her — the index, a letter's
   "Samme brevveksling", a person's three lists (Maria's decision,
   2026-07-28) — so she is recognisably the same person everywhere.
   Ink is --ink-soft: 9.08:1 on the paper ground, 8.48:1 on the hover
   tint, 8.41:1 on the site ground.                                      */
.letter-summary {
  margin: 0.7rem 0 0;
  padding-left: 0.9rem;
  border-left: 2px solid var(--gilt);
  font-size: 0.99rem;
  font-style: italic;
  line-height: 1.62;
  color: var(--ink-soft);
}
/* In the link lists she sits a touch smaller and keeps a small foot of
   air before the next letter's line.                                    */
.sibling-list .letter-summary,
.letter-list .letter-summary {
  margin: 0.35rem 0 0.65rem;
  font-size: 0.95rem;
}

/* Preserve uncertainty: the edition's own hedging, set as an editorial
   aside in gilt italic — quiet, but never absent. 5.68:1 on the ground,
   5.33:1 on the hover tint.                                             */
.date-provenance {
  display: block;
  margin-top: 0.1rem;
  font-size: 0.76rem;
  font-style: italic;
  line-height: 1.35;
  color: var(--gilt-text);
}

/* =============================================================== LETTER */

.crumb {
  margin: 1.9rem 0 0;
  font-family: var(--label);
  font-size: 0.74rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}
.crumb a {
  text-decoration: none;
  border-bottom: 1px solid rgba(46, 74, 90, 0.3);
  padding-bottom: 0.15rem;
}
.crumb a:hover { border-bottom-color: var(--gilt); }

/* --- the museum label -------------------------------------------------
   Deep sea-green card, bone type, a hairline gilt frame set just inside
   the edge. This is the one place on the letter page where colour is
   allowed to be loud; the transcription below stays on quiet paper.     */
.letter > header .letter-meta {
  margin: 2rem 0 0;
  padding: 1.6rem 1.8rem 1.7rem;
  background: var(--seagreen);
  color: var(--on-deep);
  box-shadow: inset 0 0 0 1px rgba(201, 168, 86, 0.5);
}
.letter > header .letter-meta > div {
  display: grid;
  grid-template-columns: 8.25rem 1fr;
  gap: 0.25rem 1.2rem;
  padding: 0.5rem 0;
  border-top: 1px solid rgba(242, 239, 228, 0.16);
}
.letter > header .letter-meta > div:first-child {
  padding-top: 0;
  border-top: 0;
}
.letter > header .letter-meta dt {
  font-family: var(--label);
  font-size: 0.64rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--on-deep-mut);          /* 4.94:1 */
  line-height: 1.9;
}
.letter > header .letter-meta dd {
  margin: 0;
  font-size: 1.02rem;
  line-height: 1.55;
}
.letter > header .letter-meta a {
  color: var(--on-deep-acc);          /* 6.60:1 */
  text-decoration: none;
  border-bottom: 1px solid rgba(230, 223, 203, 0.45);
}
.letter > header .letter-meta a:hover { border-bottom-color: var(--gilt-light); }
.letter > header .letter-meta .date-provenance { color: #cbd6c8; }  /* 5.85:1 */

/* --- the transcription ------------------------------------------------
   Colour frames the letter; it never floods it. Paper, a hairline, one
   gilt edge along the top, and a measure of roughly 64 characters.
   Shared with the front page's foreword (Maria, 2026-07-29): the foreword
   is a letter to the reader and wears the letters' own frame — one rule,
   so the two cannot drift apart. PresenterTest reads this file and holds
   the sharing.                                                          */
.transcription,
.presentation {
  margin: 2.6rem 0 0;
  padding: clamp(1.5rem, 5vw, 3rem);
  background: var(--paper);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--gilt);
  box-shadow: 0 14px 30px -26px rgba(46, 74, 90, 0.55);
  line-height: 1.78;
}
/* No paper where the edition prints none: three letters in b171 are
   cross-references to text printed under another number. An editorial
   line, in the same gilt italic the other honest gaps use. */
.no-transcription {
  margin: 2.6rem 0 0;
  padding: 1.4rem 0 0;
  border-top: 1px solid var(--rule);
  font-style: italic;
  color: var(--gilt-text);            /* 5.68:1 on ground */
}

/* Closing mark: a small gilt lozenge, drawn with borders so screen
   readers have nothing to announce. */
.transcription::after,
.presentation::after {
  content: "";
  display: block;
  width: 7px;
  height: 7px;
  margin: 2.4rem auto 0.2rem;
  border: 1px solid var(--gilt);
  transform: rotate(45deg);
}

.tei-p { margin: 0 0 0.25rem; }
.r-ind { text-indent: 1.4em; }
.r-cen { text-align: center; }
.r-bag, .r-baglang, .r-bagxlang, .r-bagind { text-align: right; }
.tei-l { display: block; }
.tei-div--mainText { margin: 0; }

/* Opener / salutation: the one line that gets the display face and the
   Prussian of the header band (9.12:1 on paper). Shared with the
   foreword's heading — its salutation, typographically. */
.tei-opener { margin: 0 0 1.9rem; }
.tei-salute .tei-l,
.presentation h2 {
  font-family: var(--display);
  font-size: 1.32rem;
  line-height: 1.4;
  color: var(--prussian);
}

/* Closer: signature and dateline set to the right the way they sit on
   the sheet -- as text, not as exhibits (Maria, 2026-07-29): the words
   and the placement carry it, boxes added nothing. The classes stay in
   the markup; the retired box treatment, should a display want it back:
   signed had padding 0.85rem 1.2rem, a 2px gilt left bar and a wash of
   rgba(236, 230, 217, 0.5) with the display face on its last line;
   the dateline had padding 0.4rem 0.85rem, a 1px rule border, ground
   #faf7ef and the display face at 0.98rem. */
.tei-closer {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.4rem;
  margin: 2.4rem 0 0;
  text-align: right;
}

/* Envelope address: frame within frame — the gallery-frame gesture, used
   once, on the object that most deserves it. */
.tei-trailer--addrOnEnvelope {
  margin: 2.9rem 0 0;
  padding: 1.5rem 1.7rem;
  background: var(--plaster);
  border: 1px solid var(--rule-warm);
  box-shadow:
    inset 0 0 0 1px var(--paper),
    inset 0 0 0 2px rgba(176, 141, 62, 0.45);
  line-height: 1.7;
}
.tei-trailer--addrOnEnvelope .tei-l { margin-bottom: 0.15rem; }
.tei-table { border-collapse: collapse; margin: 0.7rem 0 0; }
.tei-cell { padding: 0.1rem 1.4rem 0.1rem 0; vertical-align: top; }

.tei-postscript, .tei-lg { margin: 1.4rem 0; }
.tei-lg { padding-left: 1.5rem; }
.tei-figure-caption {
  display: block;
  color: var(--muted);
  font-size: 0.85rem;
}

/* --- the writer's own footnote ----------------------------------------
   Seven letters carry one. On the sheet it sits under a rule at the foot
   of the page, in a smaller hand; here it keeps that relationship to the
   text — set below, set smaller, ruled off — without pretending to be a
   page. The reference marker the edition prints (<seg type="refMarker">)
   is lifted to a superscript, as it is in print.                        */
.tei-note {
  display: block;
  margin: 1.9rem 0 0.4rem;
  padding: 0.9rem 0 0;
  border-top: 1px solid var(--rule);
  font-size: 0.93rem;
  line-height: 1.62;
  color: var(--ink-soft);              /* 8.98:1 on paper */
}
/* The marker leads the note's first line, as it does in print. Floated
   rather than inlined, because the note's text is a block of its own. */
.tei-note .tei-seg--refMarker {
  float: left;
  margin: 0.1em 0.45em 0 0;
  font-size: 0.72em;
  vertical-align: 0.5em;
  color: var(--gilt-text);            /* 5.68:1 on paper */
}
.tei-note .tei-p:last-child { margin-bottom: 0; }

/* A number the edition sets as a formula: only the digits survive the
   encoding, so they are set as digits and marked as what they are. */
.tei-formula { font-variant-numeric: lining-nums; }

/* --- page and leaf boundaries ----------------------------------------
   Two pagination series, two tones: blue-grey for the manuscript leaves,
   ochre for the SKS print pages. Gallery-number chips — small enough to
   read past, bordered enough that they are never "hidden". Their title
   attributes carry the edition's own wording. */
/* Hidden, not dropped (Maria, 2026-07-28): the two pagination series are
   upstream apparatus, not reading matter here. The spans and their data
   stay in the markup for a display that wants them back; the chips just
   do not print. Their two-tone design survives below, inert, with its
   measured contrast pairs, the way the dark sketch does.               */
.tei-pb {
  display: none;
  margin: 0 0.2em;
  padding: 0.02rem 0.34rem;
  border: 1px solid;
  border-radius: 2px;
  font-family: var(--label);
  font-size: 0.62rem;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: 0.05em;
  vertical-align: 0.34em;
  white-space: nowrap;
  text-indent: 0;
  cursor: help;
}
.tei-pb--manuscript {
  color: #2b4a59;                 /* 7.56:1 on its own tint */
  background: #dde8ed;
  border-color: #8aa8b6;
}
.tei-pb--print {
  color: #634d10;                 /* 6.67:1 on its own tint */
  background: #f2e9d1;
  border-color: #bda76b;
}

/* --- what the marks mean ---------------------------------------------
   Only on letters that carry a mark, and each legend line wears its own
   mark: the sample is the explanation, so meaning is never decoration
   alone. Collapsed <details>, no script. Ink --muted: 6.35:1 on ground. */
.mark-legend { margin: 1.3rem 0 0; }
.mark-legend summary {
  cursor: pointer;
  font-family: var(--label);
  font-size: 0.74rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--muted);
}
.mark-legend-list {
  list-style: none;
  margin: 0.55rem 0 0;
  padding: 0;
}
.mark-legend-list li {
  margin-top: 0.3rem;
  font-size: 0.95rem;
  line-height: 1.6;
}

/* --- editorial and manuscript marks ----------------------------------
   Preserve uncertainty: everything the edition flags stays flagged.
   supplied -> square brackets (the scholarly convention), gilt
   unclear  -> under-dots
   corr     -> a Prussian dashed rule (editor's correction, not doubt)
   add      -> the same dots OVER the run: written above the line in the
               source, so the mark sits where the writing did. Shape and
               position distinguish it, never hue alone. (The retired
               treatment -- ochre wash rgba(176,141,62,0.14) with a solid
               bottom rule -- read as a link; Maria, 2026-07-29.) */
.tei-supplied { color: var(--gilt-text); }     /* 6.13:1 on paper */
.tei-supplied::before { content: "["; }
.tei-supplied::after  { content: "]"; }

.tei-unclear { border-bottom: 1px dotted rgba(122, 91, 24, 0.8); }
.tei-corr    { border-bottom: 1px dashed rgba(46, 74, 90, 0.55); }

.tei-add {
  border-top: 1px dotted rgba(122, 91, 24, 0.8);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* Named entities: a hairline the eye can ignore while reading and find
   when looking.                                                        */
.tei-persName  { border-bottom: 1px solid rgba(46, 74, 90, 0.42); }
/* Place names keep their span and data-key but no underline (Maria,
   2026-07-28): the mark-up is a join point, not reading matter. The
   sea-green rule it had: 1px solid rgba(59, 79, 69, 0.42).            */
.tei-placeName { border-bottom: 0; }
.tei-persName .tei-persName,
.tei-persName .tei-supplied { border-bottom: 0; }

/* A named person is now a link to their page, and it must not look like
   one while you are reading. Brev 40 names thirty-four people; thirty-four
   blue, underlined runs would turn a page of prose into a speckled field,
   which every one of the design mockups warned against.

   So at rest the anchor is exactly the span it replaced: the letter's own
   ink, no underline, and the same faint entity hairline it already had.
   It says it is a link only when you point at it or reach it by keyboard
   — then the hairline goes solid Prussian and the name takes a real
   underline. Nothing about the reading text moves, because both marks
   were already occupying that pixel row.                                */
a.tei-persName {
  color: inherit;
  text-decoration: none;
  border-bottom-color: rgba(46, 74, 90, 0.42);
  transition: border-bottom-color 90ms linear;
}
a.tei-persName:hover,
a.tei-persName:focus-visible {
  border-bottom-color: var(--prussian);   /* 9.12:1 as type on paper */
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

/* The manuscript's own hand. #lat marks Latin script inside a gothic
   hand — given the display face, which is the closest a webpage gets to
   a change of script without pretending to be a facsimile. */
.r-lat { font-family: var(--display); letter-spacing: 0.01em; }
.r-und { text-decoration: underline; text-underline-offset: 0.15em; }
.r-dun { text-decoration: underline double; text-underline-offset: 0.15em; }
.r-size1 { font-size: 1.25em; }
sup, .r-sup { font-size: 0.66em; line-height: 0; }

/* The SKS rendition vocabulary also carries horizontal placement hints
   (#lang, #xlang, #x2lang … #kort). We honour them structurally — via the
   closer and envelope framing above — rather than reproducing millimetre
   indents that would only pretend to be the sheet. */

/* --- letter navigation ------------------------------------------------ */

.letter-nav {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin: 2.9rem 0 0;
}
.letter-nav a {
  padding: 0.7rem 1.05rem;
  border: 1px solid var(--rule);
  background: var(--paper);
  font-family: var(--label);
  font-size: 0.76rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
}
.letter-nav a:hover { border-color: var(--gilt); background: #fff; }
.nav-next { margin-left: auto; text-align: right; }

/* --- same correspondence ---------------------------------------------- */

/* One card for every letter list (Maria, 2026-07-28): "Samme
   brevveksling" on the letter pages and the person page's three lists
   share the museum-label band and the paper list below it.            */
.same-correspondence,
.person-letters {
  margin-top: 3.4rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--gilt);
}
.list-head {
  padding: 1.1rem 1.5rem;
  background: var(--sea-tint);
  border-bottom: 1px solid var(--rule-cool);
}
.list-head h2 {
  margin: 0;
  font-family: var(--display);
  font-size: 1.4rem;
  font-weight: 400;
  line-height: 1.2;
}
.list-head .group-note {
  margin: 0.3rem 0 0;
  font-size: 0.93rem;
  font-style: italic;
  color: var(--muted);            /* 5.88:1 on the sea tint */
}
.list-head .group-count {
  margin: 0.4rem 0 0;
  font-family: var(--label);
  font-size: 0.66rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
}

.sibling-list {
  list-style: none;
  margin: 0;
  padding: 0.75rem 0.85rem 1rem;
  display: grid;
  /* One column, full stop (Maria, 2026-07-28): with the resumés in every
     entry each letter is its own block on its own line, like the index. */
  grid-template-columns: 1fr;
  gap: 0.25rem;
}
.sibling-list li {
  padding: 0;
  font-size: 0.94rem;
  line-height: 1.45;
  border-left: 2px solid transparent;
}
/* One block, one address (Maria, 2026-07-28): the whole entry -- title,
   date, resumé -- is the link, so the row is styled as a quiet card and
   only the title wears the link hairline. Ink stays the text's own; the
   hover tint is the letter list's. */
.sibling-link {
  display: block;
  padding: 0.42rem 0.65rem 0.5rem;
  color: var(--ink);
  text-decoration: none;
}
.sibling-link:hover { background: var(--hover); }
.sibling-title {
  color: var(--prussian);
  border-bottom: 1px solid rgba(46, 74, 90, 0.28);
}
.sibling-link:hover .sibling-title { border-bottom-color: var(--gilt); }
.sibling-head { display: block; }
.sibling-list .muted {
  color: var(--muted);
  font-size: 0.86em;
}
.sibling-list li.current {
  background: var(--plaster);
  border-left-color: var(--gilt);
  padding: 0.42rem 0.65rem 0.5rem;
  font-weight: 600;
}
/* The current row is not a link and its title wears no hairline; the
   plaster ground and the gilt edge already say "you are here". */
.sibling-list li.current .sibling-title { border-bottom: 0; }
.sibling-list li.current .letter-summary { font-weight: 400; }
.current-marker {
  font-family: var(--label);
  font-size: 0.63rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--gilt-text);        /* 5.06:1 on the plaster highlight */
  white-space: nowrap;
}

.muted { color: var(--muted); }

/* =============================================================== PERSONS
   The register and the single-person page. A gallery hangs its people the
   way it hangs its rooms: a band per letter of the alphabet, named on the
   wall, with the names ruled up beneath it.

   The design borrows the index's furniture on purpose — plaster heading
   band, gilt rule, paper field, micro-caps labels — because a person page
   and a letter page are the same museum, and inventing a second visual
   language for the same site would only cost the reader.

   Contrast, all measured: name links --prussian on --paper 9.12:1; the
   marks beside them --muted on --paper 6.85:1; the biography --ink on
   --paper 15.79:1; the source line --gilt-text on --paper 6.13:1; the
   "no biography" line --muted on --paper 6.85:1.                       */

.alphabet-nav {
  margin: 2.6rem 0 0;
  padding: 1rem 1.5rem;
  background: var(--plaster);
  border-top: 2px solid var(--gilt);
  border-bottom: 1px solid var(--rule-warm);
}
.alphabet-list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 0.4rem;
  margin: 0;
  padding: 0;
}
.alphabet-list a {
  display: block;
  min-width: 2rem;
  padding: 0.3rem 0.4rem;
  border: 1px solid transparent;
  font-family: var(--display);
  font-size: 1.05rem;
  text-align: center;
  text-decoration: none;
}
.alphabet-list a:hover {
  border-color: var(--gilt);
  background: rgba(253, 252, 249, 0.6);
}

.person-band {
  margin-top: 2.6rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--gilt);
}
.alphabet-head {
  padding: 0.75rem 1.5rem 0.7rem;
  background: var(--plaster);
  border-bottom: 1px solid var(--rule-warm);
}
.alphabet-head h2 {
  margin: 0;
  font-family: var(--display);
  font-size: 1.7rem;
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0.02em;
}

.person-list {
  list-style: none;
  margin: 0;
  padding: 0.4rem 0;
  columns: 2;
  column-gap: 2rem;
}
.person-entry {
  break-inside: avoid;
  padding: 0.42rem 1.5rem;
  line-height: 1.4;
}
.person-entry a {
  text-decoration: none;
  border-bottom: 1px solid rgba(46, 74, 90, 0.28);
}
.person-entry a:hover { border-bottom-color: var(--gilt); }
.person-marks {
  display: block;
  font-family: var(--label);
  font-size: 0.65rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}
/* Whether the commentary had anything is information, so it is said in
   words on every entry — never carried by presence or absence alone. */
.person-marks--bare { font-style: italic; text-transform: none; letter-spacing: 0.02em; }

/* --- one person ------------------------------------------------------- */

.person > header { margin-bottom: 2.4rem; }

.person-meta {
  margin: 1.6rem 0 0;
  padding: 0.85rem 1.15rem;
  background: var(--plaster);
  border-left: 3px solid var(--gilt);
}
.person-meta > div {
  display: grid;
  grid-template-columns: 9rem 1fr;
  align-items: baseline;
  gap: 0.2rem 1rem;
}
.person-meta > div + div { margin-top: 0.35rem; }
.person-meta dt {
  font-family: var(--label);
  font-size: 0.61rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--muted);                /* 5.65:1 on plaster */
}
.person-meta dd { margin: 0; font-size: 0.97rem; }
.person-key { font-family: var(--label); font-size: 0.9rem; }
.person-aka { font-style: italic; color: var(--ink-soft); }  /* 7.49:1 */

.person-biography {
  margin-top: 2.2rem;
  padding: 1.4rem 1.5rem 1.3rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--gilt);
}
.person-bio {
  margin: 0;
  font-size: 1.08rem;
  line-height: 1.68;
}
.person-bio--none {
  font-style: italic;
  color: var(--muted);                /* 6.85:1 on paper */
}
/* The citation is the edition's own note id. It is not decoration: it is
   how a reader checks us against the source we drew the note out of.  */
.person-source {
  margin: 0.75rem 0 0;
  font-family: var(--label);
  font-size: 0.72rem;
  letter-spacing: 0.03em;
  color: var(--gilt-text);            /* 6.13:1 on paper */
}

/* The section card itself is styled with .same-correspondence above.  */
.person-letter-pair {
  display: block;
  font-size: 0.86rem;
  color: var(--muted);
}
.person-both { display: block; }
.person-both a { white-space: nowrap; }

/* ============================================================== TIMELINE
   One life on one linear scale. The page is a stack of years, all the same
   height. Each year is one grid with two rows: three lanes hung beside the
   scale -- where he lived, the letters, the letters that cannot be placed
   within their year -- and, in the row below, what he published. That is
   the page's ONE layout (option A, Maria 2026-07-29): the same grid at
   every width, so the geometry the Python side guarantees holds on every
   screen. Only the tokens breathe at narrow widths; below the strip's
   minimum the page asks the reader to turn the phone (.tl-rotate).

   THE ONE RULE OF THE SCALE
   -------------------------
   Every year is --tl-year tall and every mark sits at its own fraction of
   its year, so the four silent years take up as much room as the four that
   hold half the authorship. The scale is perfectly uniform: the works sit
   under their year and reserve no time on it, so no year ever stretches
   for its books and none is compressed for another's.

   EVERY MARK IS A FINGER TARGET
   -----------------------------
   --tl-hit and --tl-cell are 1.5rem = 24 CSS px, WCAG 2.5.8's minimum
   target size. sitegen/timeline.py deals the slot columns with the same 24
   px of vertical slack (CELL_HIT_PX), so the hit areas grow invisibly
   around the drawn marks and never overlap -- the coupling is test-held.

   COLOUR CARRIES NOTHING ON ITS OWN
   ---------------------------------
   Every distinction is drawn twice, as a shape and as words:
     · letter dated to the day    -> a filled line       (prussian, 9.12:1 on
                                                          the paper lane)
     · dated to a month           -> an open box as tall as the month
                                     (1px prussian border, 9.12:1; its 9% fill
                                     is decoration, 1.16:1, and says nothing
                                     the border does not)
     · dated to a year or wider   -> not on the day scale at all: a dashed
                                     "ca." chip carrying the letter's number
                                     (gilt-text border 6.13:1, number
                                     ink-soft 9.08:1 on paper)
     · signed work                -> filled lozenge, flush against the rail
     · pseudonymous work          -> open lozenge, indented, dashed rule, and
                                     the pseudonym named underneath
     · residence                  -> a band edged in sea-green (7.93:1 on the
                                     ground); dashed edges and a hatch where
                                     the dataset marks the period uncertain.
                                     The sea-tint fill is 1.08:1 -- decoration
                                     again, never the message.
   No new hues: every value below is a token from the Eckersberg palette above
   or an alpha of one.                                                      */

/* No page-local shell: the timeline sits in the site's shared 46rem column,
   which is what lets a phone held in landscape hold the whole strip.      */

.tl {
  /* The scale, and the size of one letter. Both are also numbers in
     sitegen/timeline.py, which lays out the columns of overlapping marks --
     change one and change the other (a test compares them, 16px per rem). */
  --tl-year: 11rem;
  --tl-cell: 1.5rem;
  --tl-hit: 1.5rem;

  --tl-axis: 3.1rem;
  --tl-homes: 1rem;
  --tl-letters: calc(var(--slots) * var(--tl-cell));
  --tl-gap: 0.85rem;

  margin-top: 2.8rem;
}

/* The one grid. The works row is under the strip at every width, so the
   "Kun år" lane can be the flexible column: 21 letter columns of 24 px plus
   axis, band hairline and gaps leave it 2.6rem at the narrowest and near
   4rem on desktop -- the chips wrap.                                      */
.tl-head,
.tl-year {
  display: grid;
  grid-template-columns:
    var(--tl-axis) var(--tl-homes) var(--tl-letters) minmax(0, 1fr);
  grid-template-areas:
    "axis homes letters vague"
    "works works works works";
  column-gap: var(--tl-gap);
}
.tl-axis { grid-area: axis; }
.tl-homes { grid-area: homes; }
.tl-letters { grid-area: letters; }
.tl-vague { grid-area: vague; }
.tl-works { grid-area: works; }

/* The lane names ride along at the top of the window: on a page this tall,
   a reader who scrolls into 1849 should not have to scroll back to find out
   what the columns are. */
.tl-head {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: 0.55rem 0 0.5rem;
  background: var(--ground);
  border-bottom: 2px solid var(--gilt);
  font-family: var(--label);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--muted);                  /* 6.35:1 on the ground */
}
/* Hidden, not removed: the head row is auto-placed, so a missing span in
   the middle would slide every label after it into the wrong lane. The band
   hairline has no room for a word; the legend names the bands instead. */
.tl-head-homes { visibility: hidden; }

.tl-year {
  position: relative;
  min-height: var(--tl-year);
  border-top: 1px solid var(--rule-faint);
  scroll-margin-top: 3rem;
}
.tl-year--decade { border-top: 1px solid var(--gilt); }

/* --- the axis --------------------------------------------------------- */

/* Not sticky: a stuck year label would collide with the next year's the
   moment the rows are only a screenful apart, which they usually are. */
.tl-axis {
  align-self: start;
  margin: 0;
  padding-top: 0.45rem;
  font-family: var(--display);
  font-size: 1.02rem;
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0.06em;
  color: var(--muted);
}
.tl-year--decade > .tl-axis {
  font-size: 1.35rem;
  color: var(--ink-soft);               /* 8.41:1 */
}

/* --- where he lived ----------------------------------------------------
   A hairline lane: the bands carry the time, the register at the foot of
   the page carries the addresses -- at every width.                      */

.tl-homes { position: relative; }

.tl-home {
  position: absolute;
  top: calc(var(--top) * 100%);
  height: calc(var(--height) * 100%);
  left: calc(var(--slot) * 0.5rem);
  right: 0;
}
/* The band itself: a sea-green edged strip. Bands run for years, so only the
   true beginning and the true end of a stay get a cap -- the pieces in
   between are open, and read as one continuous band down the page. */
.tl-home-band {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 0.4rem;
  background: var(--sea-tint);
  border-left: 1px solid var(--seagreen);
  border-right: 1px solid var(--seagreen);
}
.tl-home--starts > .tl-home-band { border-top: 1px solid var(--seagreen); }
.tl-home--ends > .tl-home-band { border-bottom: 1px solid var(--seagreen); }
/* Uncertain period: dashed edges and a hatched fill. Both are the same
   sea-green; the dashes are what carry it, the hatch only supports them. */
.tl-home--approx > .tl-home-band {
  border-style: dashed;
  background: repeating-linear-gradient(
    135deg,
    var(--sea-tint) 0 4px,
    rgba(59, 79, 69, 0.12) 4px 8px
  );
}

/* The dataset's own doubt, said in words next to the dashes that show it
   -- in the register at the foot of the page, where the words live. */
.tl-approx {
  display: block;
  font-family: var(--label);
  font-size: 0.58rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gilt-text);              /* 5.68:1 on the ground */
}

/* --- the letters ------------------------------------------------------
   The one lane that is a panel: paper, with a gilt frame-line down its left
   edge. That line is the spine of the page -- the only place a straight edge
   runs from 1813 to 1855 without a break.                                 */

.tl-letters {
  position: relative;
  margin: 0;
  padding: 0;
  list-style: none;
  /* Its children are all absolutely positioned, so the lane has no height of
     its own -- and it is the lane the percentages are measured against. This
     is what gives every year its floor. */
  min-height: var(--tl-year);
  background: var(--paper);
  border-left: 2px solid var(--gilt);
}

.tl-letter {
  position: absolute;
  top: calc(var(--top) * 100%);
  left: calc(var(--slot) * var(--tl-cell));
  width: calc(var(--tl-cell) - 2px);
}
.tl-letter > a {
  display: block;
  position: absolute;
  inset: 0;
}
/* Known to the day: a line, and a target tall enough to hit. */
.tl-letter--day {
  height: var(--tl-hit);
  margin-top: calc(var(--tl-hit) / -2);
}
.tl-letter--day > a::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 3px;
  margin-top: -1.5px;
  background: var(--prussian);          /* 9.12:1 on the paper lane */
}
/* Known to the month: a box the height of that month, open, because the
   edition does not say which day inside it. */
.tl-letter--span {
  height: calc(var(--height) * 100%);
  min-height: var(--tl-hit);
}
.tl-letter--span > a {
  border: 1px solid var(--prussian);
  background: rgba(46, 74, 90, 0.09);
}
.tl-letter > a:hover,
.tl-letter > a:focus-visible {
  background: rgba(122, 91, 24, 0.18);
  z-index: 1;
}
.tl-letter--day > a:hover::before,
.tl-letter--day > a:focus-visible::before {
  background: var(--gilt-text);
  height: 5px;
  margin-top: -2.5px;
}

/* --- letters with no place in their year ------------------------------
   Set apart on purpose. A letter the edition dates to "1846" or "1846-47"
   has no position on a day scale, and giving it one would be the single
   easiest lie this page could tell. It gets its number instead.          */

.tl-vague {
  align-self: start;
  min-width: 0;
  padding-top: 0.2rem;
}
.tl-vague-mark {
  margin: 0 0 0.2rem;
  font-family: var(--label);
  font-size: 0.58rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.tl-vague-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
/* The chips are letter targets too: with this padding a chip stands 24 px
   tall and at least 24 px wide -- the same WCAG 2.5.8 floor as the marks. */
.tl-vague-item > a {
  display: block;
  min-width: 1.55rem;
  padding: 0.22rem 0.3rem;
  border: 1px dashed var(--gilt-text);  /* 6.13:1 on paper */
  background: var(--paper);
  font-family: var(--label);
  font-size: 0.66rem;
  line-height: 1.5;
  text-align: center;
  text-decoration: none;
  color: var(--ink-soft);               /* 9.08:1 on paper */
}
.tl-vague-item > a:hover {
  border-style: solid;
  background: var(--plaster);
}

/* --- what he published ------------------------------------------------
   Under the year, at every width: the date names the position, the strip
   above keeps its uniform scale, and no block reserves any time.         */

.tl-works {
  margin: 0;
  padding: 0;
  list-style: none;
}
.tl-work {
  position: relative;
  padding-left: 1.05rem;
}
.tl-work:first-child { padding-top: 0.5rem; }
/* A short leader to the date -- an anchor for the eye, not a position:
   the position is the date's words now that the works sit below the year. */
.tl-work::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.5rem;
  width: 0.75rem;
  height: 1px;
  background: var(--rule-warm);
}
.tl-work-date {
  margin: 0;
  font-family: var(--label);
  font-size: 0.64rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);                  /* 6.35:1 */
}
.tl-work-list {
  margin: 0.25rem 0 0.9rem;
  padding: 0;
  list-style: none;
}

/* Signed at the rail, pseudonymous set in from it: the alternation of the
   authorship, drawn as two positions and two markers rather than two hues. */
.tl-work-item {
  position: relative;
  margin-bottom: 0.5rem;
  padding-left: 0.7rem;
  border-left: 2px solid var(--prussian);   /* 8.45:1 on the ground */
}
.tl-work-item:last-child { margin-bottom: 0; }
.tl-work-item--pseudonym {
  margin-left: 1.5rem;
  border-left-style: dashed;
}
.tl-work-mark {
  position: absolute;
  left: -0.32rem;
  top: 0.42rem;
  width: 0.48rem;
  height: 0.48rem;
  background: var(--prussian);
  transform: rotate(45deg);
}
.tl-work-item--pseudonym > .tl-work-mark {
  background: var(--paper);
  box-shadow: inset 0 0 0 1.5px var(--prussian);
}

.tl-work-title {
  display: block;
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.28;
  color: var(--ink);                    /* 14.61:1 */
}
.tl-work-name {
  display: block;
  margin-top: 0.1rem;
  font-family: var(--label);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-soft);               /* 8.41:1 */
}
/* The dataset's own wording, where a single date cannot hold it: a serial in
   four parts, nine numbers of a journal, a year of newspaper articles. */
.tl-work-period {
  display: block;
  margin-top: 0.1rem;
  font-size: 0.78rem;
  font-style: italic;
  line-height: 1.4;
  color: var(--gilt-text);              /* 5.68:1 */
}

/* --- what the rail cannot hold ---------------------------------------- */

.tl-figures {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 1.8rem;
  margin: 1.3rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.92rem;
  color: var(--ink-soft);
}
.tl-figures b {
  font-family: var(--display);
  font-size: 1.25rem;
  font-weight: 400;
  color: var(--ink);
}

.tl-legend-box {
  margin: 2.4rem 0 0;
  padding: 1.3rem 1.5rem 1.4rem;
  background: var(--plaster);
  border-top: 2px solid var(--gilt);
  border-bottom: 1px solid var(--rule-warm);
}
.tl-legend-heading {
  margin: 0 0 0.9rem;
  font-family: var(--label);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gilt-text);              /* 5.06:1 on plaster */
}
.tl-legend {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 0.5rem 2rem;
  margin: 0;
}
.tl-legend > div {
  display: grid;
  grid-template-columns: 7rem 1fr;
  gap: 0 0.9rem;
  align-items: baseline;
}
.tl-legend dt {
  font-family: var(--label);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-soft);               /* 8.98:1 on plaster */
}
.tl-legend dd {
  margin: 0;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--muted);                  /* 5.65:1 on plaster */
}
.tl-legend-note {
  margin: 1.1rem 0 0;
  font-size: 0.86rem;
  font-style: italic;
  line-height: 1.55;
  color: var(--muted);
}

.tl-section { margin-top: 3.6rem; }
.tl-section h2 {
  margin: 0;
  padding-bottom: 0.6rem;
  border-bottom: 2px solid var(--gilt);
  font-family: var(--display);
  font-size: clamp(1.55rem, 4vw, 1.95rem);
  font-weight: 400;
  line-height: 1.15;
}
.tl-section-note {
  margin: 1rem 0 0;
  max-width: 34rem;
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--ink-soft);
}

.tl-undated-list {
  margin: 1.2rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: 0.3rem 1.5rem;
  font-size: 0.94rem;
}
.tl-undated-list a { text-decoration: none; border-bottom: 1px solid rgba(46, 74, 90, 0.28); }
.tl-undated-list a:hover { border-bottom-color: var(--gilt); }

.tl-home-register {
  margin: 1.3rem 0 0;
}
.tl-home-register > div {
  display: grid;
  grid-template-columns: 15rem 1fr;
  gap: 0.2rem 1.5rem;
  padding: 0.85rem 0;
  border-top: 1px solid var(--rule-faint);
}
.tl-home-register dt {
  font-family: var(--display);
  font-size: 1.05rem;
  line-height: 1.3;
}
.tl-home-register dd { margin: 0; }
.tl-home-register .tl-home-period {
  display: block;
  font-size: 0.86rem;
  color: var(--ink-soft);
}
.tl-home-register .tl-approx { margin-top: 0.15rem; }
.tl-home-modern,
.tl-home-note {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.86rem;
  line-height: 1.55;
  color: var(--muted);
}
.tl-home-note { font-style: italic; }

.tl-dataset { margin-top: 1.8rem; }
.tl-dataset h3 {
  margin: 0 0 0.4rem;
  font-family: var(--label);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gilt-text);              /* 5.68:1 on the ground */
}
.tl-dataset p {
  margin: 0;
  max-width: 40rem;
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--ink-soft);
}
/* Source works are named, not linked: the built site fetches nothing and
   points nowhere at runtime except at the licence. */
.tl-source-list {
  margin: 0.6rem 0 0;
  padding-left: 1.1rem;
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--muted);
}

/* --------------------------------------------------- timeline, narrower
   The same grid all the way down -- only the tokens breathe. Below 48rem
   the lanes give up their slack and the strip borrows most of the gutter:
   21 columns of 24 px targets need the room, and every landscape phone
   from 640 px up should hold the whole strip. Below 40rem no landscape is
   left to fit, so the strip yields to the rotate prompt.                  */

@media (max-width: 48rem) {
  .tl {
    --tl-axis: 2.2rem;
    --tl-gap: 0.5rem;
    margin-inline: calc(0.6rem - var(--gutter));
  }
  .tl-work-item--pseudonym { margin-left: 1rem; }
  .tl-legend > div { grid-template-columns: 5.5rem 1fr; }
  .tl-home-register > div { grid-template-columns: 1fr; }
}

/* Maria's simplification (2026-07-29): no third layout for a portrait
   phone -- a friendly line asks for landscape instead, and everything
   below the strip (undated letters, the registers) stays readable. */
.tl-rotate {
  display: none;
  margin: 2.4rem 0 0;
  padding: 1.1rem 1.3rem;
  background: var(--paper);
  border-left: 2px solid var(--gilt);
  font-style: italic;
  color: var(--ink-soft);               /* 9.08:1 on paper */
}

@media (max-width: 40rem) {
  .tl { display: none; }
  .tl-rotate { display: block; }
}

/* ========================================================== PRESENTATION
   The front page's foreword: the site's one editorial-voice moment, and
   since 2026-07-29 set as what it is — a letter to the reader. It wears
   the transcriptions' paper frame, their opening face on its heading and
   their closing mark; those rules live in the LETTER section as shared
   selector lists, so the foreword and the letters cannot drift apart.
   No 34rem cap either: the foreword sits at the letters' own measure.

   Deliberately *not* italic. The 333 resumés downstairs are italic because
   they are two lines each; a hundred words of it would be a punishment, and
   the frame already says whose voice this is.

   Contrast: body --ink-soft on --paper 9.08:1; heading --prussian on
   --paper 9.12:1; links and signature --gilt-text on --paper 6.13:1.    */

.presentation h2 {
  margin: 0 0 1.9rem;
  font-weight: 400;
}
.presentation p {
  margin: 0.95rem 0 0;
  color: var(--ink-soft);
}
.presentation a {
  color: var(--gilt-text);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
}

/* The signature sits to the right the way the letters' closers do, the
   display face and gilt making it read as signed. The em dash is
   decorative and belongs to the design, not to the sentence, so it is
   drawn rather than written into the markup.                            */
.presentation .presentation-sign {
  margin-top: 2.4rem;
  font-family: var(--display);
  font-size: 1.1rem;
  line-height: 1.3;
  text-align: right;
  color: var(--gilt-text);
}
.presentation .presentation-sign::before {
  content: "— ";
  color: var(--gilt);
}

/* ==================================================================== OM
   The only page on the site that is nothing but prose, so it is set as
   prose: one column at reading measure, sections separated by air rather
   than by rules, and no tint anywhere. The page's job is to be believed,
   and a page that is trying hard is harder to believe.

   Contrast: --ink-soft on --ground 8.41:1; the commit hash --muted on
   --plaster 5.65:1.                                                     */

.prose { max-width: 34rem; }
.prose section { margin-top: 2.8rem; }
.prose h2 {
  margin: 0;
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 400;
  line-height: 1.2;
}
.prose h2::after {                    /* the same gilt tick as h1, smaller */
  content: "";
  display: block;
  width: 2rem;
  height: 2px;
  margin-top: 0.7rem;
  background: var(--gilt);
}
.prose p {
  margin: 1rem 0 0;
  color: var(--ink-soft);
  line-height: 1.72;
}
.prose a { color: var(--gilt-text); } /* 5.68:1 on --ground */
.prose code {
  padding: 0.08rem 0.25rem;
  background: var(--plaster);
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: 0.82em;
  /* A 40-character hash has to be allowed to break, or it takes the page
     sideways on a phone. */
  overflow-wrap: anywhere;
  color: var(--muted);
}
/* The pinned commit, set on its own line: it is a fact to be checked, not
   a phrase to be read, and it is too long to sit inside a sentence. The
   Om page stopped printing the hash on 2026-08-03 (the technical notes in
   the repo carry it); the rule is kept for the day a page needs it again. */
.prose .commit { margin-top: 0.6rem; }

/* The source notes at the foot of the Om page: apparatus, so a step down
   in size, but the same ink -- they are the page's evidence, and evidence
   set in grey reads as a disclaimer. The markers are links into the list
   and are left unmarked: a superscript numeral is already a signal, and
   an underline under a raised digit is a smudge.                        */
.prose .om-notes {
  margin: 1.4rem 0 0;
  padding-left: 1.5rem;
  color: var(--ink-soft);
  font-size: 0.92rem;
  line-height: 1.6;
}
.prose .om-notes li { margin-top: 0.9rem; }
.prose sup { line-height: 0; }
.prose sup a { text-decoration: none; }

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

@media (max-width: 34rem) {
  body { font-size: 1rem; }
  h1 { margin-top: 2.2rem; }
  .volume-nav { padding-inline: 1.1rem; }
  .volume-head { grid-template-columns: 1fr; }
  .volume-head .volume-count { grid-column: 1; margin-top: 0.45rem; }
  .group-head { grid-template-columns: 1fr; }
  .group-head .group-count {
    grid-column: 1;
    grid-row: auto;
    justify-self: start;
    margin-top: 0.6rem;
  }
  .letter-list { padding-inline: 0.6rem; }
  .group-head { padding-inline: 1.1rem; }
  .finder { padding-inline: 1.1rem; }
  .finder-foot { margin-top: 0.85rem; }
  .person-list { columns: 1; padding-inline: 0; }
  .person-entry { padding-inline: 1.1rem; }
  .alphabet-head { padding-inline: 1.1rem; }
  .person-biography { padding-inline: 1.1rem; }
  .person-meta > div { grid-template-columns: 1fr; gap: 0.05rem; }
  .letter > header .letter-meta > div { grid-template-columns: 1fr; gap: 0.05rem; }
  .letter > header .letter-meta dt { line-height: 1.6; }
  .tei-closer { align-items: stretch; }
  .letter-nav { flex-direction: column; }
  .nav-next { margin-left: 0; text-align: left; }
  .sibling-list { padding-inline: 0.6rem; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}
