/* Babel — institutional archive.
 *
 * The organising idea: typed catalogue apparatus against printed reference
 * prose. Monospace carries every piece of classification metadata (record
 * numbers, floor designations, status); the serif carries only what a person
 * actually reads. Separation is done with hairline rules rather than open
 * space, because that is how dense reference works and filing systems behave.
 *
 * Light theme is manila file stock. Dark theme is not inverted paper — it is a
 * microfilm reader, which is where archives genuinely end up.
 */

:root {
  --paper:        #EDE8DC;
  --paper-raised: #F5F1E8;
  --paper-sunk:   #E4DECF;
  --ink:          #21201C;
  --ink-faded:    #6B655A;
  --rule:         #C9C1AE;
  --rule-strong:  #A79E88;
  --stamp:        #A33A2A;
  /* Cross-references are the primary affordance of a reference work, so they
   * carry the accent. Muted off the stamp so a paragraph dense with links
   * doesn't vibrate, but unmistakably not body ink. */
  --link:         #9C4433;
  --link-rule:    #C98A78;

  --serif: 'Iowan Old Style', 'Palatino Linotype', Palatino, 'Book Antiqua', Georgia, serif;
  --mono: ui-monospace, 'Cascadia Mono', 'SF Mono', Menlo, Consolas, monospace;

  --measure: 34rem;
  --gap: 1.5rem;
}

/* Microfilm reader, not inverted paper. Faded ink and rules are pitched
 * brighter than a naive inversion would give — on a dark ground the mono
 * apparatus disappears otherwise, which is what made the first pass read as
 * drab rather than dim. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper:        #1A1815;
    --paper-raised: #242119;
    --paper-sunk:   #131110;
    --ink:          #EDE6D4;
    --ink-faded:    #B0A692;
    --rule:         #4A4438;
    --rule-strong:  #6B6350;
    --stamp:        #E07A5F;
    /* Lifted off the stamp value — on a dark ground the accent needs more
     * luminance than on paper to read as clearly interactive. */
    --link:         #F0A184;
    --link-rule:    #A0604A;
  }
}

/* The viewer's explicit choice must win over the OS hint in both directions. */
:root[data-theme='dark'] {
  --paper: #1A1815; --paper-raised: #242119; --paper-sunk: #131110;
  --ink: #EDE6D4; --ink-faded: #B0A692;
  --rule: #4A4438; --rule-strong: #6B6350; --stamp: #E07A5F;
  --link: #F0A184; --link-rule: #A0604A;
}
:root[data-theme='light'] {
  --paper: #EDE8DC; --paper-raised: #F5F1E8; --paper-sunk: #E4DECF;
  --ink: #21201C; --ink-faded: #6B655A;
  --rule: #C9C1AE; --rule-strong: #A79E88; --stamp: #A33A2A;
  --link: #9C4433; --link-rule: #C98A78;
}

* { box-sizing: border-box; }

/* The browser's default [hidden] rule is `display: none`, but any author
 * `display:` declaration outranks it — so an element styled `display: flex`
 * ignores the hidden attribute entirely and stays on screen. Restore the
 * intent once, globally, rather than per-component. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.62;
  -webkit-text-size-adjust: 100%;
}

/* --- masthead ------------------------------------------------------------ */

.masthead {
  background: var(--paper-raised);
}

/* The instrumentation band beneath the header. The heavy 2px seam that used to
 * sit on the masthead lives here now, at the bottom of the whole chrome stack —
 * pixel-identical on desktop, because the band renders directly below the
 * header. On mobile the band is re-ordered below the article (see the 34rem
 * query) and the seam moves to the header instead. */
.chrome-band {
  border-bottom: 2px solid var(--ink);
}

.masthead-inner {
  max-width: 56rem;
  margin: 0 auto;
  padding: 0.7rem 1.25rem;
  display: flex;
  align-items: baseline;
  gap: var(--gap);
  flex-wrap: wrap;
}

.wordmark {
  font-family: var(--mono);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}

.masthead nav {
  margin-left: auto;
  display: flex;
  gap: 1rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* The CTA is excluded, and that exclusion is load-bearing. This reset scores
 * (0,1,2) against `.cta`'s (0,1,0), so it was winning `background: none` and
 * `padding: 0` against the button's own rule — leaving the CTA with no
 * background, no padding, and `color: var(--paper-raised)` (the one declaration
 * carrying !important) painted onto a masthead whose background is
 * var(--paper-raised). Cream on cream: the call to action was invisible at every
 * width, on every page, with nothing in the console. Excluding it here rather
 * than escalating there is what keeps the fix from being another !important. */
.masthead nav a:not(.cta), .theme-toggle {
  color: var(--ink-faded);
  text-decoration: none;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  /* `font:` is a shorthand and neither of these is in it, so a <button> — the
   * one element here that is a form control — kept the UA stylesheet's values
   * and rendered "Lamp" beside an uppercase "RANDOM". Anchors inherit both
   * without being asked; form controls are where inheritance quietly stops.
   * Spotted on the production box's first page load, having been wrong on
   * every page since the toggle was added. */
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}
.masthead nav a:not(.cta):hover, .theme-toggle:hover { color: var(--stamp); }

/* --- search field -------------------------------------------------------- */

.finder { display: flex; gap: 0; flex: 1 1 16rem; min-width: 12rem; }

.finder input {
  flex: 1;
  font-family: var(--mono);
  font-size: 0.78rem;
  padding: 0.35rem 0.55rem;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  border-right: 0;
}
.finder input::placeholder { color: var(--ink-faded); }

.finder button {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.35rem 0.7rem;
  color: var(--paper-raised);
  background: var(--ink);
  border: 1px solid var(--ink);
  cursor: pointer;
}
.finder button:hover { background: var(--stamp); border-color: var(--stamp); }

/* --- acquisition-era chrome ---------------------------------------------- */

/* Growth machinery grafted onto a filing system. It sits at the edges and
 * never enters the text column — the articles keep their straight face, which
 * is the entire joke. */

.cta {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  /* No !important on either of these any more. They were here to force the
   * colour past the nav reset above, and they were the reason this failed so
   * quietly: the one property that fought its way through was the one that made
   * the button invisible, while background and padding — which would have made
   * the breakage obvious — lost silently. With the reset excluding .cta there is
   * nothing left to out-rank. */
  color: var(--paper-raised);
  background: var(--stamp);
  padding: 0.3rem 0.6rem;
  text-decoration: none;
  white-space: nowrap;
}
.cta:hover { background: var(--ink); color: var(--paper-raised); }

.trustbar {
  border-top: 1px solid var(--rule);
  background: var(--paper-sunk);
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-faded);
}
.trustbar > a {
  display: inline-block;
  padding: 0.32rem 0;
  margin-right: 1.4rem;
  color: var(--ink-faded);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.trustbar > a:hover { color: var(--link); border-bottom-color: var(--link-rule); }
.trustbar > a::before { content: '\2713\00a0'; color: var(--stamp); }
.trustbar {
  max-width: 56rem;
  margin: 0 auto;
  padding: 0 1.25rem;
  white-space: nowrap;
  overflow-x: auto;
}

/* The quota meter. Its own strip under the trust bar, because it is a claim
 * about the reader rather than about the archive — and because appended to that
 * nowrap row it scrolled off the edge unread. Stamp red so it reads as the
 * newer, keener addition rather than as more compliance boilerplate. */
.quotabar {
  /* No border-top on purpose. It shares the trust bar's background, so a rule
   * between them only adds a third horizontal line to a header that already ends
   * in the masthead's heavy 2px one — which reads as a doubled edge. Without it
   * the two strips are one band carrying two rows, which is also the truer
   * picture: the machinery accumulates in a single seam rather than in layers. */
  background: var(--paper-sunk);
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--stamp);
  max-width: 56rem;
  margin: 0 auto;
  padding: 0.32rem 1.25rem;
  text-align: right;
  /* One line on a desktop, two on a phone — and the second was arriving as a
   * single stranded word ("month") sitting under "this", which reads as a
   * rendering fault rather than as a sentence. Balancing evens the two lines
   * instead of filling the first and orphaning the remainder. A no-op wherever
   * the line already fits, so the desktop strip is untouched. */
  text-wrap: balance;
}

.consent {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  background: var(--paper-raised);
  border-top: 2px solid var(--ink);
  padding: 0.85rem 1.25rem;
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-wrap: wrap;
  z-index: 10;
}
/* The support bubble. Waits for the consent notice to be dealt with before it
 * appears — a general sibling selector on `.consent:not([hidden])`, which is why
 * the bubble comes after the notice in the DOM. Pure CSS: the notice hides
 * itself, the rule stops matching, the bubble arrives. Nothing to keep in sync.
 *
 * Holding it back rather than nudging it up, which was the first attempt: the
 * notice wraps to two lines at narrow widths, so any clearance big enough to be
 * safe left a visible hole above the bar at desktop width. There is no CSS that
 * can measure the thing it needs to avoid. Waiting is also what the real
 * furniture does — the support widget turns up once the cookie bar is gone. */
.support {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 9;
  max-width: min(20rem, calc(100vw - 2.5rem));
}
.consent:not([hidden]) ~ .support { display: none; }

.support > summary {
  display: inline-block;      /* kills the default disclosure triangle */
  cursor: pointer;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper);
  background: var(--ink);
  border: 2px solid var(--ink);
  padding: 0.55rem 1.1rem;
  float: right;               /* keeps the closed bubble hard against the edge */
}
.support > summary::-webkit-details-marker { display: none; }

.support-panel {
  clear: both;
  background: var(--paper-raised);
  border: 2px solid var(--ink);
  padding: 0.9rem 1rem;
  margin-top: 0.5rem;
}
.support-status {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  color: var(--ink-faded);
  margin: 0;
}
/* The reply itself. Tabular figures so three call numbers line up as a column,
 * which is what makes a wordless answer read as an answer. */
.support-reply {
  font-family: var(--mono);
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
  line-height: 1.9;
  margin: 0.6rem 0;
}
.support-note {
  font-size: 0.72rem;
  line-height: 1.6;
  color: var(--ink-faded);
  margin: 0.6rem 0 0;
  border-top: 1px solid var(--rule);
  padding-top: 0.6rem;
}

.consent p {
  margin: 0;
  font-size: 0.88rem;
  max-width: 42rem;
  color: var(--ink-faded);
}
.consent button {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.4rem 0.8rem;
  color: var(--paper-raised);
  background: var(--ink);
  border: 0;
  cursor: pointer;
  white-space: nowrap;
}
.consent button:hover { background: var(--stamp); }

/* --- layout -------------------------------------------------------------- */

main {
  max-width: 56rem;
  margin: 0 auto;
  padding: 2rem 1.25rem 4rem;
}

.record { max-width: 46rem; }
.record .prose, .record > p { max-width: var(--measure); }
.clear { clear: both; }

.record-line {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  color: var(--ink-faded);
  margin: 0;
}

/* --- infobox ------------------------------------------------------------- */

/* What a reference work actually does with a plate: float it out of the
 * measure, rule it, and hang the classification data beneath. */
.infobox {
  float: right;
  width: 16rem;
  margin: 0.4rem 0 1.25rem 1.75rem;
  border: 1px solid var(--rule-strong);
  background: var(--paper-raised);
  padding: 0.7rem;
}

.plate { margin: 0 0 0.7rem; }
.plate img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--rule);
  /* Plates are engravings on aged stock; on the microfilm theme they read as
   * over-bright unless knocked back slightly. */
  filter: none;
  /* An examinable plate has to look examinable. */
  cursor: zoom-in;
  transition: border-color 0.15s ease;
}
.plate img:hover { border-color: var(--stamp); }

/* --- lightbox ------------------------------------------------------------ */

/* The plate taken out of the infobox and laid on the reading table. */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 2rem 1.25rem;
  background: rgba(10, 9, 8, 0.92);
  overflow: auto;
}

.lightbox figure {
  margin: 0;
  max-width: min(1024px, 92vw);
}

.lightbox img {
  display: block;
  /* auto + max-width, never width:100% — the latter upscales a plate past its
   * native size and softens it. Plates generated before the 1024px change are
   * 768px and would visibly blur. */
  width: auto;
  max-width: 100%;
  height: auto;
  max-height: 78vh;
  object-fit: contain;
  /* Matting: the plate sits on its own stock, not floating on the scrim. */
  border: 1px solid #6B6350;
  background: #EDE8DC;
  cursor: default;
}

.lightbox figcaption {
  font-family: var(--mono);
  font-size: 0.68rem;
  line-height: 1.6;
  color: #B0A692;
  padding-top: 0.6rem;
}

.lightbox-close {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #EDE6D4;
  background: none;
  border: 1px solid #6B6350;
  padding: 0.4rem 0.8rem;
  cursor: pointer;
}
.lightbox-close:hover { border-color: #E07A5F; color: #E07A5F; }
.plate figcaption {
  font-family: var(--mono);
  font-size: 0.62rem;
  line-height: 1.45;
  color: var(--ink-faded);
  padding-top: 0.4rem;
}

.infobox .classification { font-size: 0.66rem; }

/* The plate gallery. A plate index in an archive is hung, not filed, so this is
 * the one listing that is allowed to be a grid of pictures rather than a column
 * of ink. auto-fill with a min column keeps it a wall of plates on a wide screen
 * and a single column on a phone, with no breakpoint to maintain. */
.plate-gallery {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 1.6rem 1.4rem;
}
.plate-gallery > li { margin: 0; }
/* The holding this plate belongs to. Ink like every other listing — the plate
 * is the picture, the line beneath it is the catalogue reference. */
.plate-holding {
  margin: 0.5rem 0 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.6rem;
  align-items: baseline;
}
.plate-holding .ref {
  font-family: var(--mono);
  font-size: 0.64rem;
  color: var(--ink-faded);
  font-variant-numeric: tabular-nums;
}
.plate-holding a.entry {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.plate-holding a.entry:hover { color: var(--stamp); border-bottom-color: var(--stamp); }

@media (prefers-color-scheme: dark) {
  .plate img { filter: brightness(0.86) sepia(0.12); }
}
:root[data-theme='dark'] .plate img { filter: brightness(0.86) sepia(0.12); }
:root[data-theme='light'] .plate img { filter: none; }

/* The classification block. A catalogue card, set in the typewriter face. */
/* No border-top. It was `2px solid var(--ink)` — identical in weight and colour
 * to the masthead's bottom border, and every template puts this block first in
 * `main`, so the two landed 34px apart at the top of every page and read as one
 * doubled rule. The masthead's border already draws that division, full width;
 * this one only spanned the text column, which is what made the pair look like a
 * mistake rather than a frame. The bottom hairline stays — that is what makes
 * the classification block read as a card. */
.record-head {
  border-bottom: 1px solid var(--rule);
  padding: 0 0 0.85rem;
  margin-bottom: 1.75rem;
}

.record-head h1 {
  font-size: 2.05rem;
  line-height: 1.14;
  font-weight: 600;
  margin: 0 0 0.75rem;
  text-wrap: balance;
}

.classification {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.15rem 0.9rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
}
.classification dt {
  color: var(--ink-faded);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.classification dd { margin: 0; color: var(--ink); }
/* Floor and Class are links; Record and Consulted are not. Ink, not accent:
 * there is no global anchor rule in this stylesheet, so an unstyled link here
 * would come out in browser-default blue and break the printed-page illusion
 * without erroring. Ink is also the correct choice on its own terms — the
 * accent means cross-reference, and a shelf mark points at a shelf rather than
 * at another idea. Dotted, because a catalogue card underlines nothing. */
.classification dd a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px dotted var(--rule);
}
.classification dd a:visited { color: var(--ink); }
.classification dd a:hover {
  color: var(--stamp);
  border-bottom-color: var(--stamp);
}

/* --- prose --------------------------------------------------------------- */

.prose { counter-reset: section; }
.prose > p { margin: 0 0 1.05rem; }
.prose > p:first-of-type::first-line { font-variant: small-caps; letter-spacing: 0.02em; }

.prose h2 {
  counter-increment: section;
  font-size: 1.08rem;
  font-weight: 600;
  margin: 2.1rem 0 0.7rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--rule);
}
/* Reference works number their sections; the numbering is information, not
 * ornament — Concordance citations refer to sections by number. */
.prose h2::before {
  content: counter(section) '. ';
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--stamp);
  font-variant-numeric: tabular-nums;
}

.prose h3 { font-size: 0.97rem; font-weight: 600; margin: 1.4rem 0 0.5rem; }
.prose blockquote {
  margin: 1.2rem 0;
  padding: 0.1rem 0 0.1rem 1rem;
  border-left: 2px solid var(--rule-strong);
  color: var(--ink-faded);
  font-size: 0.95rem;
}
.prose ul, .prose ol { margin: 0 0 1.05rem; padding-left: 1.3rem; }
.prose li { margin-bottom: 0.3rem; }
.prose hr { border: 0; border-top: 1px solid var(--rule); margin: 1.8rem 0; }

.prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
  margin: 1.2rem 0;
  font-variant-numeric: tabular-nums;
}
.prose th, .prose td {
  text-align: left;
  padding: 0.35rem 0.6rem 0.35rem 0;
  border-bottom: 1px solid var(--rule);
}
.prose th {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faded);
}

.table-scroll { overflow-x: auto; }

/* No link is ever browser-default blue. This has been fixed four times in one
 * place at a time — provenance links, the survey terms, the did-you-mean, the
 * record line — because there is no global anchor colour and every new stray
 * inherits the UA blue, the one colour on the page belonging to no theme. This
 * ends the class: an unstyled anchor takes its container's ink, which is correct
 * for the listing-style links that keep appearing. Prose and wikilinks override
 * to the accent below; specificity keeps every explicit rule winning. */
a { color: inherit; }

/* The record line under an article title — "MS 5080.96 · Documents and
 * ordinances", where the series links to the finding aid. A listing link, so
 * ink like every other, and it inherits the line's faded colour. */
.record-line a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--rule-strong);
}
.record-line a:hover { color: var(--stamp); border-bottom-color: var(--stamp); }

/* Link-blue would break the printed-page illusion, but ink-on-ink was too
 * quiet to find in running prose — especially on the dark theme. Accent colour
 * plus a solid rule reads as an index reference and is unmistakably clickable. */
a.wikilink {
  color: var(--link);
  text-decoration: none;
  border-bottom: 1px solid var(--link-rule);
  transition: border-color 0.12s ease, background-color 0.12s ease;
}
a.wikilink:hover {
  border-bottom-color: var(--link);
  background: color-mix(in srgb, var(--link) 12%, transparent);
}
/* Defence in depth: any anchor that reaches the prose without our class still
 * must not render in browser-default blue. The repair pass should catch these,
 * but a stray link should degrade to looking correct rather than looking broken. */
.prose a { color: var(--link); }
.prose a:visited { color: var(--link); }
a.wikilink:visited { color: var(--link); }

/* Deliberately NOT distinguishing written from unwritten targets. Marking them
 * would tell the reader which links are "real", and not being able to tell is
 * the entire point — same reason search results are styled identically. */

/* --- result listing ------------------------------------------------------ */

.results { list-style: none; margin: 0; padding: 0; }

/* Written and unwritten entries are styled identically and deliberately so.
 * The archive does not distinguish between what it holds and what it merely
 * claims to hold — and clicking an unwritten entry makes the claim true. */
.results li {
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--rule);
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: 0.15rem 1rem;
}
.results .ref {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  color: var(--ink-faded);
  padding-top: 0.28rem;
  font-variant-numeric: tabular-nums;
}
/* Entries stay ink and take the accent only on hover, which looks like an
 * oversight until you know the rule: **the front page is clean; orange is for
 * when you venture into the library.**
 *
 * The accent means *cross-reference*. A listing is not cross-referencing
 * anything — it is the catalogue — so colouring it spends the signal before the
 * reader has gone anywhere. Deliberate, and applied identically in the finding
 * aid, search results and the see-also blocks, not just here. Keyboard users get
 * the global :focus-visible ring, so nothing depends on hover alone. */
.results a.entry {
  color: var(--ink);
  text-decoration: none;
  font-size: 1.02rem;
  border-bottom: 1px solid transparent;
  /* Grid items stretch on BOTH axes, and the underline needs stopping on each.
     justify-self keeps it from running the full width of the row; align-self
     keeps the box from growing to the height of the tallest cell, which would
     leave the border floating well below the text it belongs to. Most visible
     in search results, where the reference column carries a record number *and*
     a record type, making the row twice as tall as the title. */
  justify-self: start;
  align-self: start;
}
.results a.entry:hover { color: var(--stamp); border-bottom-color: var(--stamp); }
.results .blurb { grid-column: 2; color: var(--ink-faded); font-size: 0.9rem; margin: 0.1rem 0 0; }

/* The paid placement. Ink, never the accent: a sponsored entry is still a
 * listing, and the accent means cross-reference. Colouring it would also be the
 * archive flagging its own advertisement, which is the opposite of the joke —
 * the marking should be as easy to miss here as it is everywhere else. */
.results .arranged {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  /* Runs into the sentence rather than sitting above it: a disclosure that
     begins its own line is a heading, and a heading announces the placement
     louder than the entry it belongs to. */
  margin-right: 0.35rem;
  white-space: nowrap;
}
.results .arrangement {
  grid-column: 2;
  color: var(--ink-faded);
  font-size: 0.78rem;
  line-height: 1.5;
  margin: 0.5rem 0 0;
  /* The disclosure runs longer than the entry it discloses, which is the point.
     Held to its own measure so it reads as small print rather than as prose. */
  max-width: 34rem;
}

/* A halted transcription. Ruled off from whatever prose arrived before the
 * interruption, because the two have different authors: above the rule is the
 * article being written, below it is the archive explaining itself. */
.halted {
  margin-top: 1.6rem;
  border-top: 2px solid var(--ink);
  padding-top: 1rem;
}
/* Nothing arrived before the interruption, so there is no transcript above to
 * rule off from — and a heavy rule under a hidden panel reads as a mistake. */
.halted-bare { border-top: none; padding-top: 0; }

/* The volumes the previous reader left behind, on a holding nobody has
 * transcribed. A listing, so it carries no reference column for the same reason
 * the halted offer doesn't: a reader who has just been told they cannot have
 * the thing they came for is not helped by call numbers. */
.results.desk li,
.halted .results li { grid-template-columns: 1fr; }
.desk-note {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  color: var(--ink-faded);
  margin: 0.8rem 0 0;
}
.halted-reason {
  margin: 0 0 0.5rem;
  color: var(--ink-faded);
  max-width: var(--measure);
}
/* The offered holdings are a listing, so they stay ink like every other one —
 * and this listing has a job to do, so it carries no reference column: the
 * reader has just been told they cannot have the thing they came for, and a
 * column of call numbers is not what helps. */
.halted .results li { grid-template-columns: 1fr; }

/* --- series facets ------------------------------------------------------- */

.facets {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  padding: 0.7rem 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  margin: 1.4rem 0 0.5rem;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.facets a {
  color: var(--ink-faded);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.facets a:hover { color: var(--link); border-bottom-color: var(--link-rule); }
.facets a.on { color: var(--stamp); border-bottom-color: var(--stamp); }

/* --- boxes: walking one series of the finding aid ------------------------ */

/* No border-top: every `.results li` already carries a bottom rule, so the last
 * entry has drawn this line already and a second one lands directly on it. */
.boxes {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.4rem 1.1rem;
  padding: 0.9rem 0 0;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.boxes span { display: flex; flex-wrap: wrap; gap: 0.4rem 1.1rem; }
/* The forward pair stays right-aligned when the row wraps, so "next" and "last"
 * keep pointing the way they lead rather than collapsing into the back pair. */
.boxes .boxes-on { justify-content: flex-end; margin-left: auto; }
.boxes a {
  color: var(--ink-faded);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.boxes a:hover { color: var(--link); border-bottom-color: var(--link-rule); }

.boxes-note { color: var(--ink-faded); font-size: 0.82rem; margin: 1.4rem 0 0; }

/* --- section label ------------------------------------------------------- */

.label {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faded);
  border-bottom: 1px solid var(--ink);
  padding-bottom: 0.3rem;
  margin: 2.6rem 0 0.4rem;
}
.label:first-child { margin-top: 0; }

/* "Because you consulted…". The shelf is wrapped in a div so that one `hidden`
 * covers the heading and the list together — and that wrapper makes its heading
 * a `:first-child`, which the rule directly above then strips the top margin
 * from. Measured: 0px, against 41.6px on every other module label on the page,
 * so the shelf sat directly against the block above it.
 *
 * Restored on the wrapper rather than by overriding the label, so the rule that
 * keeps a section's opening label tight to the top of its section stays true —
 * which is what it is for, and this heading really is the first thing in its
 * section. Nothing else here: the shelf reuses `.label` and `.results` exactly,
 * because it is a listing like any other and must not look like a special one. */
.because { margin-top: 2.6rem; }

/* A shelf heading under "the nearest shelved holdings". Lighter than .label —
 * it subdivides a section rather than opening one, and a second full rule this
 * close to the first is the doubled-masthead mistake in miniature. Ink, like
 * every other listing. */
.shelf-floor {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  color: var(--ink-faded);
  margin: 1.2rem 0 0.3rem;
}
.shelf-floor a {
  color: var(--ink-faded);
  text-decoration: none;
  border-bottom: 1px dotted var(--rule);
}
.shelf-floor a:hover { color: var(--stamp); border-bottom-color: var(--stamp); }

/* --- the Partial Survey --------------------------------------------------- */

/* Returns on a form, not a dashboard. The classification grid already sets a
 * catalogue card in the typewriter face, so these are the same block at reading
 * size: a survey is meant to be read down, and 0.7rem is a caption. */
.survey-figures {
  font-size: 0.82rem;
  gap: 0.35rem 1.4rem;
  margin: 0 0 0.4rem;
}
/* Terms are links here, unlike anywhere else the grid is used, so they need the
 * rule that `.classification dd a` gets — a dt is faded, and an unstyled anchor
 * inside one would come out browser-blue. */
.classification dt a {
  color: var(--ink-faded);
  text-decoration: none;
  border-bottom: 1px dotted var(--rule);
}
.classification dt a:visited { color: var(--ink-faded); }
.classification dt a:hover { color: var(--stamp); border-bottom-color: var(--stamp); }

/* The Study's instruments. Roman numerals sit where a record number goes, so
 * the reference column is narrower than a listing's and would otherwise leave
 * the titles floating a long way off. */
.instruments .ref { font-style: italic; letter-spacing: 0.08em; }
.instruments li { grid-template-columns: 2.5rem 1fr; }
/* The blurb is placed in column 2 by `.results .blurb`, which assumes the
 * listing's wider reference column. Restated here or the descriptions start
 * under the numerals. */
.instruments .blurb { grid-column: 2; }

/* The movement beside a figure in the Expansion report — "up 12%", "unchanged".
 * Faded and small: a growth office prints its deltas confidently, but this is
 * still a catalogue card, not a dashboard, so the number stays the loud part. */
.movement {
  font-size: 0.86em;
  color: var(--ink-faded);
  padding-left: 0.4rem;
}

/* The Office's own caveats. Set apart from the figures and quieter than them,
 * because a survey's notes are always in smaller type than its returns. */
.survey-note {
  font-size: 0.88rem;
  color: var(--ink-faded);
  margin: 0.5rem 0 0;
  max-width: var(--measure);
}

/* --- stamps -------------------------------------------------------------- */

/* The one place the accent appears at full strength — where a rubber stamp
 * would physically be. Rotated a hair, because stamps never land square. */
.stamp {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--stamp);
  border: 2px solid var(--stamp);
  padding: 0.2rem 0.5rem;
  transform: rotate(-1.6deg);
  opacity: 0.85;
}

/* --- transcription (streaming) ------------------------------------------- */

.transcription {
  font-family: var(--mono);
  font-size: 0.8rem;
  line-height: 1.65;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--ink-faded);
  background: var(--paper-sunk);
  border: 1px solid var(--rule);
  padding: 1rem;
  /* The box pins its own scroll to the newest line (see building.html), so it
   * has to be short enough to actually fit on screen or it is pinning the live
   * transcription to a region below the fold — which is exactly what a phone
   * did: a 26rem box opening 600px down a 730px viewport showed its top sliver
   * and streamed the rest into the dark. min() takes the viewport cap only when
   * that is the smaller of the two, so a desktop window keeps the 26rem window
   * it was designed with and a short one stops overflowing. */
  max-height: min(26rem, 50vh);
  /* iOS resolves vh against the *largest* viewport — the one with the URL bar
   * retracted — so while that bar is showing, 50vh is more than half of what
   * can actually be seen, and the cap under-delivers on the exact platform this
   * was fixed for. dvh tracks the viewport as it actually is. Declared second so
   * browsers that don't know it keep the vh line above; there is no fallback to
   * arrange, because an unsupported declaration is simply dropped. */
  max-height: min(26rem, 50dvh);
  overflow-y: auto;
}

.cursor {
  display: inline-block;
  width: 0.5em;
  height: 1em;
  background: var(--stamp);
  vertical-align: text-bottom;
  animation: blink 1.1s step-end infinite;
}
@keyframes blink { 50% { opacity: 0; } }

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

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

.colophon {
  max-width: 56rem;
  margin: 0 auto;
  padding: 1.5rem 1.25rem 3rem;
  border-top: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 0.66rem;
  line-height: 1.7;
  color: var(--ink-faded);
}
.colophon strong { color: var(--ink); font-weight: 600; }
.colophon p { margin: 0 0 0.7rem; max-width: 46rem; }
.colophon a { color: var(--link); text-decoration: none; border-bottom: 1px solid var(--link-rule); }
.colophon a:hover { border-bottom-color: var(--link); }

/* The genuine disclaimer. Everything else in the footer is in character; this
 * paragraph has to stay legible as a plain statement of fact. */
.colophon-notice { color: var(--ink-faded); }

.colophon-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.2rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--rule);
  margin-top: 0.9rem;
}

:focus-visible { outline: 2px solid var(--stamp); outline-offset: 2px; }

@media (max-width: 46rem) {
  /* Float would strand the text in a narrow gutter; stack instead. */
  .infobox { float: none; width: auto; margin: 0 0 1.5rem; }
}

@media (max-width: 34rem) {
  body { font-size: 16px; }

  /* Demote the acquisition-era instrumentation. The header proper — wordmark,
   * search, nav — is 224px of chrome on a phone and pushed every article a
   * third of the way down the screen. Body becomes a flex column so the trust
   * bar and quota bar can be re-ordered below the prose: the reader now reaches
   * the article without scrolling past five rows of compliance furniture, and
   * the machinery is kept, only moved to where it stops competing with reading.
   *
   * The fixed chrome (consent, support, lightbox) is position:fixed and so is
   * not a flex item — untouched by the reordering. */
  body { display: flex; flex-direction: column; }
  .masthead { order: 0; border-bottom: 2px solid var(--ink); }
  main { order: 1; }
  .chrome-band { order: 2; border-bottom: none; border-top: 2px solid var(--ink); }
  .colophon { order: 3; }

  /* Freed from the top of the screen, the trust bar no longer needs to hoard
   * horizontal space behind a scrollbar — it wraps, showing all four badges as
   * an accreting stack of marks rather than a strip you have to swipe. */
  .trustbar { white-space: normal; overflow-x: visible; }

  /* The support bubble floats in the outer margin on desktop; a phone has no
   * margin, so it sat on top of the last line of prose. It is set-dressing and
   * the footer already carries the finding-aid link it deflects to, so it steps
   * out on mobile rather than cover the reading it parodies helping with. */
  .support { display: none; }

  /* 0.66rem is a caption on a desktop and roughly 10px held at arm's length,
   * which is where the colophon lands now that the band sits above it. Nudged
   * rather than reset: it is still the small print, and the mono face at the
   * bottom of the page is doing the same job it always was. */
  .colophon { font-size: 0.72rem; }

  /* Right alignment is correct in the header, where this strip sits opposite a
   * single nowrap row of badges and reads as the meter on the far end of it.
   * Demoted into the band it is the only right-aligned thing under four
   * left-aligned badges that now wrap — so it hangs off the opposite edge and
   * reads as stray rather than as the last line of the stack. Aligned left it
   * shares the badges' margin and the band becomes one block. The wrap itself
   * is left alone: two lines are fine once they line up with something. */
  .quotabar { text-align: left; }

  .record-head h1 { font-size: 1.6rem; }
  .results li { grid-template-columns: 1fr; }
  .results .blurb { grid-column: 1; }
  /* Any listing child pinned to column 2 needs releasing here, not just the
     blurb: with a single-column template, `grid-column: 2` does not fall back —
     it creates an implicit second column and the element moves out beside the
     stack. The disclosure did exactly that, sitting alongside the blurb at phone
     width while everything around it stacked. */
  .results .arrangement { grid-column: 1; }
  .results .ref { padding-top: 0; }
  .masthead nav { width: 100%; }
  .cta { margin-left: auto; }
  .consent { flex-direction: column; align-items: flex-start; gap: 0.7rem; }
}

/* --- readers also asked --------------------------------------------------- */

/* The SEO accordion, in the archive's own register: a stack of hairline-ruled
 * rows in the typewriter face rather than the rounded cards this pattern
 * normally arrives in. Native <details>, so it works without JavaScript and a
 * crawler reads every answer without opening anything.
 *
 * It sits below the prose with the rest of the machinery. Questions are ink,
 * not accent — same rule as every other listing; the accent is reserved for the
 * cross-reference inside, which is where the reader is actually being sent. */
.alsoasked {
  border-top: 1px solid var(--rule);
  max-width: 46rem;
}

.alsoasked details {
  border-bottom: 1px solid var(--rule);
}

.alsoasked summary {
  cursor: pointer;
  padding: 0.6rem 0;
  color: var(--ink);
  font-size: 1.01rem;
  /* The default triangle is a browser artefact in a page made of hairlines. */
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
}
.alsoasked summary::-webkit-details-marker { display: none; }

/* A typed clerical mark instead: closed asks, open answers. */
.alsoasked summary::before {
  content: '+';
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--stamp);
  flex: none;
}
.alsoasked details[open] summary::before { content: '\2212'; }
.alsoasked summary:hover { color: var(--stamp); }

.alsoasked .answer {
  padding: 0 0 0.85rem 1.35rem;
  max-width: var(--measure);
}
.alsoasked .answer p {
  margin: 0 0 0.5rem;
  color: var(--ink-faded);
  font-size: 0.95rem;
}

/* --- redactions -----------------------------------------------------------
 *
 * The model blacks out dates and names with runs of U+2588 FULL BLOCK. Nobody
 * asked it to and it is perfectly in character, so it is kept — but a bare
 * glyph takes the text colour, which means it inverts with the theme. On cream
 * that is a black bar and reads as a redaction; on a dark background it is a
 * white bar and reads as broken text.
 *
 * So the bar is drawn rather than typed: the glyphs are hidden and the span's
 * own background becomes the mark. Covering the whole run in one span closes
 * the gaps between glyphs that made it look like a font failure rather than a
 * censor's pen.
 *
 * `--ink` and not `currentColor`: currentColor resolves against this element's
 * own `color`, which is transparent two lines below, so the bar computed to
 * fully transparent and the redaction vanished into a gap. Valid CSS, no error,
 * nothing in the console — the usual. `--ink` is redefined per theme, so the
 * bar stays ink in both. */
.redacted {
  background: var(--ink);
  color: transparent;
  border-radius: 1px;
  padding: 0 0.05em;
  /* Dark theme is a microfilm reader, not inverted paper, and that decides this.
   * Ink in both themes means a bright cream slab on a dark ground — which was
   * the original complaint, and making the run solid rather than ragged did not
   * change it: brightness was the problem, not the edges. On film a redaction
   * is an opaque absence, so it goes *darker* than the page and takes a hairline
   * to prove it was put there on purpose rather than failing to render. */
  /* The characters stay in the DOM so the bar keeps the width of what it
   * covers, but they should not be selectable or lifted out by a copy-paste —
   * a redaction that survives Ctrl-C has not redacted much. What a screen
   * reader announces is handled in the markup instead, since CSS cannot say
   * it: the span carries role="img" and a "redacted" label, so the fact of the
   * redaction is conveyed rather than a row of block characters. */
  user-select: none;
  -webkit-user-select: none;
}

/* --- passages -------------------------------------------------------------
 *
 * The commonplace book. Set as quotations rather than as a listing: a passage
 * is something to be read, not an entry to be scanned, so it keeps the serif
 * and the reading measure while the apparatus around it stays mono.
 *
 * No accent on the passage itself. Orange means cross-reference, and a quotation
 * is not pointing at anything — the provenance line beneath it is, and that is
 * where the link goes. */
.passages {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
}

.passages li {
  margin: 0 0 1.9rem;
  padding-left: 1rem;
  border-left: 2px solid var(--rule);
  max-width: var(--measure);
}

.passages .passage {
  margin: 0;
  font-size: 1.03rem;
  line-height: 1.58;
}
/* Typographic quotes, drawn rather than stored: the harvested text has had its
 * marks stripped, so a passage never arrives carrying its own. */
.passages .passage::before { content: '\201C'; }
.passages .passage::after  { content: '\201D'; }

.passages .attrib,
.passages .provenance {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  color: var(--ink-faded);
  margin: 0.45rem 0 0;
}

/* An em dash marks the source of the words. The provenance line below is the
 * archive speaking about the record, not the record speaking, so it gets none. */
.passages .attrib::before { content: '\2014\00a0'; }

/* Readers in residence. Reuses the commonplace book's markup because an account
 * *is* a quoted passage with an attribution, and a second near-identical block
 * of CSS is how two things that should look alike stop looking alike.
 *
 * Tighter than a harvested passage: these run to a sentence where a passage runs
 * to a paragraph, and at the commonplace book's spacing two of them left a hole
 * in the middle of the front page. */
.accounts li { margin-bottom: 1.35rem; }
.accounts-note {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  line-height: 1.7;
  color: var(--ink-faded);
  margin: 0.2rem 0 0;
  max-width: var(--measure);
}

/* `.entry` is styled only inside `.results`, so a provenance link inherited the
 * browser default and rendered blue and underlined — the one colour on the page
 * belonging to no theme at all. Ink, not accent: the line points back at the
 * catalogue, and by the standing rule a listing is not cross-referencing
 * anything, so colouring it would spend the signal. */
.passages .provenance a,
.passages .attrib a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--rule-strong);
}
.passages .provenance a:hover { color: var(--stamp); border-bottom-color: var(--stamp); }

/* "Did you mean" sits above the results in the search engine's own idiom. The
 * suggested title is `.entry` but outside `.results`, so it would inherit
 * browser-default blue without this — the same trap the provenance links hit.
 * Ink with a solid rule: it is a listing, not a cross-reference in prose. */
.did-you-mean {
  margin: 0 0 1.4rem;
  color: var(--ink-faded);
  font-size: 0.95rem;
}
.did-you-mean a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--rule-strong);
}
.did-you-mean a:hover { color: var(--stamp); border-bottom-color: var(--stamp); }

/* The passages field. Same furniture as the masthead's, given room to breathe
 * because it sits in the text column rather than in a header bar. */
.passages-finder {
  max-width: var(--measure);
  margin: 1.5rem 0 0.5rem;
}

/* Both signals, in both directions — the OS hint and the reader's explicit
 * choice — matching how every other themed rule in this file is written. */
@media (prefers-color-scheme: dark) {
  .redacted {
    background: var(--paper-sunk);
    box-shadow: inset 0 0 0 1px var(--rule-strong);
  }
}
:root[data-theme='dark'] .redacted {
  background: var(--paper-sunk);
  box-shadow: inset 0 0 0 1px var(--rule-strong);
}
:root[data-theme='light'] .redacted {
  background: var(--ink);
  box-shadow: none;
}

/* --- disputed matters -----------------------------------------------------
 *
 * Two accounts of one matter, set against each other and left unreconciled.
 * The rule down the left of each is the quotation treatment; what is new is the
 * word between them, which is the archive declining to choose. */
.dispute {
  max-width: var(--measure);
  margin: 0 0 2.4rem;
}

.dispute .account {
  margin: 0;
  padding-left: 1rem;
  border-left: 2px solid var(--rule);
}
.dispute .account p { margin: 0; }

.dispute .versus {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--stamp);
  /* Aligned with the rules above and below rather than centred: the register is
   * a filing system, and the seam between two accounts is a margin note, not a
   * heading over a spread. */
  margin: 0.55rem 0 0.55rem 1rem;
}

.dispute .provenance {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  color: var(--ink-faded);
  margin: 0.4rem 0 0 !important;
}
.dispute .provenance a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--rule-strong);
}
.dispute .provenance a:hover { color: var(--stamp); border-bottom-color: var(--stamp); }
