/* ==========================================================================
   EMZINI WECODE, design system

   THESIS: EDITORIAL, WARM, WITH NERVE.
   Typeset like a journal, not assembled like a product page. Big Fraunces
   display, hairline rules, numbered sections, data set as type. The nerve comes
   from scale contrast and one hot accent, not from decoration.

   COLOUR DISCIPLINE (this is the rule that keeps it from going green)
     Ground        cream    --bg
     Contrast      warm ink --ink, used in bands, never wall to wall
     Accent        TERRACOTTA --accent. This is the primary accent. Rules,
                   active states, the closing band, hover sweeps.
     Brand mint    --brand. RESERVED. The logo, and semantic success only
                   (a valid certificate). It is not a UI colour. If you find
                   yourself reaching for mint to make something look nice,
                   reach for terracotta instead.

   Palette and type come from Poseidon (../grader) so the Grader and this site
   read as one organisation.

   There is no dark theme. A single impeccable light treatment beats a light one
   plus a mediocre dark one, and the first attempt at dark was not good. See
   HANDOFF §5 before adding one back.

   SPACING
   One rhythm scale, --s1 through --s7. Sections use --section-y. Do not
   hand-tune padding per page; if a page needs different air, it needs a
   different section modifier.

   STRUCTURE
     1 fonts      5 nav + menu    9  empty/notice
     2 tokens     6 buttons       10 media/forms
     3 base       7 cards/rows    11 heroes
     4 type       8 stats         12 credential  13 footer  14 motion
     15 interior components  16 print
   ========================================================================== */

/* ── 1. fonts ─────────────────────────────────────────────────────────────
   Self-hosted variable woff2. No third-party origin: the page makes zero
   external requests and that is a property worth keeping. */

@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/static/fonts/Fraunces-var.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/static/fonts/Inter-var.woff2') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/static/fonts/JetBrainsMono-var.woff2') format('woff2');
}

/* ── 2. tokens ────────────────────────────────────────────────────────── */

:root {
  --font-display: 'Fraunces', 'Source Serif Pro', Georgia, serif;
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  --bg: #fbf8f1;
  --bg-2: #f5f1e8;
  --surface: #ffffff;
  --surface-2: #f9f6ef;
  --ink: #171a1f;
  --ink-2: #3d4148;
  --ink-3: #6b6f78;
  /* --ink-4 is the colour of nearly all mono metadata: card meta, index
     numbers, stat labels, the footer headings and the footer legal line. At
     #9aa0a8 it measured 2.64:1 on white and 2.48:1 on cream, failing AA on
     every page. #6b7076 measures 4.99 / 4.71 / 4.63 on surface / bg /
     surface-2. --ink-5 stays light because it is hairlines and disabled
     states only, never text. */
  --ink-4: #6b7076;
  --ink-5: #c4c8cf;
  --border: #e8e2d3;
  --border-2: #d4ccba;

  /* terracotta: the accent that does the work */
  --accent: #c9683a;
  --accent-deep: #a04f25;
  --accent-fg: #7a3e1f;
  --accent-bg: #f5e6dc;
  --accent-border: #e8c5ad;

  /* mint: logo and semantic success ONLY */
  --brand: #4bbca0;
  --brand-deep: #2e8a73;
  --brand-fg: #0c5a4a;
  --brand-bg: #e8f5f0;
  --brand-border: #b8e0d2;

  /* THE DARK BAND IS DEEP SPRUCE, NOT BLACK.
     The logo is mint, and with warm-black bands that mint appeared nowhere else
     on the site, so the mark read as borrowed from another brand. Spruce is the
     mint's own family darkened, which gives the logo somewhere to belong and
     makes mint usable as an accent on the band: #4bbca0 measures 5.98:1 against
     #10312a, where against warm black it was unusable.
     Measured on --spruce: cream 12.69, mint 5.97, terracotta 5.18, muted 6.81. */
  --spruce: #10312a;
  --spruce-2: #164137;
  --on-ink: #f7f3ea;
  --on-ink-2: #a9b8b1;
  --on-ink-border: #2b5349;
  /* mint is legible as small text on spruce, so the brand colour finally has a
     job beyond the logo */
  --brand-on-spruce: #5fd4b6;
  --accent-on-ink: #e08660;

  --warning: #c69449;
  --warning-bg: #faf0d9;
  --warning-fg: #8a6a2e;
  --error: #a8483d;
  --error-bg: #f7e6e2;
  --error-fg: #7a342c;

  --radius: 10px;
  --radius-sm: 6px;
  --rule: 1px solid var(--border);

  --shadow-sm: 0 1px 2px rgba(23,26,31,.04), 0 2px 8px rgba(23,26,31,.04);
  --shadow: 0 2px 4px rgba(23,26,31,.04), 0 14px 30px -10px rgba(23,26,31,.12);
  --shadow-lg: 0 4px 8px rgba(23,26,31,.05), 0 30px 60px -18px rgba(23,26,31,.18);

  /* one rhythm scale */
  --s1: .5rem;
  --s2: .875rem;
  --s3: 1.25rem;
  --s4: 2rem;
  --s5: 3rem;
  --s6: 4.5rem;
  --s7: 7rem;
  --section-y: clamp(3.5rem, 7vw, 6.5rem);

  --nav-h: 74px;
  --gutter: clamp(1.25rem, 4.5vw, 3.5rem);
  --measure: 66ch;
  --t: .22s cubic-bezier(.4,0,.2,1);
  --t-slow: .8s cubic-bezier(.16,1,.3,1);
}

/* ── 3. base ──────────────────────────────────────────────────────────── */

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

html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + var(--s3));
}

body {
  font-family: var(--font-sans);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: 'kern' 1, 'liga' 1, 'calt' 1;
}
body.is-locked { overflow: hidden; }

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
input, button, textarea, select { font: inherit; color: inherit; }
ul[role="list"], ol[role="list"] { list-style: none; }

::selection { background: var(--accent-bg); color: var(--accent-fg); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }

.skip-link {
  position: absolute; left: var(--s3); top: -5rem; z-index: 300;
  padding: .7rem 1.2rem; background: var(--ink); color: var(--bg);
  border-radius: var(--radius-sm); font-size: .9rem; font-weight: 600;
  transition: top var(--t);
}
.skip-link:focus { top: var(--s3); }

.sr-only, .visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── 4. type ──────────────────────────────────────────────────────────── */

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.06;
  letter-spacing: -.024em;
  color: var(--ink);
  /* Fraunces axes are the signature. opsz tracks size, SOFT rounds terminals,
     WONK brings in the characterful forms. Keep all three together. */
  font-variation-settings: 'opsz' 96, 'SOFT' 40, 'WONK' 1;
  text-wrap: balance;
}
h1 { font-size: clamp(2.5rem, 5.4vw, 4.1rem); }
h2 { font-size: clamp(1.95rem, 3.6vw, 2.9rem); }
h3 { font-size: clamp(1.2rem, 1.9vw, 1.45rem); letter-spacing: -.015em; }
h4 { font-size: 1.0625rem; letter-spacing: -.008em; }

.display {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(3rem, 8.2vw, 6.4rem);
  line-height: .94;
  letter-spacing: -.038em;
  font-variation-settings: 'opsz' 144, 'SOFT' 25, 'WONK' 1;
  text-wrap: balance;
}
.display em {
  font-style: italic;
  font-variation-settings: 'opsz' 144, 'SOFT' 60, 'WONK' 1;
  color: var(--accent);
}

p { margin-bottom: 1.1em; }
p:last-child { margin-bottom: 0; }

.lead {
  font-size: clamp(1.1rem, 1.6vw, 1.3rem);
  line-height: 1.55;
  color: var(--ink-2);
  max-width: 48ch;
}
.statement {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 3.4vw, 2.6rem);
  font-weight: 600;
  line-height: 1.18;
  letter-spacing: -.026em;
  font-variation-settings: 'opsz' 96, 'SOFT' 45, 'WONK' 1;
  max-width: 30ch;
  text-wrap: balance;
}

.prose { max-width: var(--measure); }
.prose a {
  color: var(--accent-fg);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .18em;
  text-decoration-color: var(--accent-border);
  transition: text-decoration-color var(--t);
}
.prose a:hover { text-decoration-color: var(--accent); }

/* mono eyebrow. The leading rule draws itself in on reveal. */
.eyebrow, .mono-label {
  display: flex;
  align-items: center;
  gap: .7rem;
  font-family: var(--font-mono);
  font-size: .71rem;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.eyebrow::before, .mono-label::before {
  content: "";
  width: 2rem;
  height: 1px;
  background: var(--accent);
  flex: none;
  transform-origin: left;
  transform: scaleX(0);
  transition: transform .7s cubic-bezier(.16,1,.3,1) .1s;
}
.is-revealed .eyebrow::before, .eyebrow.is-revealed::before,
.is-revealed .mono-label::before, html.no-js .eyebrow::before,
html.no-js .mono-label::before, html.no-motion .eyebrow::before { transform: scaleX(1); }
.eyebrow--plain::before { display: none; }

.fineprint { font-size: .85rem; line-height: 1.6; color: var(--ink-3); max-width: 60ch; }
.mono { font-family: var(--font-mono); font-variant-ligatures: none; }
.muted { color: var(--ink-3); }
.text-center { text-align: center; }
.text-center .lead, .text-center p { margin-inline: auto; }
.text-center .eyebrow, .text-center .mono-label { justify-content: center; }

/* ── 5. layout, header, full screen menu ──────────────────────────────── */

.container {
  width: 100%;
  max-width: 1300px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--md { max-width: 950px; }
.container--sm { max-width: 700px; }

/* One rhythm. A section is --section-y top and bottom, full stop. */
.section { padding-block: var(--section-y); }
.section--tight { padding-block: clamp(2.25rem, 4.5vw, 3.5rem); }
.section--flush-top { padding-top: 0; }
.section--surface, .section--white { background: var(--surface); border-block: var(--rule); }
.section--warm { background: var(--bg-2); }
/* the ink band: warm near-black,
used two or three times per page at most */
.section--spruce, .band {
  background: var(--spruce);
  color: var(--on-ink);
  position: relative;
  overflow: hidden;
}
.section--spruce h1,
.section--spruce h2,
.section--spruce h3,
.section--spruce h4, .band h4 { color: var(--on-ink); }
.section--spruce .lead,
.section--spruce p,
.section--spruce .fineprint, .band .fineprint { color: var(--on-ink-2); }
.section--spruce .eyebrow,
.section--spruce .mono-label, .band .mono-label { color: var(--on-ink-2); }

/* `* { margin: 0 }` strips heading margins, and the rhythm was restored only
   inside .section-header, so any heading not wrapped in one sat flush against
   its body copy. That was 17 places, worst on /privacy and /safeguarding where
   every section heading touched its first line. :where() has zero specificity,
   so .section-header's own values still win where they apply. */
:where(h1, h2, h3, h4) + * { margin-top: var(--s3); }

.section-header { margin-bottom: clamp(2rem, 4vw, 3.25rem); }
.section-header h2 { margin-top: var(--s2); }
.section-header .lead { margin-top: var(--s2); }

.rule { border: 0; border-top: var(--rule); }

.editorial {
  display: grid;
  grid-template-columns: minmax(0, 13rem) minmax(0, 1fr);
  gap: clamp(1.5rem, 4.5vw, 4.5rem);
  align-items: start;
}
.editorial__rail { position: sticky; top: calc(var(--nav-h) + var(--s4)); }
/* A form is the point of its page, so it gets the wide column and the rail
   becomes genuinely secondary. */
.editorial--form { grid-template-columns: minmax(0, 1fr) minmax(0, 17rem); }
.editorial--form .editorial__rail { order: 2; }
@media (max-width: 900px) {
  .editorial--form { grid-template-columns: 1fr; }
  .editorial--form .editorial__rail { order: 0; }
}
@media (max-width: 900px) {
  .editorial { grid-template-columns: 1fr; gap: var(--s3); }
  .editorial__rail { position: static; }
}

.grid { display: grid; gap: clamp(1rem, 2vw, 1.5rem); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 13.5rem), 1fr)); }
.stack { display: grid; gap: var(--s3); }
.cluster { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; }

/* ---- header ---- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--t), background var(--t);
}
.site-header.is-scrolled { border-bottom-color: var(--border); }

.nav {
  height: var(--nav-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
}

.logo { display: block; flex: none; }
.logo img { height: 52px; width: auto; transition: transform var(--t); }
.logo:hover img { transform: scale(1.04); }
/* the mint artwork turned cream for ink grounds; filter keeps the alpha */
.logo--on-ink img { filter: brightness(0) invert(1); }
.logo--footer img { height: 66px; }

.nav__right { display: flex; align-items: center; gap: var(--s2); }
/* ---- nav bar ----
   A bar of links, not a full screen panel. The panel was tried and reverted: it
   made every destination cost two clicks and hid the structure of the site from
   anyone scanning it. What makes a bar not feel like a SaaS chrome strip is the
   dropdowns carrying a line of explanation each, and an indicator that animates
   under the active section. */

.nav__menu { display: flex; align-items: center; gap: .1rem; list-style: none; }

.nav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .6rem .85rem;
  font-size: .94rem;
  font-weight: 500;
  color: var(--ink-2);
  white-space: nowrap;
  transition: color var(--t);
}
.nav__link:hover { color: var(--ink); }
/* the indicator: a terracotta rule that grows from the centre */
.nav__link::after {
  content: "";
  position: absolute;
  left: .85rem;
  right: .85rem;
  bottom: .28rem;
  height: 1.5px;
  background: var(--accent);
  transform: scaleX(0);
  transition: transform .32s cubic-bezier(.16,1,.3,1);
}
.nav__link:hover::after { transform: scaleX(1); }
.nav__link.is-active { color: var(--ink); font-weight: 600; }
.nav__link.is-active::after { transform: scaleX(1); }

.nav__item--drop { position: relative; }
.nav__item--drop > .nav__link::before {
  content: "";
  width: .32em; height: .32em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translateY(-1px);
  opacity: .45;
  order: 2;
  transition: transform var(--t);
}
.nav__item--drop:hover > .nav__link::before { transform: rotate(45deg) translateY(1px); }

/* Dropdowns carry a description per item. That single line is the difference
   between a nav and a menu you can actually decide from. */
.nav__dropdown {
  position: absolute;
  top: calc(100% - .2rem);
  left: -.4rem;
  min-width: 21rem;
  padding: .5rem;
  list-style: none;
  background: var(--surface);
  border: var(--rule);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-.4rem);
  transition: opacity .2s ease, transform .28s cubic-bezier(.16,1,.3,1), visibility 0s linear .2s;
}
.nav__item--drop:hover .nav__dropdown,
.nav__item--drop:focus-within .nav__dropdown {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity .2s ease, transform .28s cubic-bezier(.16,1,.3,1), visibility 0s;
}
.nav__dropdown a {
  display: block;
  padding: .6rem .7rem;
  border-radius: var(--radius-sm);
  transition: background var(--t);
}
.nav__dropdown a:hover { background: var(--bg-2); }
.nav__dropdown strong {
  display: block;
  font-size: .92rem;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: .1rem;
}
.nav__dropdown span { display: block; font-size: .82rem; line-height: 1.45; color: var(--ink-3); }

/* burger, mobile only */
.nav__toggle {
  display: none;
  width: 2.5rem; height: 2.5rem;
  border: var(--rule);
  border-radius: var(--radius-sm);
  background: transparent;
  cursor: pointer;
  position: relative;
}
.nav__toggle-bar {
  position: absolute;
  left: 50%; top: 50%;
  width: 1.05rem; height: 1.5px;
  background: var(--ink);
  transition: transform var(--t), opacity var(--t);
}
.nav__toggle-bar:nth-child(1) { transform: translate(-50%, calc(-50% - 5px)); }
.nav__toggle-bar:nth-child(2) { transform: translate(-50%, -50%); }
.nav__toggle-bar:nth-child(3) { transform: translate(-50%, calc(-50% + 5px)); }
.nav__toggle[aria-expanded="true"] .nav__toggle-bar:nth-child(1) { transform: translate(-50%,-50%) rotate(45deg); }
.nav__toggle[aria-expanded="true"] .nav__toggle-bar:nth-child(2) { opacity: 0; }
.nav__toggle[aria-expanded="true"] .nav__toggle-bar:nth-child(3) { transform: translate(-50%,-50%) rotate(-45deg); }

@media (max-width: 1040px) {
  .nav__toggle { display: block; }
  .nav__menu {
    position: fixed;
    inset: var(--nav-h) 0 auto;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    max-height: calc(100dvh - var(--nav-h));
    overflow-y: auto;
    padding: var(--s2) var(--gutter) var(--s4);
    background: var(--bg);
    border-bottom: var(--rule);
    box-shadow: var(--shadow-lg);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-.6rem);
    transition: opacity .24s ease, transform .3s cubic-bezier(.16,1,.3,1), visibility 0s linear .24s;
  }
  .nav__menu.is-open {
    opacity: 1; visibility: visible; transform: none;
    transition: opacity .24s ease, transform .3s cubic-bezier(.16,1,.3,1), visibility 0s;
  }
  .nav__menu > li { border-bottom: var(--rule); }
  .nav__menu > li:last-child { border-bottom: 0; }
  .nav__link { padding: .95rem .2rem; font-size: 1.05rem; }
  .nav__link::after { display: none; }
  .nav__item--drop > .nav__link::before { display: none; }
  /*
    `visibility` is the one property a descendant can use to escape an
    ancestor's hidden state. This rule used to set `visibility: visible` and
    `opacity: 1` unconditionally, so when the closed panel hid itself with
    `visibility: hidden; opacity: 0`, the nine dropdown links climbed back out:
    invisible, but still hit-testable and still in the tab order, covering most
    of the viewport on every page. Tapping the hero navigated to /learn.
    The reveal is now scoped to the open panel. motion.js also marks the closed
    panel `inert`, which is the durable guard.
  */
  .nav__dropdown {
    position: static;
    transform: none;
    box-shadow: none;
    border: 0;
    border-left: 2px solid var(--border);
    border-radius: 0;
    margin: 0 0 .8rem .2rem;
    padding: 0 0 0 .8rem;
    background: transparent;
    min-width: 0;
  }
  .nav__menu.is-open .nav__dropdown { opacity: 1; visibility: visible; }
  .nav__dropdown a { padding: .5rem 0; }
  .nav__dropdown span { display: none; }
}

/* ── 6. buttons + badges ──────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: .75rem 1.4rem;
  font-size: .94rem;
  font-weight: 550;
  line-height: 1.3;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  white-space: nowrap;
  position: relative;
  overflow: hidden;
  transition: color var(--t), background var(--t), border-color var(--t), transform var(--t);
}
.btn:active { transform: translateY(1px); }
.btn--lg { padding: 1rem 1.9rem; font-size: 1rem; }
.btn--sm { padding: .5rem 1rem; font-size: .86rem; }
.btn-group { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; }

.btn--primary, .btn--dark { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.btn--primary:hover, .btn--dark:hover { background: var(--accent); border-color: var(--accent); color: #fff; }

.btn--accent { background: var(--accent-deep); color: #fff; border-color: var(--accent-deep); }
.btn--accent:hover { background: var(--accent-fg); border-color: var(--accent-fg); }

.btn--outline, .btn--outline-dark { background: transparent; color: var(--ink); border-color: var(--border-2); }
.btn--outline:hover, .btn--outline-dark:hover { border-color: var(--ink); background: var(--surface); }

.btn--ghost { background: transparent; color: var(--ink-2); }
.btn--ghost:hover { background: var(--bg-2); color: var(--ink); }
/* on ink */
.section--spruce .btn--primary,
.section--spruce .btn--dark,
.claim-strip .btn--primary,
/* on ink */
.band .btn--primary,
.band .btn--dark {
  background: var(--accent); color: #fff; border-color: var(--accent);
}
.section--spruce .btn--primary:hover,
.claim-strip .btn--primary:hover,
.band .btn--primary:hover {
  background: var(--on-ink); border-color: var(--on-ink); color: var(--ink);
}
.section--spruce .btn--outline, .band .btn--outline,
.section--spruce .btn--outline-dark, .band .btn--outline-dark,
.section--spruce .btn--outline-light, .band .btn--outline-light {
  color: var(--on-ink); border-color: var(--on-ink-border); background: transparent;
}
.section--spruce .btn--outline:hover, .band .btn--outline:hover,
.section--spruce .btn--outline-dark:hover, .band .btn--outline-dark:hover,
.section--spruce .btn--outline-light:hover, .band .btn--outline-light:hover {
  border-color: var(--on-ink); background: rgba(255,255,255,.07);
}

.btn__arrow, .link-arrow span { transition: transform var(--t); }
.btn:hover .btn__arrow, .link-arrow:hover span { transform: translateX(4px); }

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: .9rem;
  font-weight: 550;
  color: var(--accent-fg);
}
.section--spruce .link-arrow, .band .link-arrow { color: var(--accent-on-ink); }

.badge, .tag {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .22rem .6rem;
  font-family: var(--font-mono);
  font-size: .69rem;
  font-weight: 500;
  letter-spacing: .07em;
  text-transform: uppercase;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--ink-3);
  white-space: nowrap;
}
.tag, .badge--accent { background: var(--accent-bg); border-color: var(--accent-border); color: var(--accent-fg); }
.badge--brand { background: var(--brand-bg); border-color: var(--brand-border); color: var(--brand-fg); }
.badge--warning { background: var(--warning-bg); border-color: var(--warning); color: var(--warning-fg); }
.badge--error { background: var(--error-bg); border-color: var(--error); color: var(--error-fg); }
.section--spruce .badge,
.section--spruce .tag, .band .tag {
  background: rgba(255,255,255,.06); border-color: var(--on-ink-border); color: var(--on-ink-2);
}

.unverified {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  margin-left: .4rem;
  padding: .12rem .5rem;
  font-family: var(--font-mono);
  font-size: .65rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  border-radius: 999px;
  background: var(--error-bg);
  color: var(--error-fg);
  border: 1px dashed var(--error);
  vertical-align: middle;
}

/* ── 7. cards + index rows ────────────────────────────────────────────── */

.card {
  background: var(--surface);
  border: var(--rule);
  border-radius: var(--radius);
  padding: clamp(1.25rem, 2.2vw, 1.85rem);
  transition: border-color var(--t), transform var(--t), box-shadow var(--t);
}
.card--link:hover { border-color: var(--accent-border); transform: translateY(-3px); box-shadow: var(--shadow); }
.card__title { margin-bottom: .4rem; }
.card__meta {
  font-family: var(--font-mono);
  font-size: .71rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.section--spruce .card, .band .card {
  background: rgba(255,255,255,.04); border-color: var(--on-ink-border);
}
.section--spruce .card--link:hover, .band .card--link:hover { border-color: var(--accent); }

.pillar {
  display: block;
  background: var(--surface);
  border: var(--rule);
  border-radius: var(--radius);
  padding: clamp(1.4rem, 2.4vw, 2rem);
  transition: border-color var(--t), transform var(--t), box-shadow var(--t);
}
.pillar:hover { border-color: var(--accent-border); transform: translateY(-4px); box-shadow: var(--shadow); }
.pillar__num, .pillar__no {
  display: block;
  font-family: var(--font-mono);
  font-size: .71rem;
  letter-spacing: .13em;
  /* --accent is 3.58:1 on cream, which fails AA for 11px text. --accent-fg is
     the darkened variant meant for exactly this. */
  color: var(--accent-fg);
  margin-bottom: var(--s2);
}
.pillar h3 { margin-bottom: .5rem; }
.pillar p { font-size: .95rem; color: var(--ink-3); }
.pillar__go { display: inline-flex; gap: .4rem; margin-top: var(--s3); font-size: .88rem; font-weight: 550; color: var(--accent-fg); }
.pillar:hover .pillar__go { color: var(--accent-deep); }
.pillars { display: grid; gap: clamp(1rem, 2vw, 1.5rem); grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }
.section--spruce .pillar, .band .pillar {
  background: rgba(255,255,255,.04); border-color: var(--on-ink-border);
}
.section--spruce .pillar:hover, .band .pillar:hover { border-color: var(--accent); }
.section--spruce .pillar p, .band .pillar p { color: var(--on-ink-2); }
/* Two jobs, two colours, so both mean something on the band:
   mint does identity (the section numbers), terracotta does interaction (the
   links and arrows), which is what it does everywhere else on the site.
   .pillar__num had no spruce override at all and would have inherited
   --accent-fg, a dark terracotta, onto dark green. */
.section--spruce .pillar__num, .section--spruce .pillar__no, .band .pillar__num, .band .pillar__no { color: var(--brand-on-spruce); }
.section--spruce .pillar__go, .band .pillar__go { color: var(--accent-on-ink); }
.section--spruce .index-row__no, .band .index-row__no { color: var(--brand-on-spruce); }

/* index row: a syllabus entry. The terracotta rule sweeps in on hover. */
.index-row {
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr) auto;
  gap: clamp(.9rem, 2vw, 2rem);
  align-items: baseline;
  padding-block: clamp(1.25rem, 2.4vw, 1.75rem);
  border-top: var(--rule);
  position: relative;
  transition: background var(--t);
}
.index-row:last-child { border-bottom: var(--rule); }
.index-row::after {
  content: "";
  position: absolute;
  left: 0; top: -1px;
  width: 100%; height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .5s cubic-bezier(.16,1,.3,1);
}
.index-row:hover::after { transform: scaleX(1); }
.index-row:hover { background: var(--surface-2); }
.index-row:hover .index-row__title { color: var(--accent); }
.index-row__no { font-family: var(--font-mono); font-size: .77rem; color: var(--ink-4); letter-spacing: .07em; }
/* Both are <span> so the whole row can be one <a>. Without display:block they
   flow inline and the subtitle runs straight on from the title. */
.index-row__title, .index-row__sub { display: block; }
.index-row__title {
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 2.5vw, 1.9rem);
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.14;
  font-variation-settings: 'opsz' 72, 'SOFT' 40, 'WONK' 1;
  margin-bottom: .3rem;
  transition: color var(--t);
}
.index-row__sub { color: var(--ink-3); font-size: .95rem; }
.index-row__aside { text-align: right; }
@media (max-width: 720px) {
  .index-row { grid-template-columns: 2.25rem minmax(0, 1fr); }
  .index-row__aside { grid-column: 2; text-align: left; margin-top: .6rem; }
}

.person-card {
  background: var(--surface);
  border: var(--rule);
  border-radius: var(--radius);
  padding: var(--s3);
  transition: border-color var(--t), box-shadow var(--t), transform var(--t);
}
.person-card:hover { border-color: var(--accent-border); box-shadow: var(--shadow); transform: translateY(-3px); }
.person-card__name {
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 600;
  margin-top: var(--s3);
  letter-spacing: -.015em;
  font-variation-settings: 'opsz' 32, 'SOFT' 40, 'WONK' 1;
}
.person-card__role { font-size: .88rem; color: var(--ink-2); margin-top: .15rem; }
.person-card__loc { font-family: var(--font-mono); font-size: .69rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-4); margin-top: .4rem; }
.person-card__bio { font-size: .9rem; color: var(--ink-3); margin-top: .7rem; }
.person-card__tags { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: var(--s2); }
.person-card__link { display: inline-block; margin-top: var(--s2); font-size: .85rem; font-weight: 550; color: var(--accent-fg); }
.section--spruce .person-card, .band .person-card {
  background: rgba(255,255,255,.04); border-color: var(--on-ink-border);
}
.section--spruce .person-card__name, .band .person-card__name { color: var(--on-ink); }
.section--spruce .person-card__role,
.section--spruce .person-card__bio, .band .person-card__bio { color: var(--on-ink-2); }
.section--spruce .person-card__link, .band .person-card__link { color: var(--accent-on-ink); }

.card-grid { display: grid; gap: clamp(1rem, 2vw, 1.5rem); grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); }
.card-grid--3 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr)); }
.card-grid--4 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr)); }
.card__link { display: inline-flex; gap: .4rem; margin-top: var(--s3); font-size: .88rem; font-weight: 550; color: var(--accent-fg); }
.section--spruce .card__link, .band .card__link { color: var(--accent-on-ink); }

/* ── 8. stats as typography ───────────────────────────────────────────── */

.stat-band, .hero__stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
  border-top: var(--rule);
}
.stat { padding: clamp(1.4rem, 2.6vw, 2rem) clamp(1rem, 2vw, 1.6rem); border-right: var(--rule); }
.stat:last-child { border-right: 0; }
.stat__number {
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 4.4vw, 3.2rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -.035em;
  font-variation-settings: 'opsz' 120, 'SOFT' 25, 'WONK' 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums lining-nums;
}
.stat__label {
  font-family: var(--font-mono);
  font-size: .69rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-top: .6rem;
}
.section--spruce .stat, .band .stat { border-color: var(--on-ink-border); }
/* mint on the numbers: the brand colour doing identity work */
.section--spruce .stat__number, .band .stat__number { color: var(--brand-on-spruce); }
.section--spruce .stat__label, .band .stat__label { color: var(--on-ink-2); }

.agg-row { display: flex; flex-wrap: wrap; gap: clamp(1.5rem, 4vw, 3rem); }
.agg { display: flex; flex-direction: column; }
.agg__n {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 3vw, 2.4rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -.032em;
  font-variation-settings: 'opsz' 96, 'SOFT' 25, 'WONK' 1;
  font-variant-numeric: tabular-nums;
}
.agg__l { font-family: var(--font-mono); font-size: .67rem; letter-spacing: .13em; text-transform: uppercase; color: var(--ink-3); margin-top: .4rem; }
.section--spruce .agg__n, .page-hero--deep .agg__n, .band .agg__n { color: var(--brand-on-spruce); }
.section--spruce .agg__l, .page-hero--deep .agg__l, .band .agg__l { color: var(--on-ink-2); }

/* pull quote. The brace is the logo's, drawn in type. */
.pullquote {
  position: relative;
  padding-left: clamp(2rem, 4.5vw, 3.5rem);
  font-family: var(--font-display);
  font-size: clamp(1.45rem, 3vw, 2.2rem);
  line-height: 1.22;
  letter-spacing: -.024em;
  font-variation-settings: 'opsz' 96, 'SOFT' 50, 'WONK' 1;
  text-wrap: balance;
}
.pullquote::before {
  content: "{";
  position: absolute;
  left: 0; top: -.16em;
  font-size: 2.5em;
  line-height: 1;
  color: var(--accent);
  font-weight: 400;
}
.pullquote__cite {
  display: block;
  margin-top: var(--s3);
  font-family: var(--font-mono);
  font-size: .73rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-style: normal;
}

.value-list { list-style: none; display: grid; gap: .8rem; }
.value-list li { position: relative; padding-left: 1.5rem; color: var(--ink-2); font-size: .97rem; max-width: 58ch; }
.value-list li::before {
  content: "";
  position: absolute;
  left: 0; top: .62em;
  width: .42rem; height: .42rem;
  border-radius: 50%;
  background: var(--accent);
}
.value-list strong { color: var(--ink); font-weight: 600; }
.section--spruce .value-list li, .band .value-list li { color: var(--on-ink-2); }
.section--spruce .value-list strong, .band .value-list strong { color: var(--on-ink); }

/* ---- terms: the replacement for headed bullet lists ----
   A bulleted list under a heading like "What you get" reads as a proposal
   document, not a designed page. These are the same facts as hairline-separated
   definition rows: a short display-face term, then one plain sentence. Scannable
   without dots, and it looks deliberate. Use this instead of <ul> for anything
   that is really a set of named points. */

/* Container query, not a media query. The two-column form needs the width of
   its OWN container, not of the viewport: dropped into a 208px sidebar rail on a
   1440px screen it kept the 13rem term column, squeezed the definition to
   nothing, and wrapped the text one word per line. A viewport media query cannot
   see that. */
.terms { display: grid; container-type: inline-size; }
.terms > div {
  display: grid;
  grid-template-columns: minmax(0, 13rem) minmax(0, 1fr);
  gap: var(--s2) var(--s4);
  padding-block: clamp(.9rem, 1.8vw, 1.25rem);
  border-top: var(--rule);
}
@container (max-width: 34rem) {
  .terms > div { grid-template-columns: 1fr; gap: .3rem; }
}
.terms > div:last-child { border-bottom: var(--rule); }
.terms dt {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -.012em;
  font-variation-settings: 'opsz' 32, 'SOFT' 40, 'WONK' 1;
  color: var(--ink);
}
.terms dd { color: var(--ink-2); font-size: .98rem; }
@media (max-width: 640px) {
  .terms > div { grid-template-columns: 1fr; gap: .3rem; }
}

/* -- Contact card ---------------------------------------------------------
   The named safeguarding lead, on /safeguarding. Deliberately looks like a
   card on a noticeboard rather than a form field: a parent deciding whether
   to make a difficult phone call should be able to see the whole route at a
   glance, name, role, address and number, without opening anything. */
.contact-card {
  margin-top: var(--s4);
  padding: var(--s4);
  background: var(--surface);
  border: var(--rule);
  /* --brand is the logo mint (#4bbca0), reserved for the logo and semantic
     success. A safeguarding route is the one other place it earns: it should
     read as reassurance, not as a warning. */
  border-left: 3px solid var(--brand);
  border-radius: var(--radius);
}
.contact-card__label {
  font-family: var(--font-mono);
  font-size: .67rem;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.contact-card__name {
  margin-top: .35rem;
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 600;
  font-variation-settings: 'opsz' 36, 'SOFT' 40, 'WONK' 1;
  color: var(--ink);
}
.contact-card__role { font-size: .93rem; color: var(--ink-3); }
.contact-card__routes { margin-top: var(--s3); display: grid; gap: .5rem; }
.contact-card__routes li { display: flex; flex-wrap: wrap; align-items: baseline; gap: .6rem; }
.contact-card__routes a {
  font-family: var(--font-mono);
  font-size: .95rem;
  color: var(--ink);
  text-underline-offset: 3px;
}
/* the rail is narrow at every viewport size, so it never wants two columns */
.editorial__rail .terms > div,
.post-aside .terms > div { grid-template-columns: 1fr; gap: .3rem; }
.section--spruce .terms > div, .band .terms > div { border-color: var(--on-ink-border); }
.section--spruce .terms dt, .band .terms dt { color: var(--on-ink); }
.section--spruce .terms dd, .band .terms dd { color: var(--on-ink-2); }

/* exchange: two facing sets of terms. Used for reciprocal deals ("we bring" /
   "you bring"), where the structure itself carries the argument. */
.exchange { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.5rem, 4vw, 3.5rem); }
.exchange__h {
  font-family: var(--font-mono);
  font-size: .69rem;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent-fg);
  margin-bottom: var(--s3);
}
.exchange .terms > div { grid-template-columns: 1fr; gap: .3rem; }
@media (max-width: 800px) { .exchange { grid-template-columns: 1fr; } }

/* ── 9. empty states, notices, closing band ───────────────────────────── */

.empty-state {
  border: 1px dashed var(--border-2);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 3.5vw, 2.75rem);
  text-align: center;
  background: var(--surface-2);
}
.empty-state__title {
  font-family: var(--font-display);
  font-size: 1.22rem;
  font-weight: 600;
  letter-spacing: -.016em;
  font-variation-settings: 'opsz' 48, 'SOFT' 40, 'WONK' 1;
  margin-bottom: .5rem;
}
.empty-state__body { color: var(--ink-3); font-size: .95rem; max-width: 52ch; margin: 0 auto var(--s3); }
.empty-state__body:last-child { margin-bottom: 0; }
.section--spruce .empty-state, .band .empty-state {
  background: rgba(255,255,255,.03); border-color: var(--on-ink-border);
}
.section--spruce .empty-state__title, .band .empty-state__title { color: var(--on-ink); }
.section--spruce .empty-state__body, .band .empty-state__body { color: var(--on-ink-2); }

.notice {
  border: var(--rule);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--accent-bg);
  padding: 1.15rem 1.35rem;
}
.notice--accent { border-left-color: var(--accent); background: var(--accent-bg); }
.notice p { margin-bottom: .7rem; }
.section--spruce .notice, .band .notice {
  background: rgba(201,104,58,.13); border-color: var(--on-ink-border); border-left-color: var(--accent);
}

.degraded-banner {
  background: var(--warning-bg);
  color: var(--warning-fg);
  border-bottom: 1px solid var(--warning);
  padding: .6rem var(--gutter);
  font-family: var(--font-mono);
  font-size: .75rem;
  letter-spacing: .05em;
  text-align: center;
}

/* closing band: terracotta, the one place the accent takes a whole surface */
/* The band grounds on --accent-deep, not --accent. White on #c9683a is 3.80:1,
   which fails AA for the body copy, the eyebrow and the button border all at
   once; on #a04f25 it is 5.77:1. Still unmistakably terracotta, and it is the
   one place the accent takes a whole surface. */
.cta { background: var(--accent-deep); padding-block: clamp(3.25rem, 6.5vw, 5.5rem); text-align: center; }
.cta h2, .cta .display { color: #fff; }
.cta p, .cta .lead { color: #fff; margin-inline: auto; }
.cta .eyebrow { color: #fff; justify-content: center; }
.cta .eyebrow::before { background: rgba(255,255,255,.6); }
.cta .btn--primary, .cta .btn--dark { background: var(--ink); border-color: var(--ink); color: #fff; }
.cta .btn--primary:hover, .cta .btn--dark:hover { background: #fff; border-color: #fff; color: var(--ink); }
.cta .btn--outline, .cta .btn--ghost-dark { color: #fff; border-color: rgba(255,255,255,.8); }
.cta .btn--outline:hover, .cta .btn--ghost-dark:hover { border-color: #fff; background: rgba(255,255,255,.14); }

.claim-strip {
  margin-top: var(--s5);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  align-items: center;
  justify-content: space-between;
  padding: clamp(1.4rem, 3vw, 2.1rem);
  background: var(--spruce);
  color: var(--on-ink);
  border-radius: var(--radius);
}
.claim-strip h2 { color: var(--on-ink); font-size: 1.35rem; }
.claim-strip p { color: var(--on-ink-2); font-size: .92rem; margin-top: .4rem; max-width: 52ch; }

/* ── 10. media, forms, tables ─────────────────────────────────────────── */

.img { border-radius: var(--radius); }

.img-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  padding: clamp(1.25rem, 3vw, 2.25rem);
  text-align: center;
  border: 1px dashed var(--border-2);
  border-radius: var(--radius);
  background:
    repeating-linear-gradient(-45deg, transparent 0 10px,
      color-mix(in srgb, var(--border) 45%, transparent) 10px 11px),
    var(--surface-2);
  color: var(--ink-3);
}
.img-placeholder__frame { color: var(--accent); opacity: .85; }
.img-placeholder__body { max-width: 34ch; }
.img-placeholder__tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: .63rem;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--accent-fg);
  background: var(--accent-bg);
  border: 1px solid var(--accent-border);
  border-radius: 999px;
  padding: .12rem .55rem;
  margin-bottom: .5rem;
}
.img-placeholder__want { font-size: .92rem; font-weight: 550; color: var(--ink-2); margin-bottom: .35rem; }
.img-placeholder__dir { font-size: .84rem; margin-bottom: .35rem; }
.img-placeholder__meta {
  font-family: var(--font-mono);
  font-size: .67rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.section--spruce .img-placeholder, .band .img-placeholder {
  background: rgba(255,255,255,.03); border-color: var(--on-ink-border); color: var(--on-ink-2);
}
.section--spruce .img-placeholder__want, .band .img-placeholder__want { color: var(--on-ink); }

.portrait {
  position: relative;
  display: grid;
  place-items: center;
  width: 9rem;
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: hidden;
  background: var(--accent-bg);
  border: 1px solid var(--accent-border);
  object-fit: cover;
}
.portrait--sm { width: 3.4rem; }   /* bylines, where it sits beside text */
.portrait--md { width: 9rem; }     /* cards. Was 4.5rem: a face, not a bullet */
.portrait--lg { width: 14rem; }    /* team and profile pages */
.portrait__initials {
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: 600;
  color: var(--accent-fg);
  font-variation-settings: 'opsz' 32, 'SOFT' 40, 'WONK' 1;
}
.portrait--lg .portrait__initials { font-size: 3.2rem; }
.portrait--sm .portrait__initials { font-size: 1.05rem; }
/* the badge only fits, and only reads, at the large size */
.portrait--sm .portrait__badge, .portrait--md .portrait__badge { display: none; }
.portrait__badge {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  font-family: var(--font-mono);
  font-size: .5rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  background: rgba(23,26,31,.62);
  color: #fff;
  padding: .1rem 0;
}
.section--spruce .portrait, .band .portrait { background: rgba(201,104,58,.18); border-color: var(--on-ink-border); }
.section--spruce .portrait__initials, .band .portrait__initials { color: var(--accent); }

.field { display: grid; gap: .4rem; }
.field__label, .filters label {
  font-family: var(--font-mono);
  font-size: .69rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-3);
}
input[type="text"], input[type="email"], input[type="search"], select, textarea {
  width: 100%;
  padding: .75rem .95rem;
  font-size: .95rem;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-sm);
  transition: border-color var(--t), box-shadow var(--t);
}
input::placeholder { color: var(--ink-4); }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-bg);
}
.input--mono, .verify-form input { font-family: var(--font-mono); letter-spacing: .06em; }

.filters { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: end; }
.filters__field { display: grid; gap: .4rem; flex: 0 0 auto; }
.filters__field--grow { flex: 1 1 15rem; }

/* Seven controls do not belong on one wrapping flex line: they end up ragged
   and the search box gets squeezed. A grid keeps them aligned and lets the
   search field span the top row on its own. */
.filters--grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
  gap: var(--s2) var(--s3);
  align-items: end;
  padding: var(--s3);
  background: var(--surface-2);
  border: var(--rule);
  border-radius: var(--radius);
  margin-bottom: var(--s4);
}
.filters--grid .filters__field { display: grid; gap: .35rem; min-width: 0; }
.filters--grid .filters__field--grow { grid-column: 1 / -1; }
@media (min-width: 900px) {
  .filters--grid .filters__field--grow { grid-column: span 2; }
}
.filters__actions {
  display: flex;
  align-items: center;
  gap: var(--s2);
  min-width: 0;
}

/* the cohort year reads as data rather than as a label */
.tag--year {
  background: var(--surface);
  border-color: var(--border-2);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.htmx-indicator {
  opacity: 0;
  font-family: var(--font-mono);
  font-size: .71rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--accent-fg);
  transition: opacity var(--t);
}
.htmx-request .htmx-indicator, .htmx-indicator.htmx-request { opacity: 1; }
.results-count, .pagination__count {
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  margin-top: var(--s4);
  padding-top: var(--s3);
  border-top: var(--rule);
}

.spec { width: 100%; border-collapse: collapse; font-size: .95rem; }
.spec th, .spec td { text-align: left; padding: .9rem 0; border-top: var(--rule); vertical-align: baseline; }
.spec tr:last-child th, .spec tr:last-child td { border-bottom: var(--rule); }
.spec th {
  width: 12rem;
  padding-right: var(--s3);
  font-family: var(--font-mono);
  font-size: .69rem;
  font-weight: 500;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-3);
}
@media (max-width: 620px) {
  .spec th, .spec td { display: block; width: auto; }
  .spec td { border-top: 0; padding-top: 0; }
  .spec tr:last-child th { border-bottom: 0; }
}

.cohort-list { list-style: none; display: grid; gap: .6rem; }
.cohort-list li {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  align-items: center;
  padding: .9rem 1.1rem;
  border: var(--rule);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
.cohort-list__term { font-weight: 600; }
.cohort-list__date { font-family: var(--font-mono); font-size: .74rem; letter-spacing: .06em; color: var(--ink-4); }

.scale-strip { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr)); }
.scale-strip__step {
  padding: var(--s3);
  text-align: center;
  border: var(--rule);
  border-radius: var(--radius);
  background: var(--surface);
  transition: border-color var(--t), transform var(--t);
}
.scale-strip__step:hover { border-color: var(--accent-border); transform: translateY(-2px); }
.scale-strip__step span {
  display: block;
  font-family: var(--font-display);
  font-size: 1.6rem;
  font-weight: 600;
  letter-spacing: -.028em;
  color: var(--accent-fg);
  font-variation-settings: 'opsz' 48, 'SOFT' 25, 'WONK' 1;
}
.scale-strip__step small { font-family: var(--font-mono); font-size: .65rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-4); }

.press-strip { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s3) clamp(1.5rem, 4vw, 2.75rem); }
.press-strip__item {
  font-family: var(--font-mono);
  font-size: .79rem;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-4);
  transition: color var(--t);
}
.press-strip__item:hover { color: var(--accent-fg); }

.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  list-style: none;
  font-family: var(--font-mono);
  font-size: .71rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.breadcrumb li + li::before { content: "/"; margin-right: .5rem; opacity: .6; }
.breadcrumb a { color: var(--ink-3); transition: color var(--t); }
.breadcrumb a:hover { color: var(--accent-fg); }
.breadcrumb [aria-current="page"] { color: var(--accent-fg); }
.section--spruce .breadcrumb,
.page-hero--deep .breadcrumb,
.band .breadcrumb { color: var(--on-ink-2); }
.section--spruce .breadcrumb a, .page-hero--deep .breadcrumb a, .band .breadcrumb a { color: var(--on-ink-2); }
.page-hero--deep .breadcrumb [aria-current="page"] { color: var(--accent); }

/* ── 11. heroes ───────────────────────────────────────────────────────── */

.page-hero {
  position: relative;
  padding-block: clamp(2.5rem, 5.5vw, 4.25rem) clamp(1.75rem, 3.5vw, 2.75rem);
  border-bottom: var(--rule);
  overflow: hidden;
}
.page-hero__inner { position: relative; z-index: 1; }
.page-hero h1 { margin-top: var(--s3); }
.page-hero .lead { margin-top: var(--s3); max-width: 52ch; }
.page-hero .breadcrumb { margin-bottom: var(--s3); }
.page-hero--short { padding-block: clamp(2rem, 4vw, 3rem) clamp(1.5rem, 3vw, 2.25rem); }
.page-hero--deep { background: var(--spruce); color: var(--on-ink); border-bottom: 0; }
.page-hero--deep h1 { color: var(--on-ink); }
.page-hero--deep .lead { color: var(--on-ink-2); }
.page-hero--deep .eyebrow, .page-hero--deep .mono-label { color: var(--on-ink-2); }

.hero { position: relative; overflow: hidden; }
.hero__inner {
  position: relative;
  z-index: 1;
  padding-block: clamp(3rem, 8vw, 6rem) clamp(2.5rem, 5.5vw, 4rem);
}
.hero .display { max-width: 18ch; margin-top: var(--s4); }
.hero__lead { margin-top: var(--s4); font-size: clamp(1.1rem, 1.6vw, 1.3rem); line-height: 1.55; color: var(--ink-2); max-width: 50ch; }
.hero .btn-group { margin-top: var(--s4); }

/* The braces from the logo, set as type rather than as an image. An <img> of the
   full lockup read as a stray watermark because the wordmark stayed legible;
   Fraunces braces at this scale are the mark's shape without its text. */
.hero__brace {
  position: absolute;
  z-index: 0;
  top: 50%;
  right: calc(-.5 * var(--gutter));
  transform: translateY(-50%);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(18rem, 42vw, 40rem);
  line-height: .78;
  letter-spacing: -.06em;
  color: var(--ink);
  opacity: .045;
  pointer-events: none;
  user-select: none;
  white-space: nowrap;
  animation: drift 16s ease-in-out infinite;
}
@keyframes drift {
  0%, 100% { transform: translateY(-50%) rotate(0deg); }
  50% { transform: translateY(-52%) rotate(-1.2deg); }
}
@media (max-width: 900px) { .hero__brace { display: none; } }

/* ── 12. credential document ──────────────────────────────────────────── */

.verify-form { display: flex; flex-wrap: wrap; gap: var(--s2); }
.verify-form input { flex: 1 1 16rem; padding: .9rem 1.1rem; }

.credential {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 3.5vw, 2.4rem);
  box-shadow: var(--shadow);
}
/* perforated rules: it should read as a document you could print */
.credential::before, .credential::after {
  content: "";
  position: absolute;
  inset-inline: clamp(1.5rem, 3.5vw, 2.4rem);
  height: 2px;
  background: repeating-linear-gradient(90deg, var(--accent) 0 6px, transparent 6px 12px);
  opacity: .5;
}
.credential::before { top: 0; }
.credential::after { bottom: 0; }

.credential__verdict {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding-bottom: var(--s3);
  border-bottom: var(--rule);
}
.credential__verdict h2 { font-size: 1.45rem; margin-bottom: .1rem; }
.credential__verdict p { font-size: .9rem; color: var(--ink-3); }
.credential__seal {
  flex: none;
  display: grid;
  place-items: center;
  width: 3.1rem; height: 3.1rem;
  border-radius: 50%;
}
/* mint earns its place here: semantic success, not decoration */
.credential__seal--valid { background: var(--brand-bg); border: 1px solid var(--brand-border); color: var(--brand-fg); }
.credential__seal--invalid { background: var(--error-bg); border: 1px solid var(--error); color: var(--error-fg); }
.credential .spec tr:last-child th, .credential .spec tr:last-child td { border-bottom: 0; }

.verdict { display: flex; gap: var(--s3); align-items: center; padding: var(--s3); border: 1px solid; border-radius: var(--radius); }
.verdict--valid { border-color: var(--brand-border); background: var(--brand-bg); color: var(--brand-fg); }
.verdict--revoked { border-color: var(--error); background: var(--error-bg); color: var(--error-fg); }
.verdict--unknown { border-color: var(--border-2); background: var(--surface-2); color: var(--ink-3); }
.verdict__mark { flex: none; display: grid; place-items: center; width: 3.1rem; height: 3.1rem; border-radius: 50%; background: currentColor; }
.verdict__mark > * { color: var(--surface); }
.verdict__title { font-family: var(--font-display); font-size: 1.3rem; font-weight: 600; letter-spacing: -.018em; font-variation-settings: 'opsz' 48, 'SOFT' 40, 'WONK' 1; }
.verdict__sub { font-size: .9rem; opacity: .85; margin-top: .1rem; }
.verdict__detail { overflow: hidden; border: 1px solid var(--border-2); border-radius: var(--radius); background: var(--surface); }
.verdict__detail > div { display: flex; flex-wrap: wrap; gap: .5rem var(--s3); padding: .95rem 1.25rem; border-bottom: var(--rule); }
.verdict__detail > div:last-child { border-bottom: 0; }
.verdict__detail dt {
  flex: 0 0 9.5rem;
  font-family: var(--font-mono);
  font-size: .67rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-top: .2em;
}
.verdict__detail dd { flex: 1 1 13rem; }
@media (max-width: 620px) { .verdict__detail dt { flex: 1 1 100%; } }

.tick { stroke-dasharray: 40; stroke-dashoffset: 40; animation: tick .6s .2s ease forwards; }
@keyframes tick { to { stroke-dashoffset: 0; } }

/* ── 13. footer ───────────────────────────────────────────────────────────
   Light, matching Poseidon's: --surface with a top rule rather than a dark slab.
   The site now ends on paper instead of on a block of colour, which also stops
   the page from having three heavy dark surfaces in a row. */

.site-footer {
  background: var(--surface);
  border-top: var(--rule);
  color: var(--ink-3);
  padding-block: clamp(2.75rem, 5vw, 4rem) var(--s4);
}
.footer__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) repeat(3, minmax(0, 1fr));
  gap: clamp(1.75rem, 4vw, 3.5rem);
  padding-bottom: clamp(2rem, 4vw, 2.75rem);
  border-bottom: var(--rule);
}
@media (max-width: 900px) { .footer__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .footer__grid { grid-template-columns: 1fr; gap: var(--s4); } }

.footer__tagline { margin-top: var(--s3); font-size: .92rem; line-height: 1.6; color: var(--ink-3); }

/* The one inbound route that is not a form. Sits on the dark footer ground, so
   it takes the same treatment as .footer__nav-list links rather than the body
   link colour, which fails contrast here. */
.footer__contact {
  margin-top: var(--s3);
  font-family: var(--font-mono);
  font-size: .78rem;
  letter-spacing: .04em;
  color: var(--ink-3);
}
.footer__contact a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--border-2);
  padding-bottom: 1px;
}
.footer__contact a:hover { border-bottom-color: var(--ink); }
.footer__heading {
  display: block;
  font-family: var(--font-mono);
  font-size: .67rem;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-4);
  margin-bottom: var(--s3);
}
.footer__nav-list { list-style: none; display: grid; gap: .55rem; }
.footer__nav-list a {
  display: inline-block;
  font-size: .92rem;
  color: var(--ink-2);
  transition: color var(--t), transform var(--t);
}
.footer__nav-list a:hover { color: var(--accent-fg); transform: translateX(3px); }
.footer__social { margin-top: var(--s3); }
.footer__signup { margin-top: var(--s4); }
.footer__signup-row { display: flex; gap: .5rem; margin-top: .6rem; }

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem var(--s3);
  justify-content: space-between;
  align-items: center;
  padding-top: var(--s3);
  font-size: .82rem;
  color: var(--ink-4);
}
.footer__bottom a { color: var(--ink-3); transition: color var(--t); }
.footer__bottom a:hover { color: var(--accent-fg); }
@media (max-width: 560px) { .footer__bottom { justify-content: center; text-align: center; } }

/* ── 14. motion ───────────────────────────────────────────────────────────
   Everything here is CSS driven by a class that JS adds. There is no animation
   library. The hard rule: nothing may need JS to become READABLE. `no-js` is on
   <html> in the markup and removed on motion.js's first line, and every hiding
   rule below is cancelled while it is present. A script failure costs polish,
   never content. */

.reveal { opacity: 0; transform: translateY(20px); }
.is-revealed { opacity: 1; transform: none; transition: opacity var(--t-slow), transform var(--t-slow); }

/* hero headline: words rise out of their own mask, staggered */
/* The mask that makes the word rise also clips it horizontally, and an italic
   glyph overhangs its own advance width, so the last letter of an italic word
   was being sliced down its right edge. Padding gives the glyph room inside the
   clip box; the matching negative margin means layout is unchanged. */
.rise {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  padding-inline: .16em;
  margin-inline: -.16em;
}
.rise > span {
  display: inline-block;
  transform: translateY(105%);
  transition: transform .95s cubic-bezier(.16,1,.3,1) calc(.07s * var(--i, 0));
}
.is-risen .rise > span, html.no-js .rise > span, html.no-motion .rise > span { transform: none; }

/* a rule that draws itself across */
.draw { transform: scaleX(0); transform-origin: left; }
.is-revealed.draw, .is-revealed .draw { transform: scaleX(1); transition: transform .9s cubic-bezier(.16,1,.3,1); }
html.no-js .draw, html.no-motion .draw { transform: scaleX(1); }

html.no-js .reveal { opacity: 1 !important; transform: none !important; }
html.no-motion .reveal { opacity: 1 !important; transform: none !important; }
html.no-motion .hero__brace { animation: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .reveal { opacity: 1; transform: none; }
  .rise > span { transform: none; }
  .draw { transform: scaleX(1); }
  .hero__brace { animation: none; }
  .card--link:hover, .pillar:hover, .person-card:hover, .scale-strip__step:hover { transform: none; }
}

/* ── 15. interior components ──────────────────────────────────────────────
   Older class names, restyled into this system rather than renamed so every
   page picks up the design without a template rewrite. Verified against the
   templates by scripts/audit_classes.py. */

.btn--ghost-dark { background: transparent; color: var(--ink); border-color: rgba(23,26,31,.28); }
.btn--ghost-dark:hover { border-color: var(--ink); background: rgba(23,26,31,.06); }

.track-split { display: grid; gap: clamp(1rem, 2vw, 1.5rem); grid-template-columns: repeat(auto-fit, minmax(min(100%, 21rem), 1fr)); }
.track {
  padding: clamp(1.5rem, 3vw, 2.25rem);
  background: var(--surface);
  border: var(--rule);
  border-radius: var(--radius);
  transition: border-color var(--t), transform var(--t), box-shadow var(--t);
}
.track:hover { border-color: var(--accent-border); transform: translateY(-3px); box-shadow: var(--shadow); }
.track h2, .track h3 { margin: var(--s2) 0 .7rem; font-size: clamp(1.55rem, 2.6vw, 2.05rem); }
.track p { color: var(--ink-3); font-size: .97rem; }
.track .btn { margin-top: var(--s3); }
.track__tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: .65rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent-fg);
  background: var(--accent-bg);
  border: 1px solid var(--accent-border);
  border-radius: 999px;
  padding: .18rem .6rem;
}
.section--spruce .track, .band .track { background: rgba(255,255,255,.04); border-color: var(--on-ink-border); }
.section--spruce .track p, .band .track p { color: var(--on-ink-2); }
.section--spruce .track__tag, .band .track__tag { background: rgba(75,188,160,.16); border-color: var(--on-ink-border); color: var(--brand-on-spruce); }

.course-card {
  position: relative;
  padding: clamp(1.5rem, 3vw, 2.1rem);
  background: var(--surface);
  border: var(--rule);
  border-radius: var(--radius);
  transition: border-color var(--t), transform var(--t), box-shadow var(--t);
}
.course-card:hover { border-color: var(--accent-border); transform: translateY(-3px); box-shadow: var(--shadow); }
.course-card--flagship { border-color: var(--accent-border); }
.course-card__flag {
  position: absolute;
  top: -.7rem;
  left: clamp(1.5rem, 3vw, 2.1rem);
  font-family: var(--font-mono);
  font-size: .61rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  background: var(--accent-deep);
  color: #fff;
  padding: .2rem .6rem;
  border-radius: 999px;
}
.course-card h3 { margin-top: .3rem; font-size: clamp(1.28rem, 2.2vw, 1.6rem); }
.course-card__tagline { color: var(--ink-3); font-size: .95rem; margin-top: .5rem; }
.course-card__meta { margin-top: var(--s3); display: grid; }
.course-card__meta > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s3);
  padding-block: .6rem;
  border-top: var(--rule);
}
.course-card__meta dt {
  font-family: var(--font-mono);
  font-size: .66rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.course-card__meta dd { font-size: .92rem; font-weight: 550; text-align: right; }
.section--spruce .course-card, .band .course-card { background: rgba(255,255,255,.04); border-color: var(--on-ink-border); }
.section--spruce .course-card--flagship, .band .course-card--flagship { border-color: var(--accent); }
.section--spruce .course-card__tagline, .band .course-card__tagline { color: var(--on-ink-2); }
.section--spruce .course-card__meta > div, .band .course-card__meta > div { border-color: var(--on-ink-border); }
.section--spruce .course-card__meta dd, .band .course-card__meta dd { color: var(--on-ink); }

/* ── 15a. the blog ────────────────────────────────────────────────────────
   Deliberately a different register from the rest of the site. Marketing pages
   are built from bands and cards; a blog is a reading surface, so this is a
   single measured column, a serif body at a size you would actually read a
   thousand words in, and a lead article that gets real scale instead of being
   one card among equals. */

/* stream filter, set as tabs rather than a select */
.stream-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  padding-bottom: var(--s3);
  border-bottom: var(--rule);
}
.stream-tab {
  display: inline-flex;
  align-items: baseline;
  gap: .4rem;
  padding: .4rem .85rem;
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: .71rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-3);
  border: 1px solid transparent;
  transition: all var(--t);
}
.stream-tab:hover { color: var(--ink); background: var(--bg-2); }
.stream-tab.is-on {
  color: var(--brand-fg);
  background: var(--brand-bg);
  border-color: var(--brand-border);
}
.stream-tab__n { font-size: .64rem; opacity: .7; }

/* the lead article */
.post-lead {
  display: block;
  padding-block: clamp(1.75rem, 4vw, 3rem);
  border-bottom: var(--rule);
}
.post-lead__meta,
.post-card__meta,
.post-head__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem .85rem;
  font-family: var(--font-mono);
  font-size: .69rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.post-lead__stream, .post-card__stream, .post-head__stream { color: var(--brand-fg); }
.post-lead__title {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4.6vw, 3.4rem);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -.032em;
  font-variation-settings: 'opsz' 120, 'SOFT' 35, 'WONK' 1;
  margin: var(--s3) 0 var(--s2);
  max-width: 30ch;
  transition: color var(--t);
}
.post-lead:hover .post-lead__title { color: var(--brand-fg); }
.post-lead__excerpt {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 1.5vw, 1.22rem);
  font-weight: 400;
  line-height: 1.5;
  font-variation-settings: 'opsz' 24, 'SOFT' 50, 'WONK' 0;
  color: var(--ink-2);
  max-width: 58ch;
}

/* the rest, as a ruled list rather than a card grid */
.post-list { display: grid; }
.post-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 16rem);
  gap: clamp(1rem, 3vw, 3rem);
  align-items: start;
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
  border-bottom: var(--rule);
  transition: background var(--t);
}
.post-card:hover { background: var(--surface-2); }
.post-card__title {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2.2vw, 1.7rem);
  font-weight: 600;
  line-height: 1.14;
  letter-spacing: -.022em;
  font-variation-settings: 'opsz' 72, 'SOFT' 40, 'WONK' 1;
  margin: .7rem 0 .5rem;
  transition: color var(--t);
}
.post-card:hover .post-card__title { color: var(--brand-fg); }
.post-card__excerpt { color: var(--ink-3); font-size: .96rem; line-height: 1.55; max-width: 56ch; }
.post-card__aside {
  font-family: var(--font-mono);
  font-size: .69rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-4);
  text-align: right;
  padding-top: .9rem;
}
@media (max-width: 780px) {
  .post-card { grid-template-columns: 1fr; }
  .post-card__aside { text-align: left; padding-top: .6rem; }
}

/* ---- the post itself ---- */

.post-head { padding-block: clamp(2.5rem, 5vw, 4rem) clamp(1.5rem, 3vw, 2.25rem); }
.post-head h1 {
  font-size: clamp(2.2rem, 5vw, 3.6rem);
  margin: var(--s3) 0 var(--s3);
  max-width: 26ch;
}
.post-head__excerpt {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 1.8vw, 1.4rem);
  font-weight: 400;
  line-height: 1.45;
  font-variation-settings: 'opsz' 32, 'SOFT' 50, 'WONK' 0;
  color: var(--ink-2);
  max-width: 52ch;
}

/* A reading column. Serif body, because this is the one place on the site with
   a thousand words of continuous prose and Inter is not the face for that. */
.post-body {
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 14, 'SOFT' 50, 'WONK' 0;
  font-size: 1.16rem;
  line-height: 1.72;
  color: var(--ink);
  max-width: 40rem;
}
.post-body > * + * { margin-top: 1.15em; }
.post-body h2 {
  font-size: clamp(1.5rem, 2.6vw, 1.95rem);
  margin-top: 2.4em;
  margin-bottom: -.2em;
  letter-spacing: -.022em;
}
.post-body h3 { font-size: 1.28rem; margin-top: 2em; margin-bottom: -.3em; }
.post-body strong { font-weight: 700; }
.post-body em { font-style: italic; }
.post-body a {
  color: var(--brand-fg);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .18em;
  text-decoration-color: var(--brand-border);
}
.post-body a:hover { text-decoration-color: var(--brand-deep); }
.post-body ul, .post-body ol { padding-left: 1.4em; }
.post-body li + li { margin-top: .45em; }
.post-body blockquote {
  border-left: 2px solid var(--brand);
  padding-left: 1.2em;
  color: var(--ink-2);
  font-style: italic;
}
.post-body code {
  font-family: var(--font-mono);
  font-size: .88em;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: .1em .35em;
}
.post-body pre {
  background: var(--ink);
  color: var(--on-ink);
  padding: 1.1rem 1.25rem;
  border-radius: var(--radius);
  overflow-x: auto;
}
.post-body pre code { background: none; border: 0; color: inherit; font-size: .84em; }
.post-body hr { border: 0; border-top: var(--rule); margin-block: 2.2em; }

/* first paragraph gets a raised cap: a small signal that this is a reading page */
.post-body > p:first-child::first-letter {
  float: left;
  font-size: 3.4em;
  line-height: .82;
  padding-right: .07em;
  padding-top: .06em;
  font-weight: 600;
  color: var(--brand-fg);
  font-variation-settings: 'opsz' 144, 'SOFT' 30, 'WONK' 1;
}

.post-foot {
  max-width: 40rem;
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: var(--s4);
  border-top: var(--rule);
}

/* ── 15a2. the post page: sidebar, byline, sharing ────────────────────────
   Article plus a sticky rail. The rail is the second thing a reader wants once
   they are in a piece: who wrote it, how to send it to somebody, and what else
   is here. Below 1080px it stops being a rail and becomes ordinary sections
   after the article, in that order. */

.post-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 17.5rem);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
.post-main { min-width: 0; }
.post-aside {
  position: sticky;
  top: calc(var(--nav-h) + var(--s4));
  display: grid;
  gap: var(--s4);
}
@media (max-width: 1080px) {
  .post-layout { grid-template-columns: 1fr; }
  .post-aside { position: static; margin-top: clamp(2.5rem, 5vw, 3.5rem); }
}

.aside-h {
  font-family: var(--font-mono);
  font-size: .67rem;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-4);
  margin-bottom: var(--s3);
  padding-bottom: .6rem;
  border-bottom: var(--rule);
}

/* ---- byline ---- */

.byline {
  display: flex;
  align-items: center;
  gap: .85rem;
  margin-top: var(--s4);
  padding-top: var(--s3);
  border-top: var(--rule);
}
.byline__name { font-weight: 600; font-size: .97rem; }
.byline__role { font-size: .86rem; color: var(--ink-3); }
.byline__time {
  display: block;
  font-family: var(--font-mono);
  font-size: .69rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-4);
  margin-top: .2rem;
}

/* the author card in the rail */
.author-card {
  background: var(--surface);
  border: var(--rule);
  border-radius: var(--radius);
  padding: var(--s3);
}
.author-card__name {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -.014em;
  font-variation-settings: 'opsz' 32, 'SOFT' 40, 'WONK' 1;
  margin-top: .75rem;
}
.author-card__role { font-size: .85rem; color: var(--ink-3); margin-top: .1rem; }
.author-card__bio { font-size: .88rem; line-height: 1.55; color: var(--ink-2); margin-top: .7rem; }

/* ---- share ---- */

.share { display: grid; gap: .4rem; }
.share__btn {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .55rem .7rem;
  border-radius: var(--radius-sm);
  font-size: .89rem;
  font-weight: 500;
  color: var(--ink-2);
  border: 1px solid transparent;
  background: none;
  width: 100%;
  text-align: left;
  cursor: pointer;
  transition: background var(--t), color var(--t), border-color var(--t), transform var(--t);
}
.share__btn:hover {
  background: var(--surface);
  border-color: var(--border);
  color: var(--ink);
  transform: translateX(2px);
}
.share__btn svg { width: 1.05rem; height: 1.05rem; flex: none; }
/* each platform keeps its own colour on hover, which is the one place on the
   site where a colour outside the palette is allowed: they are trademarks */
.share__btn--linkedin:hover { color: #0a66c2; border-color: #0a66c2; }
.share__btn--x:hover { color: var(--ink); border-color: var(--ink); }
.share__btn--whatsapp:hover { color: #128c7e; border-color: #128c7e; }
.share__btn--facebook:hover { color: #1877f2; border-color: #1877f2; }
.share__btn--email:hover { color: var(--accent-fg); border-color: var(--accent-border); }
.share__btn--copy:hover { color: var(--brand-fg); border-color: var(--brand-border); }
.share__btn.is-copied { color: var(--brand-fg); border-color: var(--brand-border); background: var(--brand-bg); }

/* the same actions inline under the article, for anyone who read to the end */
.share--row { display: flex; flex-wrap: wrap; gap: .4rem; }
.share--row .share__btn { width: auto; padding-inline: .8rem; border-color: var(--border); }

/* ---- more stories in the rail ---- */

.aside-post {
  display: block;
  padding-block: .9rem;
  border-bottom: var(--rule);
}
.aside-post:first-of-type { border-top: var(--rule); }
.aside-post__stream, .aside-post__title, .aside-post__meta { display: block; }
.aside-post__stream {
  font-family: var(--font-mono);
  font-size: .63rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--brand-fg);
}
.aside-post__title {
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -.012em;
  font-variation-settings: 'opsz' 24, 'SOFT' 40, 'WONK' 1;
  margin-top: .3rem;
  transition: color var(--t);
}
.aside-post:hover .aside-post__title { color: var(--brand-fg); }
.aside-post__meta {
  font-family: var(--font-mono);
  font-size: .64rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-4);
  margin-top: .35rem;
}

/* ---- reading progress ----
   A hairline at the very top of the viewport. Purely decorative: it is written
   by JS and simply never appears if the script does not run. */
.read-bar {
  position: fixed;
  inset: 0 auto auto 0;
  height: 2px;
  width: 0;
  background: var(--accent);
  z-index: 150;
  transition: width .1s linear;
  pointer-events: none;
}

/* ── 15c. newsletter signup ──────────────────────────────────────────────
   A real block rather than a field in the footer. Two columns on a spruce
   ground so it reads as an invitation rather than as furniture. */

.signup {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 22rem);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: center;
  padding: clamp(1.75rem, 4vw, 2.75rem);
  background: var(--spruce);
  color: var(--on-ink);
  border-radius: var(--radius);
}
@media (max-width: 820px) { .signup { grid-template-columns: 1fr; } }
.signup .eyebrow { color: var(--on-ink-2); }
.signup .eyebrow::before { background: var(--brand-on-spruce); }
.signup__h {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.8vw, 2.1rem);
  font-weight: 600;
  letter-spacing: -.024em;
  line-height: 1.1;
  font-variation-settings: 'opsz' 72, 'SOFT' 40, 'WONK' 1;
  color: var(--on-ink);
  margin-top: var(--s3);
}
.signup__p { color: var(--on-ink-2); font-size: .97rem; margin-top: .7rem; max-width: 46ch; }
.signup__body, .signup__form { min-width: 0; }
.signup__row { display: flex; gap: .5rem; }
.signup__row input {
  background: rgba(255,255,255,.06);
  border-color: var(--on-ink-border);
  color: var(--on-ink);
}
.signup__row input::placeholder { color: #7d968d; }
.signup__row input:focus { border-color: var(--brand-on-spruce); box-shadow: 0 0 0 3px rgba(75,188,160,.2); }
.signup__row .btn--primary { background: var(--brand-on-spruce); color: #08382d; border-color: var(--brand-on-spruce); }
.signup__row .btn--primary:hover { background: var(--on-ink); border-color: var(--on-ink); color: var(--spruce); }
.signup__note {
  font-family: var(--font-mono);
  font-size: .67rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--on-ink-2);
  margin-top: .7rem;
}

/* ── 15d. founder feature and photo blocks ───────────────────────────────
   The founder had no presence on his own site. This gives him the scale the
   story deserves: a real portrait against the spruce band, at a size that says
   this is a person rather than an org chart entry. */

.founder {
  display: grid;
  grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
  gap: clamp(1.75rem, 5vw, 4rem);
  align-items: center;
}
@media (max-width: 860px) { .founder { grid-template-columns: 1fr; } }
.founder__photo {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: var(--radius);
  /* a quiet mint edge, so the portrait belongs to the brand rather than
     floating on the band */
  box-shadow: 0 0 0 1px var(--on-ink-border), 0 24px 48px -20px rgba(0,0,0,.55);
}
.founder__name {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 3.6vw, 2.7rem);
  font-weight: 600;
  letter-spacing: -.028em;
  line-height: 1.05;
  font-variation-settings: 'opsz' 96, 'SOFT' 40, 'WONK' 1;
  color: var(--on-ink);
}
.founder__role {
  font-family: var(--font-mono);
  font-size: .71rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--brand-on-spruce);
  margin-top: .7rem;
}
.founder__quote {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  line-height: 1.4;
  font-variation-settings: 'opsz' 48, 'SOFT' 50, 'WONK' 0;
  color: var(--on-ink);
  margin-top: var(--s4);
  padding-left: var(--s3);
  border-left: 2px solid var(--brand-on-spruce);
}

/* a photograph used as a full-bleed band */
.photo-band { position: relative; overflow: hidden; }
.photo-band img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-band--tall { aspect-ratio: 16/7; }
@media (max-width: 720px) { .photo-band--tall { aspect-ratio: 4/3; } }
.photo-caption {
  font-family: var(--font-mono);
  font-size: .67rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-4);
  margin-top: .7rem;
}

/* residents, grouped by cohort year */
.cohort-group + .cohort-group { margin-top: clamp(2rem, 4vw, 3rem); }
.cohort-year {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  font-family: var(--font-mono);
  font-size: .71rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--s3);
}
.cohort-year::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border);
}
.section--spruce .cohort-year::after, .band .cohort-year::after { background: var(--on-ink-border); }

/* a face grid, for the people whose photographs we have but whose stories are
   not ours to write */
.face-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 6.5rem), 1fr));
  gap: clamp(.75rem, 2vw, 1.25rem);
}
.face { text-align: center; }
.face img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 50%;
  transition: transform var(--t);
}
.face:hover img { transform: scale(1.04); }
.face__name {
  display: block;
  font-size: .82rem;
  font-weight: 550;
  margin-top: .55rem;
  color: var(--ink-2);
}
.section--spruce .face__name, .band .face__name { color: var(--on-ink-2); }

/* ── 15e. photographic heroes and bands ──────────────────────────────────
   A photograph behind type needs a colour layer, not an opacity fade: fading
   the image greys it and the type still lands on whatever is underneath.
   A spruce multiply keeps the picture readable AS a picture while giving the
   text a predictable ground. Measured: cream on the darkened band clears 9:1
   across the whole frame, including the brightest corner. */

.hero--photo {
  position: relative;
  background: var(--spruce);
  color: var(--on-ink);
  isolation: isolate;
}
.hero--photo .hero__media {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
}
.hero--photo .hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 38%;
}
/* two layers: a flat wash for legibility, and a gradient that deepens toward
   the type so the left column is always the safest part of the frame */
.hero--photo .hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(100deg, rgba(11,38,32,.94) 0%, rgba(11,38,32,.86) 42%, rgba(11,38,32,.62) 100%),
    rgba(16,49,42,.30);
}
.hero--photo .display, .hero--photo .hero__lead { color: var(--on-ink); }
.hero--photo .display em { color: var(--brand-on-spruce); }
.hero--photo .eyebrow { color: var(--on-ink-2); }
.hero--photo .eyebrow::before { background: var(--brand-on-spruce); }
.hero--photo .stat-band { border-color: var(--on-ink-border); }
.hero--photo .stat { border-color: var(--on-ink-border); }
.hero--photo .stat__number { color: var(--brand-on-spruce); }
.hero--photo .stat__label { color: var(--on-ink-2); }
.hero--photo .btn--primary { background: var(--brand-on-spruce); color: #08382d; border-color: var(--brand-on-spruce); }
.hero--photo .btn--primary:hover { background: var(--on-ink); border-color: var(--on-ink); color: var(--spruce); }
.hero--photo .btn--outline { color: var(--on-ink); border-color: rgba(255,255,255,.42); }
.hero--photo .btn--outline:hover { border-color: var(--on-ink); background: rgba(255,255,255,.1); }
.hero--photo .hero__brace { display: none; }

/* a photograph as a full width band, with the caption outside the frame so the
   credit is never burned into the picture */
.band {
  position: relative;
  overflow: hidden;
  background: var(--spruce);
}
.band__media { position: absolute; inset: 0; }
.band__media img { width: 100%; height: 100%; object-fit: cover; }
.band__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(11,38,32,.93) 0%, rgba(11,38,32,.78) 55%, rgba(11,38,32,.5) 100%);
}
.band__inner { position: relative; z-index: 1; padding-block: clamp(3rem, 7vw, 5.5rem); }
.band h1, .band h2, .band h3, .band h4, .band .statement { color: var(--on-ink); }
.band p { color: var(--on-ink-2); }
.band .eyebrow { color: var(--on-ink-2); }
.band .eyebrow::before { background: var(--brand-on-spruce); }

/* a plain captioned figure, used inline in a column */
.figure { margin: 0; }
.figure img { width: 100%; border-radius: var(--radius); display: block; }
.figure--wide img { aspect-ratio: 16/9; object-fit: cover; }

/* ── 15f. gallery ────────────────────────────────────────────────────────
   A masonry-ish grid that lets a few images be larger than the rest, because a
   uniform grid of equal thumbnails reads as a stock library and this is a
   record of actual work. No lightbox: the images are already the right size,
   and a lightbox is a dependency plus a focus trap to maintain. */

/* A row grid rather than aspect ratios. Mixing a 16/9 feature with a 4/3
   neighbour in the same row leaves holes under the shorter one; giving every
   item a row span against a fixed row height makes the spans line up, so the
   varied sizes read as deliberate instead of broken. */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
  grid-auto-rows: clamp(5.5rem, 8vw, 8rem);
  gap: clamp(.6rem, 1.4vw, 1rem);
  grid-auto-flow: dense;
}
.gallery__item {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--bg-2);
  grid-row: span 2;
}
.gallery__item--wide { grid-column: span 2; grid-row: span 3; }
.gallery__item--tall { grid-row: span 3; }
@media (max-width: 640px) {
  .gallery { grid-auto-rows: clamp(6rem, 22vw, 9rem); }
  .gallery__item--wide { grid-column: span 1; grid-row: span 2; }
  .gallery__item--tall { grid-row: span 2; }
}
.gallery__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .6s cubic-bezier(.16,1,.3,1);
}
.gallery__item:hover img { transform: scale(1.045); }
.gallery__cap {
  position: absolute;
  inset: auto 0 0 0;
  padding: 2.5rem .9rem .8rem;
  font-family: var(--font-mono);
  font-size: .67rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #fff;
  background: linear-gradient(transparent, rgba(11,38,32,.86));
  opacity: 0;
  transform: translateY(.4rem);
  transition: opacity var(--t), transform var(--t);
}
.gallery__item:hover .gallery__cap,
.gallery__item:focus-within .gallery__cap { opacity: 1; transform: none; }
/* touch devices have no hover, so the caption is always on */
@media (hover: none) {
  .gallery__cap { opacity: 1; transform: none; }
}

/* ── 15g. social links ───────────────────────────────────────────────────
   Icon only, because five wordmarks in a footer column is a wall of text and
   these five marks are universally recognised. Each carries an aria-label and a
   title, so neither a screen reader nor a hover is left guessing. */

.social { display: flex; flex-wrap: wrap; gap: .45rem; list-style: none; }
.social__link {
  display: grid;
  place-items: center;
  width: 2.35rem;
  height: 2.35rem;
  border: var(--rule);
  border-radius: var(--radius-sm);
  color: var(--ink-3);
  transition: color var(--t), border-color var(--t), background var(--t), transform var(--t);
}
.social__link svg { width: 1.05rem; height: 1.05rem; }
.social__link:hover {
  color: var(--accent-fg);
  border-color: var(--accent-border);
  background: var(--accent-bg);
  transform: translateY(-2px);
}
.section--spruce .social__link, .band .social__link {
  color: var(--on-ink-2); border-color: var(--on-ink-border);
}
.section--spruce .social__link:hover, .band .social__link:hover {
  color: var(--on-ink); border-color: var(--on-ink); background: rgba(255,255,255,.08);
}

/* ── 15b. muted text on the ink band ──────────────────────────────────────
   --ink-3 and --ink-4 are tuned for cream and white grounds. On the ink band
   they land at 3.1 to 3.6:1 and fail AA, and the per-component override table
   only ever covered some of them. One rule instead of twenty, so a component
   used on an ink band cannot be forgotten. --on-ink-2 measures 7.03:1 there. */

.section--spruce .card__meta,
.section--spruce .index-row__no,
.section--spruce .index-row__sub,
.section--spruce .course-card__meta dt,
.section--spruce .cohort-list__date,
.section--spruce .scale-strip__step small,
.section--spruce .agg__l,
.section--spruce .stat__label,
.section--spruce .press-strip__item,
.section--spruce .results-count,
.section--spruce .pagination__count,
.section--spruce .field__label,
.section--spruce .filters label,
.section--spruce .person-card__loc,
.section--spruce .muted,
.section--spruce .fineprint,
.section--spruce .img-placeholder__meta, .band .img-placeholder__meta { color: var(--on-ink-2); }

/* ── 16. print ────────────────────────────────────────────────────────── */


/* =========================================================================
   16. THE HISTORICAL RECORD  (/history, /history/{year}, /impact)

   A reading surface, not a marketing band. The year list should look like a
   ledger you can check, because that is the argument: these numbers predate
   this platform and each one carries a citation.
   ========================================================================= */

/* -- Citations under a stat band ---------------------------------------- */
/* The source is body copy, not a footnote. A figure whose source you have to
   hunt for is an assertion wearing a number's clothes. */
.figure-notes {
  margin-top: var(--s4);
  display: grid;
  gap: .85rem;
  max-width: 68ch;
}
.figure-notes li {
  display: grid;
  grid-template-columns: minmax(0, 14rem) 1fr;
  gap: .4rem 1.6rem;
  padding-top: .85rem;
  border-top: var(--rule);
}
.figure-notes__label {
  font-family: var(--font-mono);
  font-size: .7rem;
  font-weight: 500;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-4);
  padding-top: .2rem;
}
.figure-notes__body { color: var(--ink-2); font-size: .95rem; line-height: 1.6; }
.figure-notes__body .fineprint { display: block; margin-top: .3rem; }
@media (max-width: 640px) {
  .figure-notes li { grid-template-columns: 1fr; gap: .25rem; }
}

/* -- The year ledger ----------------------------------------------------- */
.year-row + .year-row { border-top: var(--rule); }
.year-row__link {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: clamp(1rem, 3vw, 2.4rem);
  align-items: start;
  padding: clamp(1.5rem, 3vw, 2.2rem) 0;
  text-decoration: none;
  color: inherit;
}
.year-row__link:hover .year-row__headline { color: var(--accent-fg); }
.year-row__link:hover .year-row__arrow { transform: translateX(4px); }

.year-row__year {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 4vw, 2.6rem);
  font-weight: 600;
  font-variation-settings: 'opsz' 40, 'SOFT' 40, 'WONK' 1;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.year-row__body { display: grid; gap: .5rem; }
.year-row__headline {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2.2vw, 1.4rem);
  font-weight: 600;
  letter-spacing: -.012em;
  font-variation-settings: 'opsz' 32, 'SOFT' 40, 'WONK' 1;
  color: var(--ink);
  transition: color .18s ease;
}
.year-row__summary { color: var(--ink-2); font-size: .97rem; line-height: 1.6; max-width: 58ch; }

.year-row__figures {
  margin-top: .5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 1.6rem;
}
.year-figure { display: grid; gap: .1rem; }
.year-figure__n {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 600;
  font-variation-settings: 'opsz' 28, 'SOFT' 40, 'WONK' 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.year-figure__l {
  font-family: var(--font-mono);
  font-size: .65rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-4);
}

.year-row__arrow {
  color: var(--ink-4);
  font-size: 1.1rem;
  padding-top: .35rem;
  transition: transform .18s ease;
}

@media (max-width: 640px) {
  .year-row__link { grid-template-columns: 1fr; gap: .6rem; }
  .year-row__arrow { display: none; }
}


/* =========================================================================
   17. JOURNEY AND STORIES

   The journey is a vertical ledger of one person's whole relationship with the
   organisation. It is deliberately quiet: the argument is made by the rows
   existing at all, not by decoration.
   ========================================================================= */

.journey {
  margin-top: var(--s4);
  display: grid;
  gap: 0;
  position: relative;
}
.journey__item {
  display: grid;
  grid-template-columns: 4.5rem 1.25rem 1fr;
  gap: 0 1rem;
  align-items: start;
  padding: 1rem 0;
  border-top: var(--rule);
}
.journey__item:last-child { border-bottom: var(--rule); }

.journey__year {
  font-family: var(--font-mono);
  font-size: .82rem;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  padding-top: .12rem;
}

/* the spine: a dot per row, joined by a hairline through the column */
.journey__marker {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 1.4rem;
}
.journey__marker::before {
  content: "";
  position: absolute;
  left: 50%;
  top: .45rem;
  width: 7px;
  height: 7px;
  margin-left: -3.5px;
  border-radius: 50%;
  background: var(--ink-4);
}
.journey__marker::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 1.1rem;
  bottom: -1.4rem;
  width: 1px;
  margin-left: -.5px;
  background: var(--rule-color, rgba(23, 26, 31, .12));
}
.journey__item:last-child .journey__marker::after { display: none; }

/* Each kind gets its own dot colour. Achievements are the loud one, because
   they are the thing worth noticing on a profile. */
.journey__item--achievement .journey__marker::before { background: var(--accent); }
.journey__item--role .journey__marker::before { background: var(--brand-deep); }
.journey__item--club .journey__marker::before { background: var(--brand); }

.journey__body { display: grid; gap: .18rem; }
.journey__kind {
  font-family: var(--font-mono);
  font-size: .62rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.journey__title { font-weight: 500; color: var(--ink); }
.journey__detail { font-size: .93rem; color: var(--ink-2); }
.journey__status {
  justify-self: start;
  font-family: var(--font-mono);
  font-size: .62rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent-fg);
  background: var(--accent-bg);
  border: 1px solid var(--accent-border);
  border-radius: 3px;
  padding: .1rem .4rem;
  margin-top: .15rem;
}

@media (max-width: 560px) {
  .journey__item { grid-template-columns: 3.2rem 1rem 1fr; }
}

/* -- Stories --------------------------------------------------------------- */
.chip-row { display: flex; flex-wrap: wrap; gap: .5rem; }
.chip {
  display: inline-block;
  padding: .38rem .8rem;
  border: var(--rule);
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-2);
  text-decoration: none;
  background: var(--surface);
}
.chip:hover { border-color: var(--ink-3); color: var(--ink); }
.chip--on {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bg);
}

.story-list { display: grid; gap: 0; }
.story {
  display: grid;
  grid-template-columns: minmax(0, 15rem) 1fr;
  gap: 1rem 2rem;
  align-items: start;
  padding: clamp(1.4rem, 3vw, 2rem) 0;
  border-top: var(--rule);
}
.story:last-child { border-bottom: var(--rule); }

.story__who {
  display: flex;
  align-items: center;
  gap: .8rem;
  text-decoration: none;
  color: inherit;
}
.story__who:hover .story__name { color: var(--accent-fg); }
.story__name { display: block; font-weight: 600; color: var(--ink); transition: color .18s ease; }
.story__cohort {
  display: block;
  font-family: var(--font-mono);
  font-size: .64rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-4);
}

.story__body { display: grid; gap: .4rem; }
.story__title {
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 2vw, 1.3rem);
  font-weight: 600;
  letter-spacing: -.01em;
  font-variation-settings: 'opsz' 30, 'SOFT' 40, 'WONK' 1;
  color: var(--ink);
}
.story__detail { color: var(--ink-2); font-size: .97rem; line-height: 1.6; max-width: 58ch; }
.story__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .7rem;
  margin-top: .2rem;
  font-family: var(--font-mono);
  font-size: .7rem;
  color: var(--ink-4);
}
.story__year { font-variant-numeric: tabular-nums; }

@media (max-width: 700px) {
  .story { grid-template-columns: 1fr; gap: .8rem; }
}


/* =========================================================================
   18. PARTNER WALL

   Logos where we hold the file, set wordmarks where we do not. The wordmark is
   a designed state rather than a gap: an empty box reads as neglect, a set name
   reads as a choice.
   ========================================================================= */

.partner-wall {
  margin-top: var(--s4);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0;
}
.partner-card {
  background: var(--bg);
  border: var(--rule);
  /* collapse the shared edges so it still reads as one wall */
  margin: 0 -1px -1px 0;
}
.partner-card__link {
  display: grid;
  gap: .5rem;
  height: 100%;
  padding: clamp(1.4rem, 3vw, 2rem);
  text-decoration: none;
  color: inherit;
  transition: background .18s ease;
}
.partner-card__link:hover { background: var(--surface-2); }
.partner-card > .partner-card__mark { display: block; padding: clamp(1.4rem, 3vw, 2rem); }

.partner-card__mark {
  display: flex;
  align-items: center;
  min-height: 3.2rem;
}
.partner-card__mark img {
  max-width: 100%;
  max-height: 3.2rem;
  width: auto;
  height: auto;
  object-fit: contain;
}
.partner-card__wordmark {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 2vw, 1.25rem);
  font-weight: 600;
  letter-spacing: -.015em;
  font-variation-settings: 'opsz' 30, 'SOFT' 40, 'WONK' 1;
  color: var(--ink);
  line-height: 1.2;
}
.partner-card__name {
  font-size: .9rem;
  font-weight: 500;
  color: var(--ink);
}
.partner-card__rel {
  font-size: .88rem;
  line-height: 1.5;
  color: var(--ink-3);
}


/* -- Logo download, on the press kit -------------------------------------
   The mark shown at size rather than described. A journalist should see what
   they are getting before they download it. Checkerboard behind it so the
   transparent background is visible as transparency. */
.logo-download {
  margin-top: var(--s4);
  display: grid;
  grid-template-columns: minmax(0, 18rem) 1fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
  padding: clamp(1.5rem, 4vw, 2.5rem);
  border: var(--rule);
  border-radius: var(--radius);
  background: var(--surface);
}
.logo-download__preview {
  display: grid;
  place-items: center;
  padding: 2rem;
  border-radius: var(--radius);
  background-color: var(--bg);
  background-image:
    linear-gradient(45deg, var(--bg-2) 25%, transparent 25%),
    linear-gradient(-45deg, var(--bg-2) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--bg-2) 75%),
    linear-gradient(-45deg, transparent 75%, var(--bg-2) 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}
.logo-download__preview img { width: 100%; max-width: 11rem; height: auto; }
.logo-download__body h3 {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2.2vw, 1.4rem);
  font-weight: 600;
  font-variation-settings: 'opsz' 32, 'SOFT' 40, 'WONK' 1;
  color: var(--ink);
}
.logo-download__body p { color: var(--ink-2); margin-top: .4rem; }

@media (max-width: 640px) {
  .logo-download { grid-template-columns: 1fr; }
}


/* -- "As seen in" strip ---------------------------------------------------
   A band that does not grow. Six outlets or sixty, this stays one row of
   marks; the archive lives in the press room. A home page that lists every
   article pushes everything else down the moment coverage starts working. */
.seen-in {
  margin-top: var(--s4);
  display: grid;
  /* auto-fit rather than a fixed column count: six outlets sit on one row, and
     a seventh reflows instead of orphaning the last one onto a line of its own,
     which is what a flex-basis did. */
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
  border-top: var(--rule);
  border-bottom: var(--rule);
}
.seen-in__item { border-right: var(--rule); }
.seen-in__item:last-child { border-right: 0; }
.seen-in__link {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 5.5rem;
  padding: 1.2rem 1rem;
  text-decoration: none;
  transition: background .18s ease;
}
.seen-in__link:hover { background: var(--surface-2); }
.seen-in__link img { max-height: 2.4rem; max-width: 100%; width: auto; object-fit: contain; }
.seen-in__name {
  font-family: var(--font-display);
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: -.01em;
  font-variation-settings: 'opsz' 28, 'SOFT' 40, 'WONK' 1;
  color: var(--ink-2);
  text-align: center;
  line-height: 1.25;
  transition: color .18s ease;
}
.seen-in__link:hover .seen-in__name { color: var(--ink); }
@media (max-width: 560px) {
  .seen-in__item { flex: 1 1 50%; border-bottom: var(--rule); }
  .seen-in__link { min-height: 4.4rem; }
}

/* -- Coverage archive, grouped by year ------------------------------------ */
.coverage-year { margin-top: var(--s4); }
.coverage-year__label {
  font-family: var(--font-mono);
  font-size: .7rem;
  font-weight: 500;
  letter-spacing: .16em;
  color: var(--ink-4);
  padding-bottom: .5rem;
}

/* -- Partner page head ----------------------------------------------------- */
.partner-head {
  margin-top: 1.5rem;
  display: grid;
  grid-template-columns: minmax(0, 14rem) 1fr;
  gap: clamp(1.5rem, 4vw, 2.5rem);
  align-items: center;
}
.partner-head__mark {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 7rem;
  padding: 1.5rem;
  border: var(--rule);
  border-radius: var(--radius);
  background: var(--surface);
  text-align: center;
}
.partner-head__mark img { max-width: 100%; max-height: 4.5rem; width: auto; object-fit: contain; }
@media (max-width: 640px) {
  .partner-head { grid-template-columns: 1fr; }
}

@media print {
  .site-header, .site-footer, .skip-link, .claim-strip, .verify-form { display: none; }
  body { background: #fff; color: #000; }
  .credential, .verdict__detail { border: 1px solid #000; box-shadow: none; }
}
