/* ============================================================
   TRIAL ONE — MONOCHROME ACCENT HIERARCHY
   Implements Design Rulebook — Trial 1.
   Base is monochromatic; one accent per page; accent reliance
   scales with the importance of the area it sits on.
   ============================================================ */

/* ─── 0. FONTS ────────────────────────────────────────────── */
/* Test-release copies of the three licensed faces named in the type-role
   tokens below, wired up to confirm the file structure and rendering
   before the purchased files replace them. The fallback names already in
   those tokens (Zilla Slab, Inter, IBM Plex Mono) carry the page if any
   file here is ever unavailable. */

@font-face {
  font-family: 'Rockwell';
  src: url('../assets/fonts/rockwell/ROCK.TTF') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Rockwell';
  src: url('../assets/fonts/rockwell/Rockwell-Bold.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Aktiv Grotesk';
  src: url('../assets/fonts/aktiv-grotesk/AktivGroteskVF_Trial_Wght.ttf') format('truetype-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Söhne Mono';
  src: url('../assets/fonts/sohne-mono/TestSohneMono-Buch.otf') format('opentype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Söhne Mono';
  src: url('../assets/fonts/sohne-mono/TestSohneMono-Kraftig.otf') format('opentype');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* ─── 1. TOKENS ───────────────────────────────────────────── */

:root {
  /* Typography — Rockwell display, Aktiv Grotesk text, Söhne Mono labels.
     Licensed faces lead the stack; open fallbacks follow. */
  --font-display: 'Rockwell', 'Rockwell Nova', 'Zilla Slab', Georgia, serif;
  --font-text:    'Aktiv Grotesk', 'Inter', 'Helvetica Neue', Arial, sans-serif;
  --font-mono:    'Söhne Mono', 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', monospace;

  /* Monochromatic base — warm paper family, tonal only */
  --paper:    #F2EDE3;
  --paper-2:  #EAE3D5;
  --paper-3:  #E0D8C7;
  --ink:      #1C1A17;
  --ink-2:    #453F37;
  --ink-3:    #6E675C;
  --rule:     rgba(28, 26, 23, 0.15);
  --rule-2:   rgba(28, 26, 23, 0.30);
  --on-accent:#F7F3EA;

  /* Accent — set per page via --accent-base on <html>. Ruby Leaf default.

     Two roles, and the distinction matters:
     --accent      a FILLED FIELD (opener panel, divider band). Held
                   identical in both modes — a deep field reads fine on
                   either base, and always carries --on-accent text.
     --accent-ink  the accent drawn ON the monochromatic base (numerals,
                   rules, strips, borders). This is the one that has to
                   survive the base flipping. */
  --accent-base: #8C2A3A;
  --accent: var(--accent-base);
  --accent-ink: var(--accent-base);
  --accent-wash: rgba(140, 42, 58, 0.07);
  --on-accent: #F7F3EA;

  --grain: 0.5;
  --grain-blend: multiply;
}

/* Light mode: --accent-ink is darkened slightly so every accent clears
   contrast where it carries small text. */
@supports (color: color-mix(in oklab, red, blue)) {
  :root {
    --accent-ink: color-mix(in oklab, var(--accent-base) 84%, #120C0A);
    --accent-wash: color-mix(in oklab, var(--accent-base) 8%, transparent);
  }
}

/* Dark mode — the monochromatic base flips. The accent is HELD: filled
   accent fields keep their exact colour, and cream stays on top of them.
   Only the accent drawn on the base fails contrast once the base goes
   dark, so exactly one uniform lift is applied there — the same formula
   for every accent colour on the site, never tuned per colour. */
[data-theme="dark"] {
  --paper:    #14120F;
  --paper-2:  #1C1A15;
  --paper-3:  #26231D;
  --ink:      #F2EDE3;
  --ink-2:    #CFC7B8;
  --ink-3:    #948C7F;
  --rule:     rgba(242, 237, 227, 0.16);
  --rule-2:   rgba(242, 237, 227, 0.32);

  --grain: 0.22;
  --grain-blend: screen;
}

@supports (color: color-mix(in oklab, red, blue)) {
  [data-theme="dark"] {
    --accent-ink: color-mix(in oklab, var(--accent-base) 55%, #F6F1E6);
    --accent-wash: color-mix(in oklab, var(--accent-base) 22%, transparent);
  }
}

/* ─── 2. RESET & PAGE GROUND ──────────────────────────────── */

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

/* The design is drawn at ~1500px wide. Past that it must not sit in a
   narrow strip in the middle of a large monitor — but it must not read
   as a blown-up zoom either. So the container and the type scale at
   DIFFERENT rates:

     container  grows generously  (1380px → ~2100px at 2560px)
     body text  grows gently      (16px   → 18px    at 2560px)
     display    grows moderately  (112px  → 140px   at 2560px)

   The result fills the screen while reading size stays comfortable.
   Every clamp below self-limits under 1500px, so small and medium
   screens render exactly as designed. */
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  font-size: clamp(16px, calc(16px + (100vw - 1500px) * 0.00189), 19px);
}

body {
  font-family: var(--font-text);
  font-size: 1rem;
  line-height: 1.75;
  color: var(--ink-2);
  background-color: var(--paper);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* The grain is absolutely positioned against the document, not fixed to
   the viewport, so it travels with the words as you scroll — the texture
   belongs to the page rather than to the screen behind it. Both layers
   tile seamlessly (stitchTiles), so they run the full document height. */
body { position: relative; }

/* Paper grain. Sits behind all content, never over it. */
body::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: var(--grain);
  mix-blend-mode: var(--grain-blend);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='260'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='260' height='260' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
}

/* Long paper fibres — very low contrast, adds age without pattern */
body::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.5;
  background-image:
    repeating-linear-gradient(92deg, transparent 0 3px, rgba(120, 96, 60, 0.035) 3px 4px),
    repeating-linear-gradient(3deg, transparent 0 7px, rgba(120, 96, 60, 0.028) 7px 8px);
}
[data-theme="dark"] body::after { opacity: 0.35; }

.site-nav, .page, .site-footer { position: relative; z-index: 1; }

img { max-width: 100%; display: block; }
a { color: inherit; }
[hidden] { display: none !important; }

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

.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--ink); color: var(--paper);
  padding: 0.75rem 1.25rem; z-index: 200;
  font-family: var(--font-mono); font-size: 0.7rem;
  letter-spacing: 0.14em; text-transform: uppercase;
}
.skip-link:focus { left: 0; }

:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 3px; }

/* Links to pages not yet built (data-href in place of href) go nowhere.
   Clicking one shakes it — a short, damped side-to-side refusal. */
a[data-href]:not([href]) { cursor: pointer; }

.is-shaking { animation: pending-shake 0.42s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; }

@keyframes pending-shake {
  10%, 90%      { transform: translateX(-1px); }
  20%, 80%      { transform: translateX(3px); }
  30%, 50%, 70% { transform: translateX(-5px); }
  40%, 60%      { transform: translateX(5px); }
}

/* ─── 3. TYPE ROLES ───────────────────────────────────────── */

/* Rockwell — display tier and the tier immediately below it */
.t-display {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(3rem, 8.5vw, 7rem);
  line-height: 0.92;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.t-h1 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2.4rem, 6vw, 4.6rem);
  line-height: 0.96;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.t-h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.5rem, 2.9vw, 2.3rem);
  line-height: 1.12;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* Aktiv Grotesk — mid-level headings and below, plus all body copy */
.t-h3 {
  font-family: var(--font-text);
  font-weight: 650;
  font-size: 1.06rem;
  line-height: 1.4;
  letter-spacing: -0.005em;
  color: var(--ink);
}
.t-h4 {
  font-family: var(--font-text);
  font-weight: 600;
  font-size: 0.92rem;
  line-height: 1.45;
  color: var(--ink);
}
.t-body { font-size: 1rem; line-height: 1.78; color: var(--ink-2); }
.t-body--lead { font-size: 1.12rem; line-height: 1.7; color: var(--ink-2); }
.t-body + .t-body { margin-top: 1.1rem; }

/* Söhne Mono — captions, labels, numerals */
.t-label {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.t-num {
  font-family: var(--font-mono);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}
.t-caption {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  line-height: 1.6;
  letter-spacing: 0.04em;
  color: var(--ink-3);
}

.measure { max-width: 62ch; }

/* Large screens: the Rockwell tiers get a little more growth than body
   copy does, so headings keep their presence against a wider container
   without the page reading as zoomed. Each lower bound is the size the
   tier already has at 1500px, so nothing below that width changes. */
@media (min-width: 1500px) {
  .t-display { font-size: clamp(7rem, 5.47vw, 8rem); }
  .t-h1      { font-size: clamp(4.6rem, 3.6vw, 5.2rem); }
  .t-h2      { font-size: clamp(2.3rem, 1.8vw, 2.6rem); }
  .portrait  { max-width: min(42rem, 54vh); }
}

/* ─── 4. LAYOUT ───────────────────────────────────────────── */

/* Container grows faster than the type — this is what makes a large
   monitor feel filled rather than zoomed. Holds at 1380px below 1500px. */
.wrap {
  width: 100%;
  max-width: clamp(1380px, 82vw, 2500px);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4vw, 4rem);
}
.wrap--narrow { max-width: 67.5rem; }

.stack > * + * { margin-top: 1.1rem; }

.rule-line { height: 1px; background: var(--rule); border: 0; }

/* ─── 5. NAV ──────────────────────────────────────────────── */

.site-nav {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 1.5rem;
  height: 3.875rem;
  padding-inline: clamp(1.25rem, 4vw, 4rem);
  background: var(--paper);
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--rule);
}

.nav-mark {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.nav-mark span { color: var(--accent-ink); }

.nav-links {
  display: flex;
  align-items: center;
  gap: 1.6rem;
  margin-left: auto;
}
.nav-link {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
  text-decoration: none;
  padding-block: 0.4rem;
  border-bottom: 1px solid transparent;
  transition: color 0.18s, border-color 0.18s;
}
.nav-link:hover { color: var(--ink); }
.nav-link[aria-current="page"] {
  color: var(--accent-ink);
  border-bottom-color: var(--accent-ink);
}

.theme-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: none;
  border: 1px solid var(--rule-2);
  color: var(--ink-3);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 0.42rem 0.75rem;
  cursor: pointer;
  transition: color 0.18s, border-color 0.18s;
}
.theme-toggle:hover { color: var(--ink); border-color: var(--ink-3); }
.theme-toggle svg { width: 0.8125rem; height: 0.8125rem; }
.theme-toggle .icon-dark { display: none; }
[data-theme="dark"] .theme-toggle .icon-dark { display: block; }
[data-theme="dark"] .theme-toggle .icon-light { display: none; }

.nav-toggle {
  display: none;
  background: none;
  border: 0;
  color: var(--ink);
  cursor: pointer;
  padding: 0.4rem;
  margin-left: auto;
}
.nav-toggle svg { width: 1.25rem; height: 1.25rem; }

/* ─── 6. OPENERS — the three accent-reliance tiers ────────── */

/*  TIER 1 · HEAVY — accent fills a full-bleed field, line art reversed.
    Reserved for the highest-importance pages.                        */
.opener--heavy {
  position: relative;
  background: var(--accent);
  color: var(--on-accent);
  overflow: hidden;
}
.opener--heavy::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: overlay;
  opacity: 0.3;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23g)'/%3E%3C/svg%3E");
}
.opener--heavy .opener-inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
  padding-block: clamp(3.5rem, 9vw, 7rem);
}
.opener--heavy .t-display,
.opener--heavy .t-h1,
.opener--heavy .t-h2 { color: var(--on-accent); }
.opener--heavy .t-label,
.opener--heavy .t-caption { color: var(--on-accent); opacity: 0.72; }
.opener--heavy .t-body { color: var(--on-accent); opacity: 0.9; }

/*  The index hero holds the majority of the first screen at any size,
    with the remaining contents reached by scrolling.                  */
.opener--hero {
  min-height: calc(100vh - 3.875rem);
  min-height: calc(100svh - 3.875rem);
  /* Centre the content in the taller-than-content hero, rather than
     letting it sit at the top with the slack collecting underneath. */
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.opener--hero .opener-inner {
  grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
  /* Height-led padding: it gives way on short screens so the larger
     portrait still fits the first screen with the scroll cue beneath. */
  padding-top: clamp(2.5rem, 8vh, 7rem);
  padding-bottom: clamp(5.5rem, 12vh, 9rem);
}

/*  Background plan — line-drawn roads behind the portrait. It envelops
    the hero's right side at full height and disperses as it runs left:
    the drawing itself thins out, and the mask fades what remains.     */
.hero-plan {
  position: absolute;
  top: 0;
  right: 0;
  width: 64%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  object-position: right center;
  opacity: 0.5;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to left, #000 42%, transparent 100%);
          mask-image: linear-gradient(to left, #000 42%, transparent 100%);
}

/*  The name sits further left than the standard gutter — the block is
    pulled toward the page edge, and the slab's side bearing is taken
    off the display line so the E aligns flush with the copy beneath. */
.opener-inner--left { padding-left: clamp(1rem, 1.7vw, 1.9rem); }
.hero-name { margin-left: -0.055em; }

/*  Scroll cue — a drawn leader line and chevron, pulsing downward.    */
.scroll-cue {
  position: absolute;
  left: 50%;
  bottom: clamp(1.5rem, 3vw, 2.5rem);
  transform: translateX(-50%);
  z-index: 3;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
  text-decoration: none;
  color: var(--on-accent);
}
.scroll-cue-label {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  opacity: 0.7;
}
.scroll-cue-arrow {
  width: 0.875rem;
  height: 1.875rem;
  animation: cue-pulse 2.1s ease-in-out infinite;
}
.scroll-cue:hover .scroll-cue-arrow { animation-play-state: paused; }

@keyframes cue-pulse {
  0%, 100% { transform: translateY(0);   opacity: 0.6; }
  50%      { transform: translateY(0.4375rem); opacity: 1; }
}

/*  Portrait frame — reversed, for use on a filled accent field.       */
.portrait {
  /* Tied to viewport height as well as width so a short screen shrinks
     the portrait rather than pushing the hero past the fold. */
  max-width: min(36rem, 54vh);
  margin-left: auto;
  border: 1px solid currentColor;
  border-color: color-mix(in srgb, currentColor 45%, transparent);
  padding: 0.65rem;
  /* A solid mount, so the background plan stops at the frame. */
  background: var(--accent);
}
.portrait-frame {
  position: relative;
  aspect-ratio: 4 / 5;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 1px solid currentColor;
  border-color: color-mix(in srgb, currentColor 28%, transparent);
  background: rgba(0, 0, 0, 0.06);
}
.portrait-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}
.portrait-cap {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 0.6rem;
}

/*  TIER 2 · LIGHT — neutral ground, accent held to a strip, numerals
    and small blocks. Mid-importance pages.                          */
.opener--light {
  position: relative;
  border-bottom: 1px solid var(--rule);
}
.opener--light .opener-inner {
  display: grid;
  grid-template-columns: 0.5rem minmax(0, 1fr) minmax(0, 0.72fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: center;
  padding-block: clamp(3rem, 7vw, 5.5rem);
}
.opener-strip {
  align-self: stretch;
  background: var(--accent-ink);
  min-height: 11.25rem;
}

/*  TIER 3 · MINIMAL — fully monochromatic; accent survives only as the
    title strip and small numerals. Lowest-importance pages. The strip
    matches Tier 2's in weight and extent — it spans the title block,
    not the full opener.                                             */
.opener--minimal {
  border-bottom: 1px solid var(--rule);
}
.opener--minimal .opener-inner {
  --opener-pad: clamp(3rem, 7vw, 5.5rem);
  --strip-gap: clamp(1.5rem, 4vw, 3.5rem);
  position: relative;
  padding-block: var(--opener-pad);
  padding-left: calc(0.5rem + var(--strip-gap));
}
.opener--minimal .opener-inner::before {
  content: '';
  position: absolute;
  left: 0;
  top: var(--opener-pad);
  bottom: var(--opener-pad);
  width: 0.5rem;
  background: var(--accent-ink);
}

/*  CORE SECTIONS — a title band modelled on the index page's divider
    band, added over Tier 2 or Tier 3. A solid accent field with reversed
    text: no grain, no line art and a shorter height, so Section 02's
    Tier 1 opener stays the heaviest page on the site. Subpages and the
    404 page keep their plain tier.
    The field is the accent deepened by one fixed amount on every page,
    so reversed text clears 4.5:1 on all ten hues. The raw accent does
    not: cream on Antique Gold is 3.2:1. The strip is dropped, since the
    whole field now carries the accent it stood for.                   */
.opener--core {
  --core-field: color-mix(in oklab, var(--accent-base) 75%, #120C0A);
  background: var(--core-field);
  color: var(--on-accent);
  border-bottom: 0;
}
.opener--core.opener--light .opener-inner {
  grid-template-columns: minmax(0, 1fr);
  padding-block: clamp(3rem, 6vw, 4.5rem);
}
.opener--core .opener-strip { display: none; }
.opener--core.opener--minimal .opener-inner {
  --opener-pad: clamp(3rem, 6vw, 4.5rem);
  padding-left: 0;
  padding-top: var(--opener-pad);
}
.opener--core.opener--minimal .opener-inner::before { display: none; }
.opener--core .t-h1 { color: var(--on-accent); }
.opener--core .t-label { color: var(--on-accent); opacity: 0.9; }
.opener--core .t-body { color: var(--on-accent); }
.opener--core .tag {
  color: var(--on-accent);
  border-color: color-mix(in srgb, var(--on-accent) 50%, transparent);
}
.opener--core .tag--on { background: var(--on-accent); border-color: var(--on-accent); color: var(--core-field); }

.opener-eyebrow {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  margin-bottom: 1.6rem;
}
.opener-eyebrow::after {
  content: '';
  flex: 1;
  height: 1px;
  background: currentColor;
  opacity: 0.35;
  max-width: 7.5rem;
}
.opener-sub {
  margin-top: 1.4rem;
  max-width: 52ch;
}
.opener-art { width: 100%; height: auto; color: currentColor; }

/* Technical legend block — lifted from the map-legend reference */
.legend {
  margin-top: 2.2rem;
  border-top: 1px solid currentColor;
  padding-top: 0.9rem;
  display: grid;
  gap: 0.5rem;
  max-width: 26.875rem;
}
.legend-row {
  display: grid;
  grid-template-columns: 5.75rem 1fr;
  gap: 1rem;
  align-items: baseline;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.05em;
}
.legend-row dt { opacity: 0.62; text-transform: uppercase; letter-spacing: 0.16em; font-size: 0.6rem; }
.legend-row dd { color: inherit; }
.opener--light .legend, .opener--minimal .legend { border-color: var(--rule-2); }
.opener--light .legend-row dd, .opener--minimal .legend-row dd { color: var(--ink); }

/* ─── 7. CONTENTS INDEX ───────────────────────────────────── */

.contents { border-top: 1px solid var(--rule); }

.contents-row {
  display: grid;
  grid-template-columns: 5.375rem minmax(0, 1fr) minmax(0, 1.15fr) 2.5rem;
  gap: clamp(1rem, 3vw, 2.5rem);
  align-items: baseline;
  padding-block: clamp(1.5rem, 2.6vw, 2.1rem);
  border-bottom: 1px solid var(--rule);
  text-decoration: none;
  color: inherit;
  transition: background 0.2s, padding-left 0.2s;
  padding-inline: 0.5rem;
}
.contents-row:hover { background: var(--accent-wash); padding-left: 1.1rem; }

.contents-num {
  font-family: var(--font-mono);
  font-size: clamp(1.4rem, 2.4vw, 1.9rem);
  font-variant-numeric: tabular-nums;
  color: var(--accent-ink);
  letter-spacing: -0.01em;
}
.contents-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.35rem, 2.4vw, 1.95rem);
  line-height: 1.1;
  color: var(--ink);
  letter-spacing: -0.01em;
}
.contents-meta { margin-top: 0.45rem; }
.contents-desc { font-size: 0.92rem; line-height: 1.7; color: var(--ink-2); }
.contents-arrow {
  justify-self: end;
  align-self: center;
  color: var(--accent-ink);
  transition: transform 0.2s;
}
.contents-row:hover .contents-arrow { transform: translate(3px, -3px); }
.contents-arrow svg { width: 0.9375rem; height: 0.9375rem; }

.contents-row--soon { opacity: 0.58; }
.contents-row--soon .contents-title { color: var(--ink-2); }

/* ─── 8. SECTIONS ─────────────────────────────────────────── */

.section { padding-block: clamp(3rem, 6vw, 5rem); border-bottom: 1px solid var(--rule); }
/* Anchored sections land clear of the sticky site nav. */
.section[id] { scroll-margin-top: 3.875rem; }
.section:last-of-type { border-bottom: 0; }

.section-head {
  display: flex;
  align-items: baseline;
  gap: 1.1rem;
  margin-bottom: 2rem;
}
.section-head .t-num {
  font-size: 0.78rem;
  color: var(--accent-ink);
  flex-shrink: 0;
}
.section-head-line { flex: 1; height: 1px; background: var(--rule); }
.section-head .t-label { flex-shrink: 0; }

.grid-2 {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.75rem, 4vw, 3.5rem);
}
.grid-2--wide-left { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
}

/* Pull-quote — accent hairline only, never a filled block */
.quote {
  border-left: 2px solid var(--accent-ink);
  padding: 0.35rem 0 0.35rem 1.5rem;
  margin-block: 1.75rem;
}
.quote p {
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 1.9vw, 1.4rem);
  line-height: 1.4;
  color: var(--ink);
}
.quote cite {
  display: block;
  margin-top: 0.75rem;
  font-family: var(--font-mono);
  font-size: 0.65rem;
  font-style: normal;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* Entry — a linked sub-item */
.entry {
  display: block;
  border: 1px solid var(--rule);
  padding: 1.5rem 1.5rem 1.35rem;
  text-decoration: none;
  color: inherit;
  background: var(--paper-2);
  transition: border-color 0.2s, transform 0.2s;
}
.entry:hover { border-color: var(--accent-ink); transform: translateY(-2px); }
.entry-num { display: block; font-size: 0.68rem; color: var(--accent-ink); margin-bottom: 0.85rem; }
.entry-title { margin-bottom: 0.3rem; }
/* One mono line of hard detail under the title — level, provider, the
   award it already carries. It is what a reader checks first. */
.entry-meta { margin-bottom: 0.7rem; }
.entry-desc { font-size: 0.88rem; line-height: 1.65; color: var(--ink-2); }

/* Data list — mono key/value rows */
.datalist { border-top: 1px solid var(--rule); }
.datalist-row {
  display: grid;
  grid-template-columns: minmax(7.5rem, 0.5fr) minmax(0, 1fr);
  gap: 1.25rem;
  padding-block: 0.85rem;
  border-bottom: 1px solid var(--rule);
  align-items: baseline;
}
.datalist-row dt {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.datalist-row dd { font-size: 0.94rem; color: var(--ink); }

/* Plate — image frame with mono caption */
.plate { border: 1px solid var(--rule); background: var(--paper-2); }
.plate-body {
  aspect-ratio: 4 / 3;
  display: grid;
  place-items: center;
  color: var(--ink-3);
  background:
    repeating-linear-gradient(45deg, transparent 0 9px, var(--rule) 9px 10px);
}
.plate-body svg { width: 2.125rem; height: 2.125rem; opacity: 0.5; }
.plate-cap {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.65rem 0.85rem;
  border-top: 1px solid var(--rule);
}

/* Marker list */
.marks { list-style: none; display: grid; gap: 0.7rem; }
.marks li {
  display: grid;
  grid-template-columns: 1.125rem 1fr;
  gap: 0.9rem;
  font-size: 0.95rem;
  line-height: 1.65;
  color: var(--ink-2);
}
.marks li::before {
  content: '';
  width: 0.5rem; height: 0.5rem;
  margin-top: 0.55rem;
  border: 1.5px solid var(--accent-ink);
}

/* Status pill row */
.tags { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.tag {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 0.32rem 0.65rem;
  border: 1px solid var(--rule-2);
  color: var(--ink-3);
}
.tag--on { border-color: var(--accent-ink); color: var(--accent-ink); }
.opener--heavy .tag { color: var(--on-accent); border-color: currentColor; opacity: 0.62; }
.opener--heavy .tag--on { color: var(--on-accent); border-color: currentColor; opacity: 1; }

/* Jump bar — the page's contents, set between the opener's rule and the
   first section. Built from the tag chip at a larger size: one chip per
   section, in page order, spanning the width of the content column. The
   section numeral carries the accent; the chip for the section in view
   takes the --on treatment. */
.jump {
  display: grid;
  /* Auto-fit rather than a fixed three, so a page with a fourth section
     fills one even row instead of leaving a single chip stranded. */
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 0.75rem;
  padding-top: clamp(2rem, 4vw, 3rem);
}
.jump + .section { padding-top: clamp(2.5rem, 5vw, 4rem); }
.jump-link {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 1rem 1.15rem;
  font-size: 0.74rem;
  line-height: 1.4;
  text-decoration: none;
  transition: border-color 0.2s, color 0.2s, background 0.2s;
}
.jump-num { color: var(--accent-ink); opacity: 0.8; flex-shrink: 0; }
.jump-arrow {
  width: 0.9rem; height: 0.9rem;
  margin-left: auto;
  flex-shrink: 0;
  opacity: 0.45;
  transition: transform 0.2s, opacity 0.2s;
}
.jump-link:hover,
.jump-link:focus-visible { border-color: var(--accent-ink); color: var(--ink); background: var(--accent-wash); }
.jump-link:hover .jump-arrow,
.jump-link:focus-visible .jump-arrow { opacity: 1; transform: translateY(3px); }
.jump-link[aria-current="location"] { border-color: var(--accent-ink); color: var(--accent-ink); }
.jump-link[aria-current="location"] .jump-num { opacity: 1; }
.jump-link[aria-current="location"] .jump-arrow { opacity: 0.9; }

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.72rem 1.35rem;
  border: 1px solid var(--accent-ink);
  color: var(--accent-ink);
  transition: background 0.2s, color 0.2s;
}
/* Inverting against --paper keeps the filled state legible in both modes. */
.btn:hover { background: var(--accent-ink); color: var(--paper); }
.btn svg { width: 0.8125rem; height: 0.8125rem; }
.btn--solid { background: var(--accent-ink); color: var(--paper); }
.btn--solid:hover { opacity: 0.88; background: var(--accent-ink); color: var(--paper); }
/* Buttons sitting on a filled accent field reverse out of it. */
.opener--heavy .btn,
.band .btn {
  border-color: var(--on-accent);
  color: var(--on-accent);
}
.opener--heavy .btn:hover,
.band .btn:hover { background: var(--on-accent); color: var(--accent); }

/* Section-break band — heavy accent used as a divider */
.band {
  position: relative;
  background: var(--accent);
  color: var(--on-accent);
  overflow: hidden;
}
.band-inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2rem;
  align-items: center;
  padding-block: clamp(2.5rem, 5vw, 4rem);
}
.band .t-h2, .band .t-display { color: var(--on-accent); }
.band .t-label { color: var(--on-accent); opacity: 0.7; }
.band .t-body { color: var(--on-accent); opacity: 0.9; }

/* ─── 9. FOOTER — minimal accent, lowest tier ─────────────── */

.site-footer { border-top: 1px solid var(--rule-2); background: var(--paper-2); }
.footer-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.75rem, 4vw, 3.5rem);
  padding-block: clamp(2.5rem, 5vw, 3.75rem);
}
.footer-mark { font-family: var(--font-display); font-size: 1.35rem; font-weight: 700; color: var(--ink); }
.footer-mark span { color: var(--accent-ink); }
.footer-bio { margin-top: 0.9rem; font-size: 0.88rem; line-height: 1.7; color: var(--ink-2); max-width: 44ch; }
.footer-list { display: grid; gap: 0.45rem; margin-top: 1rem; }
.footer-list a {
  font-size: 0.88rem;
  color: var(--ink-2);
  text-decoration: none;
  width: fit-content;
  border-bottom: 1px solid transparent;
  transition: color 0.18s, border-color 0.18s;
}
.footer-list a:hover { color: var(--accent-ink); border-bottom-color: var(--accent-ink); }
.footer-mail {
  display: inline-flex; align-items: center; gap: 0.55rem;
  margin-top: 1rem; font-size: 0.88rem; color: var(--ink);
  text-decoration: none; border-bottom: 1px solid var(--rule-2);
  padding-bottom: 2px; width: fit-content;
  transition: color 0.18s, border-color 0.18s;
}
.footer-mail:hover { color: var(--accent-ink); border-color: var(--accent-ink); }
.footer-mail svg { width: 0.875rem; height: 0.875rem; }
.footer-base {
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  padding-block: 1.1rem; border-top: 1px solid var(--rule);
}

/* ─── 10. AWARDS — carousel, rail, ledger, enlarged view ──── */

/* The awards page is a subpage of Qualifications, so it sits at the
   minimal tier: the base stays monochromatic and the accent survives
   only as the mount's hairline, the numerals, and the active markers.
   The certificates themselves carry the colour. */

/* Filter row — the tag chip, pressed state borrowed from .tag--on.
   Doubles as the record's category breakdown, since each chip counts
   its own category. */
.awards-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: clamp(1.75rem, 3vw, 2.5rem);
}
.awards-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 0.5rem;
  background: none;
  cursor: pointer;
  font-family: var(--font-mono);
  transition: border-color 0.2s, color 0.2s, background 0.2s;
}
.awards-chip:hover { border-color: var(--accent-ink); color: var(--ink); }
.awards-chip-n { opacity: 0.55; font-variant-numeric: tabular-nums; }
.awards-chip[aria-pressed="true"] {
  border-color: var(--accent-ink);
  color: var(--accent-ink);
  background: var(--accent-wash);
}
.awards-chip[aria-pressed="true"] .awards-chip-n { opacity: 0.85; }

/* Carousel. Every slide is a real <figure> in the document flow, so with
   scripting off the page degrades to a plain stack of captioned
   certificates — the record survives without the mechanism. */
/* The viewer sits in a column narrower than the container. At full
   width a portrait certificate occupies barely a third of the mount and
   the rest reads as empty field; this keeps the sheet dominant and the
   caption to a readable measure. The rail below stays full width. */
.awards-stage-wrap,
.awards-bar {
  max-width: 50rem;
  margin-inline: auto;
}
.awards-stage-wrap { position: relative; }

.award { margin: 0; }
.award[hidden] { display: none; }
.js-awards .award { animation: award-in 0.34s ease both; }

@keyframes award-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* The mount. Certificates are mixed portrait and landscape, so the image
   is fitted inside a fixed stage rather than cropped to it — a cropped
   certificate is a damaged document. */
/* The mount is a button, not a div with a click handler on the image —
   enlarging a certificate has to be reachable by keyboard, not only by
   mouse. */
.award-stage {
  position: relative;
  /* Deliberately not a centring grid: a percentage max-height on the
     image would resolve against an auto-sized row, which grows to the
     image's intrinsic height and defeats the clamp. The padded content
     box is a definite size, so the image is fitted into it instead. */
  display: block;
  width: 100%;
  height: clamp(19rem, 56vh, 38rem);
  padding: clamp(0.85rem, 2vw, 1.6rem);
  border: 1px solid var(--rule);
  background: var(--paper-2);
  color: var(--ink-3);
  font: inherit;
  cursor: zoom-in;
}
.award-stage img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  /* drop-shadow, not box-shadow: it follows the letterboxed sheet
     rather than drawing a rectangle around the whole padded box.
     A scanned document stays as scanned — never tinted or inverted to
     suit the mode. In dark mode the sheet reads as a lit page on a dark
     desk, which is what the shadow is for. */
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.18)) drop-shadow(0 10px 22px rgba(0, 0, 0, 0.15));
}
[data-theme="dark"] .award-stage img {
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5)) drop-shadow(0 14px 30px rgba(0, 0, 0, 0.45));
}

.award-zoom {
  position: absolute;
  right: 0.7rem;
  bottom: 0.7rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.55rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  opacity: 0;
  transition: opacity 0.2s;
  pointer-events: none;
}
.award-stage:hover .award-zoom,
.award-stage:focus-visible .award-zoom { opacity: 1; }
.award-zoom svg { width: 0.75rem; height: 0.75rem; }

/* Arrows sit outside the mount on wide screens and overlap it once the
   gutters run out. */
.awards-arrow {
  position: absolute;
  top: clamp(9rem, 28vh, 17rem);
  transform: translateY(-50%);
  z-index: 3;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  background: var(--paper);
  border: 1px solid var(--rule-2);
  color: var(--ink-2);
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s, background 0.2s;
}
.awards-arrow:hover { border-color: var(--accent-ink); color: var(--accent-ink); background: var(--accent-wash); }
.awards-arrow svg { width: 1rem; height: 1rem; }
.awards-arrow--prev { left: -1.375rem; }
.awards-arrow--next { right: -1.375rem; }

/* Autoplay progress — a hairline that fills across the foot of the mount.
   It is the only moving accent on the page, and it stops with the
   rotation it reports. */
.awards-progress {
  height: 2px;
  background: var(--rule);
  overflow: hidden;
}
.awards-progress-fill {
  height: 100%;
  width: 0;
  background: var(--accent-ink);
  transition: width 0.15s linear;
}
.awards-progress[data-state="off"] .awards-progress-fill { width: 0; }

/* Caption. The title sits directly under the certificate, as specified,
   with the category and date above it on one mono line. A minimum height
   keeps the controls from jumping as captions of different lengths
   replace one another. */
.award-cap {
  padding-top: 1.4rem;
  min-height: 11.5rem;
}
.award-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.1rem;
  margin-bottom: 0.7rem;
}
.award-meta .t-label { color: var(--ink-3); }
.award-cat { color: var(--accent-ink) !important; }
.award-flag {
  padding: 0.18rem 0.5rem;
  font-size: 0.55rem;
}
.award-title { margin-bottom: 0.75rem; }
.award-desc {
  font-size: 0.97rem;
  line-height: 1.75;
  color: var(--ink-2);
  max-width: 72ch;
}

/* Control bar — counter, rotation toggle. Mono throughout. */
.awards-bar {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  flex-wrap: wrap;
  padding-top: 1.4rem;
  margin-top: 1.4rem;
  border-top: 1px solid var(--rule);
}
.awards-count {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  color: var(--ink-3);
}
.awards-count b { color: var(--accent-ink); font-weight: 500; }
.awards-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
  background: none;
  border: 1px solid var(--rule-2);
  color: var(--ink-3);
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 0.42rem 0.75rem;
  cursor: pointer;
  transition: color 0.18s, border-color 0.18s;
}
.awards-toggle:hover { color: var(--ink); border-color: var(--ink-3); }
.awards-toggle svg { width: 0.75rem; height: 0.75rem; }
.awards-toggle .icon-play { display: none; }
.awards-toggle[aria-pressed="false"] .icon-play { display: block; }
.awards-toggle[aria-pressed="false"] .icon-pause { display: none; }

/* Thumbnail rail — direct access to any certificate. Reaching the last
   of thirty-three by pressing "next" thirty-two times is not a record. */
.awards-rail {
  display: flex;
  gap: 0.6rem;
  margin-top: 1.5rem;
  padding-bottom: 0.6rem;
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--rule-2) transparent;
}
/* The rail keeps a neutral, thinner bar of its own: it is a minor
   control inside the page, and an accent thumb here would compete with
   the page scrollbar rather than support it. The border is cleared
   because the page-level thumb rule would otherwise swallow a 6px bar. */
.awards-rail::-webkit-scrollbar { height: 6px; }
.awards-rail::-webkit-scrollbar-thumb { background: var(--rule-2); border: 0; }
.awards-rail::-webkit-scrollbar-track { background: transparent; }
.rail-item {
  flex: 0 0 auto;
  width: 4.75rem;
  height: 3.5rem;
  padding: 0.25rem;
  background: var(--paper-2);
  border: 1px solid var(--rule);
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 0.2s, border-color 0.2s;
}
.rail-item img { width: 100%; height: 100%; object-fit: contain; }
.rail-item:hover { opacity: 1; }
.rail-item[aria-current="true"] { opacity: 1; border-color: var(--accent-ink); }
.rail-item[hidden] { display: none; }

/* Ledger — the whole body of work in one scan, grouped by category.
   This is the part an admissions reader actually reads. */
.section-head + .ledger-group { border-top: 1px solid var(--rule-2); }
.ledger-group { border-bottom: 1px solid var(--rule-2); }

/* Each category is a title bar, stacked flush against the next; pressing
   it opens the awards beneath. Native <details>, so it works from the
   keyboard and without script. */
.ledger-head {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 1.05rem 0.5rem;
  cursor: pointer;
  list-style: none;
  transition: background 0.2s;
}
.ledger-head::-webkit-details-marker { display: none; }
.ledger-head:hover { background: var(--accent-wash); }
.ledger-head:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: -2px; }
.ledger-group[open] > .ledger-head { border-bottom: 1px solid var(--rule); }
.ledger-head .t-label { color: var(--accent-ink); }
.ledger-head-n { margin-left: auto; font-family: var(--font-mono); font-size: 0.66rem; color: var(--ink-3); }
.ledger-chevron { width: 0.9rem; height: 0.9rem; flex: none; color: var(--accent-ink); transition: transform 0.2s; }
.ledger-group[open] > .ledger-head .ledger-chevron { transform: rotate(180deg); }
.ledger-group .ledger-row:last-child { border-bottom: 0; }
@media (prefers-reduced-motion: reduce) {
  .ledger-head, .ledger-chevron { transition: none; }
}
.ledger-row {
  display: grid;
  grid-template-columns: 8.5rem minmax(0, 1fr) 1.5rem;
  gap: 1.25rem;
  align-items: baseline;
  width: 100%;
  text-align: left;
  padding: 0.85rem 0.5rem;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule);
  color: inherit;
  cursor: pointer;
  transition: background 0.2s, padding-left 0.2s;
}
.ledger-row:hover { background: var(--accent-wash); padding-left: 1.1rem; }
.ledger-date {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.ledger-title { font-size: 0.95rem; line-height: 1.5; color: var(--ink); }
.ledger-title .award-flag { margin-left: 0.6rem; vertical-align: 0.1em; }
.ledger-arrow { justify-self: end; color: var(--accent-ink); opacity: 0.5; transition: opacity 0.2s, transform 0.2s; }
.ledger-row:hover .ledger-arrow { opacity: 1; transform: translate(2px, -2px); }
.ledger-arrow svg { width: 0.8rem; height: 0.8rem; }

/* ─── FEATURE BLOCK — a section that sells its subpage ─────
   A contents row states that a page exists. This shows what is on it:
   real documents, the bodies that issued them, and a count. The whole
   block is the link. */

.feature {
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1fr);
  /* A block whose media is a readable document, rather than a strip of
     thumbnails, gives the document the larger share. */
  gap: clamp(1.5rem, 3.5vw, 3rem);
  align-items: center;
  padding: clamp(1.4rem, 2.5vw, 2rem);
  border: 1px solid var(--rule);
  background: var(--paper-2);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.2s, background 0.2s;
}
.feature--link:hover { border-color: var(--accent-ink); background: var(--accent-wash); }
.feature--doc { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); }

/* Proof strip — the actual documents, small. Evidence does the
   advertising; there is no claim here that a scan does not carry. */
.feature-media {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.6rem;
}
.proof-thumb {
  display: grid;
  place-items: center;
  aspect-ratio: 1 / 1;
  padding: 0.4rem;
  border: 1px solid var(--rule);
  background: var(--paper);
  transition: transform 0.25s, border-color 0.25s;
}
.proof-thumb img { width: 100%; height: 100%; object-fit: contain; }
.feature--link:hover .proof-thumb { border-color: var(--rule-2); transform: translateY(-2px); }

.feature-line {
  display: block;
  margin-top: 0.6rem;
  color: var(--ink-3);
}
.feature-body .tags { margin-top: 1rem; }
.feature-body .t-h2 { margin-top: 0.35rem; }
.feature-quote {
  font-family: var(--font-display);
  font-size: clamp(1.02rem, 1.6vw, 1.22rem);
  line-height: 1.45;
  color: var(--ink);
  border-left: 2px solid var(--accent-ink);
  padding-left: 1.1rem;
  margin-top: 1.1rem;
}
.feature-cue {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 1.25rem;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent-ink);
}
.feature-cue svg { width: 0.8125rem; height: 0.8125rem; transition: transform 0.2s; }
.feature--link:hover .feature-cue svg { transform: translateX(3px); }

/* A carousel standing inside a feature block: no filter, no rail, no
   rotation — just the documents, one at a time, each enlarging on click.
   It overrides the reading-column width and arrow offsets the full-page
   carousel uses, since it sits in a half-width column. */
.feature-carousel .awards-stage-wrap { max-width: none; margin-inline: 0; }
/* Sized so the letter can be read where it sits, not merely recognised.
   It takes the full media column and as much height as the viewport will
   give it; the enlarged view remains there for reading it closely. */
.feature-carousel { margin-inline: auto; width: 100%; }
.award-stage--xs { height: clamp(24rem, 66vh, 42rem); }

/* Controls sit under the mount rather than over it. At this size an
   overlaid arrow would cover the document it is there to move past. */
.feature-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin-top: 0.85rem;
}
.feature-nav {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  background: none;
  border: 1px solid var(--rule-2);
  color: var(--ink-3);
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s, background 0.2s;
}
.feature-nav:hover { border-color: var(--accent-ink); color: var(--accent-ink); background: var(--accent-wash); }
.feature-nav svg { width: 0.85rem; height: 0.85rem; }
.feature-count {
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  min-width: 4.5rem;
  text-align: center;
}
.feature-count b { color: var(--accent-ink); font-weight: 500; }

/* ─── LETTERS ──────────────────────────────────────────────
   The certificates page leads with the document, because the document
   is the achievement. A letter's achievement is its words, so these
   lead with the quotation and keep the scan beside it as the proof. */

.letter {
  display: grid;
  /* Scan first and given the wider column: the document is what a reader
     came to see, and these are portrait, so they need the width. */
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: stretch;
  padding-block: clamp(2.25rem, 4.5vw, 3.5rem);
  border-bottom: 1px solid var(--rule);
}
.letter:last-of-type { border-bottom: 0; }

/* Quote at the top, attribution driven to the foot, whatever the height
   of the scan beside it. */
.letter-body {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-width: 0;
}
.letter .quote { margin-block: 0; }
.letter .quote p {
  font-size: clamp(1.15rem, 1.9vw, 1.55rem);
  line-height: 1.38;
}
.letter .quote cite { display: none; }

.letter-from {
  margin-top: 2rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rule);
  text-align: right;
}
.letter-writer {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.08rem;
  line-height: 1.3;
  color: var(--ink);
}
.letter-from .t-caption { margin-top: 0.3rem; }
.letter-from .award-title { margin-bottom: 0; }
.letter-from .t-label { display: block; margin-top: 0.45rem; color: var(--accent-ink); }

/* Taller mount than the promo carousel: on this page the scan is the
   point, and it sits one-up beside its text. */
.award-stage--sm { height: clamp(21rem, 58vh, 33rem); }

/* Enlarged view. The scan at full size, on a ground dark enough that the
   sheet is the only thing in the room. */
.lb {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: grid;
  /* Counter, sheet, caption. The counter is a row rather than another
     absolutely positioned layer: stacked over the figure it lost the
     paint order and disappeared behind the certificate. */
  grid-template-rows: auto 1fr auto;
  gap: 1rem;
  padding: clamp(1rem, 3vw, 2.5rem);
  background: rgba(10, 9, 7, 0.93);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s;
  /* Clicking anywhere but the sheet or a control dismisses the view. */
  cursor: zoom-out;
}
.lb[data-open="true"] { opacity: 1; pointer-events: auto; }
/* The caption dismisses like the rest of the ground, so it keeps the
   same pointer; only the controls differ. */
.lb-btn { cursor: pointer; }
/* Same reasoning as the mount: the figure is a definite box and the
   scan is fitted into it, rather than centred in a row that grows. */
.lb-figure { position: relative; min-height: 0; }
.lb-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 20px 50px rgba(0, 0, 0, 0.6));
}
.lb-cap {
  max-width: 68ch;
  margin-inline: auto;
  text-align: center;
  color: #E9E3D6;
}
.lb-cap .t-label { color: #E9E3D6; opacity: 0.66; }
.lb-title { font-family: var(--font-display); font-weight: 700; font-size: 1.15rem; color: #F7F3EA; margin: 0.5rem 0 0.4rem; }
.lb-desc { font-size: 0.87rem; line-height: 1.65; color: #C9C2B4; }
.lb-btn {
  position: absolute;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  background: none;
  border: 1px solid rgba(233, 227, 214, 0.3);
  color: #E9E3D6;
  cursor: pointer;
  transition: border-color 0.2s, background 0.2s;
}
.lb-btn:hover { border-color: #E9E3D6; background: rgba(233, 227, 214, 0.1); }
.lb-btn svg { width: 1rem; height: 1rem; }
.lb-close { top: clamp(1rem, 3vw, 2.5rem); right: clamp(1rem, 3vw, 2.5rem); }
.lb-prev { left: clamp(0.5rem, 2vw, 1.5rem); top: 50%; transform: translateY(-50%); }
.lb-next { right: clamp(0.5rem, 2vw, 1.5rem); top: 50%; transform: translateY(-50%); }
.lb-count {
  text-align: center;
  /* Clear of the close button in the same corner band. */
  padding-inline: 3.5rem;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  color: #E9E3D6;
  opacity: 0.7;
  font-variant-numeric: tabular-nums;
}
body[data-lb-open="true"] { overflow: hidden; }

/* ─── 11. RESPONSIVE ──────────────────────────────────────── */

@media (max-width: 1080px) {
  .contents-row { grid-template-columns: 62px minmax(0, 1fr) 34px; }
  .contents-desc { display: none; }
  .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Once the page gutters run out, the arrows come inside the mount. */
  .awards-arrow--prev { left: 0.6rem; }
  .awards-arrow--next { right: 0.6rem; }
}

/* The nav carries nine section links plus the theme toggle — too many to
   fit the bar's width once the viewport narrows past a wide desktop, well
   before the general mobile breakpoint below. It collapses to the same
   hamburger menu early so the bar never overflows or wraps. */
@media (max-width: 1220px) {
  .nav-links {
    position: fixed;
    inset: 62px 0 auto 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
    padding: 0.5rem clamp(1.25rem, 4vw, 4rem) 1.25rem;
    display: none;
  }
  .nav-links[data-open="true"] { display: flex; }
  .nav-link { padding-block: 0.7rem; width: 100%; font-size: 0.72rem; }
  .theme-toggle { margin-top: 0.85rem; }
  .nav-toggle { display: inline-flex; }
}

@media (max-width: 860px) {
  .opener--heavy .opener-inner,
  .opener--light .opener-inner { grid-template-columns: minmax(0, 1fr); }
  /* The accent strip turns from a full-height rule into a marker bar */
  .opener-strip { min-height: 0; height: 5px; width: 84px; }
  .opener--minimal .opener-inner {
    padding-left: 0;
    padding-top: calc(var(--opener-pad) + 5px + var(--strip-gap));
  }
  .opener--minimal .opener-inner::before { bottom: auto; height: 5px; width: 84px; }
  .jump { grid-template-columns: minmax(0, 1fr); gap: 0.5rem; }
  .jump-link { padding: 0.85rem 1rem; }
  .opener-art { max-width: 420px; }
  .portrait { margin-left: 0; max-width: 26rem; }
  /* Stacked layout: the portrait sits low, so the plan gathers in the
     bottom-right corner behind it and disperses up and to the left. It
     hangs below the hero's edge so the bottom road clears the scroll cue. */
  .hero-plan {
    top: auto;
    bottom: -14%;
    width: 100%;
    height: 86%;
    object-position: right bottom;
    -webkit-mask-image: radial-gradient(ellipse 130% 100% at 100% 100%, #000 38%, transparent 82%);
            mask-image: radial-gradient(ellipse 130% 100% at 100% 100%, #000 38%, transparent 82%);
  }

  .grid-2, .grid-2--wide-left { grid-template-columns: minmax(0, 1fr); }
  .band-inner { grid-template-columns: minmax(0, 1fr); }
  .footer-inner { grid-template-columns: minmax(0, 1fr); }

  .feature { grid-template-columns: minmax(0, 1fr); }
  .letter { grid-template-columns: minmax(0, 1fr); }
  .letter-from { margin-top: 1.4rem; }
  .award-stage { height: clamp(15rem, 48vh, 22rem); }
  .award-stage--sm { height: clamp(16rem, 52vh, 24rem); }
  /* Held to the middle of the mount — half the stage height above. The
     wrapper runs past the mount to the foot of the caption, so anchoring
     these to its bottom would drop them onto the description. */
  .awards-arrow { top: clamp(7.5rem, 24vh, 11rem); width: 2.4rem; height: 2.4rem; }
  .award-cap { min-height: 0; }
  .ledger-row { grid-template-columns: 7rem minmax(0, 1fr) 1.25rem; gap: 0.9rem; }
}

@media (max-width: 560px) {
  .grid-3 { grid-template-columns: minmax(0, 1fr); }
  .contents-row { grid-template-columns: 48px minmax(0, 1fr) 26px; gap: 1rem; }
  .datalist-row { grid-template-columns: minmax(0, 1fr); gap: 0.25rem; }
  .legend-row { grid-template-columns: 78px 1fr; gap: 0.75rem; }

  .ledger-row { grid-template-columns: minmax(0, 1fr) 1.25rem; gap: 0.3rem 0.9rem; }
  .ledger-date { grid-column: 1; }
  .ledger-arrow { grid-row: 1 / span 2; }
  .awards-toggle { margin-left: 0; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
  /* No movement — a brief outline marks the refusal instead. */
  .is-shaking { outline: 1px solid currentColor; outline-offset: 3px; }
  /* Rotation never starts under this preference; the fade goes too. */
  .js-awards .award { animation: none; }
}

@media print {
  .site-nav, .theme-toggle, .nav-toggle { display: none; }
  body::before, body::after { display: none; }
  /* Printed, the carousel is a stack again: every certificate on the
     page, no controls. */
  .awards-filter, .awards-arrow, .awards-bar, .awards-rail,
  .awards-progress, .award-zoom, .lb { display: none !important; }
  .award[hidden] { display: block !important; }
  .award { break-inside: avoid; page-break-inside: avoid; margin-bottom: 1.5rem; }
  .award-stage { height: auto; border-color: #999; }
  .award-cap { min-height: 0; }
}
