/* ==========================================================================
   Khary Lazarre-White — Redesign
   Design system / global stylesheet
   "Literary gravitas meets civic optimism"
   Type: Fraunces (display serif) + Figtree (sans)
   ========================================================================== */

/* ----- Accent — one uniform blue ----------------------------------------
   A single blue (#4a78b8) used at the SAME value on every background, light
   or dark — the hue/value never shifts. It is the optimal single value for
   these two backgrounds: ~4.05:1 on cream and ~4.07:1 on espresso. That
   clears AA for large text, UI components, and white-on-blue buttons (4.5:1);
   small text lands ~4.05:1 — marginally under the 4.5:1 AA threshold, the
   accepted tradeoff for keeping one uniform blue across light and dark.
   soft/wash are light tints of the same blue, used only for fills. */
:root {
  --accent:          #4a78b8;                                  /* the single blue (same on all backgrounds) */
  --accent-ink:      #4a78b8;                                  /* text & links on light */
  --accent-soft:     color-mix(in srgb, #4a78b8 26%, #ffffff); /* light fill — same hue */
  --accent-wash:     color-mix(in srgb, #4a78b8 11%, #ffffff); /* faint tint — same hue */
  --accent-on-dark:  #4a78b8;                                  /* same blue on dark — no shift */
  --accent-btn-text: #ffffff;                                  /* white text on a solid-blue button (4.5:1) */
}

:root {
  /* Neutrals — warm, dark-on-light (the original tones) */
  --paper:        #f7f2e9;
  --paper-2:      #f2ebde;  /* slightly deeper cream for alt sections */
  --surface:      #fbf8f1;
  --surface-2:    #ffffff;
  --ink:          #1c1814;  /* warm near-black, body text */
  --ink-soft:     #2c251d;
  --muted:        #5a5048;
  --muted-2:      #857a6c;
  --hairline:     #e3dac9;
  --hairline-2:   #d6cab2;

  /* Dark sections (full-bleed drama) */
  --espresso:     #181410;
  --espresso-2:   #211b14;
  --cream:        #f1e9da;  /* primary text on dark */
  --cream-muted:  #c6b8a2;  /* secondary text on dark */
  --hairline-dark:#3a3128;

  /* Crosshatch texture — four 1px rules on an 8px period at 22.5° increments, giving
     a fine engraved/laid-paper weave. Pure CSS, so no asset, no tiling seams and it
     stays crisp at any zoom (the two problems that sank the scanned-paper attempt).
     Strokes are warm ink rgba(28,24,20) rather than the cool greys of the original
     snippet, which would have dulled the cream toward grey. Alpha descends per layer
     so the weave reads as woven rather than as a uniform screen. These four alphas
     are the tuning knobs.
     Muted to 20% of the reference snippet's strength: at full strength the weave
     measured sd 5.9 on paper and dropped the blue accent to 2.93 where text crossed
     the darkest strokes — under the 3.0 AA floor. At 20% it measures sd ~1.3 and the
     accent worst case is comfortably clear. Scale both sets together to stay balanced.
     Note this is near the floor of perceptibility — much lower and the weave stops
     reading on standard-brightness displays. */
  --crosshatch:
    repeating-linear-gradient(22.5deg,  transparent 0 2px, rgba(28,24,20,0.011) 2px 3px, transparent 3px 8px),
    repeating-linear-gradient(67.5deg,  transparent 0 2px, rgba(28,24,20,0.009) 2px 3px, transparent 3px 8px),
    repeating-linear-gradient(112.5deg, transparent 0 2px, rgba(28,24,20,0.007) 2px 3px, transparent 3px 8px),
    repeating-linear-gradient(157.5deg, transparent 0 2px, rgba(28,24,20,0.006) 2px 3px, transparent 3px 8px);
  /* Cream strokes for espresso surfaces — the ink version is invisible on near-black. */
  --crosshatch-dark:
    repeating-linear-gradient(22.5deg,  transparent 0 2px, rgba(241,233,218,0.009) 2px 3px, transparent 3px 8px),
    repeating-linear-gradient(67.5deg,  transparent 0 2px, rgba(241,233,218,0.007) 2px 3px, transparent 3px 8px),
    repeating-linear-gradient(112.5deg, transparent 0 2px, rgba(241,233,218,0.006) 2px 3px, transparent 3px 8px),
    repeating-linear-gradient(157.5deg, transparent 0 2px, rgba(241,233,218,0.005) 2px 3px, transparent 3px 8px);

  /* Type — all set to Barlow Semi Condensed */
  --serif: "Barlow Semi Condensed", "Arial Narrow", Arial, sans-serif;
  --sans:  "Barlow Semi Condensed", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* Rhythm */
  --container: 1240px;
  --container-narrow: 820px;
  /* Essay measure now matches --container-narrow, so every content column on the site
     is the same 692px. The larger .prose--essay type keeps it at ~80 chars/line. */
  --container-reading: var(--container-narrow);
  --gutter: clamp(1.25rem, 5vw, 4rem);
  --section-y: clamp(4.5rem, 9vw, 9rem);
  --radius: 4px;
  --radius-lg: 8px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ----- Reset / base ------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 88px;
}

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  line-height: 1.7;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "kern";
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, picture, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; background: none; border: none; }
ul, ol { list-style: none; padding: 0; }

::selection { background: var(--accent); color: #fff; }

/* ----- Typography -------------------------------------------------------- */
h1, h2, h3, h4 {
  font-family: var(--serif);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.015em;
  font-optical-sizing: auto;
  color: var(--ink);
  text-wrap: balance;
}

.display {
  font-size: clamp(2.9rem, 1.6rem + 5.6vw, 5.6rem);
  font-weight: 600;
  line-height: 0.98;
  letter-spacing: -0.025em;
}

.h1 { font-size: clamp(2.3rem, 1.5rem + 3.4vw, 3.7rem); }
.h2 { font-size: clamp(1.8rem, 1.3rem + 2.1vw, 2.7rem); }
.h3 { font-size: clamp(1.25rem, 1.1rem + 0.7vw, 1.5rem); }

p { text-wrap: pretty; }
strong { font-weight: 600; }
em { font-style: italic; }

.lead {
  font-size: clamp(1.15rem, 1.05rem + 0.6vw, 1.45rem);
  line-height: 1.6;
  color: var(--ink-soft);
  font-weight: 400;
}

/* Eyebrow / kicker label */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  font-family: var(--sans);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent-ink);
}
.eyebrow--center { justify-content: center; }

/* Links inside prose */
.prose a,
.link {
  color: var(--accent-ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent);
  transition: text-decoration-color 0.25s var(--ease), color 0.25s var(--ease);
}
.prose a:hover,
.link:hover { text-decoration-color: var(--accent); }

/* Arrow link */
/* One treatment for every arrow-link on the site: bold, accent-blue, underlined —
   matching what the in-prose links already looked like. Before this, an .arrow-link
   was ink with no underline UNLESS it sat inside .prose (where `.prose a` recoloured
   it), so "Read the full biography" read as a link and "All writings" / "Read essay"
   did not. Every arrow-link is painted on a light surface — cream, card surface or
   white, including the ones in .section--navy, which sit inside light cards — so the
   accent clears contrast in all of them. */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  color: var(--accent-ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent);
  transition: text-decoration-color 0.25s var(--ease), color 0.25s var(--ease);
}
.arrow-link span.line {
  display: inline-block;
  width: 1.6em; height: 1px;
  background: currentColor;
  transition: width 0.3s var(--ease);
}
.arrow-link:hover { text-decoration-color: var(--accent); }
.arrow-link:hover span.line { width: 2.4em; }

/* ----- Layout ------------------------------------------------------------ */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--narrow { max-width: var(--container-narrow); }
/* Desktop: don't centre the narrow column in the viewport — that pushes its content
   ~210px right of every full-width section, so headings don't line up down the page.
   Instead let the box span the standard container (matching everyone else's left
   edge) and cap the children at the width the narrow container used to yield.
   Below 901px the 820px box is already near-full-width, so leave it centred. */
@media (min-width: 901px) {
  .container--narrow { max-width: var(--container); }
  .container--narrow > * { max-width: calc(var(--container-narrow) - 2 * var(--gutter)); }
}
/* Reading measure for long-form essays — max-width includes the gutter, so this
   lands ~576px of text (~78 characters in Barlow Semi Condensed). */
.container--reading { max-width: var(--container-reading); }
/* Desktop: left-align rather than centre, same as .container--narrow above — the
   essay's left edge then matches every other section down the site instead of
   floating in the middle of a wide viewport. Content width is unchanged. */
@media (min-width: 901px) {
  .container--reading { max-width: var(--container); }
  .container--reading > * { max-width: calc(var(--container-reading) - 2 * var(--gutter)); }
}

.section {
  position: relative;
  z-index: 1;
  padding-block: var(--section-y);
}
.section--tight { padding-block: clamp(3rem, 6vw, 5rem); }
.section--alt { background: var(--paper-2); }
.section--surface { background: var(--surface); }

/* Dark full-bleed panel (espresso) — for dark sections that contain light cards;
   light-navy accents read with strong contrast against the near-black. */
/* Same seam problem as .quote-band and .section--dark: when a navy section is the
   last one on the page, the footer below it is also espresso and the two merge into
   one block. Harmless where a light section follows — the line falls exactly on the
   colour change. */
.section--navy { background: var(--espresso); border-bottom: 1px solid var(--hairline-dark); }
.section--navy h1, .section--navy h2, .section--navy h3, .section--navy h4 { color: var(--cream); }
.section--navy .eyebrow { color: var(--accent-on-dark); }
.section--navy .lead { color: color-mix(in srgb, var(--cream) 85%, transparent); }

/* Dark full-bleed section */
.section--dark {
  background: var(--espresso);
  color: var(--cream);
  /* Same reason as .quote-band: the footer below is also espresso, so without this
     the closing CTA and the footer merge into one block. */
  border-bottom: 1px solid var(--hairline-dark);
}
.section--dark h1,
.section--dark h2,
.section--dark h3,
.section--dark h4 { color: var(--cream); }
.section--dark .eyebrow { color: var(--accent-on-dark); }
.section--dark .lead { color: var(--cream-muted); }
.section--dark .arrow-link { color: var(--cream); }
.section--dark .arrow-link:hover { color: var(--accent-on-dark); }

.section-head { max-width: 56ch; margin-bottom: clamp(2rem, 4vw, 3.25rem); }
/* Section headings are short editorial lines, not prose. At 56ch (480px) four of
   them broke to two lines while half the container sat empty beside them — the
   widest, "A life of service, scholarship and story.", needs 627px. 42rem clears
   it with room to spare. Desktop only: below 901px the container is narrower than
   this anyway, so the cap stops mattering and headings wrap as they should.
   Safe to widen because a .section-head holds only an eyebrow and the h2 — there
   is no paragraph here whose measure this would blow out. */
@media (min-width: 901px) {
  .section-head { max-width: 42rem; }
}
.section-head .h2 { margin-top: 0.7rem; }
.section-head--center { margin-inline: auto; text-align: center; }

hr.rule {
  border: 0;
  height: 1px;
  background: var(--hairline);
  margin: 0;
}
.section--dark hr.rule { background: var(--hairline-dark); }

/* ----- Buttons ----------------------------------------------------------- */
.btn {
  --btn-bg: var(--ink);
  --btn-fg: var(--paper);
  --btn-bd: var(--ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  padding: 0.95em 1.6em;
  font-family: var(--sans);
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  border-radius: var(--radius);
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-bd);
  transition: background 0.25s var(--ease), color 0.25s var(--ease), border-color 0.25s var(--ease);
}

.btn--accent {
  --btn-bg: var(--accent);
  --btn-fg: var(--accent-btn-text);
  --btn-bd: var(--accent);
}
.btn--accent:hover { --btn-bg: color-mix(in srgb, var(--accent) 86%, #000); --btn-bd: var(--btn-bg); }

.btn--outline {
  --btn-bg: transparent;
  --btn-fg: var(--ink);
  --btn-bd: var(--hairline-2);
}
.btn--outline:hover { --btn-bg: var(--ink); --btn-fg: var(--paper); --btn-bd: var(--ink); }

/* Buttons on dark / navy backgrounds */
.on-dark .btn,
.section--dark .btn,
.section--navy .btn {
  --btn-bg: var(--accent);
  --btn-fg: var(--accent-btn-text);
  --btn-bd: var(--accent);
}
.on-dark .btn:hover,
.section--dark .btn:hover,
.section--navy .btn:hover { --btn-bg: color-mix(in srgb, var(--accent) 82%, #ffffff); --btn-bd: color-mix(in srgb, var(--accent) 82%, #ffffff); }
.on-dark .btn--outline,
.section--dark .btn--outline,
.section--navy .btn--outline {
  --btn-bg: transparent;
  --btn-fg: var(--cream);
  --btn-bd: color-mix(in srgb, var(--cream) 42%, transparent);
}
.on-dark .btn--outline:hover,
.section--dark .btn--outline:hover,
.section--navy .btn--outline:hover { --btn-bg: var(--cream); --btn-fg: var(--ink); --btn-bd: var(--cream); }

.btn-row { display: flex; flex-wrap: wrap; gap: 0.85rem; }

/* ----- Site header / nav ------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: saturate(1.2) blur(10px);
  -webkit-backdrop-filter: saturate(1.2) blur(10px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.site-header.is-scrolled {
  border-bottom-color: var(--hairline);
  box-shadow: 0 1px 24px -16px rgba(28, 24, 20, 0.5);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  height: 72px;
}
.brand {
  font-family: var(--serif);
  font-weight: 700;
  font-size: 1.6rem;
  letter-spacing: -0.01em;
  color: var(--ink);
  white-space: nowrap;
}
.brand .brand__dot { color: var(--accent); }

.nav { display: flex; align-items: center; gap: clamp(1rem, 2.2vw, 2.1rem); }
.nav a {
  position: relative;
  font-family: var(--sans);
  font-size: 0.93rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--ink-soft);
  padding: 0.35em 0;
  transition: color 0.2s var(--ease);
}
.nav a::after {
  content: "";
  position: absolute;
  left: 0; bottom: -2px;
  width: 100%;
  height: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s var(--ease);
}
.nav a:hover { color: var(--ink); }
.nav a:hover::after,
.nav a[aria-current="page"]::after { transform: scaleX(1); }
.nav a[aria-current="page"] { color: var(--ink); }

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px; height: 44px;
  margin-right: -8px;
}
.nav-toggle span {
  display: block;
  height: 2px; width: 24px;
  background: var(--ink);
  border-radius: 2px;
  transition: transform 0.3s var(--ease), opacity 0.2s var(--ease);
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ----- Hero -------------------------------------------------------------- */
.hero {
  position: relative;
  z-index: 1;
  background: var(--espresso);
  color: var(--cream);
  overflow: hidden;
}
.hero__inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
  min-height: min(86vh, 760px);
  padding-block: clamp(3.5rem, 7vw, 6rem);
}
.hero__roles {
  font-family: var(--sans);
  font-size: clamp(0.82rem, 0.78rem + 0.25vw, 0.95rem);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent-on-dark);
  margin-bottom: 1.4rem;
}
.hero__title {
  color: var(--cream);
  margin-bottom: 1.4rem;
}
.hero__org {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.15rem, 1rem + 0.7vw, 1.5rem);
  color: var(--cream);
  margin-bottom: 1.6rem;
}
.hero__org .accent { color: var(--accent-on-dark); font-style: normal; }
.hero__intro {
  max-width: 46ch;
  color: var(--cream-muted);
  font-size: clamp(1.02rem, 0.98rem + 0.3vw, 1.18rem);
  margin-bottom: 2.2rem;
}
.hero .btn-row { margin-top: 0.5rem; }

/* Portrait placeholder (swap with real photography) */
.portrait {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background:
    linear-gradient(150deg, color-mix(in srgb, var(--accent) 34%, var(--espresso-2)), var(--espresso-2) 70%);
  /* No border — the near-black hairline was invisible on the dark hero but read as a
     hard black outline against the light biography section. The soft shadow carries
     the edge definition on its own. */
  box-shadow: 0 40px 80px -40px rgba(0,0,0,0.6);
}
.portrait img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}
/* A photo that keeps its own proportions. The base .portrait is locked to 4/5 and
   crops anything else via object-fit; this square rooftop shot would lose its sky and
   its foreground to that. Overriding position/height lets the image flow naturally —
   the radius and shadow stay, so it reads as a sibling of the portrait above it. */
.portrait--natural { aspect-ratio: auto; }
.portrait--natural img { position: static; height: auto; }

.portrait__mono {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(4rem, 12vw, 8rem);
  color: color-mix(in srgb, var(--cream) 16%, transparent);
  letter-spacing: -0.04em;
}
.portrait__label {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.85rem 1rem;
  font-family: var(--sans);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--cream-muted);
  background: linear-gradient(transparent, rgba(0,0,0,0.45));
}

/* ----- Generic media placeholder (book cover, etc.) ---------------------- */
.ph {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-wash);
  border: 1px solid var(--hairline-2);
  border-radius: var(--radius);
  color: var(--accent-ink);
  text-align: center;
  overflow: hidden;
}
.ph__label {
  font-family: var(--sans);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-2);
}

/* ----- Intro / two-column prose ------------------------------------------ */
.split {
  display: grid;
  grid-template-columns: minmax(0, 0.42fr) minmax(0, 0.58fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
.split--reverse > :first-child { order: 2; }
/* Text-led split: wider column first (prose), narrower second (a photo). Base .split
   is 0.42/0.58, sized for image-left/text-right. A modifier rather than an inline
   grid-template-columns — inline would beat the max-width:900px rule further down
   that collapses .split to a single column on mobile. */
.split--text-first { grid-template-columns: minmax(0, 0.58fr) minmax(0, 0.42fr); }
/* Vertically centres a split's columns. Base .split is align-items:start, which is
   right for text beside text, but leaves a short hero heading stranded at the top of
   a tall portrait. Safe to pair with the mobile collapse — the max-width:900px rule
   only touches grid-template-columns. */
.split--center { align-items: center; }
.prose p + p { margin-top: 1.1em; }
.prose p { color: var(--muted); }
.prose .lead { color: var(--ink-soft); margin-bottom: 1.2rem; }

/* Long-form essay body (writings-*.html). Barlow is condensed, so a 692px column at
   normal body size runs ~97 characters per line — far too long at essay length. The
   larger type here is what makes that width readable: measured 80.1 chars at 1.3rem
   vs 97 at 1.05rem. Raise the width and you must raise this too, or the measure blows
   out. Pair with .container--reading on BOTH the page-hero and the body container so
   the column stays aligned down the page. */
.prose--essay p { font-size: 1.15rem; line-height: 1.75; color: var(--ink-soft); }
/* The size bump only pairs with the wider desktop column (≥901px). On mobile the
   column is already full-width, so enlarging the type there just squeezes the line
   to ~38 characters instead of a comfortable ~41. */
@media (min-width: 901px) {
  .prose--essay p { font-size: 1.3rem; }
}
.prose--essay p + p { margin-top: 1.15em; }

/* ----- Stat strip -------------------------------------------------------- */
.stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.25rem, 3vw, 2.5rem);
}
.stat__num {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(2.4rem, 1.8rem + 2.6vw, 3.6rem);
  line-height: 1;
  color: var(--ink);
  letter-spacing: -0.02em;
}
.section--dark .stat__num { color: var(--cream); }
.stat__num .unit { color: var(--accent-ink); }
.section--dark .stat__num .unit { color: var(--accent-on-dark); }
.stat__label {
  margin-top: 0.6rem;
  font-size: 0.92rem;
  color: var(--muted);
}
.section--dark .stat__label { color: var(--cream-muted); }

/* ----- Big pull quote ---------------------------------------------------- */
/* Bottom hairline divider. On awards/biography/writings the quote band is followed
   by another espresso section, so without this the two merge into one dark block.
   Where a light section follows (index, novel) the colour change already divides
   them and this line reads as nothing. */
.quote-band {
  position: relative;
  border-bottom: 1px solid var(--hairline-dark);
}
.quote-band .container { position: relative; z-index: 1; }
.bigquote {
  position: relative;
  max-width: 52rem;
  margin: 0 auto;
  text-align: center;
}
.bigquote__mark {
  font-family: var(--serif);
  font-size: clamp(5rem, 14vw, 9rem);
  line-height: 0.7;
  color: var(--accent-on-dark);
  display: block;
  margin-bottom: -0.2em;
}
.bigquote blockquote {
  font-family: var(--serif);
  font-weight: 500;
  font-style: italic;
  font-size: clamp(1.5rem, 1.1rem + 2.4vw, 2.6rem);
  line-height: 1.28;
  letter-spacing: -0.01em;
  color: var(--cream);
  max-width: none;
  margin-inline: auto;
}
.bigquote cite {
  display: block;
  margin-top: 1.6rem;
  font-family: var(--sans);
  font-style: normal;
  font-size: 0.86rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-on-dark);
}
.bigquote cite span {
  display: block;
  margin-top: 0.3rem;
  font-weight: 400;
  letter-spacing: 0.03em;
  text-transform: none;
  color: var(--cream-muted);
}

/* ----- Explore cards grid ------------------------------------------------ */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
/* The seamless grid paints --hairline behind the cells, so a partial last row shows
   as a filled empty block. Use this variant when the item count is not a multiple of
   the column count (e.g. the 5 essays on writings.html) — separated cards, same flat
   1px-hairline language, and no empty cell to fill. */
.cards--separate {
  background: none;
  border: 0;
  border-radius: 0;
  gap: clamp(1rem, 2vw, 1.5rem);
}
.cards--separate .card {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
}
/* Fixed 2-up layout for the homepage "Latest" row. The default auto-fit grid would
   put 4 cards in 3 columns and strand the fourth alone on a second row. A class with
   its own breakpoint, NOT an inline grid-template-columns — inline would beat the
   collapse rule below and leave two ~160px cards on a phone. */
.cards--2up { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 720px) {
  .cards--2up { grid-template-columns: 1fr; }
}
.card {
  /* A variable, not a literal, because .card--media pulls its media out to the
     card edges with exactly this value negated — the two must move together. */
  --card-pad: clamp(1.6rem, 3vw, 2.4rem);
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: var(--card-pad);
  background: var(--surface);
  transition: background 0.3s var(--ease), transform 0.3s var(--ease);
}
.card:hover { background: var(--surface-2); }
.card__index {
  font-family: var(--serif);
  font-size: 0.95rem;
  color: var(--accent-ink);
  font-weight: 600;
  letter-spacing: 0.04em;
}
.card__title {
  font-family: var(--serif);
  font-size: clamp(1.3rem, 1.1rem + 0.9vw, 1.7rem);
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.1;
}
.card p { color: var(--muted); font-size: 0.97rem; flex: 1; }
.card .arrow-link { margin-top: 0.6rem; }
.card__title::after { content: ""; }

/* Card variant used as standalone tiles (e.g. essays/press lists) */
.tile {
  display: block;
  padding: clamp(1.5rem, 3vw, 2.2rem);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  transition: transform 0.3s var(--ease), border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.tile:hover {
  transform: translateY(-3px);
  border-color: var(--hairline-2);
  box-shadow: 0 30px 50px -34px rgba(28,24,20,0.4);
}
.tile__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1rem;
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-ink);
  margin-bottom: 0.9rem;
}
.tile__meta .src { color: var(--muted-2); font-weight: 500; }
.card > .src,
.tile > .src {
  display: block;
  margin-top: -0.35rem;
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.tile__title {
  font-family: var(--serif);
  font-size: clamp(1.3rem, 1.1rem + 1vw, 1.85rem);
  font-weight: 500;
  line-height: 1.12;
  letter-spacing: -0.015em;
  margin-bottom: 0.7rem;
}
.tile p { color: var(--muted); }
.tile .arrow-link { margin-top: 1.1rem; }

/* ----- Novel feature ----------------------------------------------------- */
.book {
  display: grid;
  grid-template-columns: 0.8fr 1.2fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.book__cover {
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 40px 70px -36px rgba(0,0,0,0.55);
  border: 1px solid var(--hairline-2);
  background: var(--espresso-2);
  align-self: start;
}
.book__cover img {
  width: 100%;
  height: auto;
  display: block;
}
.book__cover .ph__label { color: var(--cream-muted); }
.book__cover .cover-title {
  font-family: var(--serif);
  font-size: clamp(2rem, 6vw, 2.8rem);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.book__cover .cover-by { font-size: 0.85rem; color: var(--cream-muted); letter-spacing: 0.1em; text-transform: uppercase; }
/* Book title + byline on novel.html. These were inline styles on the element;
   they live here so the mobile bump below can override them — an inline
   font-size beats any stylesheet rule short of !important. */
.book__byline {
  display: block;
  margin-top: 0.4rem;
  font-size: 0.4em;   /* em — tracks the title size */
  font-weight: 400;
  line-height: 1.3;
  color: var(--muted);
}
@media (max-width: 900px) {
  /* The global .h2 clamp bottoms out at 1.8rem, which left the book title —
     the page's main subject — no larger than a section heading on a phone,
     and its 0.4em byline down at ~11px. Both get a lift here. */
  .book__title { font-size: 2.4rem; }
  .book__byline { font-size: 0.46em; }
}
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.45em 0.9em;
  background: var(--accent-wash);
  color: var(--accent-ink);
  border: 1px solid var(--accent-soft);
  border-radius: 999px;
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.06em;
}

/* ----- Media cards (homepage "Latest") ------------------------------------
   These sit in the standard .cards grid. .cards--separate is required, not
   optional: .cards paints --hairline behind its cells, and auto-fit drops to
   2 columns at tablet widths, which would leave the 3rd item's empty cell
   showing as a filled block. */
.card--media { background: var(--surface); }
/* The video cards are not links — they hold embeds — so the base .card hover,
   which lightens the background, would promise interactivity they don't have.
   Neutralise it for those, but NOT for a media card that is itself an anchor
   (the NYT card), where the hover is a true affordance. */
.card--media:not(a):hover { background: var(--surface); }
/* The card already supplies the frame — a second border around the media reads
   as a box in a box. */
.card--media .video__frame {
  border: 0;
  /* Full-bleed to the card's top and side edges. */
  margin: calc(-1 * var(--card-pad)) calc(-1 * var(--card-pad)) 0.6rem;
  /* Match the card's rounded top corners. The card carries a 1px border, so the
     inner radius is 1px tighter — square corners would poke outside the curve. */
  border-radius: calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px) 0 0;
}
.video__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  overflow: hidden;
  /* Espresso rather than cream: it matches the letterboxing YouTube itself paints
     while the player loads, so the frame doesn't flash light-then-dark. */
  background: var(--espresso-2);
  border: 1px solid var(--hairline);
}
.video__frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
/* Not every item in the row is a video — the NYT feature is a still. It shares the
   16/9 frame so the three line up; cover-cropping the 4:3 original trims sky and
   parked cars and leaves the building, which is the subject. */
.video__frame img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* ----- Endorsement / review quotes --------------------------------------- */
.quotes {
  columns: 2;
  column-gap: clamp(1.5rem, 3vw, 2.5rem);
}
.quote-card {
  break-inside: avoid;
  margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
  padding: clamp(1.4rem, 3vw, 2rem);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
}
.quote-card blockquote {
  font-family: var(--serif);
  font-size: 1.05rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
.quote-card cite {
  display: block;
  margin-top: 1rem;
  font-style: normal;
  font-family: var(--sans);
}
/* Attribution lines are short labels, not prose. At the inherited 1.7 the wrapped
   ones (three of the eleven run to two lines) drifted apart badly — tighter than the
   blockquote's own 1.5, since this text is smaller and secondary to it. */
.quote-card cite b { display: block; font-weight: 600; color: var(--ink); font-size: 0.95rem; line-height: 1.3; }
.quote-card cite span { display: block; font-size: 0.85rem; color: var(--muted-2); margin-top: 0.1rem; line-height: 1.4; }

/* Three-up support quotes */
.support {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 270px), 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
}
.support__item {
  padding-top: 1.5rem;
  /* Ink rather than the accent blue (2026-08-30, user's request). The palette has
     exactly one blue by design, so there is no darker blue to reach for — the darker
     option on a light surface is the body ink. */
  border-top: 2px solid var(--ink);
}
.support__item blockquote {
  font-family: var(--serif);
  font-size: clamp(1.05rem, 1rem + 0.3vw, 1.2rem);
  line-height: 1.45;
  color: var(--ink-soft);
  margin-bottom: 1rem;
}
.section--dark .support__item blockquote { color: var(--cream); }
.support__item cite {
  font-style: normal;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.82rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-ink);
  /* Same reasoning as .quote-card cite: a short attribution label, not prose.
     Susan L. Taylor's runs to two lines and at the inherited 1.7 they drifted.
     ⚠️ `display: block` is REQUIRED for the line-height to do anything. A <cite>
     is inline by default, and an inline box cannot shrink the line box below the
     containing block's strut — that strut came from .support__item inheriting the
     global 1.7 (17px x 1.7 = 28.9px, exactly the baseline gap that was measured).
     Setting line-height on the inline cite alone changed nothing. */
  display: block;
  line-height: 1.4;
}
.section--dark .support__item cite { color: var(--accent-on-dark); }

/* ----- Press list -------------------------------------------------------- */
.press-list { border-top: 1px solid var(--hairline); }
.press-item {
  display: grid;
  grid-template-columns: 120px 80px 1fr auto;
  gap: 1.5rem;
  align-items: baseline;
  padding: 1.35rem 0.5rem;
  /* A row of short labels — date, title, outlet — not running prose, so the global
     1.7 was prose leading applied to list text. Set on the row so all three children
     share one rhythm: 9 of the 40 titles wrap on desktop, and the date and outlet
     wrap too once .press-item__outlet loses its nowrap below 900px. */
  line-height: 1.45;
  border-bottom: 1px solid var(--hairline);
  transition: background 0.25s var(--ease);
}
/* Source thumbnails are small (many are only 104×81), so they display at 80×60 to
   stay reasonably crisp. align-self opts the image out of the row's baseline
   alignment, which is what keeps the date/title/outlet text aligned to each other. */
.press-item__thumb {
  align-self: center;
  width: 80px;
  height: 60px;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  background: var(--surface-2);
}
/* Background change only — rows must not shift on hover, same rule as the buttons. */
.press-item:hover { background: var(--surface); }
/* Many pre-2016 items link to defunct Flash video or articles that have since been
   pulled, so those rows render unlinked — no hover affordance to imply otherwise. */
.press-item--nolink:hover { background: none; }
.press-item__date {
  font-family: var(--sans);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--accent-ink);
  text-transform: uppercase;
}
.press-item__title { font-size: 1.05rem; color: var(--ink-soft); }
.press-item__outlet {
  font-family: var(--sans);
  font-size: 0.85rem;
  color: var(--muted-2);
  white-space: nowrap;
}

/* ----- Awards timeline --------------------------------------------------- */
.timeline { position: relative; margin-left: 0.5rem; }
.timeline::before {
  content: "";
  position: absolute;
  left: 5px; top: 8px; bottom: 8px;
  width: 2px;
  background: var(--hairline-2);
}
.award {
  position: relative;
  padding: 0 0 2rem 2.4rem;
}
.award::before {
  content: "";
  position: absolute;
  left: 0; top: 7px;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--paper);
  box-shadow: 0 0 0 1px var(--accent);
}
.award h3 {
  font-family: var(--serif);
  font-size: clamp(1.15rem, 1.05rem + 0.5vw, 1.4rem);
  font-weight: 500;
  line-height: 1.2;
}
/* Tighter than the global 1.7 — these are short one- or two-line captions
   under a title, not running prose, so body leading reads as drift. */
.award p { color: var(--muted); margin-top: 0.3rem; font-size: 0.96rem; line-height: 1.45; }

/* ----- Contact ----------------------------------------------------------- */
.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}
.contact-block h3 {
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-on-dark);
  /* The label must sit tight to its own content, or it reads as floating
     between blocks. The margin alone won't do it: at the inherited 1.7 the
     h3's own line box adds ~4.5px of dead space UNDER the glyphs, so a 0.5rem
     margin still rendered an ~18px visual gap. Tightening the leading here is
     what actually closes it — 1.2 + 0.25rem lands the glyph gap at ~11px,
     matching the paragraph's internal line spacing. */
  line-height: 1.2;
  margin-bottom: 0.25rem;
}
.section:not(.section--dark) .contact-block h3 { color: var(--accent-ink); }
.contact-block p { color: var(--cream-muted); font-size: 0.98rem; }
.section:not(.section--dark) .contact-block p { color: var(--muted); }
.contact-block a { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: color-mix(in srgb, currentColor 35%, transparent); }
.contact-block strong { color: var(--cream); font-weight: 600; }
.section:not(.section--dark) .contact-block strong { color: var(--ink); }

/* ----- CTA banner -------------------------------------------------------- */
.cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem 2rem;
}
.cta .h2 { max-width: 18ch; }

/* ----- Social icons ------------------------------------------------------ */
.socials { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.socials a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px; height: 42px;
  border: 1px solid var(--hairline-2);
  border-radius: 50%;
  color: var(--ink-soft);
  transition: background 0.25s var(--ease), color 0.25s var(--ease), border-color 0.25s var(--ease);
}
/* Colour change only — nothing moves on hover, same rule as the buttons and press rows. */
.socials a:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.socials svg { width: 18px; height: 18px; }
.on-dark .socials a, .site-footer .socials a {
  border-color: var(--hairline-dark);
  color: var(--cream-muted);
}
.on-dark .socials a:hover, .site-footer .socials a:hover {
  background: var(--accent); color: var(--accent-btn-text); border-color: var(--accent);
}

/* ----- Footer ------------------------------------------------------------ */
.site-footer {
  position: relative;
  z-index: 1;
  background: var(--espresso);
  color: var(--cream-muted);
  padding-block: clamp(3rem, 6vw, 5rem) 2rem;
}
.site-footer__top {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: 2.5rem;
  align-items: start;
  padding-bottom: 2.5rem;
  border-bottom: 1px solid var(--hairline-dark);
}
/* Socials sit right-aligned in the footer's second column. Desktop only — once the
   grid collapses to one column at ≤900px they stay left, lining up with the brand
   block above instead of drifting to the far edge. */
@media (min-width: 901px) {
  .site-footer .socials { justify-content: flex-end; }
}
.site-footer .brand { color: var(--cream); font-size: 1.5rem; }
.site-footer__tag { margin-top: 0.8rem; max-width: 42ch; color: var(--cream-muted); }
.footer-info { margin-top: 1.4rem; }
.footer-info__name { font-weight: 600; color: var(--cream); margin-bottom: 0.5rem; }
.footer-info address { font-style: normal; font-size: 0.92rem; line-height: 1.8; color: var(--cream-muted); }
.footer-info address a { color: var(--cream-muted); text-decoration: none; transition: color 0.2s var(--ease); }
.footer-info address a:hover { color: var(--cream); }
.footer-info address a[href^="http"] { color: var(--accent-on-dark); text-decoration: underline; text-underline-offset: 3px; }
.footer-info address a[href^="http"]:hover { color: var(--cream); }
.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.8rem 2rem;
  padding-top: 1.8rem;
  font-size: 0.82rem;
  color: var(--cream-muted);
}
.site-footer__bottom a { color: var(--cream); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: color-mix(in srgb, var(--accent-on-dark) 60%, transparent); }

/* ----- Page hero (interior pages) ---------------------------------------- */
/* Dark opener on every interior page, matching the homepage hero. Every colour
   below is an override: h1-h4 set --ink, .lead sets --ink-soft and .breadcrumb
   sets --muted-2, so without these the text would be dark-on-dark. */
.page-hero {
  position: relative;
  z-index: 1;
  padding-block: clamp(3.5rem, 7vw, 6.5rem) clamp(2.5rem, 5vw, 4rem);
  background: var(--espresso);
  color: var(--cream);
  border-bottom: 1px solid var(--hairline-dark);
}
.page-hero h1,
.page-hero h2,
.page-hero h3 { color: var(--cream); }
.page-hero .eyebrow { color: var(--accent-on-dark); }
.page-hero .lead { color: color-mix(in srgb, var(--cream) 85%, transparent); }
/* .breadcrumb still carries the essay source lines and the novel cover credit,
   which sit inside this dark band. */
.page-hero .breadcrumb { color: var(--cream-muted); }
.page-hero .h1 { margin-top: 0.8rem; max-width: 18ch; }
.page-hero .lead { margin-top: 1.2rem; max-width: 60ch; }
.breadcrumb {
  font-family: var(--sans);
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  color: var(--muted-2);
}
.breadcrumb a:hover { color: var(--accent-ink); }
/* Essay source lines break the date onto its own line under the outlet, instead
   of trailing it after a middot. Block rather than <br> so the gap is tunable. */
.breadcrumb__date { display: block; margin-top: 0.3rem; }

/* ----- Crosshatch texture -------------------------------------------------
   MUST stay after every rule that sets a `background` shorthand — the shorthand
   resets background-image, so these get wiped if they move earlier.
   Plain `.section` needs no rule: it is transparent, so the body's weave shows
   through. Cards stay flat on purpose — clean stock against a textured ground. */
body,
.section--alt,
.section--surface { background-image: var(--crosshatch); }

.hero,
.page-hero,
.site-footer,
.section--navy,
.section--dark { background-image: var(--crosshatch-dark); }

/* Backgrounds don't print by default, but be explicit rather than gambling on
   the user's "print background graphics" setting. */
@media print {
  body, .section--alt, .section--surface, .page-hero,
  .hero, .site-footer, .section--navy, .section--dark { background-image: none; }
}

/* ----- Reveal animations ------------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
}
.reveal.is-visible { opacity: 1; transform: none; }
[data-stagger] > * {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
[data-stagger].is-visible > * { opacity: 1; transform: none; }
[data-stagger].is-visible > *:nth-child(2) { transition-delay: 0.08s; }
[data-stagger].is-visible > *:nth-child(3) { transition-delay: 0.16s; }
[data-stagger].is-visible > *:nth-child(4) { transition-delay: 0.24s; }
[data-stagger].is-visible > *:nth-child(5) { transition-delay: 0.32s; }
[data-stagger].is-visible > *:nth-child(6) { transition-delay: 0.40s; }

/* Hero entrance */
.hero [data-hero] { opacity: 0; transform: translateY(24px); animation: rise 0.9s var(--ease) forwards; }
.hero [data-hero="1"] { animation-delay: 0.05s; }
.hero [data-hero="2"] { animation-delay: 0.15s; }
.hero [data-hero="3"] { animation-delay: 0.25s; }
.hero [data-hero="4"] { animation-delay: 0.35s; }
.hero [data-hero="5"] { animation-delay: 0.45s; }
.hero .portrait { opacity: 0; transform: translateY(24px) scale(0.98); animation: rise 1s var(--ease) 0.3s forwards; }
@keyframes rise { to { opacity: 1; transform: none; } }

/* ----- Accessibility helpers --------------------------------------------- */
.skip-link {
  position: absolute;
  left: 1rem; top: -100px;
  z-index: 300;
  background: var(--ink);
  color: var(--paper);
  padding: 0.7em 1.1em;
  border-radius: var(--radius);
  transition: top 0.2s var(--ease);
}
.skip-link:focus { top: 1rem; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ----- Responsive -------------------------------------------------------- */
@media (max-width: 900px) {
  .hero__inner { grid-template-columns: 1fr; min-height: 0; gap: 2.5rem; }
  .hero__media { order: -1; max-width: 360px; }
  .split { grid-template-columns: 1fr; }
  .split--reverse > :first-child { order: 0; }
  .book { grid-template-columns: 1fr; }
  .book__cover { max-width: 280px; }
  .quotes { columns: 1; }
  .site-footer__top { grid-template-columns: 1fr; gap: 2rem; }
  .press-item { grid-template-columns: 1fr; gap: 0.3rem; }
  .press-item__outlet { white-space: normal; }
  /* Stacked: the thumb sits above the date and needs its own breathing room,
     since the row gap is tightened to 0.3rem for the text lines. */
  .press-item__thumb { align-self: start; margin-bottom: 0.5rem; }
}

@media (max-width: 720px) {
  .nav-toggle { display: flex; }
  .nav {
    position: fixed;
    inset: 72px 0 auto 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    background: var(--paper);
    border-bottom: 1px solid var(--hairline);
    padding: 0.5rem var(--gutter) 1.5rem;
    transform: translateY(-12px);
    opacity: 0;
    visibility: hidden;
    transition: transform 0.3s var(--ease), opacity 0.3s var(--ease), visibility 0.3s;
    box-shadow: 0 24px 40px -24px rgba(28,24,20,0.5);
  }
  .nav.is-open { transform: none; opacity: 1; visibility: visible; }
  .nav a { width: 100%; padding: 0.85rem 0; border-bottom: 1px solid var(--hairline); font-size: 1.05rem; }
  .nav a::after { display: none; }
  .stats { grid-template-columns: 1fr; gap: 1.5rem; text-align: left; }
  .cta { flex-direction: column; align-items: flex-start; }
}

/* ----- Reduced motion ---------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0ms !important;
    transition-duration: 0.001ms !important;
  }
  .reveal, [data-stagger] > *, .hero [data-hero], .hero .portrait { opacity: 1 !important; transform: none !important; }
}
