/* ===========================================================================
   ATHANOR — "The Illuminated Catalogue"

   The owner-approved flagship design (2026-08-03), ported from
   affiliate_site/prototype/flagship.css. One idea: a deep-green realm for the
   topbar and masthead, parchment for everything below it, on every page — the
   brand shell now wraps all four page types, not just the index.

   Brand system (docs/brand/): Illuminated-A lockup, furnace seal, fleur
   divider, gold + deep-green + parchment palette, Cinzel (display) over
   EB Garamond (body). The signature element is the catalogue card: a matted,
   contain-fit cover plate, a small-caps caption row, and a price/CTA foot.

   Type faces are self-hosted (@font-face below) — no CDN, no third-party font
   request. Both families are VARIABLE fonts, so one binary per family serves
   every weight via `font-weight: 400 600` range syntax; declaring 400 and 600
   as separate @font-face src files made browsers fetch the same ~70 KB twice.

   Quality floor: responsive grid, visible :focus-visible states, motion gated
   behind prefers-reduced-motion, no layout shift (aspect-ratio on plates),
   44px minimum tap targets, AA contrast on every text/background pair.
   =========================================================================== */

@font-face {
  font-family: "Cinzel";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("/assets/fonts/cinzel-600-latin.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: "EB Garamond";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("/assets/fonts/eb-garamond-400-latin.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: "EB Garamond";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/eb-garamond-400-italic-latin.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 {
  /* The design IS the theme: dark-green masthead realm, parchment body — for
     every visitor. `only light` stops auto-dark browsers inverting the
     parchment (the masthead is dark BY DESIGN, not by theme). A dark variant
     was built and rejected by the owner; don't reintroduce one by inversion. */
  color-scheme: only light;

  /* brand kit (docs/brand/BRAND_CSS_TOKENS.css) */
  --ink:          #1F1B14;
  --deep-green:   #0E1B14;
  --antique-gold: #7A5E2E;
  --warm-gold:    #C8A96A;
  --parchment:    #F6F1E3;
  --aged-paper:   #E5D7B2;

  /* derived */
  --bg:            var(--parchment);
  --bg-tint:       #efe8d4;
  --panel:         #f2ebd9;
  --panel-edge:    #ddcda6;
  --text:          var(--ink);
  --text-2:        #57503f;
  /* Small-caps labels, captions and accession numbers. Measured 5.09:1 on the
     parchment and 4.83:1 on the card panel — the previous #837863 passed on
     paper but failed AA on the panel, which is where it is mostly used. */
  --text-3:        #6f6550;
  --hairline:      #d5c49d;
  --hairline-soft: #e3d6b4;
  /* Border of an interactive CONTROL (select, text/number/search input, the
     Reset button). WCAG 1.4.11 wants 3:1 for the boundary that identifies a
     component; --hairline is only 1.31-1.52:1 on these fills, which is fine for
     the decorative rules it also draws but not for a control. Alias, not a new
     colour: --antique-gold measures 4.62-5.37:1 on every light fill we use. */
  --control-edge:  var(--antique-gold);
  --accent:        var(--antique-gold);
  --accent-2:      #1c3a2a;
  --price:         #1c3a2a;
  --matte:         #ece2c8;
  --matte-2:       #efe8d4;
  --matte-edge:    #d9c9a2;
  --shadow-1:      0 1px 2px rgba(31,27,20,.07), 0 4px 14px rgba(31,27,20,.06);
  --shadow-2:      0 2px 4px rgba(31,27,20,.10), 0 12px 28px rgba(31,27,20,.12);

  --font-display: "Cinzel", "Trajan Pro", Georgia, "Times New Roman", serif;
  --font-body:    "EB Garamond", Garamond, "Iowan Old Style", Palatino, Georgia, serif;
  --font-ui:      system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --maxw:         1200px;
}

* { box-sizing: border-box; }

/* The toolbar toggles [hidden] on cards/sections; .entry sets display:flex,
   which would otherwise win over the UA [hidden] rule — force it off. */
[hidden] { display: none !important; }

/* NB: no `scroll-behavior: smooth` here — a deliberate omission, matching the
   approved prototype, which never set it either.

   An earlier version of this comment justified the omission by claiming that
   with `smooth` set "Chrome does not move AT ALL" on a fragment navigation to
   #disclosure (scrollY observed stuck at 0 while `auto` jumped to 1747). That
   reason was FALSE and is retracted. Smooth scrolling is animated by the
   compositor; the headless review harness this was measured in never
   composites (rAF does not fire), so the scroll position is simply still 0 at
   the instant it gets sampled. The same rig freezes CSS transitions at frame 0
   and times out on captureScreenshot. It is a property of the measuring
   apparatus, not of Chrome, and not a reason to avoid `smooth`.
   If a future editor wants smooth anchor scrolling, it is safe to add — but
   verify it in a compositing browser, not here. */
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  background-image: radial-gradient(120% 90% at 50% 0%, var(--bg-tint), transparent 60%);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 17.5px;
  line-height: 1.55;
  font-variant-numeric: oldstyle-nums;   /* book typography: text figures */
  text-rendering: optimizeLegibility;
}

a { color: var(--accent); }
img { max-width: 100%; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 clamp(1rem, 3vw, 2rem); }

/* Figures that must stay unambiguous/aligned keep lining (tabular) numerals. */
.price, .accession, .count, .fb-count, .tile-count, .site-foot .built {
  font-variant-numeric: lining-nums tabular-nums;
}

/* Focus indicator — WCAG 1.4.11 needs 3:1 against whatever it lands on, and this
   site has BOTH a parchment body and a deep-green masthead/topbar. Measured, no
   single brand token clears 3:1 on both: --warm-gold is 1.72-1.99:1 on the five
   light surfaces, --antique-gold is 2.17-2.93:1 on the dark ones, --accent-2 and
   --ink are 1.03-1.52:1 on the dark ones. (The old rule was --warm-gold alone:
   1.89:1 on the panel, failing on ~580 focusable elements.)

   So the ring is two-tone, built from two existing tokens — no new brand colour:
     [element] -> 2px --warm-gold (box-shadow) -> 2px --accent-2 (outline) -> page
   On a light surface the OUTER dark band does the work (9.49:1 on the Reset
   button's fill, up to 11.02:1 on parchment); on a dark surface the INNER gold
   band does (5.85-8.40:1 vs fill). The two bands are 5.53:1 against each other,
   so the ring reads as a ring on any background. */
:focus-visible {
  outline: 2px solid var(--accent-2);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--warm-gold);
}

/* The two gold-FILLED controls live on the dark band, where the order above puts
   gold-on-gold inside and a dark outer band on a dark page (1.42-1.52:1). Flip
   the two tones for them: dark inside against the gold fill (7.88:1), gold
   outside against the band (7.88-8.40:1). Both render only when a capture
   backend is configured, so neither is in the current build — fixed anyway so
   turning the form on cannot quietly ship an invisible focus ring. */
.topbar .letter:focus-visible,
.masthead .capture button:focus-visible {
  outline-color: var(--warm-gold);
  box-shadow: 0 0 0 2px var(--deep-green);
}

/* Label text that belongs to screen readers but not to the layout. */
.vh {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* --- Topbar (sitewide utility nav) --------------------------------------- */

.topbar {
  background: #0a130e;
  border-bottom: 1px solid rgba(200,169,106,.38);
}
.topbar .wrap {
  display: flex; align-items: center; gap: 1.2rem;
  min-height: 52px;
}
.topbar .home { display: flex; align-items: center; }
.topbar .home img { height: 30px; width: auto; }
.topbar nav { display: flex; gap: clamp(.9rem, 2.4vw, 1.8rem); margin: 0 auto; }
.topbar nav a {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: .72rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #cbb98c;
  text-decoration: none;
  padding: .35rem 0;
  border-bottom: 1px solid transparent;
}
.topbar nav a:hover,
.topbar nav a[aria-current] { color: #ecd9ae; border-bottom-color: rgba(200,169,106,.6); }
.topbar .letter {
  font-family: var(--font-ui);
  font-size: .72rem;
  letter-spacing: .06em;
  color: #0d1a12;
  background: linear-gradient(180deg, #ddc48e, var(--warm-gold));
  border: 0; border-radius: 2px;
  padding: .42rem .8rem;
  text-decoration: none;
  white-space: nowrap;
}
.topbar .letter:hover { background: linear-gradient(180deg, #e8d3a4, #d2b478); }

@media (max-width: 640px) {
  /* The nav was display:none here, on the assumption the bar still held the
     "letter" CTA. That CTA only renders when AFFILIATE_CAPTURE_ACTION is set,
     and there is no email backend -- so mobile got a full-width bar holding
     nothing but the mark, and Collections was reachable only from the chip
     band and the footer. Two short links need no hamburger. */
  .topbar nav { gap: 1.1rem; }
  /* .75rem block padding takes the tap target from 32px to ~44px (Apple HIG
     minimum) without growing the 52px bar. The border-bottom underline rides
     lower as a result, which only shows on the current page. */
  .topbar nav a { font-size: .82rem; letter-spacing: .1em; padding: .75rem 0; }
  .topbar .letter { margin-left: auto; }
}

/* --- Masthead (frontispiece band) ---------------------------------------- */

.masthead {
  text-align: center;
  padding: clamp(1.8rem, 4.5vw, 3rem) 1rem 2.1rem;
  background:
    radial-gradient(110% 130% at 50% 0%, #17291d 0%, var(--deep-green) 52%, #060d09 100%);
  border-bottom: 1px solid rgba(200,169,106,.4);
  box-shadow: 0 3px 22px rgba(4,9,6,.5);
}
/* The <h1> IS the brand mark (image); never recreate the wordmark in live text. */
.masthead h1 { margin: 0; line-height: 0; }
.masthead .lockup {
  width: clamp(230px, 30vw, 330px);
  height: auto;
  filter: drop-shadow(0 4px 14px rgba(0,0,0,.55));
}
.masthead .tagline {
  font-style: italic;
  font-size: clamp(1rem, 1.6vw, 1.14rem);
  color: #cdbd97;
  max-width: 36rem;
  margin: 1.1rem auto 0;
  line-height: 1.5;
}
.masthead .capture {
  display: flex; justify-content: center; align-items: stretch; gap: .55rem;
  flex-wrap: wrap;
  margin: 1.25rem auto 0;
}
.masthead .capture input {
  font-family: var(--font-ui);
  font-size: .92rem;
  width: min(21rem, 72vw);
  background: rgba(246,241,227,.07);
  /* .45 measured ~2.6-2.9:1 against the masthead band — under the 3:1 the
     boundary of a text input needs (1.4.11). .6 gives ~3.6-4.0:1. A range, not a
     point: the band is a radial gradient, so the exact ratio depends on where on
     it the border sits. Both ends of the range clear 3:1. */
  border: 1px solid rgba(200,169,106,.6);
  border-radius: 2px;
  color: #ecdfc0;
  padding: .7rem .8rem;
}
.masthead .capture input::placeholder { color: #9c9070; }
.masthead .capture button {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #0d1a12;
  background: linear-gradient(180deg, #ddc48e, var(--warm-gold) 55%, #b0925a);
  border: 0; border-radius: 2px;
  padding: .7rem 1.15rem;
  min-height: 44px;
  cursor: pointer;
}
.masthead .capture button:hover { background: linear-gradient(180deg, #e8d3a4, #d2b478 55%, #bd9f66); }
.masthead .micro {
  font-style: italic;
  font-size: .78rem;
  color: #b0a381;                 /* 5.5:1 on the band — AA at this size */
  max-width: 40rem;
  margin: .7rem auto 0;
}
.masthead .micro a { color: #cbb98c; }

/* --- Seam + section furniture -------------------------------------------- */

.seam { text-align: center; margin: 1.5rem 0 0; line-height: 0; }
.seam img { height: 30px; width: auto; opacity: .85; }

.sect-head {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1.1rem;
  margin: 2.2rem 0 .4rem;
}
.sect-head::before, .sect-head::after { content: ""; border-top: 3px double var(--hairline); }
.sect-head h2 {
  font-family: var(--font-display);
  font-weight: 600;
  /* 18px floor: Cinzel below ~18px loses its serifs on a phone
     (docs/strategy/05_SITE_DESIGN.md §2.4). */
  font-size: clamp(1.125rem, 2vw, 1.3rem);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent-2);
  margin: 0;
  text-align: center;
}
.sect-sub {
  text-align: center;
  font-family: var(--font-ui);
  font-size: .72rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-3);
  margin: 0 0 1.3rem;
}

/* --- Collections chip band ------------------------------------------------ */

.chips {
  display: flex; gap: .5rem;
  overflow-x: auto;
  padding: 1.1rem 0 .4rem;
  scrollbar-width: none;
}
.chips::-webkit-scrollbar { display: none; }
.chip {
  flex: 0 0 auto;
  font-family: var(--font-ui);
  font-size: .78rem;
  letter-spacing: .03em;
  color: var(--text-2);
  background: var(--panel);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  padding: .5rem .85rem;
  text-decoration: none;
  white-space: nowrap;
}
.chip b { font-weight: 400; color: var(--text-3); margin-left: .3rem; }
.chip:hover { border-color: var(--warm-gold); color: var(--accent); }
.chip--all { border-style: dashed; }

/* --- Toolbar (sort + filters) -------------------------------------------- */

.toolbar {
  display: flex; align-items: center; gap: .9rem; flex-wrap: wrap;
  border-top: 1px solid var(--hairline-soft);
  border-bottom: 1px solid var(--hairline-soft);
  padding: .55rem 0;
  margin: .4rem 0 1.6rem;
  font-family: var(--font-ui);
  font-size: .78rem;
  color: var(--text-3);
}
.toolbar .spacer { flex: 1 1 0; min-width: 0; }
.toolbar select,
.toolbar input[type="search"],
.toolbar input[type="number"] {
  font-family: var(--font-ui); font-size: .82rem;
  color: var(--text-2);
  background: var(--panel);
  border: 1px solid var(--control-edge);
  border-radius: 2px;
  padding: .38rem .5rem;
}
/* A UA-default placeholder on this fill measures 3.87:1 — under AA for text.
   --text-3 is the palette's designated caption ink: 4.83:1 on the panel. */
.toolbar ::placeholder { color: var(--text-3); opacity: 1; }

/* A <select> is intrinsically as wide as its LONGEST option, and #f-subject
   carries one option per subject in the corpus (159 of them). Behind an opened
   "More filters" that pushed 55px of horizontal overflow onto the document at
   320px and 15px at 360px. Flex items floor at min-content unless told
   otherwise, so the field AND the select each need min-width:0 — measured, each
   is independently worth the full 55px — before either can shrink.

   No max-width here on purpose: a 15rem cap was tried and measured to buy
   exactly 0px of overflow protection (min-width:0 already does all of it) while
   truncating a double-digit share of the subject options in the closed control
   at 1280px. It bought nothing and cost desktop legibility. */
.tb-field { display: flex; align-items: center; gap: .4rem; min-width: 0; }
.tb-field > span { white-space: nowrap; }
.tb-field > select { min-width: 0; max-width: 100%; }
.tb-check { display: flex; align-items: center; gap: .4rem; padding: .3rem 0; }
.tb-search input { width: min(18rem, 60vw); }
.tb-range { display: flex; align-items: center; gap: .35rem; }
.tb-range input { width: 5rem; }

/* The long tail of filters folds away by default. Fully expanded, this block is
   ~330px of form standing between a phone visitor and the first book — the
   burial the design review measured (S1-3). */
/* …and the <details> itself must be allowed to shrink, or none of that matters.
   It is a flex item of .toolbar, so its automatic minimum size is min-content —
   which is still driven by the select's longest OPTION (312px) even though
   max-width clamps the select's used width to 240px. Measured at a 320px
   viewport: .toolbar resolved to 273px while .tb-more stayed 359px and pushed
   the difference onto the document. min-width:0 removes that floor; the panel
   and fields below already have theirs, so the shrink then propagates. */
.tb-more, .tb-search, .tb-range { min-width: 0; }
.tb-more > summary {
  cursor: pointer;
  list-style: none;
  padding: .3rem 0;
  color: var(--accent);
  border-bottom: 1px dotted var(--warm-gold);
}
.tb-more > summary::-webkit-details-marker { display: none; }
.tb-more > summary::after { content: " ▾"; }
.tb-more[open] > summary::after { content: " ▴"; }
.tb-panel {
  display: flex; flex-wrap: wrap; align-items: center; gap: .8rem 1.1rem;
  padding: .8rem 0 .3rem;
}
.tb-reset {
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: .1em;
  font-size: .7rem;
  color: var(--text);
  background: #ece0c4;
  border: 1px solid var(--control-edge);
  border-radius: 2px;
  padding: .5rem .95rem;
  min-height: 44px;
  cursor: pointer;
}
.tb-reset:hover { background: #e2d3b1; }
.fb-count {
  flex: 1 0 100%;
  margin: .35rem 0 0;
  font-size: .72rem;
  color: var(--text-3);
}

/* --- Catalogue grid + card (the signature element) ----------------------- */

.catalogue {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(248px, 1fr));
  gap: 1.5rem 1.4rem;
}
@media (max-width: 560px) {
  .catalogue { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 1rem .8rem; }
  /* Two-up cards are ~165px wide at 375px, and the CTA label is nowrap — side by
     side with the price it pushed ~38px of horizontal overflow onto the whole
     document (measured at 375; 320px went 1-up and was fine, which is why this
     only bites at the most common phone width). Stack the foot instead: the CTA
     gets its own full-width, centred, 44px row. */
  .entry .foot { flex-wrap: wrap; row-gap: .5rem; }
  .entry .foot .cta { flex: 1 1 100%; justify-content: center; }
}

.entry {
  display: flex; flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--panel-edge);
  border-radius: 2px;
  box-shadow: var(--shadow-1);
  padding: .65rem .65rem .85rem;
  position: relative;
}
@media (prefers-reduced-motion: no-preference) {
  .entry { transition: box-shadow .22s ease, transform .22s ease, border-color .22s ease; }
  .entry:hover { transform: translateY(-2px); box-shadow: var(--shadow-2); border-color: var(--warm-gold); }
}

/* The plate: uniform matte, contain-fit — flatters amateur marketplace photos
   by keeping them level and consistently framed. NEVER enlarge them; that is
   the whole reason this design has no hero. */
.plate {
  position: relative;
  aspect-ratio: 3 / 4;
  background: radial-gradient(120% 100% at 50% 30%, var(--matte), var(--matte-2));
  border: 1px solid var(--matte-edge);
  box-shadow: 0 0 0 4px var(--panel), 0 0 0 5px var(--hairline-soft), inset 0 1px 6px rgba(31,27,20,.12);
  margin-bottom: .7rem;
  overflow: hidden;
}
.plate img {
  position: absolute; inset: 7%;
  width: 86%; height: 86%;
  object-fit: contain;
  filter: drop-shadow(0 3px 6px rgba(31,27,20,.28));
}

/* illuminated monogram placeholder when no cover exists */
.plate--empty { display: grid; place-items: center; }
.plate--empty .monogram {
  font-family: var(--font-display);
  font-size: 3.4rem;
  font-weight: 600;
  color: var(--accent-2);
  opacity: .55;
  text-shadow: 0 1px 0 #fff4e0;
}
.plate--empty .glyph {
  position: absolute;
  bottom: .5rem;
  color: var(--antique-gold);
  font-size: 1rem;
  opacity: .75;
}

/* "just listed" corner ribbon */
.ribbon {
  position: absolute; top: 8px; left: -1px;
  z-index: 2;
  font-family: var(--font-ui);
  font-size: .58rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #ecd9ae;
  background: linear-gradient(180deg, #1d3b2a, #12271b);
  border: 1px solid rgba(200,169,106,.5);
  border-left: 0;
  padding: .22rem .55rem .22rem .5rem;
  box-shadow: 0 2px 5px rgba(0,0,0,.25);
}

.caption {
  display: flex; justify-content: space-between; gap: .6rem;
  font-family: var(--font-ui);
  font-size: .62rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: .35rem;
}
/* text-overflow only ever fires on a line that cannot wrap; without nowrap the
   accession number just wrapped and the ellipsis was dead code. */
.caption .accession { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.caption .age { white-space: nowrap; }

.entry h3 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.04rem;
  line-height: 1.3;
  margin: 0 0 .2rem;
  overflow-wrap: break-word;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.entry h3 a { color: var(--text); text-decoration: none; }
.entry h3 a:hover { color: var(--accent); text-decoration: underline; text-decoration-color: var(--warm-gold); }

.entry .byline { font-style: italic; color: var(--text-2); font-size: .92rem; margin: 0 0 .3rem; }

/* Shelfmark: the card's one internal link into the collections layer. */
.entry .shelf {
  font-family: var(--font-ui);
  font-size: .64rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--text-3);
  margin: 0 0 .45rem;
}

/* The curator's own sentence. Rendered only when there IS one. */
.entry .note {
  font-style: italic;
  color: var(--text-2);
  font-size: .88rem;
  line-height: 1.42;
  margin: .1rem 0 .55rem;
}
.entry .note::before { content: "❧ "; color: var(--accent); font-style: normal; }
/* Owner prose, so it can contain anything — a long token must wrap, not widen
   the card (the grid track has no auto floor, but the card is also a flex box). */
.entry .note, .entry .byline { overflow-wrap: break-word; }

.entry .foot {
  margin-top: auto;
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  border-top: 1px solid var(--hairline-soft);
  padding-top: .6rem;
}

.price {
  font-variant-numeric: lining-nums tabular-nums;
  font-weight: 600;
  font-size: 1.22rem;
  color: var(--price);
  white-space: nowrap;
}
.price .cur { font-size: .68rem; vertical-align: .35em; color: var(--text-3); margin-right: .06rem; }

/* --- Call-to-action ------------------------------------------------------ */

.cta {
  display: inline-flex; align-items: center;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: .66rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: #ecd9ae;
  background: linear-gradient(180deg, #1e3d2b, #142c1e 60%, #0e2015);
  border: 1px solid rgba(200,169,106,.45);
  border-radius: 2px;
  padding: .5rem .8rem;
  text-decoration: none;
  white-space: nowrap;
}
@media (prefers-reduced-motion: no-preference) {
  .cta { transition: background .2s ease, color .2s ease; }
}
.cta:hover { color: #f6e7c4; border-color: var(--warm-gold); background: linear-gradient(180deg, #26492f, #1a3624 60%, #122a1b); }

/* Thumb target: 44px minimum wherever a finger is doing the tapping (review
   S3-2). Keyed on `hover: none` as well as width, because a 1024px tablet is a
   touch device that no width breakpoint would catch. Pointer-driven desktop
   keeps the compact button the design was approved with. */
@media (max-width: 900px), (hover: none) {
  .cta { min-height: 44px; padding-top: .7rem; padding-bottom: .7rem; }
  .chip { display: inline-flex; align-items: center; min-height: 44px; }
  .tb-more > summary { min-height: 44px; display: flex; align-items: center; }
}

/* --- Editorial band (mid-grid) ------------------------------------------- */

.guides-band {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: auto 1fr 1fr;
  gap: 1.2rem;
  align-items: center;
  background: radial-gradient(130% 160% at 50% 0%, #17291d, var(--deep-green) 70%);
  border: 1px solid rgba(200,169,106,.4);
  border-radius: 2px;
  padding: 1.3rem 1.5rem;
  margin: .4rem 0;
}
.guides-band .seal { width: 84px; height: 84px; background: url("/assets/brand/athanor-seal.png") center/contain no-repeat; }
.guides-band a { text-decoration: none; display: block; }
.guides-band .g-eyebrow {
  font-family: var(--font-ui); font-size: .62rem; letter-spacing: .2em;
  text-transform: uppercase; color: #bfad84; display: block; margin-bottom: .3rem;
}
.guides-band h3 {
  font-family: var(--font-display); font-weight: 600; text-transform: uppercase;
  letter-spacing: .06em; font-size: .98rem; line-height: 1.4; color: #ecd9ae; margin: 0 0 .25rem;
}
.guides-band p { font-style: italic; font-size: .86rem; color: #cdbd97; margin: 0; }
.guides-band a:hover h3 { color: #f6e7c4; }
@media (max-width: 760px) {
  .guides-band { grid-template-columns: 1fr; text-align: center; }
  .guides-band .seal { margin: 0 auto; }
}

/* --- Colophon footer ----------------------------------------------------- */

.colophon {
  margin-top: 3.2rem;
  border-top: 1px solid var(--hairline);
  text-align: center;
  padding: 2.4rem 1.5rem 3rem;
  color: var(--text-2);
  font-size: .86rem;
}
.colophon .seal {
  width: 108px; height: 108px; margin: 0 auto .7rem;
  background: url("/assets/brand/athanor-seal.png") center/contain no-repeat;
}
/* NB: a `margin` SHORTHAND here silently kills the auto-centering below. */
.colophon .motto {
  font-family: var(--font-ui); font-size: .64rem; letter-spacing: .3em;
  text-transform: uppercase; color: var(--text-3); margin: 0 auto .9rem;
}
.colophon p { max-width: 44rem; margin: .45rem auto; }
.colophon nav { display: flex; justify-content: center; gap: 1.4rem; margin: 1.1rem 0 .6rem; flex-wrap: wrap; }
.colophon nav a {
  font-family: var(--font-display); font-weight: 600; font-size: .68rem;
  letter-spacing: .16em; text-transform: uppercase; color: var(--accent); text-decoration: none;
  padding: .4rem 0;
}
.colophon nav a:hover { text-decoration: underline; text-decoration-color: var(--warm-gold); }
.colophon .built { font-family: var(--font-ui); font-size: .72rem; color: var(--text-3); }

/* --- Affiliate disclosure ------------------------------------------------ */

/* The one-liner, in the brand's own voice, near the top of a page. */
.disclosure-line {
  text-align: center;
  font-size: .85rem;
  color: var(--text-2);
  max-width: 46rem;
  margin: 1.4rem auto;
}
.disclosure-line a { color: var(--accent); }

/* The full text. Lives in the colophon and is the anchor target of every
   "Details / Full disclosure" link on the site. */
.disclosure {
  display: block;
  text-align: left;
  background: var(--panel);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--antique-gold);
  color: var(--text-2);
  font-size: .8rem;
  line-height: 1.5;
  padding: .8rem 1.1rem;
  margin: 1.4rem auto 0;
  max-width: 46rem;
  border-radius: 2px;
  scroll-margin-top: 4rem;
}
.disclosure strong { color: var(--text); }

/* --- Per-listing page ---------------------------------------------------- */

.crumb {
  font-family: var(--font-ui); font-size: .76rem; letter-spacing: .03em;
  color: var(--text-3); margin: 1.4rem 0 0;
}
.crumb a { color: var(--text-2); text-decoration: none; }
.crumb a:hover { color: var(--accent); }
.crumb-sep { color: var(--text-3); margin: 0 .15rem; }

.leaf {
  display: grid;
  grid-template-columns: minmax(230px, 330px) minmax(0, 1fr);
  gap: clamp(1.4rem, 3.5vw, 2.6rem);
  background: var(--panel);
  border: 1px solid var(--panel-edge);
  border-radius: 2px;
  box-shadow: var(--shadow-1);
  padding: clamp(1.2rem, 3vw, 2rem);
  margin: 1.2rem 0 2rem;
}
.leaf .plate { margin-bottom: 0; }
@media (max-width: 680px) {
  /* minmax(0, 1fr), never a bare `1fr`: a bare 1fr is minmax(AUTO, 1fr), and
     that auto floor is min-content — the longest unbreakable run in the column.
     `overflow-wrap: break-word` cannot rescue it, because break-word does not
     reduce min-content sizing (only `anywhere` does).

     The driver is the SELLER HANDLE in .specs, not the title. Handles are single
     unbroken tokens with no wrap opportunity at all — the corpus worst case when
     this was written was "voltaireandrousseaubookshop" (27 chars) — whereas long
     titles carry spaces, hyphens and slashes that all break. So do NOT drop this
     rule on the grounds that titles look short: the longest title is not the
     thing that overflows, and no title-length guard substitutes for it.
     (Deliberately no exact corpus figures here. Three earlier revisions of this
     comment quoted measured numbers that were stale or wrong within days; the
     mechanism is stable, the statistics are not. Re-measure if you need them.) */
  .leaf { grid-template-columns: minmax(0, 1fr); }
  .leaf .plate { max-width: 270px; margin-inline: auto; }
}
.leaf h1 {
  font-family: var(--font-body); font-weight: 600;
  font-size: clamp(1.35rem, 2.6vw, 1.8rem);
  line-height: 1.28; margin: 0 0 .45rem; color: var(--text);
  overflow-wrap: break-word;
}
.leaf .byline { font-style: italic; font-size: 1.1rem; color: var(--text-2); margin: 0 0 .6rem; }
.leaf .note-lead {
  font-style: italic; font-size: 1.06rem; color: var(--text-2);
  border-left: 3px solid var(--warm-gold);
  padding-left: .9rem; margin: .8rem 0 1.1rem; line-height: 1.5;
  overflow-wrap: break-word;
}
.leaf .note-lead .who {
  display: block; font-family: var(--font-ui); font-style: normal;
  font-size: .6rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--text-3); margin-top: .4rem;
}

.specs { list-style: none; margin: 0 0 1.2rem; padding: 0; }
.specs li { display: flex; gap: 1rem; padding: .34rem 0; border-bottom: 1px dotted var(--hairline); font-size: .95rem; }
/* The value cell is a flex item, so it floors at min-content — a long seller
   handle or subject phrase widened the row and overflowed the page at 320px.
   min-width:0 removes the floor; break-word then wraps inside the word. */
.specs li > span:not(.k) { min-width: 0; overflow-wrap: break-word; }
.specs .k {
  font-family: var(--font-ui); font-size: .68rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-3); min-width: 6.4rem; padding-top: .2rem;
}
.tag {
  display: inline-block;
  font-family: var(--font-ui);
  font-size: .7rem;
  letter-spacing: .04em;
  padding: .08rem .55rem;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  color: var(--text-2);
  background: #f3ead8;
}

.buy { display: flex; align-items: center; gap: 1.2rem; flex-wrap: wrap; }
.buy .price { font-size: 1.7rem; }
.buy .cta { font-size: .8rem; padding: .72rem 1.3rem; min-height: 44px; }

/* --- Subject links ------------------------------------------------------- */

.subject-link {
  color: inherit;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-decoration-color: var(--warm-gold);
  text-underline-offset: 2px;
}
.subject-link:hover { color: var(--accent); text-decoration-style: solid; }

/* --- Collection page + hub ----------------------------------------------- */

.collection-header { text-align: center; margin: 1.8rem auto 1.2rem; max-width: 46rem; }
.collection-header .eyebrow {
  display: inline-block;
  font-family: var(--font-ui);
  text-transform: uppercase;
  letter-spacing: .22em;
  font-size: .72rem;
  color: var(--text-3);
  margin: 0 auto .5rem;
  padding: 0 1rem .4rem;
  border-bottom: 3px double var(--hairline);
}
.collection-header h1 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.6rem, 4vw, 2.4rem);
  line-height: 1.15;
  letter-spacing: .06em;
  text-transform: uppercase;
  margin: .2rem 0 .5rem;
  color: var(--accent-2);
  overflow-wrap: break-word;
}
.collection-intro {
  color: var(--text-2);
  font-style: italic;
  font-size: 1.02rem;
  margin: 0 auto;
  max-width: 40rem;
}
.collection-foot { margin: 2rem 0 1rem; text-align: center; }
.collection-foot a { color: var(--accent); text-decoration: none; }
.collection-foot a:hover { text-decoration: underline; text-decoration-color: var(--warm-gold); }

/* hub tiles reuse the .entry shell (card frame + hover lift) */
.collection-tile { text-decoration: none; color: var(--text); }
.collection-tile h3 {
  font-family: var(--font-body);
  font-size: 1.04rem;
  font-weight: 600;
  text-align: center;
  margin: .1rem 0 .2rem;
}
.collection-tile .tile-count {
  margin: 0;
  text-align: center;
  font-family: var(--font-ui);
  font-size: .68rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--text-3);
}
.collection-tile:hover h3 { color: var(--accent); }

/* --- Misc ---------------------------------------------------------------- */

/* dev banner shown only when affiliate IDs are placeholders */
.devnote {
  background: #f4eccf;
  border: 1px dashed var(--antique-gold);
  color: #6b551f;
  font-size: .8rem;
  padding: .6rem 1rem;
  margin: 1.2rem auto;
  border-radius: 2px;
  text-align: center;
}

.empty-state { text-align: center; color: var(--text-2); font-style: italic; padding: 3rem 1rem; }
/* The 404's lead line. Was the last inline style="" left in dist/. */
.empty-state .ended-lead { font-size: 1.3rem; }
