/* ==========================================================================
   Sickness Medicine True Self
   The cover art is the design system. The site is night; the excerpt is the
   one lit page inside it. That contrast is the argument for the book, made
   structurally rather than in copy -- do not flatten it.
   ========================================================================== */

@font-face {
  font-family: "Nanum Myeongjo";
  src: url("../fonts/nanum-myeongjo-latin.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Spectral SC";
  src: url("../fonts/spectral-sc.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "IM Fell Great Primer SC";
  src: url("../fonts/im-fell-great-primer-sc.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Source Serif 4";
  src: url("../fonts/source-serif-4.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Source Serif 4";
  src: url("../fonts/source-serif-4-italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
}

:root {
  /* The ground is sampled from the cover's water (#10222C) -- the art's own
     blue, not the teal it used to be. --deep/--edge/--edge-text are rebuilt on
     that hue at 1.8x their old saturation, which is enough to read as blue
     without becoming the link-blue that would fight the gold links; each was
     then re-solved for lightness so its measured ratio survives the move:
     --edge holds its 1.76:1 border visibility (now 1.77) and --edge-text its
     4.88:1 as text (now 4.90). --gold/--pale/--amber were re-checked against
     the new ground and all still clear 4.5:1 (6.51, 11.11, 5.03). */
  --ink:       #10222C;
  --deep:      #193C4F;
  --edge:      #2F4B5A;
  --edge-text: #6493AC; /* --edge is a border/rule color at 1.77:1 on --ink; too faint to read as text */
  --gold:      #CD9B4B;
  --pale:      #ECD2A1;
  --amber:     #C67E44; /* lightened from #A26634 (3.52:1 on --ink) to clear 4.5:1 for text on the dark ground */
  --amber-paper: #955C2C; /* darker sibling for amber text set on --paper, where a light amber would wash out */
  --paper:     #F7F3EA;
  --paper-ink: #1A1A1A;
  --paper-rule: rgba(26, 26, 26, 0.32); /* hairline for rules set on --paper; --edge is tuned for the dark ground */
  --paper-rule-heavy: rgba(26, 26, 26, 0.5); /* the book's luma(50%) strokes: the readout's two 2pt edges */

  --font-title:    "Nanum Myeongjo", Georgia, serif;
  --font-sc:       "Spectral SC", Georgia, serif;
  --font-epigraph: "IM Fell Great Primer SC", Georgia, serif;
  --font-body:     "Source Serif 4", Georgia, serif;

  --measure: 34em;

  /* The site is night: native scrollbars, form chrome and Safari's overscroll
     should be too, or a rubber-band scroll flashes white. */
  color-scheme: dark;
}

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

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

body {
  margin: 0;
  background: var(--ink);
  color: var(--pale);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.75;
}

img { max-width: 100%; height: auto; display: block; }

a { color: var(--gold); text-underline-offset: 0.18em; }
a:hover { color: var(--pale); }

/* Chromium's default focus ring measures 2.34:1 against --ink, under WCAG
   2.2's 3:1 for a non-text indicator. Measured in-browser: --gold is 6.57:1
   on the night ground, but only 2.24:1 on the cream band, so the paper
   sibling takes over inside .band--paper (4.93:1). The 3px offset keeps the
   ring clear of .btn--primary's own gold fill. */
:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}
.band--paper :focus-visible { outline-color: var(--amber-paper); }

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

.wrap {
  width: min(100% - 2.5rem, 62rem);
  margin-inline: auto;
}

/* Three levels of vertical space, not one constant. At the old 9rem the gap
   between two sections' content was 18rem at desktop, which read as unrelated
   islands rather than a paced document. Ordinary bands come down; the cream
   excerpt keeps more air because it is the page's one tonal shift; the slim
   bands stay genuinely subordinate. */
.band { padding: clamp(3.5rem, 8vw, 6.5rem) 0; }

/* A band holding one line. Full band padding around a single sentence reads
   as an empty section rather than an aside. */
.band--slim { padding: clamp(2rem, 4vw, 3.25rem) 0; }

.band--paper {
  color-scheme: light;
  background: var(--paper);
  color: var(--paper-ink);
  padding: clamp(4.5rem, 10vw, 8rem) 0;
}

.band { position: relative; }
.band + .band { border-top: 1px solid var(--edge); }

/* An alchemical mark sitting on the rule between sections, the way a fleuron
   sits in a printed break. Drawn rather than typed: the four element symbols
   live at U+1F701-1F704, which none of this site's faces carry, so a character
   would fall back to whatever symbol font the machine happens to have -- Apple
   Symbols on a Mac, frequently nothing at all on Android. As SVG they render
   identically everywhere, inherit currentColor, and cost no font.

   The horizontal padding is what breaks the rule: the mark paints the band's
   own ground over it, so the hairline appears to stop and resume. */
.band-mark {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 21px;
  height: 21px;
  padding: 0 14px;
  box-sizing: content-box;
  background: var(--ink);
  color: var(--gold);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.3;
  stroke-linejoin: round;
}
.band--paper + .band, .band + .band--paper { border-top: 0; }

/* --- running head -----------------------------------------------------------
   The one piece of shared navigation, kept as quiet as a book's running head:
   small caps in --edge-text over a hairline, so the hero still leads. */
.running-head {
  font-family: var(--font-sc);
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  border-bottom: 1px solid var(--edge);
}
.running-head nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.75rem;
  padding-block: 0.9rem;
}
.running-head a { color: var(--edge-text); text-decoration: none; }
.running-head a:hover { color: var(--gold); }
.running-head [aria-current] { color: var(--amber); }

/* --- type ----------------------------------------------------------------- */

h1, h2, h3 {
  font-family: var(--font-title);
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: 0.01em;
  color: var(--gold);
  margin: 0 0 1.5rem;
}

/* The title is set in caps, as it is on the cover. Caps need more tracking
   than mixed case at display size or they close up. */
h1 {
  font-size: clamp(2.25rem, 7vw, 4.25rem);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
h2 { font-size: clamp(1.5rem, 3.5vw, 2.25rem); }
h3 { font-size: 1.15rem; color: var(--pale); }

.band--paper h1, .band--paper h2, .band--paper h3 { color: var(--paper-ink); }

/* Spectral SC is a true small-caps face: its lowercase glyphs ARE the small
   caps. `text-transform: uppercase` was converting them to full-height display
   capitals, which is exactly what the face exists to avoid -- so the transform
   is gone and the copy's own casing does the work. Tracking comes in from
   0.2em, which was set for transformed caps and is loose for real ones.
   Only the hero byline uses this now -- the section labels it used to style
   were consolidated into .section-title below. */
.eyebrow {
  font-family: var(--font-sc);
  font-size: 0.8rem;
  line-height: 1.4;
  letter-spacing: 0.15em;
  color: var(--amber);
  margin: 0 0 1.75rem;
}

/* One title per section, not two. Sections used to carry a small amber label
   above a large gold heading, which said the same thing twice at two scales;
   where both existed the heading's WORDS survived and the label's TREATMENT
   did. Sized between the two it replaces -- bigger than the old label, well
   short of the old heading -- so a section announces itself without shouting.

   .section-title (0,1,0) outranks the h1,h2,h3 rule (0,0,1) for everything
   they share; font-weight is the one property that rule does not set. */
.section-title {
  font-family: var(--font-sc);
  font-size: 1.1rem;
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: 0.11em;
  color: var(--amber);
  margin: 0 0 1.75rem;
  max-width: var(--measure);
}

.band--paper .section-title { color: var(--amber-paper); }

/* TRIAL -- side headings. At desktop the prose column hugged the left of a
   62rem wrap and left the right half empty. From 64rem each section title
   hangs in a left margin beside its text, the way older books print side
   headings. Self-contained: delete this block to revert. The collage phase
   bands are excluded; their grids want the full width. */
@media (min-width: 64rem) {
  .band:not(:has(.gallery)) > .wrap:has(> .section-title) {
    position: relative;
    padding-left: 13rem;
  }
  .band:not(:has(.gallery)) > .wrap > .section-title {
    position: absolute;
    left: 0;
    top: 0.35em;
    width: 10.5rem;
    text-align: right;
    font-size: 1rem;
    margin: 0;
  }
}

.lede {
  font-size: 1.2rem;
  max-width: var(--measure);
}

/* The one-line pitch under the cover's litany. Small caps so it reads as a
   label on the book rather than another sentence of it. */
/* The cover breaks the litany into two blocks; the second is a continuation,
   so it sits closer than a paragraph gap and never takes a capital treatment
   of its own -- the mixed case in the markup is the cover's and is left
   exactly as it is. */
.lede--second { font-size: 1.rem; margin-top: -0.5em; }

.tagline {
  font-family: var(--font-sc);
  font-size: 0.95rem;
  letter-spacing: 0.08em;
  color: var(--pale);
  margin-bottom: 2.5rem;
}

p { max-width: var(--measure); margin: 0 0 1.35em; }
p:last-child { margin-bottom: 0; }

/* --- buttons -------------------------------------------------------------- */

.btn {
  display: inline-block;
  font-family: var(--font-sc);
  font-size: 0.85rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.85em 1.6em;
  border: 1px solid var(--gold);
  color: var(--gold);
  margin: 0 0.75rem 0.75rem 0;
}
.btn:not(.btn--pending):hover { background: var(--gold); color: var(--ink); }
.btn--primary { background: var(--gold); color: var(--ink); }

/* Not a link until there is somewhere to go. Keeps the author's words and the
   button's footprint, but is not focusable and does not pretend to act -- a
   dashed edge and the quiet colour say "pending" without a tooltip. */
.btn--pending {
  border-style: dashed;
  border-color: var(--edge-text);
  color: var(--edge-text);
  cursor: default;
}
.btn--primary:hover { background: var(--pale); border-color: var(--pale); }

/* --- the hero ------------------------------------------------------------
   The cover used to close the hero at the full 62rem column, so the page
   opened on a wall of cover art and the title had to be scrolled past. Type
   leads; the cover is a supporting object beside it, and stacks under it when
   there is no room to sit alongside.

   .hero__cover's max-width is the other half of the <picture>'s `sizes`
   attribute -- change one and change the other. The intrinsic width/height on
   the <img> stay put: they are what reserves the box and keeps the hero from
   shifting when the image arrives. */

/* The cover's night sea is nearly --ink, so without an edge the book dissolves
   into the page. A hairline, the same one the plates carry, makes it an
   object. */
.hero__cover img { width: 100%; outline: 1px solid var(--edge); }

/* Narrow screens have no room for a column beside the type, and the cover
   stranded below the buttons sat 1000px down -- an afterthought nobody
   scrolled to. It goes above the title instead, at a size that identifies the
   book without becoming the wall of art this hero was rebuilt to avoid. The
   DOM order is unchanged, so the image still follows the title for a screen
   reader; only the visual order flips. */
.hero { display: flex; flex-direction: column; }
.hero__cover { order: -1; margin-bottom: 2.25rem; }

.hero__cover picture { display: block; max-width: 170px; }

.hero__actions { max-width: none; }

@media (min-width: 34rem) {
  .hero__cover picture { max-width: 220px; }
}

@media (min-width: 58rem) {
  /* The type column runs longer than the cover, so `align-items: start` left
     a visible gap under the image. Centring turns that into balanced negative
     space on both sides of the object. Deliberately NOT sticky: the problem is
     composition, and making the cover follow the scroll would turn a still
     page into a piece of behaviour. */
  .hero__cover { order: 0; margin-bottom: 0; align-self: center; }
  .hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: clamp(2.5rem, 5vw, 4.5rem);
    align-items: start;
  }
  .hero__cover picture { max-width: 340px; }
}

/* The litany is the cover's title-page block, not a paragraph: a size down,
   tighter leading and balanced lines so it stacks the way a Victorian title
   page does. The words and their casing are the cover's and stay untouched;
   the "and then" continuation is set in italic. */
.hero .lede {
  font-size: 1.05rem;
  line-height: 1.55;
  max-width: 30em;
  text-wrap: balance;
}
.hero .lede--second { font-style: italic; }

/* --- the excerpt: the lit page -------------------------------------------- */

/* .band--paper is cream-on-black; the light --amber tuned for the dark
   ground washes out here, so anything amber inside it drops to the paper
   sibling. */
.band--paper .eyebrow,
.band--paper .plate figcaption,
.band--paper .dl-row .meta,
.band--paper .elision { color: var(--amber-paper); }

/* --- the apothecary broadsheet -------------------------------------------
   Part II stages its interstitials as a patent-medicine handbill, and
   ../smts-mainbook/content/part2_case_notes/_style.typ is the authority for
   every proportion below. What the book does, and what this reproduces:

     apothecary-masthead   IM Fell small caps at 19pt, a 52%-wide hairline,
                           then the pitchline in the emphasis voice (Spectral
                           SC -- NOT italic serif, which is what this used to
                           set) and an italic serif provenance at 9.5pt.
     apothecary-aside      the barker, sans, 10.5pt.
     apothecary-field      an IM Fell small-caps label at the SAME size as its
                           serif body, 0.15em above it, the block closed at
                           1.2em. Tight, not airy: a run of labelled fields,
                           not a run of web headings with sections under them.
     apothecary-rule       a short centered hairline between movements.
     the readout           mono, bold, two 2pt luma(50%) strokes left and
                           right and nothing top or bottom.

   What is deliberately NOT reproduced is the object: no frame, no border, no
   simulated paper stock. Drawing a picture of a page inside a page is one
   skeuomorphic step too far -- the three registers and the measure are what
   make this read as the book, and they do it without the costume. */

/* 40rem put the barker at a measured 83 characters per line. Sans-serif text
   loses the line above ~75; 36rem brings it to roughly 72. */
.handbill {
  max-width: 36rem;
  margin-inline: auto;
  font-size: 1rem;
}

/* The frame is the margin now. Inside it the box width IS the measure, so
   the site-wide 34em cap would only produce a ragged right edge inside a
   centered bill. */
.handbill p { max-width: none; }

.ad-masthead { text-align: center; margin: 0 0 2rem; }

.ad-masthead h2 {
  font-family: var(--font-epigraph);
  font-size: clamp(1.45rem, 5vw, 2rem);
  letter-spacing: 0.06em;
  line-height: 1.2;
  margin: 0;
}

/* The 52%-width hairline under the title in the Typst masthead. */
.ad-masthead hr {
  border: 0;
  height: 1px;
  width: 52%;
  background: var(--paper-rule);
  margin: 0.7rem auto 0.9rem;
}

/* emphasis-voice in the book, which is Spectral SC. */
.ad-masthead .ad-pitchline {
  font-family: var(--font-sc);
  font-size: 1rem;
  letter-spacing: 0.05em;
  line-height: 1.35;
  margin: 0 0 0.9rem;
}

.ad-masthead .ad-provenance {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--amber-paper);
  margin: 0;
}

/* The barker. Sans on purpose -- this is the only sans on the site and it is
   doing the same job it does in the book. No webfont: a system stack is the
   honest way to get a register change without a fifth face in the colophon.
   Justified, because a handbill's barker column is: the ragged edge is what
   made this read as an article. The field column below is NOT justified: at
   ~350px it opened rivers, and a labelled field on a printed form is ragged
   anyway. */
.ad-barker {
  font-family: ui-sans-serif, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  font-size: 0.95rem;
  line-height: 1.55;
}

.ad-barker p { margin-bottom: 0.85em; }

/* apothecary-rule(width: 30%). */
.ad-rule {
  border: 0;
  height: 1px;
  width: 30%;
  background: var(--paper-rule);
  margin: 2.25rem auto;
}

/* The fields. A label on a bottle sits beside what it labels, so above 42rem
   it does: a small-caps rail on the left, the field's body in a column of its
   own, and a hairline across both opening each row the way a ruled form does.
   Below that there is no room for a rail, and it falls back to exactly the
   book's arrangement -- label tight above body. */
.ad-fields {
  margin: 0;
  border-bottom: 1px solid var(--paper-rule);
}

/* The elision sits between two field lists, and the first one's border-bottom
   met the next list's dt border-top -- two hairlines with the asterisks
   trapped between them. The cut should read as a cut, not as a boxed row. */
.ad-fields:has(+ .elision) { border-bottom: 0; }

.ad-fields dt {
  font-family: var(--font-epigraph);
  font-size: 1rem;
  letter-spacing: 0.08em;
  line-height: 1.4;
  border-top: 1px solid var(--paper-rule);
  padding-top: 1.1rem;
}

.ad-fields dd {
  margin: 0.15em 0 0;
  padding-bottom: 1.2rem;
  font-size: 1rem;
}

.ad-fields dd p { margin-bottom: 0.8em; }
.ad-fields dd p:last-child { margin-bottom: 0; }

@media (min-width: 42rem) {
  .ad-fields {
    display: grid;
    grid-template-columns: 7.5em minmax(0, 1fr);
    column-gap: 1.75rem;
  }
  .ad-fields dt {
    grid-column: 1;
    text-align: right;
    padding-bottom: 1.2rem;
  }
  .ad-fields dd {
    grid-column: 2;
    margin-top: 0;
    border-top: 1px solid var(--paper-rule);
    padding-top: 1.1rem;
  }
}

/* The equation the whole book is haunted by. It is set as a line, not a
   sentence, so it gets to sit on its own. */
.ad-equation {
  font-family: var(--font-sc);
  letter-spacing: 0.12em;
  white-space: nowrap;
}

/* The cut where the book's three-phase Effects field was. Marked, not hidden:
   it reads as an elision inside the bill, not as an ornament. */
.elision {
  text-align: center;
  letter-spacing: 0.6em;
  text-indent: 0.6em; /* letter-spacing trails the last glyph; put it back */
  font-size: 0.8rem;
  margin: 1.75rem 0;
}

/* v(3em) before the countdown, v(2em) after: the ride gets air on both sides
   of it, and it is the label on the readout rather than an afterthought. */
.ad-countdown {
  font-family: var(--font-epigraph);
  font-size: clamp(1.15rem, 3.5vw, 1.4rem);
  letter-spacing: 0.06em;
  line-height: 1.3;
  text-align: center;
  margin: 3rem 0 1.75rem;
}

.ad-readout {
  border-left: 2px solid var(--paper-rule-heavy);
  border-right: 2px solid var(--paper-rule-heavy);
  padding: 1.4em 1em;
  margin: 0 auto;
  max-width: 26em;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: clamp(0.75rem, 2.4vw, 0.8rem);
  font-weight: 700;
  line-height: 2.4;
  text-align: center;
  text-transform: none;
}

.ad-readout p { margin: 0; }

/* The three movements that close the bill. In the book: a 30%-wide centered
   hairline, then the pullquote and its one-line gloss in the literary serif,
   then the void stanza back in the barker's sans -- the same voice that
   opened the pitch, which is the point of ending in it. */

/* .ad-rule is already defined above; this one only needs more air, because it
   separates a movement rather than two blocks of the same movement. */
.ad-readout + .ad-rule { margin-top: 3.5rem; }

.ad-pullquote {
  margin: 0 auto;
  max-width: 30em;
  text-align: center;
}

.ad-pullquote p {
  font-family: var(--font-body);
  font-size: 1.1rem;
  font-style: italic;
  margin-bottom: 0.9em;
}

.ad-pullquote cite {
  font-style: normal;
  font-size: 0.95rem;
  color: var(--amber-paper);
}

/* Qualified with .handbill: `.handbill p` is (0,1,1) and a bare class is
   (0,1,0), so an unqualified .ad-gloss/.ad-void loses its measure entirely --
   both computed to max-width:none before this. */
.handbill .ad-gloss {
  text-align: center;
  font-style: italic;
  font-size: 0.95rem;
  margin: 2rem auto 0;
  max-width: 30em;
}

/* Sans, like the barker: the bill ends in the voice it opened in. */
.handbill .ad-void {
  font-family: ui-sans-serif, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  text-align: center;
  font-size: 1rem;
  line-height: 1.9;
  margin: 3.5rem auto 0;
  max-width: 30em;
}

.ad-void b { font-weight: 700; }


/* Justification is what a printed column does, and hyphenation is what makes
   it survivable. Only above the narrow breakpoint: at 375px the lines are too
   short to justify without rivers. */
@media (min-width: 34rem) {
  .ad-barker p {
    text-align: justify;
    hyphens: auto;
  }
}

/* --- you might arrive here ----------------------------------------------
   Six conditions, set as a litany: no bullets, no numerals, no columns. They
   are long and uneven, so the only structure they need is a hairline between
   them and room to breathe. The sixth turns rather than sorts, so it is
   unruled and set up a size. */

.arrivals {
  list-style: none;
  padding: 0;
  margin: 0;
  max-width: 42em;
}

.arrivals li {
  padding-bottom: 1.75rem;
  margin-bottom: 1.75rem;
  border-bottom: 1px solid var(--edge);
}

/* Last item keeps its spacing but drops the rule -- a trailing hairline with
   nothing under it reads as a missing seventh entry. */
.arrivals li:last-child { border-bottom: 0; padding-bottom: 0; }

/* The litany's repeated opening, set as a small-caps run-in the way older
   books open a paragraph. Spectral SC's lowercase IS its small caps. */
.lead-in {
  font-family: var(--font-sc);
  letter-spacing: 0.06em;
  color: var(--gold);
}

/* The coda steps outside the list: it addresses the reader who matched none
   of the six, so it is unruled, set up a size, and given room from the list
   it is answering. */
.arrivals-coda {
  max-width: 42em;
  margin-top: 2.75rem;
  font-size: 1.15rem;
  color: var(--pale);
}

/* The author's note on the collages page. Its last two sentences have a page
   of their own in the memoir, so here they are set apart from the paragraphs
   above them; the sign-off closes the measure on the right, as it does in
   the book. */
.note-coda {
  margin-top: 2.25rem;
  font-style: italic;
  color: var(--pale);
}

.note-signoff { text-align: right; }

/* The collages section's call to action, moved out of a style attribute. */
.collages-cta { margin-top: 3rem; }

/* --- the koan --------------------------------------------------------------
   Blue Cliff Record case 87, where the book's title comes from. It closes the
   page, so it is centred and set a size up from the body. */

.koan {
  margin: 0 auto;
  max-width: 34em;
  text-align: center;
}

.koan p {
  max-width: none;
  font-size: 1.15rem;
  font-style: italic;
  color: var(--pale);
  margin-bottom: 1.25em;
}

.koan cite {
  font-family: var(--font-epigraph);
  font-style: normal;
  font-size: 0.9rem;
  letter-spacing: 0.12em;
  color: var(--amber);
}

/* --- cards and plates ----------------------------------------------------- */

/* .cards is for UNIFORM items only: the row of three same-size plates on
   index.html. Its default `align-items:
   stretch` is deliberate and load-bearing there -- it is what squares the
   bordered tiles off row by row; setting `align-items: start` instead leaves
   them visibly ragged, which is worse.
   It is NOT a general grid. collages.html used to mix a 304px-square plate
   and a bare text tile in one track, and stretch duly inflated every tile to
   the plate's height. The fix is not to unset stretch, it is to stop mixing:
   collages.html uses .gallery, below. */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 2.5rem;
  margin-top: 3.5rem;
}

/* Three plates, three columns, from tablet up. auto-fit found room for only
   two at 820px and stranded the third on a row of its own. */
@media (min-width: 34rem) {
  #collages .cards { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.5rem; }
}

.plate { margin: 0; }
.plate .thumb img { border: 1px solid var(--edge); transition: border-color 0.2s; }
.plate .thumb:hover img,
.plate .thumb:focus-visible img { border-color: var(--gold); }
.plate figcaption {
  font-family: var(--font-sc);
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  color: var(--amber);
  margin-top: 0.7rem;
}
.plate figcaption b { color: var(--pale); font-weight: 400; }

/* --- collage gallery ------------------------------------------------------
   Every plate on collages.html is a thumbnail in its phase's grid. Each cell
   is square and the image is contained, not cropped: Plate 3 is not square,
   and the book itself refuses to trim it to fit (`bleed: false`), so the
   site does not either.

   A fixed four-column grid (two below 48rem), not auto-fill: thumbnails line
   up down the whole page, and a phase of two or three leaves empty columns
   the way a printed plate grid does, rather than wrapping 3+1. */
.gallery {
  list-style: none;
  margin: 2.5rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2.25rem 1.75rem;
}
@media (min-width: 48rem) {
  .gallery { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* A phase band holds one row of plates; full band padding stranded each one
   in dark space. */
.band:has(.gallery) { padding: clamp(2.5rem, 5vw, 4rem) 0; }

.thumb {
  display: block;
  text-decoration: none;
  /* "Close" returns here by fragment; keep the plate off the viewport edge. */
  scroll-margin-block: 20vh;
}
/* No ground and no border on the cell: Plate 3 is portrait, and a filled
   square put a slab of blue either side of it that is not part of the art.
   The hover/focus signal moves to the caption instead. */
.thumb img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
}

.thumb__caption {
  display: block;
  font-family: var(--font-sc);
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  line-height: 1.6;
  color: var(--amber);
  margin-top: 0.7rem;
}
.thumb__caption b { color: var(--pale); font-weight: 400; transition: color 0.2s; }
.thumb:hover .thumb__caption b,
.thumb:focus-visible .thumb__caption b { color: var(--gold); }

/* --- lightbox -------------------------------------------------------------
   CSS-only: a lightbox is shown while its id is the URL fragment, so every
   control is an ordinary link and the site stays free of JavaScript. The
   cost is that there is no Escape key; Close, the backdrop and the browser's
   Back button all dismiss it. display:none (not visibility) is load-bearing:
   it is what keeps each lazy 2400px image from being fetched until its plate
   is actually opened. */
.lightbox {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 10;
  padding: 1rem;
  justify-items: center;
  align-content: center;
  gap: 0.75rem;
}
.lightbox:target { display: grid; }

body:has(.lightbox:target) { overflow: hidden; }

.lightbox__backdrop {
  position: absolute;
  inset: 0;
  background: #081218; /* solid: at 0.97 the page behind showed through */
}

.lightbox__figure {
  position: relative;          /* above the backdrop */
  margin: 0;
  display: grid;
  justify-items: center;
}
/* The figure hugs its image so the caption and controls sit right under it
   at any aspect ratio; 8rem is what the caption and nav take below. */
.lightbox__figure img {
  max-width: 100%;
  max-height: calc(100vh - 8rem);
  max-height: calc(100dvh - 8rem);
  width: auto;
  height: auto;
}
.lightbox__figure figcaption {
  font-family: var(--font-sc);
  font-size: 0.82rem;
  letter-spacing: 0.1em;
  color: var(--amber);
  margin-top: 0.6rem;
  text-align: center;
}
.lightbox__figure figcaption b { color: var(--pale); font-weight: 400; }

.lightbox__nav {
  position: relative;
  display: flex;
  gap: clamp(1rem, 5vw, 3rem);
  font-family: var(--font-sc);
  font-size: 0.85rem;
  letter-spacing: 0.1em;
}
/* 44px tap targets: the controls are the only way out on a phone. */
.lightbox__nav a {
  text-decoration: none;
  padding: 0.75rem 1rem;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

/* On a phone the plate runs edge to edge. */
@media (max-width: 34rem) {
  .lightbox { padding: 0.5rem 0; }
  .lightbox__nav { gap: 0; }
}

/* No JS means no focus trap; this is the CSS-only guard. With a plate open,
   the footer behind the overlay leaves the tab order. */
body:has(.lightbox:target) footer,
body:has(.lightbox:target) .running-head { visibility: hidden; }

/* --- downloads ------------------------------------------------------------ */

.downloads { margin-top: 2.5rem; }

.dl-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: baseline;
  padding: 1.6rem 0;
  border-bottom: 1px solid var(--edge);
}
.dl-row > :first-child { flex: 1 1 14rem; }
.dl-row .meta { font-size: 0.85rem; color: var(--amber); }
.dl-row .btn { margin: 0; }

/* The file details under a standalone download button (collages.html). */
p.meta {
  font-size: 0.85rem;
  color: var(--amber);
  margin-top: -0.25rem;
}

/* Deactivated, not dimmed. `opacity: 0.45` here composited this row's meta
   text to 2.04:1 against --ink -- worse than the 1.76:1 defect the --edge-text
   token was added to fix, and it did it downstream of the token, so a
   contrast audit run "from committed hex" could not see it. Never dim text
   with opacity. The row reads as inactive through a quieter colour (the same
   --edge-text used for the footer; measured
   in-browser at 4.88:1 for both the label and the meta, against 11.21:1 and
   5.07:1 on the live rows) and a dashed rule, neither of which a contrast
   check can miss. */
/* .dl-row sets border-bottom: 1px solid var(--edge); changing only the style
   left the rule at full --edge strength under text that had gone quiet. */
.dl-row--soon {
  color: var(--edge-text);
  border-bottom-style: dashed;
  border-bottom-color: var(--edge-text);
}
.dl-row--soon b { color: var(--edge-text); font-weight: 400; }
.dl-row--soon .meta { color: var(--edge-text); }

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

footer {
  padding: 4.5rem 0 5.5rem;
  border-top: 1px solid var(--edge);
  font-size: 0.9rem;
  color: var(--edge-text);
}
footer a { color: var(--amber); }
footer p { max-width: 46em; }

/* --- responsive ----------------------------------------------------------- */

@media (max-width: 34rem) {
  body { font-size: 1rem; }
  .btn { display: block; text-align: center; margin-right: 0; }
  .dl-row .btn { width: 100%; }
}

/* --- printerly detail ------------------------------------------------------
   All progressive enhancements: browsers without them fall back to ordinary
   wrapping, and none of it is load-bearing. */

/* Balance short display lines; let long prose avoid single-word last lines. */
h1, h2, h3,
.ad-masthead h2, .ad-pitchline, .ad-countdown,
.ad-pullquote p, .arrivals-coda {
  text-wrap: balance;
}

p, .arrivals li, .ad-fields dd p {
  text-wrap: pretty;
}

/* Optical margins where a quote or a run of prose opens on punctuation.
   `first` only -- `last` is effectively unsupported. */
@supports (hanging-punctuation: first) {
  .ad-pullquote p, .ad-gloss, .arrivals-coda, #book p {
    hanging-punctuation: first;
  }
}

/* The justified excerpt columns already hyphenate; keep the breaks from
   getting stupid (no two-letter fragments, no breaking short words). */
@media (min-width: 34rem) {
  .ad-barker p { hyphenate-limit-chars: 6 3 3; }
}

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

/* --- print -----------------------------------------------------------------
   Browsers drop backgrounds when printing, which left pale-on-night text at
   1.5:1 on white paper. In print the whole site becomes the lit page: dark
   ink on paper, no buttons, and link targets spelled out. */
@media print {
  :root {
    --ink: #fff;
    --pale: #1A1A1A;
    --gold: #1A1A1A;
    --amber: #955C2C;
    --edge: #bbb;
    --edge-text: #555;
    color-scheme: light;
  }
  body { font-size: 11pt; }
  .running-head, .hero__actions, .collages-cta, .downloads .btn,
  .band-mark, .lightbox, p.meta { display: none; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.85em; }
  .band, .band--paper, .band--slim { padding: 1.5rem 0; }
  .handbill { break-inside: auto; }
  .ad-readout, .ad-fields > *, .plate, .thumb { break-inside: avoid; }
}
