/* ==========================================================================
   OnMeaning — design system
   Palette: warm paper, deep ink, gold light (brand: light over dark water)
   Type: Newsreader (essays & headings), Inter (interface)
   ========================================================================== */

:root {
  /* Warm paper rather than near-white. The hero is a photograph of dawn over
     dark water; a page of #fbf9f4 beneath it read as two unrelated documents
     stapled together. Carrying more of the gold into the ground lets the
     light in the picture continue onto the page instead of stopping at it. */
  --paper: #f7f2e7;
  --surface: #efe7d6;
  --ink: #221d14;
  --ink-soft: #5f5741;
  /* Small text: read times, card meta, footer, dates. Darkened alongside the
     warmer paper — the old #7a715d sat at 4.50:1 on the near-white ground and
     would have dropped to 4.30 here, under AA. This clears 5.09:1. */
  --ink-faint: #6f6650;
  --gold: #a97e2b;
  --gold-deep: #8a6620;
  --gold-bright: #d9ae54;
  --dark: #14110b;
  --dark-soft: #1e1a12;
  --line: #e4dbc5;
  --line-strong: #d5cbaf;
  /* Not pure white. A #ffffff card on warm paper is the single strongest
     "default blog template" signal there is; this reads as a sheet of the
     same paper, laid on top. */
  --card: #fefcf6;
  --shadow: 0 1px 2px rgb(34 29 20 / 0.05), 0 8px 24px rgb(34 29 20 / 0.06);
  --shadow-lift: 0 2px 4px rgb(34 29 20 / 0.06), 0 16px 40px rgb(34 29 20 / 0.12);
  --serif: "Newsreader", "Iowan Old Style", Georgia, serif;
  --sans: "Inter", -apple-system, "Segoe UI", Roboto, sans-serif;
  --header-h: 4.25rem;
}

:root[data-theme="dark"] {
  --paper: #16130d;
  --surface: #1d1912;
  --ink: #ece5d4;
  --ink-soft: #b3a98e;
  /* Was #857c64 at 4.47:1 — just under AA. Lifted so it clears 4.5:1 on the
     raised card surface too (#1d1912), not only on the page ground, since
     form notes and card meta sit on cards. 4.5 on card, 4.77 on page. */
  --ink-faint: #898169;
  --gold: #d0a548;
  --gold-deep: #b98f38;
  --gold-bright: #e3bc63;
  --dark: #0e0c07;
  --dark-soft: #16130d;
  --line: #2c261a;
  --line-strong: #3b3322;
  --card: #1d1912;
  --shadow: 0 1px 2px rgb(0 0 0 / 0.4), 0 8px 24px rgb(0 0 0 / 0.35);
  --shadow-lift: 0 2px 4px rgb(0 0 0 / 0.45), 0 16px 40px rgb(0 0 0 / 0.5);
}

/* ---------- Base ---------- */

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

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

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

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

/* The `hidden` attribute is only `display: none` in the UA sheet, so any
   author `display` rule (.btn is inline-flex, .form-row is grid) silently
   overrides it. Keep this above component styles. */
[hidden] {
  display: none !important;
}

a {
  color: var(--gold-deep);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

a:hover {
  color: var(--gold);
}

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  border-radius: 2px;
}

::selection {
  background: rgb(169 126 43 / 0.25);
}

h1, h2, h3, h4 {
  font-family: var(--serif);
  font-weight: 600;
  line-height: 1.15;
  color: var(--ink);
  margin: 0 0 0.5em;
  text-wrap: balance;
}

.container {
  width: min(100% - 3rem, 68.75rem);
  margin-inline: auto;
}

.skip-link {
  position: absolute;
  top: -100%;
  left: 1rem;
  z-index: 100;
  padding: 0.6rem 1rem;
  background: var(--dark);
  color: #fff;
  border-radius: 0 0 8px 8px;
  font-size: 0.875rem;
  text-decoration: none;
}

.skip-link:focus {
  top: 0;
  color: #fff;
}

/* ---------- Header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  height: var(--header-h);
  background: color-mix(in srgb, var(--paper) 85%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
}

.site-header.is-scrolled {
  border-bottom-color: var(--line);
  box-shadow: 0 4px 20px rgb(34 29 20 / 0.05);
}

/* ---------- Header over the hero ----------
   The homepage opens on a full-bleed photograph. A cream bar sitting on top
   of it cuts the image off at the top of the screen; in light mode that reads
   as a stark white band. Until the reader scrolls off the image the bar
   carries no surface of its own and its contents go light, because the
   photograph is dark in both themes. Everything returns on scroll, where the
   bar is over the page again and needs to be legible against it. */
/* A sticky header still occupies its space in flow, so the image began below
   it. Pulling the hero up by exactly the header's height lets the bar float
   over the photograph instead of cropping it. */
.site-header.over-hero + main .hero {
  margin-top: calc(var(--header-h) * -1);
  padding-top: calc(6rem + var(--header-h));
}

.site-header.over-hero:not(.is-scrolled) {
  background: transparent;
  /* blur(0) rather than none: `none` is not a length, so it cannot be
     interpolated and the blur would snap on instead of fading in. */
  backdrop-filter: blur(0px);
  -webkit-backdrop-filter: blur(0px);
}

/* The bar and its contents cross-fade together as the hero scrolls away.
   `is-animated` is added a frame after load so a page opened part-way down
   arrives already solid rather than animating into it. */
.site-header.over-hero.is-animated,
.site-header.over-hero.is-animated .brand,
.site-header.over-hero.is-animated .site-nav > ul > li > a,
.site-header.over-hero.is-animated .theme-toggle,
.site-header.over-hero.is-animated .nav-toggle {
  transition:
    background-color 0.3s ease,
    backdrop-filter 0.3s ease,
    -webkit-backdrop-filter 0.3s ease,
    color 0.3s ease,
    border-color 0.3s ease,
    box-shadow 0.3s ease;
}

@media (prefers-reduced-motion: reduce) {
  .site-header.over-hero.is-animated,
  .site-header.over-hero.is-animated .brand,
  .site-header.over-hero.is-animated .site-nav > ul > li > a,
  .site-header.over-hero.is-animated .theme-toggle,
  .site-header.over-hero.is-animated .nav-toggle {
    transition: none;
  }
}

/* Cream, to be read against the hero photograph.

   Opening the menu used to switch this whole treatment off and drop a solid
   bar in behind it, on the reasoning that a transparent bar above a solid
   panel reads as a mistake. On a phone at the top of the page it reads as
   something worse: the header changes colour the instant you tap the menu,
   before you have scrolled anywhere, and the change is the first thing you
   see. The panel is inset from the edges and rounded — it is a card floating
   over the photograph, not a sheet welded to the bar — so the bar has no
   reason to follow it. It stays exactly as it was until the hero scrolls away.

   What does still switch off is the type inside the panel: cream written for
   a photograph disappears on paper, so the nav links alone keep the
   `:not(.is-nav-open)` guard and fall back to the ordinary header colours. */
.site-header.over-hero:not(.is-scrolled) .brand,
.site-header.over-hero:not(.is-scrolled):not(.is-nav-open) .site-nav ul a,
.site-header.over-hero:not(.is-scrolled) .theme-toggle,
.site-header.over-hero:not(.is-scrolled) .nav-toggle {
  color: #f4eee1;
}

.site-header.over-hero:not(.is-scrolled):not(.is-nav-open) .site-nav ul a:hover,
.site-header.over-hero:not(.is-scrolled) .theme-toggle:hover {
  color: #fff;
  background: rgb(244 238 225 / 0.12);
  border-color: transparent;
}

.site-header.over-hero:not(.is-scrolled):not(.is-nav-open) .site-nav ul a[aria-current="page"] {
  color: var(--gold-bright);
}

.site-header.over-hero:not(.is-scrolled) .nav-toggle {
  border-color: rgb(244 238 225 / 0.45);
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 100%;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: var(--ink);
}

.brand svg {
  width: 1.85rem;
  height: 1.85rem;
  flex: none;
  color: var(--gold);
}

.brand-name {
  font-family: var(--sans);
  font-size: 1.2rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.site-nav ul {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-nav ul a {
  display: inline-block;
  padding: 0.45rem 0.85rem;
  font-size: 0.925rem;
  font-weight: 500;
  color: var(--ink-soft);
  text-decoration: none;
  border-radius: 999px;
  transition: color 0.15s ease, background-color 0.15s ease;
}

.site-nav ul a:hover {
  color: var(--ink);
  background: var(--surface);
}

.site-nav ul a[aria-current="page"] {
  color: var(--gold-deep);
}

/* ---------- The timeline, as its own thing ----------
   It is not a page, it is an application with its own chrome — so it does not
   sit in the row of page links looking like one. It is the only inverted
   surface in the header: ink on a light page, light on a dark one, which is
   the strongest contrast available and reads as a door rather than a tab.

   Above the menu breakpoint the nav stops being a box so its children join
   the header's own flex row; that is what lets the button sit past the
   light/dark toggle while still living inside the menu on a phone. */
@media (min-width: 40.01em) {
  .site-nav {
    display: contents;
  }

  .nav-app {
    order: 3;
  }

  .theme-toggle {
    order: 2;
  }
}

.nav-app {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0;
  flex-shrink: 0;
  height: 2.5rem;
  padding: 0 0.7rem;
  /* Rounded square, not a pill. */
  border-radius: 12px;
  border: 1px solid transparent;
  background: var(--ink);
  color: var(--paper);
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
}

.nav-app svg {
  width: 1.15rem;
  height: 1.15rem;
  flex-shrink: 0;
}

/* Closed to nothing, opened on hover. max-width rather than width because
   the label has no fixed measure and `auto` cannot be transitioned. */
.nav-app-label {
  display: block;
  max-width: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-width 0.28s cubic-bezier(0.2, 0.8, 0.3, 1),
              opacity 0.2s ease,
              margin-left 0.28s cubic-bezier(0.2, 0.8, 0.3, 1);
}

.nav-app:hover,
.nav-app:focus-visible {
  background: var(--gold-deep);
  color: #fff;
  box-shadow: 0 4px 16px rgb(34 29 20 / 0.18);
}

.nav-app:hover .nav-app-label,
.nav-app:focus-visible .nav-app-label {
  max-width: 7rem;
  opacity: 1;
  margin-left: 0.5rem;
}

:root[data-theme="dark"] .nav-app:hover,
:root[data-theme="dark"] .nav-app:focus-visible {
  background: var(--gold);
  color: #17120a;
}

/* On the timeline's own pages it stays open, because you are already there. */
.nav-app[aria-current="page"] .nav-app-label {
  max-width: 7rem;
  opacity: 1;
  margin-left: 0.5rem;
}

/* Over the hero the page is dark whatever the theme says, so the inversion
   has to follow the photograph rather than the palette. */
.site-header.over-hero:not(.is-scrolled):not(.is-nav-open) .nav-app {
  background: #f4eee1;
  color: #17120a;
}

.site-header.over-hero:not(.is-scrolled):not(.is-nav-open) .nav-app:hover {
  background: var(--gold-bright);
  color: #17120a;
}

/* Nav and the two icon buttons share the right end of the header. On a phone
   the nav drops out of flow (absolutely positioned), leaving the buttons. */
.header-right {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.4rem;
  height: 2.4rem;
  padding: 0;
  background: none;
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--ink-soft);
  cursor: pointer;
  transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}

.theme-toggle:hover {
  color: var(--ink);
  background: var(--surface);
  border-color: var(--line);
}

.theme-toggle svg {
  width: 1.15rem;
  height: 1.15rem;
}

/* Each theme shows its own mark: a moon while dark, a sun while light. The
   button's accessible name says what pressing it will do. */
.theme-toggle .icon-sun { display: none; }
[data-theme="light"] .theme-toggle .icon-sun { display: block; }
[data-theme="light"] .theme-toggle .icon-moon { display: none; }

@media (max-width: 40em) {
  .theme-toggle {
    width: 2.75rem;
    height: 2.75rem;
    border-color: var(--line-strong);
  }
}

.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  background: none;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  color: var(--ink);
  cursor: pointer;
}

.nav-toggle svg {
  width: 1.25rem;
  height: 1.25rem;
}

.nav-toggle .icon-close { display: none; }
.nav-toggle[aria-expanded="true"] .icon-menu { display: none; }
.nav-toggle[aria-expanded="true"] .icon-close { display: block; }

/* ---------- The menu ----------
   A card that arrives, not a slab that appears. It was a full-bleed panel
   welded to the underside of the bar with square corners — the one piece of
   the site that looked like an unstyled default. It is now inset from the
   edges with the same radius and lift the cards elsewhere use, and it snaps
   in rather than blinking on, because `display` cannot be animated and the
   old one had nothing to animate anyway. */
@media (max-width: 40em) {
  .nav-toggle {
    display: inline-flex;
  }

  /* A dropdown hung off the button that opened it, not a sheet pulled across
     the whole screen. Edge to edge it was a lot of panel for four short words,
     and it read as a page taking over rather than a menu opening. Anchored to
     the right under the toggle it stays near the thumb that tapped it, the
     rows are only as long as they need to be, and the photograph is still
     visible down the other side — which is what keeps it feeling like a layer
     over the page. The min() keeps it inside the screen on the narrowest
     phones, where it goes back to nearly full width because there is no room
     to be anything else. */
  .site-nav {
    position: absolute;
    top: calc(var(--header-h) - 0.35rem);
    left: auto;
    right: 0.75rem;
    width: min(15.5rem, calc(100vw - 1.5rem));
    display: block;
    padding: 0.5rem;
    border-radius: 18px;
    border: 1px solid var(--line-strong);
    /* Near-opaque rather than glass. The blur is a nicety; the menu still has
       to be readable on a browser that ignores it, and at 94% the paragraph
       underneath was legible straight through the links. */
    background: color-mix(in srgb, var(--card) 99%, transparent);
    backdrop-filter: blur(16px) saturate(1.3);
    -webkit-backdrop-filter: blur(16px) saturate(1.3);
    box-shadow: var(--shadow-lift);
    transform-origin: top right;
    /* Closed state. visibility keeps it out of the tab order while shut, and
       flips only after the collapse has played. */
    opacity: 0;
    visibility: hidden;
    transform: translateY(-0.5rem) scale(0.97);
    transition:
      opacity 0.19s ease,
      transform 0.24s cubic-bezier(0.2, 0.9, 0.3, 1.15),
      visibility 0s 0.24s;
  }

  .site-nav.is-open {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition:
      opacity 0.16s ease,
      transform 0.26s cubic-bezier(0.2, 0.9, 0.3, 1.15),
      visibility 0s;
  }

  .site-nav ul {
    flex-direction: column;
    align-items: stretch;
    gap: 0.15rem;
    padding: 0;
  }

  .site-nav ul a {
    display: flex;
    align-items: center;
    padding: 0.8rem 0.85rem;
    min-height: 48px;
    font-size: 1.02rem;
    border-radius: 12px;
  }

  .site-nav ul a:hover,
  .site-nav ul a[aria-current="page"] {
    background: color-mix(in srgb, var(--gold) 11%, transparent);
  }

  /* In the menu it is already open — there is no hover on a phone to open it
     with, and the bottom of the menu is where a door belongs. Same inverted
     fill and same rounded square, run the full width.

     Its label sits on the same left edge as Essays, About and Contact. It used
     to be centred, which left three words down one side of the panel and a
     fourth floating in the middle — the filled row read as a stray button
     dropped under a list rather than the last entry of it.

     It runs the width of the panel like the rows above it. What made it look
     heavy was the panel, not the row — see the width note on .site-nav. */
  .nav-app {
    display: flex;
    justify-content: flex-start;
    width: 100%;
    height: auto;
    min-height: 50px;
    margin: 0.45rem 0 0;
    /* Matched to .site-nav ul a above, so the four labels share one edge. */
    padding: 0.8rem 0.85rem;
    border-radius: 13px;
    font-size: 1rem;
  }

  /* The mark trails the word rather than leading it, so the word itself keeps
     the left edge the three links above it sit on, and the mark holds the far
     end of the row. */
  .nav-app svg {
    order: 2;
    margin-left: auto;
    width: 1.2rem;
    height: 1.2rem;
  }

  .nav-app-label {
    order: 1;
    max-width: none;
    opacity: 1;
    margin-left: 0;
    overflow: visible;
    transition: none;
  }

  /* The menu is a solid card whatever the bar above it is doing, so the
     over-hero treatment must not follow the link inside it. */
  .site-header.over-hero .site-nav .nav-app {
    background: var(--ink);
    color: var(--paper);
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-nav {
    transition: opacity 0.01s, visibility 0s;
    transform: none;
  }
}

/* ---------- Reading progress (essay pages) ---------- */

/* Reading progress, riding the bottom edge of the header rather than the top
   edge of the screen. At the very top it was disappearing behind the sticky
   bar: the header is translucent with a backdrop-filter, and a filtered
   element will paint over a higher-z sibling in some browsers regardless of
   what the z-index says. Sitting it under the header sidesteps the question
   entirely — and it reads better there, as a rule attached to the chrome
   rather than a hairline at the edge of the glass.

   Pinned by its edges rather than given a width: `100%` resolves against the
   initial containing block, which is not always the width the document
   actually has. */
.progress {
  position: fixed;
  /* Directly beneath the bar, not inside its last three pixels. The first
     attempt at this sat at `--header-h - 3px`, which is still within the
     header's own box — so a header that paints over its siblings covered it
     just as completely as when it was at the top of the screen. Clearing the
     box entirely is the only version that cannot be overlapped. */
  top: var(--header-h);
  left: 0;
  right: 0;
  z-index: 120;
  height: 3px;
  background: transparent;
  pointer-events: none;
}

.progress span {
  display: block;
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--gold), var(--gold-bright));
  box-shadow: 0 0 10px color-mix(in srgb, var(--gold) 55%, transparent);
}

/* ---------- Hero (home) ---------- */

.hero {
  position: relative;
  display: grid;
  place-items: center;
  min-height: min(88vh, 46rem);
  padding: 6rem 0;
  background: #0a0805;
  color: #f4eee1;
  overflow: hidden;
  text-align: center;
}

.hero-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 65%;
  /* Full strength now. The light on the water is doing real work in this
     composition, and the gradient above it controls the exposure instead. */
  opacity: 1;
}

/* Light with a direction, rather than a vignette pressing in from all sides.
   The photograph is a sunrise: it should be darkest overhead, clearing as it
   falls to the horizon, and warm where the sun actually is. That gives the
   type a dark sky to sit in, the constellation somewhere to be seen, and the
   glow at the foot something to hand to the page. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    /* The handover to the page. Kept to the last few percent — at a tenth of
       the hero it climbed some seventy pixels up the photograph and put a
       haze over the very thing the picture is of. It should read as light
       peeking under the edge, not as fog. */
    linear-gradient(180deg, transparent 96%, var(--paper) 100%),
    radial-gradient(80% 55% at 50% 88%, rgb(255 196 108 / 0.16) 0%, transparent 70%),
    linear-gradient(180deg,
      rgb(4 3 2 / 0.82) 0%,
      rgb(4 3 2 / 0.55) 34%,
      rgb(4 3 2 / 0.34) 58%,
      rgb(4 3 2 / 0.42) 100%);
}

/* The star map. Sits over the vignette so the threads are not dimmed by it,
   and under the type, which always wins.

   Masked to clear the middle. Drawn edge to edge the lines ran straight
   through the headline, and a constellation you have to read words out of is
   worse than no constellation — so it is dense at the margins and opens out
   where the type sits, the way a real sky is emptiest where you are looking.
   It also starts below the header, so nothing threads through the nav. */
.hero-sky {
  position: absolute;
  inset: var(--header-h) 0 0;
  z-index: 2;
  pointer-events: none;
  overflow: hidden;
  -webkit-mask-image: radial-gradient(66% 58% at 50% 40%,
    transparent 0%, transparent 52%, #000 92%);
  mask-image: radial-gradient(66% 58% at 50% 40%,
    transparent 0%, transparent 52%, #000 92%);
}

.hs-svg {
  width: 100%;
  height: 68%;
  display: block;
}

/* Hairline and low. This is the texture of the sky, not a chart to be read —
   at full strength it turned the quietest part of the page into the busiest. */
.hs-line {
  fill: none;
  stroke: var(--tc);
  stroke-width: 0.75;
  stroke-linejoin: round;
  stroke-linecap: round;
  opacity: 0.2;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}

.hs-dots circle {
  fill: var(--tc);
  opacity: 0;
}

/* Arrivals still take the brightest tone — the one thing up here worth
   picking out. */
.hs-dots circle.is-f {
  fill: #ffd691;
}

/* Quick and overlapping. The whole sky settles in about a second and a half,
   so it is over by the time the headline has been read rather than still
   crawling behind it. */
.hero-sky.is-lit .hs-line {
  animation: hs-draw 1.1s ease forwards;
  animation-delay: calc(var(--i) * 0.13s);
}

.hero-sky.is-lit .hs-dots circle {
  animation: hs-star 0.5s ease forwards;
  animation-delay: calc(var(--i) * 0.13s + 0.62s);
}

.hero-sky.no-anim .hs-line {
  stroke-dashoffset: 0;
  animation: none;
}

.hero-sky.no-anim .hs-dots circle {
  opacity: 0.5;
  animation: none;
}

@keyframes hs-draw {
  to { stroke-dashoffset: 0; }
}

@keyframes hs-star {
  to { opacity: 0.5; }
}

/* Dawn continuing onto the page. The hero is sunrise over dark water, so the
   section under it opens in that same gold, thinning to paper — the light
   carries across the seam instead of stopping dead at it. This is the whole
   answer to a dark photograph sitting on a pale page: not less contrast, but
   somewhere for the contrast to go. */
.hero + .section {
  background:
    radial-gradient(70rem 26rem at 50% -8rem,
      color-mix(in srgb, var(--gold) 26%, transparent) 0%,
      color-mix(in srgb, var(--gold) 7%, transparent) 45%,
      transparent 72%),
    var(--paper);
}

:root[data-theme="dark"] .hero + .section {
  background:
    radial-gradient(70rem 26rem at 50% -8rem,
      color-mix(in srgb, var(--gold) 15%, transparent) 0%,
      transparent 68%),
    var(--paper);
}

.hero-inner {
  position: relative;
  z-index: 3;
  max-width: 48rem;
  padding-inline: 1.5rem;
}

/* The logo that used to head this is gone. The wordmark sits sixty-eight
   pixels above it in the header; saying it twice cost the headline its room
   and made the composition a stack of brand rather than an invitation. */
.hero-eyebrow {
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgb(244 238 225 / 0.58);
  margin: 0 0 1.5rem;
}

.hero h1 {
  font-size: clamp(2.7rem, 7vw, 4.6rem);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.015em;
  color: #faf6ec;
  margin: 0 0 0.55em;
  text-wrap: balance;
  text-shadow: 0 2px 30px rgb(4 3 2 / 0.5);
}

.hero h1 em {
  font-style: italic;
  color: var(--gold-bright);
}

.hero-lede {
  font-family: var(--serif);
  font-size: clamp(1.08rem, 2.4vw, 1.28rem);
  line-height: 1.65;
  color: rgb(244 238 225 / 0.82);
  max-width: 30em;
  margin: 0 auto 2.4rem;
  text-wrap: pretty;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.85rem;
}

/* Third in weight as well as in order — two buttons and a link, rather than
   three buttons that argue over which one to press. */
.hero-tertiary {
  display: inline-block;
  margin-top: 1.5rem;
  font-size: 0.9rem;
  color: rgb(244 238 225 / 0.62);
  text-decoration: underline;
  text-decoration-color: rgb(244 238 225 / 0.28);
  text-underline-offset: 4px;
  transition: color 0.2s ease, text-decoration-color 0.2s ease;
}

.hero-tertiary:hover {
  color: #fff;
  text-decoration-color: rgb(244 238 225 / 0.7);
}

/* The entrance. Each line arrives just after the one above it — the whole
   thing is over in under a second, and it is the difference between a page
   that loads and a page that opens. */
@media (prefers-reduced-motion: no-preference) {
  .hero-eyebrow,
  .hero h1,
  .hero-lede,
  .hero-actions,
  .hero-tertiary {
    animation: hero-rise 0.85s cubic-bezier(0.16, 0.8, 0.3, 1) both;
  }

  .hero h1 { animation-delay: 0.08s; }
  .hero-lede { animation-delay: 0.18s; }
  .hero-actions { animation-delay: 0.28s; }
  .hero-tertiary { animation-delay: 0.38s; }
}

@keyframes hero-rise {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.8rem 1.6rem;
  font-family: var(--sans);
  font-size: 0.95rem;
  font-weight: 600;
  text-decoration: none;
  border-radius: 999px;
  border: 1px solid transparent;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}

.btn-solid {
  background: var(--gold);
  color: #17120a;
  box-shadow: 0 4px 16px rgb(169 126 43 / 0.35);
}

.btn-solid:hover {
  background: var(--gold-bright);
  color: #17120a;
  transform: translateY(-1px);
}

/* The timeline is the only thing on this page you operate rather than read,
   so it takes a third treatment: glass against the hero photograph, edged in
   gold, carrying the spine mark it uses inside. It sits between the two
   existing buttons, which puts it at the centre of a centred row without
   demoting the essays from primary. */
.btn-feature {
  color: #fff;
  background: rgb(19 15 9 / 0.55);
  border-color: rgb(255 206 138 / 0.5);
  box-shadow: 0 4px 20px rgb(0 0 0 / 0.3);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.btn-feature:hover {
  color: #fff;
  background: rgb(19 15 9 / 0.72);
  border-color: var(--gold-bright);
  transform: translateY(-1px);
  box-shadow: 0 6px 24px rgb(0 0 0 / 0.38);
}

.btn-feature .btn-spine {
  width: 1.05rem;
  height: 1.05rem;
  flex-shrink: 0;
  margin-left: -0.15rem;
  color: var(--gold);
}

.btn-ghost {
  color: #f4eee1;
  border-color: rgb(244 238 225 / 0.35);
}

.btn-ghost:hover {
  color: #fff;
  border-color: rgb(244 238 225 / 0.7);
  background: rgb(244 238 225 / 0.08);
}

.btn-outline {
  color: var(--gold-deep);
  border-color: var(--line-strong);
}

.btn-outline:hover {
  color: var(--gold-deep);
  border-color: var(--gold);
  background: color-mix(in srgb, var(--gold) 8%, transparent);
}

/* ---------- Sections ---------- */

.section {
  padding: 5rem 0;
}

.section + .section {
  padding-top: 0;
}

.section-head {
  max-width: 40rem;
  margin-bottom: 3rem;
}

.section-head.is-centered {
  margin-inline: auto;
  text-align: center;
}

.eyebrow {
  display: block;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold-deep);
  margin-bottom: 0.85rem;
}

.section-head h2 {
  font-size: clamp(1.9rem, 4vw, 2.6rem);
  font-weight: 500;
}

.section-head p {
  font-size: 1.05rem;
  color: var(--ink-soft);
  margin: 0.75rem 0 0;
}

/* ---------- The essay series ----------
   A numbered running order rather than a wall of cards. Three tall cards in a
   row is the default shape of every blog on the internet, and it spent most
   of a screen saying so; this reads as the contents page of one work in
   several parts, which is what the essays actually are. */

.essay-series {
  counter-reset: essay;
  list-style: none;
  max-width: 52rem;
  margin: 0 auto;
  padding: 0;
  border-top: 1px solid var(--line);
}

.essay-row {
  counter-increment: essay;
  border-bottom: 1px solid var(--line);
}

.essay-row-link {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 1.35rem;
  padding: 1.15rem 0.5rem;
  text-decoration: none;
  color: inherit;
  transition: background-color 0.18s ease, padding-inline 0.18s ease;
}

.essay-row-link:hover {
  background: color-mix(in srgb, var(--gold) 7%, transparent);
}

/* The art earns a place only as a token — enough to carry the mood of the
   piece, not enough to become the piece. */
.essay-row-art {
  display: block;
  width: 4.25rem;
  height: 4.25rem;
  border-radius: 12px;
  overflow: hidden;
  flex-shrink: 0;
  box-shadow: var(--shadow);
}

.essay-row-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.4s ease;
}

.essay-row-link:hover .essay-row-art img {
  transform: scale(1.06);
}

.essay-row-body {
  display: block;
  min-width: 0;
}

.essay-row-kicker {
  display: block;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

.essay-row-kicker em {
  font-style: normal;
  color: var(--ink-faint);
}

.essay-row-title {
  display: block;
  margin-top: 0.2rem;
  font-family: var(--serif);
  font-size: clamp(1.25rem, 2.4vw, 1.55rem);
  font-weight: 600;
  line-height: 1.2;
  color: var(--ink);
}

.essay-row-link:hover .essay-row-title {
  color: var(--gold-deep);
}

.essay-row-blurb {
  display: block;
  margin-top: 0.3rem;
  font-family: var(--serif);
  font-size: 1rem;
  line-height: 1.5;
  color: var(--ink-soft);
  /* One line of invitation. The essay itself is where the reading happens. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.essay-row-meta {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  flex-shrink: 0;
  font-size: 0.82rem;
  color: var(--ink-faint);
  white-space: nowrap;
}

.essay-row-meta svg {
  width: 1rem;
  height: 1rem;
  color: var(--line-strong);
  transition: transform 0.18s ease, color 0.18s ease;
}

.essay-row-link:hover .essay-row-meta svg {
  color: var(--gold);
  transform: translateX(3px);
}

@media (max-width: 34em) {
  .essay-row-link {
    gap: 1rem;
    padding: 1rem 0.25rem;
  }

  .essay-row-art {
    width: 3.4rem;
    height: 3.4rem;
  }

  .essay-row-blurb {
    -webkit-line-clamp: 2;
    font-size: 0.94rem;
  }

  /* The read time keeps its place; the chevron is what goes when it is tight. */
  .essay-row-meta svg {
    display: none;
  }
}

/* ---------- The featured essay (essays index) ----------
   One piece leads at the size of an invitation. Three equal cards made the
   reader choose before they knew anything; this tells them where to start. */

/* The featured essay leads, but it should not tower over the series it leads.
   It was 485px against 141px rows beneath it and 62rem wide against their
   52rem, so it read as a different page element rather than the first item in
   a list. Now it shares their width and the artwork no longer sets the height
   (see .essay-lead-art), which brings it to roughly twice a row — still
   plainly the featured one, no longer shouting. */
.essay-lead {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 0.88fr) minmax(0, 1.12fr);
  align-items: stretch;
  gap: 0;
  max-width: 52rem;
  margin: 0 auto 2.5rem;
  border: 1px solid var(--line);
  border-radius: 20px;
  overflow: hidden;
  background: var(--card);
  box-shadow: var(--shadow);
  text-decoration: none;
  color: inherit;
  transition: transform 0.22s ease, box-shadow 0.22s ease, border-color 0.22s ease;
}

.essay-lead:hover {
  transform: translateY(-3px);
  border-color: var(--line-strong);
  box-shadow: var(--shadow-lift);
}

/* The source image is square, so at full column width it rendered 483px tall
   and dragged the card up with it. A fixed ratio decouples the card's height
   from whatever aspect the artwork happens to have — the same technique the
   narrow-screen rule below already used, just never applied here. */
.essay-lead-art {
  display: block;
  overflow: hidden;
  min-height: 0;
  aspect-ratio: 4 / 3;
}

.essay-lead-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s ease;
}

.essay-lead:hover .essay-lead-art img {
  transform: scale(1.045);
}

.essay-lead-body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 1.9rem 2rem 1.8rem;
}

.essay-lead-kicker {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

.essay-lead-title {
  margin-top: 0.45rem;
  font-family: var(--serif);
  font-size: clamp(1.8rem, 3.4vw, 1.95rem);
  font-weight: 600;
  line-height: 1.14;
  color: var(--ink);
  text-wrap: balance;
}

.essay-lead-blurb {
  margin-top: 0.6rem;
  font-family: var(--serif);
  font-size: 1rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

.essay-lead-go {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 1.1rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--gold-deep);
}

.essay-lead-go svg {
  width: 1rem;
  height: 1rem;
  transition: transform 0.2s ease;
}

.essay-lead:hover .essay-lead-go svg {
  transform: translateX(4px);
}

@media (max-width: 46em) {
  .essay-lead {
    grid-template-columns: 1fr;
  }

  .essay-lead-art {
    min-height: 0;
    aspect-ratio: 16 / 9;
  }

  .essay-lead-body {
    padding: 1.6rem 1.5rem 1.75rem;
  }
}

/* The rest of the series, under a quiet label. */
.essay-series-label {
  max-width: 52rem;
  margin: 0 auto 0.9rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.essay-series.is-index .essay-row-art {
  width: 5rem;
  height: 5rem;
}

/* Matched to the same specificity as the rule above, or the index's larger
   art wins over the phone sizing and the row gets top-heavy. */
@media (max-width: 34em) {
  .essay-series.is-index .essay-row-art {
    width: 3.6rem;
    height: 3.6rem;
  }
}

/* ---------- Essay cards (unused on the index now; kept for any page that
   still wants a card grid) ---------- */

.essay-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1.75rem;
}

.essay-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: var(--shadow);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.essay-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
}

.essay-card-media {
  aspect-ratio: 16 / 10;
  overflow: hidden;
}

.essay-card-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.4s ease;
}

.essay-card:hover .essay-card-media img {
  transform: scale(1.04);
}

.essay-card-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: 0.6rem;
  padding: 1.5rem 1.5rem 1.4rem;
}

.essay-card .card-kicker {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

.essay-card h2,
.essay-card h3 {
  font-size: 1.45rem;
  font-weight: 600;
  margin: 0;
}

.essay-card h2 a,
.essay-card h3 a {
  color: inherit;
  text-decoration: none;
}

/* Whole card is clickable */
.essay-card h2 a::after,
.essay-card h3 a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.essay-card p {
  font-family: var(--serif);
  font-size: 1.02rem;
  color: var(--ink-soft);
  margin: 0;
  flex: 1;
}

.essay-card .card-meta {
  font-size: 0.83rem;
  color: var(--ink-faint);
  margin-top: 0.4rem;
}

/* ---------- Quote band (home) ---------- */

.quote-band {
  background: var(--dark);
  color: #efe8d8;
  padding: 5.5rem 0;
  text-align: center;
}

.quote-band blockquote {
  max-width: 44rem;
  margin: 0 auto;
  padding: 0;
}

.quote-band blockquote p {
  font-family: var(--serif);
  font-size: clamp(1.4rem, 3vw, 1.9rem);
  font-weight: 400;
  font-style: italic;
  line-height: 1.5;
  margin: 0 0 1.5rem;
}

.quote-band cite {
  font-family: var(--sans);
  font-size: 0.85rem;
  font-style: normal;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold-bright);
}

/* ---------- Commitments (about) ----------
   Numbered in the same mono the timeline uses for its eras, so the three
   claims read as part of the same publication rather than as a feature grid
   borrowed from a product page. */

.principles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 2rem 2.5rem;
  max-width: 62rem;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

.principles li {
  position: relative;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line-strong);
}

.principle-n {
  display: block;
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  color: var(--gold-deep);
}

.principles h3 {
  margin: 0.65rem 0 0.5rem;
  font-family: var(--serif);
  font-size: 1.28rem;
  font-weight: 600;
  line-height: 1.25;
  text-wrap: balance;
}

.principles p {
  margin: 0;
  font-family: var(--serif);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink-soft);
}

/* ---------- Page header (inner pages) ---------- */

/* Was a flat grey band with a rule under it — the shape every template ships
   with. It is now the same opening the essays and the home page use: dawn
   light behind the title, no hard edges, and the type large enough to be the
   reason you are looking at the top of the page. */
.page-head {
  position: relative;
  padding: 5.5rem 0 3.5rem;
  text-align: center;
  overflow: hidden;
}

.page-head::before {
  content: "";
  position: absolute;
  left: 50%;
  top: -8rem;
  width: min(60rem, 100%);
  height: 24rem;
  transform: translateX(-50%);
  background: radial-gradient(50% 50% at 50% 50%,
    color-mix(in srgb, var(--gold) 20%, transparent) 0%, transparent 70%);
  pointer-events: none;
}

/* A hairline that fades out at the edges rather than ruling straight across:
   a full-width border is what made this read as a header bar. */
.page-head::after {
  content: "";
  position: absolute;
  left: 12%;
  right: 12%;
  bottom: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line-strong), transparent);
}

.page-head > .container {
  position: relative;
}

.page-head .eyebrow {
  margin-bottom: 1.1rem;
}

.page-head h1 {
  font-size: clamp(2.5rem, 6vw, 3.9rem);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.012em;
  margin: 0 0 0.4em;
  text-wrap: balance;
}

.page-head p {
  font-family: var(--serif);
  font-size: clamp(1.05rem, 2.2vw, 1.22rem);
  line-height: 1.65;
  color: var(--ink-soft);
  max-width: 34em;
  margin: 0 auto;
  text-wrap: pretty;
}

/* ---------- Article (essay) ---------- */

/* The same dawn light that opens the homepage, so an essay arrived at
   directly still reads as part of the same place. */
.article-header {
  position: relative;
  max-width: 46rem;
  margin: 0 auto;
  padding: 4rem 0 0;
  text-align: center;
}

/* Never wider than its own column. This was 130vw, which on a phone hung
   about 30px past each edge of the screen and gave the whole page a
   horizontal scroll — a decorative glow is the last thing that should be
   able to do that. */
.article-header::before {
  content: "";
  position: absolute;
  left: 50%;
  top: -6rem;
  width: min(64rem, 100%);
  height: 22rem;
  transform: translateX(-50%);
  background: radial-gradient(50% 50% at 50% 50%,
    color-mix(in srgb, var(--gold) 18%, transparent) 0%, transparent 70%);
  pointer-events: none;
  z-index: -1;
}

.article-header .eyebrow {
  margin-bottom: 1rem;
}

.article-header h1 {
  font-size: clamp(2.3rem, 5.5vw, 3.4rem);
  font-weight: 500;
  margin-bottom: 0.6em;
}

.article-meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.35rem 0.75rem;
  font-size: 0.9rem;
  color: var(--ink-faint);
}

.article-meta .sep {
  color: var(--line-strong);
}

/* A banner, not a poster. At 30rem the art pushed the first sentence most of
   a screen down the page, so arriving at an essay meant scrolling before you
   could start it. Tied to the viewport instead of a fixed height: it takes a
   band across the top on any screen and never more than a third of it. */
.article-art {
  max-width: 52rem;
  margin: 2.25rem auto 0;
}

.article-art img {
  width: 100%;
  height: clamp(9rem, 30vh, 17rem);
  object-fit: cover;
  object-position: center 45%;
  border-radius: 16px;
  box-shadow: var(--shadow-lift);
}

/* Tighter on a phone, where every pixel above the first sentence is a pixel
   the reader has to scroll past to begin. */
@media (max-width: 40em) {
  .article-header {
    padding-top: 2.25rem;
  }

  .article-art {
    margin-top: 1.75rem;
  }

  .article-art img {
    height: clamp(8rem, 22vh, 12rem);
    border-radius: 14px;
  }
}

.article-body {
  max-width: 44rem;
  margin: 0 auto;
  padding: 3.5rem 0 5rem;
}

/* Contents card */
.toc {
  margin: 0 0 3.25rem;
  padding: 1.5rem 1.75rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
}

.toc-label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  text-align: left;
  color: var(--gold-deep);
  margin-bottom: 0.6rem;
  cursor: pointer;
}

.toc-chevron {
  width: 0.9rem;
  height: 0.9rem;
  margin-left: auto;
  transition: transform 0.2s ease;
}

/* Closed by default below the rail breakpoint, so the essay starts where the
   essay starts. */
@media (max-width: 63.99em) {
  .toc:not(.is-open) ol {
    display: none;
  }

  .toc:not(.is-open) .toc-label {
    margin-bottom: 0;
  }

  .toc.is-open .toc-chevron {
    transform: rotate(180deg);
  }
}

/* On the rail it is a heading again: always open, nothing to press. */
@media (min-width: 64em) {
  .toc-label {
    cursor: default;
  }

  .toc-chevron {
    display: none;
  }
}

.toc ol {
  margin: 0;
  padding: 0 0 0 1.4rem;
  columns: 2;
  column-gap: 2.5rem;
  font-size: 0.95rem;
}

.toc li {
  margin: 0.3rem 0;
  break-inside: avoid;
}

.toc a {
  color: var(--ink-soft);
  text-decoration: none;
}

.toc a:hover,
.toc a.is-active {
  color: var(--gold-deep);
}

@media (max-width: 34em) {
  .toc ol {
    columns: 1;
  }
}

/* ---------- The reading rail ----------
   Above 68em the contents stop being a card the reader scrolls past once and
   become a companion that stays with them: a sticky rail beside the text,
   marking where they are. These essays run to forty minutes; knowing your
   place in one is not a luxury. The scrollspy that lights it was already
   here — it had nowhere visible to report to. */
@media (min-width: 64em) {
  /* Only where there is actually a contents list to put in the rail. The
     prelude has no headings and so no table of contents; an unconditional
     two-column grid dropped its prose into the 14rem rail column and set the
     whole essay in a gutter. `:has()` is the gate, and a browser without it
     simply keeps the single-column layout — which is the correct fallback. */
  .article-body:has(.toc) {
    max-width: 64rem;
    display: grid;
    /* The rail gives way before the prose does: the text measure is the one
       thing here that must not be compromised. */
    grid-template-columns: minmax(10.5rem, 14rem) minmax(0, 44rem);
    gap: 3rem;
    justify-content: center;
    align-items: start;
  }

  .toc {
    position: sticky;
    top: calc(var(--header-h) + 2rem);
    max-height: calc(100vh - var(--header-h) - 5rem);
    overflow-y: auto;
    margin: 0;
    padding: 0 0 0 0;
    background: none;
    border: 0;
    border-left: 1px solid var(--line);
    border-radius: 0;
  }

  .toc-label {
    padding-left: 1.15rem;
    margin-bottom: 0.9rem;
  }

  /* Numbered in mono, like the eras on the timeline — the number is data
     about the essay's shape, not decoration. */
  .toc ol {
    columns: 1;
    counter-reset: toc;
    list-style: none;
    padding: 0;
    font-size: 0.9rem;
  }

  .toc li {
    counter-increment: toc;
    margin: 0;
  }

  .toc a {
    display: block;
    padding: 0.42rem 0 0.42rem 1.15rem;
    margin-left: -1px;
    border-left: 2px solid transparent;
    line-height: 1.4;
    transition: color 0.15s ease, border-color 0.15s ease;
  }

  .toc a::before {
    content: counter(toc, decimal-leading-zero);
    margin-right: 0.55rem;
    font-family: var(--sans);
    font-size: 0.68rem;
    letter-spacing: 0.08em;
    color: var(--ink-faint);
  }

  .toc a.is-active {
    color: var(--gold-deep);
    border-left-color: var(--gold);
  }

  .toc a.is-active::before {
    color: var(--gold-deep);
  }

  /* The rail's scrollbar is styled with the rest of them — see the scrollbars
     block below the prose rules. */
}

/* ---------- scrollbars ----------
   The page's own scrollbar is the most-seen element on the site and was the
   browser default on every essay — a grey slab against a warm paper ground.
   This puts it, and the contents rail, on the same quiet treatment the
   timeline uses.

   Declared twice on purpose: `scrollbar-color` is the standard property that
   Firefox and current Chrome honour, while the ::-webkit- rules cover older
   WebKit, which ignores it. Both paths use the same tokens, so the result is
   the same either way.

   Themed, not fixed: --line-strong and --ink-faint both flip with the theme,
   so the bar stays legible on paper and on ink without a second rule. */
html,
.toc {
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}

html::-webkit-scrollbar,
.toc::-webkit-scrollbar {
  width: 11px;
}

html::-webkit-scrollbar-track,
.toc::-webkit-scrollbar-track {
  background: transparent;
}

/* Transparent border + background-clip insets the thumb so it reads as a pill
   floating in the margin rather than a bar welded to the window edge. */
html::-webkit-scrollbar-thumb,
.toc::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  background-clip: padding-box;
  border: 3px solid transparent;
  border-radius: 99px;
}

html::-webkit-scrollbar-thumb:hover,
.toc::-webkit-scrollbar-thumb:hover {
  background: var(--ink-faint);
  background-clip: padding-box;
}

/* Prose typography */

.prose {
  font-family: var(--serif);
  font-size: 1.185rem;
  line-height: 1.75;
  color: var(--ink);
}

.prose p {
  margin: 0 0 1.35em;
}

.prose h2 {
  position: relative;
  font-size: 1.8rem;
  font-weight: 600;
  margin: 2.6em 0 0.9em;
  padding-top: 1.4rem;
  scroll-margin-top: calc(var(--header-h) + 1.5rem);
}

.prose h2::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 3rem;
  height: 3px;
  border-radius: 2px;
  background: var(--gold);
}

.prose h3 {
  font-size: 1.35rem;
  margin: 2em 0 0.7em;
  scroll-margin-top: calc(var(--header-h) + 1.5rem);
}

.prose a {
  color: var(--gold-deep);
}

/* A button inside prose is still a button. `.prose a` outranks `.btn-solid`
   on specificity, which was repainting the gold button's label gold — 1.3:1
   against its own background, effectively invisible. These restore each
   button's own colour and are written per variant so a new one added inside
   prose fails visibly rather than silently. */
.prose a.btn-solid {
  color: #17120a;
}

.prose a.btn-ghost {
  color: #f4eee1;
}

.prose a.btn-feature {
  color: #fff;
}

/* Currently the same value `.prose a` would give it, so this changes nothing
   today — it is here so the button keeps its own colour if either token ever
   moves, which is the whole point of listing the variants explicitly. */
.prose a.btn-outline {
  color: var(--gold-deep);
}

.prose ul,
.prose ol {
  margin: 0 0 1.35em;
  padding-left: 1.5em;
}

.prose li {
  margin: 0.45em 0;
}

.prose li::marker {
  color: var(--gold-deep);
}

.prose hr {
  border: 0;
  height: 1px;
  background: var(--line-strong);
  margin: 3em auto;
  width: 6rem;
}

.prose strong {
  font-weight: 600;
}

/* Opening drop cap */
.prose .dropcap::first-letter {
  float: left;
  font-size: 3.4em;
  line-height: 0.82;
  padding: 0.06em 0.12em 0 0;
  font-weight: 500;
  color: var(--gold-deep);
}

/* Pull quotes: a raised sheet, distinct from the page. */
.prose blockquote {
  margin: 2em 0;
  padding: 1.4rem 1.75rem;
  background: var(--surface);
  border-left: 3px solid var(--gold);
  border-radius: 0 12px 12px 0;
  font-size: 1.08rem;
}

/* Scripture is different. It is not the author's aside — it is the text the
   whole essay is answering to, and boxing it made it read as a callout
   pulled out of the argument. A hairline and a shift into italic sets it
   apart without lifting it off the page, the way a printed book would. */
.prose blockquote.scripture {
  margin: 2.1em 0;
  padding: 0.15rem 0 0.15rem 1.7rem;
  background: none;
  border-left: 2px solid color-mix(in srgb, var(--gold) 50%, transparent);
  border-radius: 0;
  font-size: 1.1rem;
  font-style: italic;
  color: var(--ink-soft);
}

/* Long passages get a little more room to breathe than a single verse. */
.prose blockquote.scripture p + p {
  margin-top: 0.8em;
}

.prose blockquote p {
  margin-bottom: 0.85em;
}

.prose blockquote p:last-of-type {
  margin-bottom: 0;
}

.prose blockquote cite {
  display: block;
  margin-top: 0.9em;
  font-family: var(--sans);
  font-size: 0.8rem;
  font-style: normal;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

/* The reference leads, so you know what you are about to read before you
   read it — and it is set in the interface face, upright, so it never gets
   mistaken for part of the verse. */
.prose blockquote.scripture cite {
  margin-top: 0;
  margin-bottom: 0.7em;
  font-size: 0.74rem;
  letter-spacing: 0.14em;
}

/* Stacked lines — "God is Spirit. God is Light. God is Love." — read as a
   litany rather than a paragraph, so they are given the space of one. */
.prose .litany {
  margin: 1.8em 0;
  padding-left: 1.7rem;
  border-left: 2px solid var(--line-strong);
}

.prose .litany span {
  display: block;
  padding: 0.12em 0;
}

/* Poetic / verse lines */
.prose .verse {
  font-style: italic;
}

.prose .verse span {
  display: block;
}

/* Emphasis litany (short stacked lines) */
.prose .litany span {
  display: block;
}

/* Footnotes */
.footnote-ref a {
  font-family: var(--sans);
  font-size: 0.7em;
  text-decoration: none;
  vertical-align: super;
  line-height: 1;
}

.footnotes {
  max-width: 44rem;
  margin: 0 auto;
  padding-bottom: 4rem;
}

.footnotes h2 {
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

.footnotes ol {
  margin: 1rem 0 0;
  padding-left: 1.25rem;
  font-size: 0.95rem;
  color: var(--ink-soft);
}

.footnotes li {
  margin-bottom: 0.75em;
}

.footnotes li:target {
  background: color-mix(in srgb, var(--gold) 12%, transparent);
  border-radius: 6px;
  padding: 0.35rem 0.5rem;
}

/* Prev / next navigation */
/* The publication date lives here rather than under the title. These are
   essays, not issues of a periodical — a date at the top invites the reader
   to weigh how current it is before they have read a word. At the foot it is
   still on the record, for anyone who wants it. */
.article-published {
  max-width: 44rem;
  margin: 3rem auto 0;
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
}

.article-nav {
  max-width: 44rem;
  margin: 0 auto;
  padding: 2.5rem 0 5rem;
  border-top: 1px solid var(--line);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
}

.article-nav a {
  display: block;
  padding: 1.15rem 1.35rem;
  border: 1px solid var(--line);
  border-radius: 14px;
  text-decoration: none;
  background: var(--card);
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.article-nav a:hover {
  border-color: var(--gold);
  transform: translateY(-2px);
}

.article-nav .nav-label {
  display: block;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.35rem;
}

.article-nav .nav-title {
  font-family: var(--serif);
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--ink);
}

.article-nav .is-next {
  text-align: right;
}

@media (max-width: 34em) {
  .article-nav {
    grid-template-columns: 1fr;
  }

  .article-nav .is-next {
    text-align: left;
  }
}

/* ---------- About page ---------- */

.about-split {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: 4rem;
  align-items: center;
  padding: 4.5rem 0;
}

.about-split .prose {
  font-size: 1.15rem;
}

/* Wraps so the second button drops beneath the first rather than squeezing
   the pair — this column is already the narrow half of a two-column split. */
.about-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem 0.85rem;
  margin-top: 0.5rem;
}

.about-actions .btn-spine {
  width: 1.05rem;
  height: 1.05rem;
  flex-shrink: 0;
  margin-left: -0.15rem;
}

.about-figure img {
  border-radius: 18px;
  box-shadow: var(--shadow-lift);
  width: 100%;
  object-fit: cover;
}

.about-figure.is-tall img {
  aspect-ratio: 3 / 4;
}

.about-split .btn {
  margin-top: 1.25rem;
}

@media (max-width: 50em) {
  .about-split {
    grid-template-columns: 1fr;
    gap: 2.5rem;
  }
}

/* ---------- Contact ---------- */

.contact-wrap {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: 4rem;
  padding: 4.5rem 0 5.5rem;
  align-items: start;
}

@media (max-width: 50em) {
  .contact-wrap {
    grid-template-columns: 1fr;
    gap: 2.5rem;
  }
}

.contact-intro h2 {
  font-size: 1.9rem;
  font-weight: 500;
}

.contact-intro p {
  font-family: var(--serif);
  font-size: 1.1rem;
  color: var(--ink-soft);
}

.contact-facts {
  list-style: none;
  margin: 1.75rem 0 0;
  padding: 0;
  display: grid;
  gap: 1.1rem;
}

.contact-facts li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.85rem;
  align-items: start;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
  font-size: 0.97rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

.contact-facts li:first-child {
  padding-top: 0;
  border-top: 0;
}

.contact-facts svg {
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.15rem;
  color: var(--gold-deep);
}

.contact-facts strong {
  display: block;
  font-weight: 600;
  color: var(--ink);
}

.contact-aside {
  margin-top: 1.75rem;
  padding-left: 1rem;
  border-left: 2px solid color-mix(in srgb, var(--gold) 50%, transparent);
  font-style: italic;
  color: var(--ink-faint);
}

.contact-form {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 2rem;
  box-shadow: var(--shadow);
  display: grid;
  gap: 1.15rem;
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.15rem;
}

@media (max-width: 34em) {
  .form-row {
    grid-template-columns: 1fr;
  }
}

.field label {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  margin-bottom: 0.4rem;
}

.field .required {
  color: var(--gold-deep);
}

.field input,
.field textarea {
  width: 100%;
  padding: 0.7rem 0.9rem;
  font: inherit;
  font-size: 0.95rem;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 20%, transparent);
}

.field textarea {
  resize: vertical;
  min-height: 8.5rem;
}

.contact-form .btn {
  justify-self: start;
  border: 0;
  cursor: pointer;
}

.form-note {
  font-size: 0.85rem;
  color: var(--ink-faint);
  margin: 0;
}

.form-status {
  margin: 0;
  padding: 0.85rem 1.1rem;
  border-radius: 10px;
  font-size: 0.95rem;
  font-weight: 500;
}

.form-status.is-success {
  background: color-mix(in srgb, var(--gold) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--gold) 40%, transparent);
  color: var(--gold-deep);
  font-family: var(--serif);
  font-size: 1.05rem;
}

.form-status.is-error {
  background: color-mix(in srgb, #b3402e 10%, transparent);
  border: 1px solid color-mix(in srgb, #b3402e 35%, transparent);
  color: #a03a2a;
}

[data-theme="dark"] .form-status.is-error {
  color: #e08a77;
}

/* ---------- Feature band (Road to Emmaus) ---------- */

/* Night, the same night the timeline is drawn on, so arriving there is a
   continuation rather than a change of scene. The glow at the top is the
   constellation's own light on the surface it sits on. */
.feature-band {
  position: relative;
  padding: 5.5rem 0 5rem;
  overflow: hidden;
  background:
    radial-gradient(60rem 24rem at 50% 0%, rgb(217 174 84 / 0.13), transparent 70%),
    var(--dark);
  color: #efe8d8;
}

.feature-head {
  max-width: 42rem;
  margin: 0 auto 2.5rem;
  text-align: center;
}

.feature-band .eyebrow {
  color: var(--gold-bright);
}

.feature-band h2 {
  color: #faf6ec;
  font-size: clamp(2rem, 4.4vw, 2.9rem);
  font-weight: 500;
  margin: 0;
}

.feature-band h2 em {
  font-style: italic;
  color: var(--gold-bright);
}

.feature-head p {
  font-family: var(--serif);
  font-size: 1.12rem;
  line-height: 1.7;
  color: rgb(239 232 216 / 0.78);
  margin: 0.85rem auto 0;
  max-width: 34em;
}

/* ---------- The constellation ---------- */

.feature-chart {
  max-width: 62rem;
  margin: 0 auto;
}

.hc-svg {
  display: block;
  width: 100%;
  height: clamp(160px, 26vw, 260px);
}

.hc-bars rect {
  fill: rgb(239 232 216 / 0.17);
}

.hc-silence {
  stroke: rgb(239 232 216 / 0.16);
  stroke-width: 1;
  stroke-dasharray: 2 6;
}

.hc-line {
  fill: none;
  stroke: var(--tc);
  stroke-width: 1.8;
  stroke-linejoin: round;
  stroke-linecap: round;
  filter: drop-shadow(0 0 4px color-mix(in srgb, var(--tc) 45%, transparent));
  /* pathLength normalises every thread to 1, so one keyframe draws them all
     at the same pace regardless of how far each one actually travels. */
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}

.hc-dots circle {
  fill: var(--tc);
  opacity: 0;
}

.hc-dots circle.is-f {
  fill: var(--gold-bright);
}

/* Held until the band is scrolled to — a constellation that finished drawing
   before you arrived has shown you nothing. Each thread follows the last. */
.feature-chart.is-drawn .hc-line {
  animation: hc-draw 1.6s ease forwards;
  animation-delay: calc(var(--i) * 0.42s);
}

.feature-chart.is-drawn .hc-dots circle {
  animation: hc-dot 0.5s ease forwards;
  animation-delay: calc(var(--i) * 0.42s + 1.2s);
}

.feature-chart.no-anim .hc-line {
  stroke-dashoffset: 0;
  animation: none;
}

.feature-chart.no-anim .hc-dots circle {
  opacity: 1;
  animation: none;
}

@keyframes hc-draw {
  to { stroke-dashoffset: 0; }
}

@keyframes hc-dot {
  to { opacity: 1; }
}

/* ---------- Legend + actions ---------- */

.feature-threads {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1.35rem;
  margin: 1.6rem 0 0;
  padding: 0;
  list-style: none;
}

.feature-threads li {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.82rem;
  font-weight: 500;
  color: rgb(239 232 216 / 0.7);
}

.feature-threads li.is-more {
  color: rgb(239 232 216 / 0.45);
  font-style: italic;
}

.feature-threads .dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--thread-color);
  box-shadow: 0 0 7px color-mix(in srgb, var(--thread-color) 60%, transparent);
}

.feature-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.85rem;
  margin-top: 2.25rem;
}

@media (max-width: 40em) {
  .feature-band {
    padding: 4rem 0 3.5rem;
  }

  /* The bars get too fine to read much below this, and the constellation is
     the point — so it keeps its height while the page narrows. */
  .hc-svg {
    height: 200px;
  }

  .feature-threads {
    gap: 0.45rem 1rem;
    font-size: 0.78rem;
  }
}

/* ---------- Thread pages ---------- */

.thread-head {
  padding: 4.5rem 0 3.25rem;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  position: relative;
}

.thread-head::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 4px;
  background: var(--thread-color);
}

.thread-head .eyebrow {
  color: var(--thread-color);
  filter: saturate(0.9) brightness(0.72);
}

[data-theme="dark"] .thread-head .eyebrow {
  filter: none;
}

.thread-head h1 {
  font-size: clamp(2.4rem, 6vw, 3.5rem);
  font-weight: 500;
  margin-bottom: 0.15em;
}

.thread-subtitle {
  font-family: var(--serif);
  font-size: clamp(1.15rem, 2.6vw, 1.45rem);
  font-style: italic;
  color: var(--ink-soft);
  margin: 0 0 1.25rem;
}

.thread-meta {
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 1.75rem;
}

.thread-meta .swatch {
  width: 10px;
  height: 10px;
  border-radius: 999px;
  background: var(--thread-color);
}

.thread-body {
  max-width: 44rem;
  padding: 3.5rem 0 1rem;
}

.thread-body .prose p:first-child::first-letter {
  float: left;
  font-size: 3.4em;
  line-height: 0.82;
  padding: 0.06em 0.12em 0 0;
  font-weight: 500;
  color: var(--thread-color);
  filter: saturate(0.85) brightness(0.7);
}

[data-theme="dark"] .thread-body .prose p:first-child::first-letter {
  filter: none;
}

.thread-section-label {
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 3.5rem 0 1.5rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--line);
}

/* The walk: every stop in order, promise rising then arriving */
.thread-arc {
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
}

.thread-arc::before {
  content: "";
  position: absolute;
  left: 5px;
  top: 0.75rem;
  bottom: 0.75rem;
  width: 2px;
  background: var(--thread-color);
  opacity: 0.35;
}

.thread-arc li {
  position: relative;
  padding: 0 0 1.75rem 2.25rem;
}

.thread-arc li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.5rem;
  width: 12px;
  height: 12px;
  border-radius: 999px;
  background: var(--thread-color);
  outline: 4px solid var(--paper);
}

.thread-arc li.is-fulfillment::before {
  box-shadow: 0 0 0 3px var(--paper), 0 0 0 5px var(--gold);
}

.thread-arc .arc-ref {
  display: block;
  font-family: var(--sans);
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  margin-bottom: 0.3rem;
}

.thread-arc .arc-ref a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--line-strong);
}

.thread-arc .arc-ref a:hover {
  border-bottom-color: var(--thread-color);
}

.thread-arc li.is-fulfillment .arc-ref::before {
  content: "\2726\00a0";
  color: var(--gold-deep);
}

.thread-arc .arc-text {
  font-family: var(--serif);
  font-size: 1.08rem;
  line-height: 1.6;
  color: var(--ink-soft);
  margin: 0;
}

.thread-arc li.is-fulfillment .arc-text {
  color: var(--ink);
}

/* Closing statement */
.thread-close {
  margin-top: 1rem;
  padding: 1.75rem 2rem;
  border-radius: 16px;
  background: color-mix(in srgb, var(--gold) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--gold) 28%, transparent);
}

.thread-close h2 {
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold-deep);
  margin-bottom: 0.9rem;
}

.thread-close p {
  font-family: var(--serif);
  font-size: 1.15rem;
  line-height: 1.65;
  margin: 0;
}

/* Thread-to-thread navigation */
.thread-nav {
  max-width: 44rem;
  margin: 0 auto;
  padding: 2.5rem 0 5rem;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
}

.thread-nav a {
  display: block;
  padding: 1.15rem 1.35rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--nav-color, var(--line-strong));
  border-radius: 12px;
  text-decoration: none;
  background: var(--card);
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.thread-nav a:hover {
  transform: translateY(-2px);
}

.thread-nav .is-next {
  text-align: right;
  border-left: 1px solid var(--line);
  border-right: 3px solid var(--nav-color, var(--line-strong));
}

.thread-nav .nav-label {
  display: block;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.3rem;
}

.thread-nav .nav-title {
  font-family: var(--serif);
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--ink);
}

@media (max-width: 34em) {
  .thread-nav {
    grid-template-columns: 1fr;
  }

  .thread-nav .is-next {
    text-align: left;
    border-left: 3px solid var(--nav-color, var(--line-strong));
    border-right: 1px solid var(--line);
  }
}

/* Floating return to the timeline — appears once you have read a way down */
.floating-back {
  position: fixed;
  right: 1.5rem;
  bottom: 1.5rem;
  z-index: 40;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.8rem 1.3rem;
  border-radius: 999px;
  background: var(--dark);
  color: #f4eee1;
  border: 1px solid var(--thread-color, var(--gold));
  box-shadow: 0 6px 28px rgb(0 0 0 / 0.35);
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease, box-shadow 0.2s ease;
}

.floating-back.is-visible {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.floating-back:hover {
  color: #fff;
  box-shadow: 0 8px 34px rgb(0 0 0 / 0.45);
}

.floating-back svg {
  width: 1rem;
  height: 1rem;
  flex: none;
  color: var(--thread-color, var(--gold));
}

@media (max-width: 34em) {
  .floating-back {
    right: 1rem;
    bottom: 1rem;
    padding: 0.7rem 1.1rem;
    font-size: 0.85rem;
  }
}

/* Thread index cards */
.thread-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: 1.5rem;
}

.thread-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1.75rem 1.75rem 1.6rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-top: 3px solid var(--thread-color);
  border-radius: 14px;
  box-shadow: var(--shadow);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.thread-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lift);
}

.thread-card h2 {
  font-size: 1.5rem;
  margin: 0;
}

.thread-card h2 a {
  color: inherit;
  text-decoration: none;
}

.thread-card h2 a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.thread-card .card-sub {
  font-family: var(--serif);
  font-style: italic;
  color: var(--ink-soft);
  font-size: 1.02rem;
}

.thread-card p {
  font-family: var(--serif);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink-soft);
  margin: 0.35rem 0 0;
  flex: 1;
}

.thread-card .card-meta {
  font-size: 0.8rem;
  color: var(--ink-faint);
  margin-top: 0.9rem;
}

/* ---------- CTA band ---------- */

.cta-band {
  background: var(--surface);
  border-block: 1px solid var(--line);
  padding: 4.5rem 0;
  text-align: center;
}

.cta-band h2 {
  font-size: clamp(1.8rem, 4vw, 2.4rem);
  font-weight: 500;
}

.cta-band p {
  font-family: var(--serif);
  font-size: 1.1rem;
  color: var(--ink-soft);
  max-width: 36em;
  margin: 0.5rem auto 1.75rem;
}

/* ---------- Footer ---------- */

.site-footer {
  background: var(--dark);
  color: #b9ae95;
  padding: 4rem 0 2.5rem;
}

.footer-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: 2.5rem;
  padding-bottom: 2.5rem;
  border-bottom: 1px solid rgb(255 255 255 / 0.08);
}

.footer-brand img {
  width: 10.5rem;
}

.footer-brand p {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1rem;
  margin: 1rem 0 0;
  color: #8f8569;
}

.footer-nav {
  display: flex;
  gap: 2.5rem;
}

.footer-nav h3,
.footer-nav .footer-head {
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: #8f8569;
  margin: 0 0 0.85rem;
}

.footer-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.footer-nav li {
  margin: 0.5rem 0;
}

.footer-nav a {
  color: #d6ccb2;
  text-decoration: none;
  font-size: 0.95rem;
}

.footer-nav a:hover {
  color: var(--gold-bright);
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.75rem;
  padding-top: 2rem;
  font-size: 0.85rem;
  /* Was #7d7357 at 4.0:1 on the footer's near-black. The footer stays dark in
     both themes, so this is a fixed value rather than a token. */
  color: #877e64;
}

.footer-bottom a {
  color: inherit;
}

/* ---------- Motion preferences ---------- */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001s !important;
    transition-duration: 0.001s !important;
  }
}
