/* ---------------------------------------------------------------------------
   Typefaces. Self-hosted because the CSP is default-src 'self' and no CDN
   font can load. Fallbacks are metric-matched so swapping in causes no shift.
   --------------------------------------------------------------------------- */
/* Redaction, by MCKL, drawn for Titus Kaphar and Reginald Dwayne Betts' show at
   MoMA PS1. It is cut in grades that simulate how type degrades as ink spreads
   on cheap stock; the family ships everything from grade 10 to grade 100, and
   this is the base cut, the one before any degradation is applied. A face built
   to be read off a poor-quality public record is the right voice for a
   portfolio assembled out of HMDA, EPA, EIA and NTSB filings, and it is not a
   face anyone reaches for by default. SIL OFL, copyright 2019 MCKL Inc. */
@font-face {
  font-family: "Redaction";
  src: url("../fonts/redaction-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Public Sans is the typeface of the US Web Design System, which is to say the
   face the federal data on this site is already published in. Choosing it is a
   claim about where the evidence came from rather than a taste preference.
   SIL OFL, forked from Libre Franklin. */
@font-face {
  font-family: "Public Sans";
  src: url("../fonts/public-sans-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Public Sans Fallback";
  src: local("Segoe UI"), local("Helvetica Neue"), local("Arial");
  ascent-override: 95%;
  descent-override: 24%;
  line-gap-override: 0%;
  size-adjust: 101%;
}

@font-face {
  font-family: "Plex Mono";
  src: url("../fonts/plex-mono-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Plex Mono";
  src: url("../fonts/plex-mono-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #F7F6F2;
  --surface: #FCFBF7;
  --surface-soft: #E8ECEC;
  --surface-strong: #D7DEDF;
  --ink: #142B33;
  --ink-soft: #243B43;
  --text: #344A52;
  --muted: #56676D;
  --soft: #56676D;
  --line: #CEC9BF;
  --line-strong: #AAA49A;
  --accent: #28566B;
  --accent-dark: #1E4759;
  --accent-soft: #E8ECEC;
  --signal: #A7772C;
  --signal-dark: #765119;
  --signal-soft: #EFE7D7;
  --light: #FCFBF7;
  --light-muted: #C4CFCC;
  --focus: #28566B;
  --against: #8B3542;
  --button-bg: #28566B;
  --button-fg: #FCFBF7;
  --button-hover: #1E4759;
  --hero-bg: #142B33;
  --hero-fg: #FCFBF7;
  --hero-text: #CBD5D2;
  --hero-muted: #E8DFCA;
  --hero-line: #527078;
  --hero-focus: #E8C887;
  --shadow-sm: 0 10px 28px rgba(20, 43, 51, 0.1);
  --shadow-lg: 0 24px 70px rgba(20, 43, 51, 0.22);
  /* Corners are small but not square. Large soft radii belong to a consumer
     app, not a technical document, and the metric cards already sit at 2px;
     28px panels beside them read as two different sites. Square corners were
     the other option and were rejected: hairline rules plus zero radius is
     its own house style, and this is not that either. */
  --radius-sm: 2px;
  --radius: 3px;
  --radius-lg: 4px;
  --max: 1180px;
  --reading: 58ch;
  --gutter: clamp(1.25rem, 4vw, 3rem);

  --font-display: "Redaction", Georgia, "Times New Roman", serif;
  --font-sans: "Public Sans", "Public Sans Fallback", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "Plex Mono", "Cascadia Code", ui-monospace, "SFMono-Regular", Consolas, monospace;

  /* One fluid major-third scale. Every heading and label reads from this;
     no component defines its own font-size in absolute terms. */
  --step--2: clamp(0.694rem, 0.68rem + 0.07vw, 0.738rem);
  --step--1: clamp(0.833rem, 0.81rem + 0.11vw, 0.889rem);
  --step-0:  clamp(1rem, 0.96rem + 0.2vw, 1.125rem);
  --step-1:  clamp(1.25rem, 1.18rem + 0.35vw, 1.424rem);
  --step-2:  clamp(1.563rem, 1.44rem + 0.61vw, 1.802rem);
  --step-3:  clamp(1.953rem, 1.76rem + 0.97vw, 2.281rem);
  /* The top two steps were 46px and 58px. Measured in place, a 58px h1 inside
     a 611px hero column set about 12 characters to the line and broke to four
     lines; headings need roughly 22 to 30. The constraint is size against
     column width, not size alone, so the top of the scale comes down rather
     than the columns widening. */
  --step-4:  clamp(2.05rem, 1.82rem + 1.15vw, 2.45rem);
  --step-5:  clamp(2.45rem, 2.08rem + 1.85vw, 3.05rem);

  /* Accent that clears AA on the dark ground. The base --accent is 2.89:1
     on --ink and must never be used for text there. */
  --accent-on-ink: #E5C98E;

  /* Inverted surfaces. --ink and --light are named for how they look, so any
     rule using them as a figure/ground pair collapses when both invert. These
     are named for the role instead and are redefined per theme. */
  --inverse-bg: #142B33;
  --inverse-fg: #F7F6F2;
}


/* ---------------------------------------------------------------------------
   Dark theme. Applied when the visitor's system asks for it, unless they have
   explicitly chosen otherwise, and applied unconditionally when they pick dark.
   Values are a deepened version of the existing ink rather than an inversion of
   the cream, so the palette keeps its identity. All pairs verified at AA.
   --------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #101C20;
    --surface: #17272D;
    --surface-soft: #1D3137;
    --surface-strong: #274048;
    --ink: #F1EFE7;
    --ink-soft: #DDE3DF;
    --text: #D7DDD9;
    --muted: #A8B5B4;
    --soft: #93A29F;
    --line: #2D454C;
    --line-strong: #4A6269;
    --accent: #8DB5C5;
    --accent-dark: #B7D4DE;
    --accent-soft: #243F48;
    --accent-on-ink: #D1A65A;
    --signal: #D1A65A;
    --signal-dark: #E0BA74;
    --signal-soft: #3B3324;
    --light: #F7F5EF;
    --light-muted: #A8B5B4;
    --focus: #D1A65A;
    --button-bg: #D1A65A;
    --button-fg: #101C20;
    --button-hover: #E0BA74;
    --hero-bg: #0B1519;
    --hero-fg: #F7F5EF;
    --hero-text: #CCD6D2;
    --hero-muted: #A8B5B4;
    --hero-line: #3B535A;
    --hero-focus: #E8C887;
    --shadow-sm: 0 10px 30px rgba(0, 0, 0, 0.4);
    --shadow-lg: 0 30px 90px rgba(0, 0, 0, 0.55);
    --inverse-bg: #F1EFE7;
    --inverse-fg: #101C20;
    /* A true oxblood is unreadable on a dark ground, so the dark theme lifts
       the same hue. 5.1:1 on --surface, 5.5:1 on --bg. */
    --against: #E28A96;
    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --bg: #101C20;
  --surface: #17272D;
  --surface-soft: #1D3137;
  --surface-strong: #274048;
  --ink: #F1EFE7;
  --ink-soft: #DDE3DF;
  --text: #D7DDD9;
  --muted: #A8B5B4;
  --soft: #93A29F;
  --line: #2D454C;
  --line-strong: #4A6269;
  --accent: #8DB5C5;
  --accent-dark: #B7D4DE;
  --accent-soft: #243F48;
  --accent-on-ink: #D1A65A;
  --signal: #D1A65A;
  --signal-dark: #E0BA74;
  --signal-soft: #3B3324;
  --light: #F7F5EF;
  --light-muted: #A8B5B4;
  --focus: #D1A65A;
  --button-bg: #D1A65A;
  --button-fg: #101C20;
  --button-hover: #E0BA74;
  --hero-bg: #0B1519;
  --hero-fg: #F7F5EF;
  --hero-text: #CCD6D2;
  --hero-muted: #A8B5B4;
  --hero-line: #3B535A;
  --hero-focus: #E8C887;
  --shadow-sm: 0 10px 30px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 30px 90px rgba(0, 0, 0, 0.55);
  --inverse-bg: #F1EFE7;
  --inverse-fg: #101C20;
  --against: #E28A96;
  color-scheme: dark;
}

:root[data-theme="light"] {
  color-scheme: light;
}

/* The ink sections are already dark in light mode; in dark mode they would
   vanish into the page, so they lift slightly instead of dropping. */
:root[data-theme="dark"] .section-ink {
  background-color: var(--surface-soft);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .section-ink {
    background-color: var(--surface-soft);
  }
}

/* Theme control ---------------------------------------------------------- */
.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: inherit;
  cursor: pointer;
  opacity: 0.62;
  transition: opacity 180ms ease, color 180ms ease;
}

.theme-toggle:hover,
.theme-toggle:focus-visible {
  color: var(--accent);
  opacity: 1;
}

/* One icon per state, all three present in the markup and switched by CSS, so
   there is no icon request and no flash of the wrong glyph before JS runs.
   Monitor for auto: sun and moon are binary and cannot express "follow my
   system", which is why a three-state control needs a third glyph. */
.theme-icon {
  grid-area: 1 / 1;
  width: 18px;
  height: 18px;
  display: none;
}

.theme-icon--auto {
  display: block;
}

:root[data-theme="light"] .theme-icon--auto,
:root[data-theme="dark"] .theme-icon--auto {
  display: none;
}

:root[data-theme="light"] .theme-icon--light {
  display: block;
}

:root[data-theme="dark"] .theme-icon--dark {
  display: block;
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: 6rem;
}

body {
  min-width: 300px;
  font-size: var(--step-0);
  margin: 0;
  color: var(--text);
  background: var(--bg);
  font-family: var(--font-sans);
  line-height: 1.65;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

body.nav-open {
  overflow: hidden;
}

::selection {
  color: var(--inverse-fg);
  background: var(--inverse-bg);
}

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

a {
  color: inherit;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 0.08em;
}

a:hover {
  text-decoration-thickness: 0.12em;
}

button,
a {
  -webkit-tap-highlight-color: transparent;
}

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 4px;
}

h1,
h2,
h3,
p,
dl,
dd,
figure {
  margin-top: 0;
}

/* Three voices, each with a job. Redaction sets the headings, Public Sans the
   running text, Plex Mono every figure. The site never mixes them: if it is a
   measurement it is in mono, and if it is a claim it is in the serif.

   Only the base cut of Redaction is loaded, so weight stays at 400 throughout.
   Asking for 600 here would make the browser synthesise a bold that was never
   drawn, which on a display serif is very visible. Tracking is near zero rather
   than the tight negative values the previous sans wanted: Redaction is drawn
   with generous sidebearings on purpose, and closing them up fights the face. */
h1,
h2,
h3 {
  color: inherit;
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: 0;
  text-wrap: balance;
}

h1 {
  margin-bottom: 1.25rem;
  font-size: var(--step-5);
  line-height: 1.08;
  letter-spacing: -0.005em;
}

h2 {
  margin-bottom: 1rem;
  font-size: var(--step-4);
  line-height: 1.15;
  letter-spacing: -0.003em;
}

h3 {
  margin-bottom: 0.7rem;
  font-size: var(--step-2);
  line-height: 1.28;
  letter-spacing: 0;
}

p:last-child,
ul:last-child,
ol:last-child {
  margin-bottom: 0;
}

code {
  padding: 0.1em 0.35em;
  border: 1px solid var(--line);
  border-radius: 5px;
  color: var(--ink);
  background: var(--surface-soft);
  font-family: var(--font-mono);
  font-size: 0.9em;
}

.container {
  width: min(var(--max), calc(100% - (var(--gutter) * 2)));
  margin-inline: auto;
}

.nav-shell .theme-toggle {
  order: 3;
  margin-left: 0.6rem;
}

@media (max-width: 900px) {
  /* Sits beside the menu button rather than inside the collapsible nav, so the
     theme control stays reachable when the menu is closed. */
  .nav-shell .theme-toggle {
    order: 2;
    margin-right: 0.5rem;
    margin-left: auto;
  }
}


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

.skip-link {
  position: fixed;
  top: 0.75rem;
  left: 0.75rem;
  z-index: 1000;
  padding: 0.75rem 1rem;
  border-radius: var(--radius-sm);
  color: var(--inverse-fg);
  background: var(--inverse-bg);
  font-weight: 700;
  text-decoration: none;
  transform: translateY(-150%);
  transition: transform 160ms ease;
}

.skip-link:focus {
  transform: translateY(0);
}

.eyebrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  margin-bottom: 1.15rem;
  color: var(--muted);
  font-family: var(--font-sans);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1.35;
  text-transform: none;
}

.section-ink .eyebrow {
  color: var(--muted);
}

.hero .eyebrow,
.page-title .eyebrow {
  color: var(--muted);
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  border-bottom: 1px solid var(--line-strong);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(18px);
}

.nav-shell {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 68px;
}

.brand {
  display: block;
  color: var(--ink);
  line-height: 1.05;
  text-decoration: none;
}

.brand strong {
  font-size: 0.98rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.brand span {
  display: none;
}

.nav-menu {
  display: flex;
  align-items: center;
  gap: 0.2rem;
}

.nav-menu a {
  min-height: 44px;
  padding: 0.65rem 0.78rem;
  border-radius: var(--radius-sm);
  color: var(--muted);
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
  transition: color 160ms ease, background 160ms ease, transform 160ms ease;
}

.nav-menu a:hover,
.nav-menu a[aria-current="page"] {
  color: var(--ink);
  background: transparent;
  text-decoration: underline;
}

.nav-menu .nav-cta,
.nav-menu .nav-cta[aria-current="page"] {
  margin-left: 0.35rem;
  padding-inline: 1rem;
  color: var(--button-fg);
  background: var(--button-bg);
}

.nav-menu .nav-cta:hover {
  color: var(--button-fg);
  background: var(--button-hover);
  text-decoration: none;
  transform: none;
}

.nav-toggle {
  position: relative;
  display: none;
  width: 46px;
  height: 46px;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  color: var(--ink);
  background: var(--surface);
  cursor: pointer;
}

.nav-toggle span,
.nav-toggle::before,
.nav-toggle::after {
  content: "";
  position: absolute;
  left: 13px;
  display: block;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: transform 180ms ease, opacity 180ms ease;
}

.nav-toggle span {
  top: 21px;
}

.nav-toggle::before {
  top: 15px;
}

.nav-toggle::after {
  top: 27px;
}

.nav-toggle[aria-expanded="true"] span {
  opacity: 0;
}

.nav-toggle[aria-expanded="true"]::before {
  transform: translateY(6px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"]::after {
  transform: translateY(-6px) rotate(-45deg);
}

/* The page bands. These were ink blocks with light text on every page, which
   put a wall of near-black in front of every first impression and left the site
   sitting on the near-black-plus-one-accent look it was supposed to avoid. The
   bands read on the page ground now. .section-ink keeps the dark treatment, so
   the contrast still exists, but it is spent twice on the site rather than at
   the top of every page. */
.hero,
.page-title {
  position: relative;
  color: var(--text);
  background-color: var(--bg);
}

/* Was a full-bleed near-black block. It is a tinted band now: it still separates
   this section from the ones around it, without putting another slab of black on
   a page that had 24 percent of its area in it. The class name is kept only
   because two pages reference it; nothing here is ink any more. */
.section-ink {
  position: relative;
  color: var(--text);
  background-color: var(--surface-soft);
}

.hero {
  overflow: hidden;
  padding: clamp(3.25rem, 6vw, 5.5rem) 0 clamp(3rem, 5.5vw, 4.75rem);
}

/* A hairline rule at the foot of the dark blocks, in place of the blurred
   decorative circles that previously sat behind them. */
.hero::after,
.page-title::after {
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 1px;
  background: var(--line);
  pointer-events: none;
}

.hero-grid,
.page-title .container {
  position: relative;
  z-index: 1;
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.04fr) minmax(390px, 0.82fr);
  gap: clamp(3rem, 7vw, 6.5rem);
  align-items: center;
}

.hero-grid > * {
  min-width: 0;
}

.hero-content {
  max-width: 720px;
}

.hero h1 {
  max-width: 26ch;
  margin-bottom: 1.35rem;
}

/* Deck, not a second headline. It sat at 600 weight and competed with the h1;
   the display serif above should be the only loud thing in the hero. */
.hero-subtitle {
  max-width: 46ch;
  margin-bottom: 1.15rem;
  color: var(--ink);
  font-size: var(--step-1);
  font-weight: 400;
  line-height: 1.45;
  text-wrap: balance;
}

.hero-copy {
  max-width: var(--reading);
  margin-bottom: 0;
  color: var(--muted);
  font-size: var(--step-0);
  line-height: 1.6;
}

.home-hero {
  padding: clamp(3rem, 5vw, 4rem) 0;
  border-bottom: 4px solid var(--signal);
  color: var(--hero-fg);
  background: var(--hero-bg);
}

.home-hero::after {
  display: none;
}

.home-hero .hero-grid {
  grid-template-columns: minmax(0, 1.08fr) minmax(360px, 0.92fr);
  gap: clamp(2.5rem, 5vw, 4.75rem);
}

.home-hero .hero-content {
  max-width: 690px;
}

.home-hero h1 {
  max-width: 16ch;
  color: var(--hero-fg);
  font-size: clamp(3rem, 4.8vw, 4.25rem);
  margin-bottom: 1rem;
}

.hero-role {
  max-width: 56ch;
  margin-bottom: 1.1rem;
  color: var(--hero-muted);
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.home-hero .hero-subtitle,
.home-hero .hero-copy {
  color: var(--hero-text);
}

.home-hero .hero-subtitle {
  margin-bottom: 0.9rem;
}

.hero-capabilities {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem 1.15rem;
  padding: 0;
  margin: 1rem 0 0;
  color: var(--hero-text);
  font-size: 0.78rem;
  font-weight: 650;
  list-style: none;
}

.hero-capabilities li {
  display: inline-flex;
  gap: 0.55rem;
  align-items: center;
}

.hero-capabilities li::before {
  content: "";
  width: 4px;
  height: 4px;
  flex: 0 0 4px;
  background: var(--signal);
}

.home-hero .hero-availability {
  margin-bottom: 1rem;
  border-left-color: var(--signal);
  color: var(--hero-text);
}

.home-hero .hero-availability strong {
  color: var(--hero-fg);
}

.home-hero .hero-ledger {
  margin-top: 1.1rem;
  border-left-color: var(--signal);
  color: var(--hero-text);
}

.home-hero .hero-ledger strong,
.home-hero .hero-ledger a {
  color: var(--hero-fg);
}

.home-hero .hero-ledger a {
  text-decoration: underline;
}

.home-hero .hero-credibility {
  margin-top: 1.15rem;
  border-top-color: var(--hero-line);
}

.home-hero .hero-credibility div + div {
  border-left-color: var(--hero-line);
}

.home-hero .hero-credibility dt {
  color: var(--hero-muted);
}

.home-hero .hero-credibility dd {
  color: var(--hero-fg);
}

.home-hero .button.ghost {
  border-color: var(--hero-line);
  color: var(--hero-fg);
}

.home-hero .button.ghost:hover {
  border-color: var(--hero-fg);
  color: var(--hero-fg);
  background: transparent;
}

.home-hero .hero-actions {
  margin-top: 1.25rem;
}

.home-hero :focus-visible {
  outline-color: var(--hero-focus);
}

.home-hero .proof-panel {
  max-width: 520px;
  justify-self: end;
}

.home-hero .proof-panel figcaption {
  padding: 1rem 1.2rem 1.1rem;
}

.home-hero .proof-panel figcaption h2 {
  margin-bottom: 0.45rem;
  font-size: clamp(1.65rem, 2.5vw, 2.15rem);
}

.home-hero .proof-panel figcaption p {
  margin-bottom: 0.7rem;
}

.home-hero .proof-metrics {
  margin-bottom: 0.75rem;
}

.home-hero .hero-actions .text-link {
  margin-left: 0.25rem;
}

.home-page .eyebrow,
.home-page .project-label {
  color: var(--accent-dark);
  font-family: var(--font-sans);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-transform: none;
}

/* Data tables. Figures are tabular-lined so columns of numbers align, and the
   container scrolls independently so a wide table never scrolls the page. */
.eval-table {
  max-width: var(--reading);
  margin: 1.4rem 0;
  overflow-x: auto;
}

.eval-table table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step--1);
}

.eval-table th,
.eval-table td {
  padding: 0.6rem 0.9rem 0.6rem 0;
  text-align: left;
  border-bottom: 1px solid var(--line);
}

.eval-table th {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.eval-table td {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.eval-table td:first-child {
  font-family: var(--font-sans);
  font-variant-numeric: normal;
}

.eval-table tbody tr:last-child th,
.eval-table tbody tr:last-child td {
  border-bottom: 0;
}

.eval-table strong {
  color: var(--accent-dark);
}

.writing-list {
  display: grid;
  gap: 0;
  padding: 0;
  margin: 0;
  list-style: none;
  counter-reset: none;
}

.writing-entry {
  padding: 2.4rem 0;
  border-top: 1px solid var(--line);
}

.writing-entry:last-child {
  border-bottom: 1px solid var(--line);
}

.writing-meta {
  margin: 0 0 0.6rem;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.writing-entry h2 {
  max-width: 26ch;
  margin: 0 0 0.7rem;
  font-size: var(--step-2);
  line-height: 1.2;
}

.writing-entry h2 a {
  color: inherit;
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: border-color 180ms ease, color 180ms ease;
}

.writing-entry h2 a:hover,
.writing-entry h2 a:focus-visible {
  color: var(--accent-dark);
  border-bottom-color: var(--accent);
}

.writing-entry > p:last-child {
  max-width: 68ch;
  margin: 0;
  color: var(--muted);
}

/* This was a translucent white pill on a dark band. On the light band it was
   white on near-white at 1.16:1, and the 999px radius made a statement of
   availability look like a disabled button. It is a line of text now, marked
   with the same rule the ledger note uses, because both are claims rather than
   controls. */
.hero-availability {
  display: block;
  max-width: 54ch;
  padding: 0 0 0 1rem;
  margin-bottom: 1.35rem;
  border-left: 3px solid var(--ink);
  color: var(--text);
  font-size: 0.98rem;
  line-height: 1.55;
}

.hero-availability strong {
  color: var(--ink);
  font-weight: 700;
}

.hero-credibility {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  padding: 0;
  margin: 1.5rem 0 0;
  border-top: 1px solid var(--line-strong);
}

.hero-credibility div {
  min-width: 0;
  padding: 1rem 0.8rem 0 0;
}

.hero-credibility div + div {
  padding-left: 0.8rem;
  border-left: 1px solid var(--line-strong);
}

.hero-credibility dt {
  margin-bottom: 0.3rem;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.hero-credibility dd {
  margin: 0;
  color: var(--ink);
  font-size: 0.88rem;
  font-weight: 700;
  line-height: 1.35;
}

.hero-actions,
.button-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1.65rem;
}

.hero-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem 1.2rem;
  padding: 1.4rem 0 0;
  margin: 1.6rem 0 0;
  border-top: 1px solid var(--line-strong);
  color: var(--light-muted);
  font-family: var(--font-mono);
  font-size: 0.76rem;
  list-style: none;
}

.hero-links li:not(:first-child)::before {
  content: "/";
  margin-right: 1.2rem;
  color: var(--muted);
}

.hero-links a {
  color: var(--ink);
  font-weight: 700;
  text-decoration: none;
}

.button {
  display: inline-flex;
  min-height: 48px;
  align-items: center;
  justify-content: center;
  padding: 0.78rem 1.12rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  color: var(--ink);
  background: var(--surface);
  font-size: 0.92rem;
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  transition: border-color 160ms ease, color 160ms ease, background 160ms ease;
}

.button:hover {
  border-color: var(--accent);
}

.button.primary {
  border-color: var(--button-bg);
  color: var(--button-fg);
  background: var(--button-bg);
}

.button.primary:hover {
  border-color: var(--button-hover);
  color: var(--button-fg);
  background: var(--button-hover);
}

/* Was --accent on --light: both resolve to #FFFFFF under the dark theme, so
   every Live Demo button rendered white on white and disappeared. The pair has
   to be role-named, not appearance-named, for the same reason --inverse-bg
   exists at all. */
.button.demo {
  border-color: var(--inverse-bg);
  color: var(--inverse-fg);
  background: var(--inverse-bg);
}

.button.demo:hover {
  border-color: color-mix(in srgb, var(--inverse-bg) 82%, var(--inverse-fg));
  background: color-mix(in srgb, var(--inverse-bg) 82%, var(--inverse-fg));
}

.button.ghost {
  background: transparent;
}

.hero .button.primary {
  border-color: var(--button-bg);
  color: var(--button-fg);
  background: var(--button-bg);
}

.hero .button.ghost {
  border-color: var(--hero-line);
  color: var(--hero-fg);
}

.button.light {
  border-color: var(--light);
  color: var(--inverse-bg);
  background: var(--inverse-fg);
}

.text-link {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--accent-dark);
  font-weight: 700;
  text-decoration: none;
}

.text-link:hover {
  color: var(--accent);
}

.text-link span {
  transition: transform 160ms ease;
}

.text-link:hover span {
  transform: translateX(3px);
}

.text-link.light {
  color: var(--light);
}

.proof-panel {
  margin: 0;
  overflow: hidden;
  border: 1px solid var(--line);
  border-top: 4px solid var(--signal);
  border-radius: var(--radius-sm);
  background: var(--surface);
  box-shadow: none;
  transform: none;
}

.proof-image-link {
  display: block;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
}

.proof-panel img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: contain;
  object-position: top left;
}

.home-hero .proof-panel img {
  aspect-ratio: 16 / 9;
  object-fit: cover;
  object-position: top left;
}

.proof-panel figcaption {
  padding: 1.4rem;
  color: var(--muted);
  font-size: 0.94rem;
}

.proof-panel figcaption h2 {
  margin-bottom: 0.6rem;
  color: var(--ink);
  font-size: clamp(1.7rem, 2.5vw, 2.35rem);
}

.proof-panel figcaption p {
  margin-bottom: 1rem;
}

.project-label {
  display: inline-flex;
  width: fit-content;
  flex-wrap: wrap;
  gap: 0.35rem;
  align-items: center;
  margin-bottom: 0.9rem;
  color: var(--accent-dark);
  font-family: var(--font-sans);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1.4;
  text-transform: none;
}

.proof-panel .project-label {
  color: var(--muted);
}

.proof-limit {
  padding-top: 0.75rem;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.82rem;
}

.page-title .project-label {
  color: var(--muted);
}

.proof-metrics {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  margin: 1.1rem 0 0;
  border-top: 1px solid var(--line);
}

.proof-metrics div {
  padding: 0.8rem 0.75rem 0 0;
}

.proof-metrics div + div {
  padding-left: 0.75rem;
  border-left: 1px solid var(--line);
}

/* The label is language and the value is a measurement, so the label is set in
   the text face and the value in mono. This pair was the wrong way round: the
   caption was in the instrument face and the figure was not, which is exactly
   the rule the rest of the site keeps. */
.proof-metrics dt {
  color: var(--muted);
  font-size: 0.65rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.proof-metrics dd {
  margin: 0.35rem 0 0;
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 1.3rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.proof-metrics dd.method-label {
  font-size: clamp(0.95rem, 1.35vw, 1.2rem);
  letter-spacing: -0.02em;
  line-height: 1.08;
}

.signal-strip {
  padding: 0;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}

.signal-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 0;
}

.signal-grid > div {
  min-height: 150px;
  padding: 1.75rem 1.5rem 1.75rem 0;
}

.signal-grid > div + div {
  padding-left: 1.5rem;
  border-left: 1px solid var(--line);
}

.signal-grid dt {
  margin-bottom: 0.65rem;
  color: var(--soft);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.signal-grid dd {
  margin: 0;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.45;
}

.signal-grid strong {
  display: block;
  margin-bottom: 0.3rem;
  color: var(--ink);
  font-size: clamp(1.65rem, 3vw, 2.4rem);
  line-height: 1;
  letter-spacing: -0.05em;
}

.section {
  padding: clamp(4.75rem, 9vw, 8rem) 0;
}

.section.compact {
  padding: clamp(3.25rem, 6vw, 5rem) 0;
}

.section.tinted {
  border-block: 1px solid var(--line);
  background: var(--surface-soft);
}

.section-ink {
  padding: clamp(4.75rem, 9vw, 8rem) 0;
}

.section-ink p,
.section-ink li {
  color: var(--muted);
}

.section-ink h2,
.section-ink h3,
.section-ink strong {
  color: var(--ink);
}

.section-head {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(300px, 0.75fr);
  gap: clamp(2rem, 6vw, 5rem);
  align-items: end;
  margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
}

/* 13ch was a cap for two-word section labels. A heading that states a finding
   needs a measure, not a cap: at 13ch a 58-character heading broke to four
   lines of nine characters. The column is wide enough for 22ch, so the size
   holds and only the wrapping changes. */
.section-head h2 {
  max-width: 26ch;
  margin-bottom: 0;
}

.section-head > p {
  max-width: 590px;
  margin-bottom: 0.15rem;
  color: var(--muted);
  font-size: 1.05rem;
}

.section-ink .section-head > p {
  color: var(--muted);
}

.section-lede {
  max-width: 820px;
  color: var(--muted);
  font-size: clamp(1.1rem, 1.6vw, 1.3rem);
}

/* Padding was sized for a full-bleed ink block. Now that the band shares the
   page ground, the same values read as an empty gap rather than a masthead, so
   they come down and the hairline does the separating. */
.page-title {
  overflow: hidden;
  padding: clamp(3rem, 5vw, 4.25rem) 0 clamp(2.25rem, 4vw, 3.25rem);
  border-bottom: 1px solid var(--line);
}

.page-title h1 {
  max-width: 26ch;
  margin-bottom: 1.4rem;
  font-size: var(--step-5);
}

.page-title .project-summary {
  max-width: 880px;
  margin-bottom: 0;
  color: var(--muted);
  font-size: clamp(1.12rem, 2vw, 1.42rem);
  line-height: 1.5;
}

.page-title .button {
  border-color: var(--line-strong);
  color: var(--ink);
  background: transparent;
}

.page-title .button.demo,
.page-title .button.primary {
  border-color: var(--inverse-bg);
  color: var(--inverse-fg);
  background: var(--inverse-bg);
}

.page-title--about h1,
.page-title--contact h1 {
  max-width: 26ch;
}

.about-page .page-title--about {
  color: var(--hero-fg);
  background: var(--hero-bg);
  border-bottom: 4px solid var(--signal);
}

.about-page .page-title--about::after {
  display: none;
}

.about-page .page-title--about h1,
.about-page .page-title--about .eyebrow {
  color: var(--hero-fg);
}

.about-page .page-title--about .project-summary {
  color: var(--hero-text);
}

.about-page #logic-model {
  background: var(--surface-soft);
}

.about-page .about-operating {
  border-bottom: 1px solid var(--line);
  color: var(--text);
  background: var(--bg);
}

.about-page .about-operating .step-number {
  color: var(--signal-dark);
}

.page-jump-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  margin-top: 1.6rem;
}

.page-jump-links a {
  min-height: 44px;
  padding: 0.65rem 0.9rem;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 999px;
  color: var(--light);
  font-size: 0.85rem;
  font-weight: 700;
  text-decoration: none;
}

.page-jump-links a:hover {
  border-color: var(--accent-on-ink);
  color: var(--accent-soft);
}

.approach-summary {
  max-width: 880px;
  padding: 1.1rem 1.25rem;
  margin-top: 1.5rem;
  border-left: 3px solid var(--accent-on-ink);
  background: rgba(255, 255, 255, 0.06);
}

.approach-summary p {
  margin: 0;
  color: var(--light-muted);
}

.approach-summary strong {
  color: var(--light);
}

.project-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem;
}

.project-card {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 1rem;
  min-height: 100%;
  padding: 1.5rem;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.02);
  text-decoration: none;
  transition: transform 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
}

.project-card:hover {
  border-color: var(--line-strong);
  box-shadow: var(--shadow-sm);
  transform: translateY(-3px);
}

.project-card.featured {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(390px, 1.1fr);
  gap: 0;
  min-height: 470px;
  padding: 0;
}

.project-card.featured > div:first-child {
  display: flex;
  min-width: 0;
  flex-direction: column;
  align-items: flex-start;
  padding: clamp(1.75rem, 4vw, 3rem);
}

.project-card.featured:nth-child(even) > div:first-child {
  grid-column: 2;
  grid-row: 1;
}

.project-card.featured:nth-child(even) > .media-frame {
  grid-column: 1;
  grid-row: 1;
  border-right: 1px solid var(--line);
  border-left: 0;
}

.project-card h2,
.project-card h3 {
  margin-bottom: 0.75rem;
  color: var(--ink);
}

.project-card.featured h2,
.project-card.featured h3 {
  max-width: 26ch;
  font-size: var(--step-3);
  line-height: 1.12;
}

.project-card:not(.featured) h2,
.project-card:not(.featured) h3 {
  font-size: clamp(1.4rem, 2.3vw, 1.9rem);
}

.project-card p {
  color: var(--muted);
}

.project-card.featured p {
  max-width: 650px;
}

.project-value {
  width: 100%;
  padding: 1rem 0 0;
  margin: 0.15rem 0 0.4rem;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.96rem;
}

.project-value strong {
  color: var(--accent-dark);
}

.evidence-status {
  position: relative;
  width: fit-content;
  max-width: 100%;
  padding-left: 1rem;
  margin: 0.4rem 0 0;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.73rem;
  line-height: 1.5;
}

.evidence-status::before {
  content: "";
  position: absolute;
  top: 0.48em;
  left: 0;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.outcome-list {
  display: grid;
  width: 100%;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0;
  padding: 1.15rem 0;
  margin: 0.35rem 0 0;
  border-block: 1px solid var(--line);
  list-style: none;
}

.outcome-list li {
  min-width: 0;
  padding-right: 0.8rem;
}

.outcome-list li + li {
  padding-left: 0.8rem;
  border-left: 1px solid var(--line);
}

.outcome-list strong {
  display: block;
  margin-bottom: 0.25rem;
  color: var(--ink);
  font-size: clamp(1.25rem, 2.5vw, 1.8rem);
  line-height: 1;
  letter-spacing: -0.05em;
}

.outcome-list span {
  display: block;
  color: var(--soft);
  font-size: 0.72rem;
  line-height: 1.35;
}

.project-meta,
.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  padding: 0;
  margin: auto 0 0;
  list-style: none;
}

.project-card .project-meta {
  width: 100%;
  padding-top: 1.25rem;
}

.project-meta li,
.tag-list li {
  padding: 0.38rem 0.62rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--muted);
  background: var(--bg);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  line-height: 1.35;
}

.section-ink .tag-list li {
  border-color: var(--line-strong);
  color: var(--muted);
  background: var(--surface);
}

.media-frame {
  width: 100%;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #E4E4E4;
}

.project-card.featured .media-frame {
  height: 100%;
  min-height: 0;
  border: 0;
  border-left: 1px solid var(--line);
  border-radius: 0;
}

/* Evidence screenshots must never be cropped: charts are the claim. */
.media-frame img {
  width: 100%;
  height: 100%;
  min-height: 0;
  object-fit: contain;
  object-position: center;
  transition: transform 300ms ease;
}

.project-card:hover .media-frame img {
  transform: scale(1.015);
}

.home-work {
  padding: clamp(3.25rem, 4.5vw, 4rem) 0 0;
}

.home-work .section-head {
  margin-bottom: 0;
}

.home-work .section-head h2 {
  max-width: 26ch;
}

.home-work-intro {
  max-width: 560px;
}

.home-work-intro p {
  margin-bottom: 1rem;
  color: var(--muted);
  font-size: 1.05rem;
}

.home-work .featured-work {
  margin-top: clamp(2.25rem, 4vw, 3rem);
}

.home-case.project-chapter {
  grid-template-columns: minmax(320px, 0.9fr) minmax(0, 1.1fr);
  gap: clamp(2.5rem, 5vw, 4.5rem);
  padding: clamp(2.1rem, 3vw, 2.75rem) 0;
}

.home-case .project-chapter-copy h3 {
  max-width: 26ch;
  margin-bottom: 1rem;
  font-size: var(--step-4);
}

.home-case .project-chapter-summary {
  margin-bottom: 1.25rem;
  font-size: 1.04rem;
}

.home-case-facts {
  margin: 0;
  border-top: 1px solid var(--line-strong);
}

.home-case-facts div {
  display: grid;
  grid-template-columns: 82px minmax(0, 1fr);
  gap: 1rem;
  padding: 0.72rem 0;
  border-bottom: 1px solid var(--line);
}

.home-case-facts dt {
  color: var(--accent-dark);
  font-family: var(--font-sans);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-transform: none;
}

.home-case-facts dd {
  margin: 0;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.5;
}

.home-case .project-preview-frame {
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  box-shadow: none;
}

.home-case .project-preview-frame img {
  aspect-ratio: 16 / 10;
  object-fit: contain;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  transition: none;
}

.home-case .project-preview-frame:hover img {
  box-shadow: none;
  transform: none;
}

.home-case .project-chapter-preview figcaption {
  line-height: 1.5;
}

.selected-case-list {
  border-top: 1px solid var(--line);
}

.selected-case {
  display: grid;
  grid-template-areas: "number title description proof link";
  grid-template-columns: 44px minmax(180px, 0.75fr) minmax(250px, 1.2fr) minmax(100px, 0.35fr) auto;
  gap: clamp(1rem, 2vw, 2rem);
  align-items: center;
  padding: clamp(1.75rem, 3vw, 2.5rem) 0;
  border-bottom: 1px solid var(--line);
}

.case-number {
  grid-area: number;
  align-self: start;
  padding-top: 0.2rem;
  color: var(--soft);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
}

.selected-case-title {
  grid-area: title;
}

.selected-case .project-label {
  margin-bottom: 0.45rem;
}

.selected-case h3 {
  margin: 0;
  font-size: var(--step-3);
  line-height: 1;
}

.selected-case > p {
  grid-area: description;
  margin: 0;
  color: var(--muted);
  font-size: 0.96rem;
}

.selected-case-proof {
  grid-area: proof;
}

.selected-case-proof strong,
.selected-case-proof span {
  display: block;
}

.selected-case-proof strong {
  margin-bottom: 0.3rem;
  color: var(--ink);
  font-size: clamp(1.35rem, 2.2vw, 1.8rem);
  line-height: 1;
  letter-spacing: -0.04em;
}

.selected-case-proof span {
  color: var(--soft);
  font-size: 0.72rem;
  line-height: 1.35;
}

.selected-case > .text-link {
  grid-area: link;
  white-space: nowrap;
}

.featured-work {
  border-top: 1px solid var(--line);
}

.project-chapter {
  display: grid;
  grid-template-columns: minmax(260px, 0.72fr) minmax(0, 1.28fr);
  gap: clamp(3rem, 7vw, 7rem);
  align-items: center;
  padding: clamp(5rem, 9vw, 8rem) 0;
  border-bottom: 1px solid var(--line);
}

.project-chapter > * {
  min-width: 0;
}

.project-chapter-copy h3 {
  max-width: 26ch;
  margin-bottom: 1.25rem;
  font-size: var(--step-4);
  line-height: 0.96;
}

.project-chapter-summary {
  max-width: 620px;
  color: var(--muted);
  font-size: 1.03rem;
}

.project-chapter .outcome-list {
  margin-top: 1.75rem;
}

.project-chapter-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 1.25rem;
  align-items: center;
  margin-top: 1.75rem;
}

.project-chapter-preview {
  margin: 0;
}

.project-preview-frame {
  display: block;
  padding: clamp(1rem, 2.2vw, 1.8rem);
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: calc(var(--radius-lg) + 4px);
  background: #E4E4E4;
  box-shadow: var(--shadow-sm);
}

.project-preview-frame img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: contain;
  object-position: top left;
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.1);
  transition: transform 240ms ease, box-shadow 240ms ease;
}

.project-preview-frame:hover img {
  box-shadow: 0 20px 48px rgba(0, 0, 0, 0.15);
  transform: translateY(-3px);
}

.project-chapter-preview figcaption {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 0.85rem;
  color: var(--soft);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  line-height: 1.4;
  text-transform: uppercase;
}

.more-projects {
  margin-top: clamp(3.5rem, 7vw, 6.5rem);
}

.more-projects-head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 2rem;
  margin-bottom: 1.5rem;
}

.more-projects-head h3 {
  max-width: 26ch;
  margin-bottom: 0;
  font-size: var(--step-3);
}

.more-projects-head p {
  margin-bottom: 0;
  color: var(--muted);
}

.compact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: 1rem;
}

.project-card.compact {
  min-height: 285px;
  padding: 1.3rem;
}

.project-card.compact h3 {
  margin-bottom: 0.25rem;
  font-size: 1.3rem;
}

.project-card.compact p {
  font-size: 0.92rem;
}

.project-card.compact .text-link {
  margin-top: auto;
  font-size: 0.88rem;
}

.more-projects-all {
  margin-top: 1.25rem;
}

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  margin-bottom: 0.8rem;
}

.filter-chip {
  min-height: 46px;
  padding: 0.62rem 1rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  color: var(--muted);
  background: var(--surface);
  font: inherit;
  font-size: 0.86rem;
  font-weight: 700;
  cursor: pointer;
  transition: transform 160ms ease, border-color 160ms ease, color 160ms ease, background 160ms ease;
}

.filter-chip:hover {
  border-color: var(--accent);
  color: var(--ink);
  transform: translateY(-1px);
}

.filter-chip.is-active {
  border-color: var(--inverse-bg);
  color: var(--inverse-fg);
  background: var(--inverse-bg);
}

.filter-status {
  margin-bottom: 1.5rem;
  color: var(--soft);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
}

.project-card[hidden] {
  display: none !important;
}

.experience-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--line-strong);
}

.experience-grid article {
  padding: 2rem 1.7rem 0 0;
}

.experience-grid article + article {
  padding-left: 1.7rem;
  border-left: 1px solid var(--line);
}

.experience-grid.principles {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.step-number {
  display: block;
  margin-bottom: 1.5rem;
  color: var(--accent-on-ink);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
}

.experience-grid h3 {
  font-size: 1.35rem;
}

.experience-grid p {
  font-size: 0.94rem;
}

.approach-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.7fr) minmax(0, 1.3fr);
  gap: clamp(3rem, 7vw, 7rem);
}

.approach-grid > div:first-child h2 {
  max-width: 26ch;
}

.approach-content {
  min-width: 0;
}

.principle-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
  margin: 2.2rem 0;
}

.principle-grid article {
  padding: 1.3rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.principle-grid article > span {
  display: block;
  margin-bottom: 2.2rem;
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
}

.principle-grid h3 {
  font-size: 1.16rem;
}

.principle-grid p {
  color: var(--muted);
  font-size: 0.9rem;
}

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

.cta-panel {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(300px, 0.85fr);
  gap: clamp(2rem, 7vw, 6rem);
  align-items: end;
  padding: clamp(2rem, 4vw, 3rem);
  border: 0;
  border-top: 4px solid var(--signal);
  border-radius: 0;
  background: var(--signal-soft);
}

.cta-panel h2 {
  max-width: 26ch;
  margin-bottom: 0;
  font-size: var(--step-4);
}

.home-senior {
  padding: clamp(3.75rem, 6vw, 5.5rem) 0;
}

.home-senior-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: clamp(3rem, 8vw, 7rem);
  align-items: start;
}

.home-senior h2 {
  max-width: 26ch;
  margin-bottom: 1.35rem;
}

.home-senior-lede,
.home-availability {
  color: var(--light-muted);
}

.home-senior-lede {
  max-width: 600px;
  font-size: 1.04rem;
}

.home-credentials {
  padding: 0;
  margin: 1.8rem 0 0;
  border-top: 1px solid rgba(255, 255, 255, 0.24);
  list-style: none;
}

.home-credentials li {
  display: grid;
  grid-template-columns: minmax(180px, 1fr) minmax(140px, 0.8fr);
  gap: 1rem;
  padding: 0.9rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.24);
}

.home-credentials strong {
  color: var(--light);
  font-size: 0.9rem;
}

.home-credentials span {
  color: var(--light-muted);
  font-size: 0.86rem;
}

.home-method h3 {
  max-width: 26ch;
  margin-bottom: 1.4rem;
  color: var(--light);
  font-size: var(--step-3);
  line-height: 1;
}

.home-method-list {
  padding: 0;
  margin: 0;
  border-top: 1px solid rgba(255, 255, 255, 0.24);
  list-style: none;
}

.home-method-list li {
  display: grid;
  grid-template-columns: 34px 1fr;
  gap: 0.8rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.24);
}

.home-method-list li > span {
  color: var(--accent-on-ink);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 700;
}

.home-method-list p {
  margin: 0;
  color: var(--light-muted);
  font-size: 0.91rem;
}

.home-method-list strong {
  margin-right: 0.35rem;
  color: var(--light);
}

.home-availability {
  margin: 1.25rem 0 0;
  font-size: 0.92rem;
}

.home-senior-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.25rem;
  align-items: center;
  margin-top: 1.35rem;
}

.home-page .site-footer {
  padding: 1.75rem 0 1rem;
}

.home-contact .cta-panel {
  padding: clamp(1.75rem, 3vw, 2.25rem);
}

.home-profile {
  padding: clamp(2.8rem, 4.5vw, 3.75rem) 0;
}

.profile-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(300px, 0.85fr);
  gap: clamp(3rem, 7vw, 6rem);
  align-items: start;
}

.profile-story h2,
.profile-focus h2 {
  max-width: 19ch;
}

.profile-lede {
  max-width: 58ch;
  color: var(--muted);
  font-size: 1.04rem;
}

.profile-record {
  margin: 2rem 0 0;
  border-top: 1px solid var(--line-strong);
}

.profile-record div {
  display: grid;
  grid-template-columns: minmax(130px, 0.34fr) minmax(0, 1fr);
  gap: 1.25rem;
  padding: 0.78rem 0;
  border-bottom: 1px solid var(--line);
}

.profile-record dt,
.profile-record dd {
  margin: 0;
}

.profile-record dt {
  color: var(--ink);
  font-size: 0.82rem;
  font-weight: 750;
}

.profile-record dd {
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.55;
}

.profile-focus {
  padding-left: clamp(1.5rem, 3vw, 2.5rem);
  border-left: 1px solid var(--line-strong);
}

.focus-list {
  margin: 1.75rem 0 1.4rem;
  border-top: 1px solid var(--line-strong);
}

.focus-list article {
  padding: 0.78rem 0;
  border-bottom: 1px solid var(--line);
}

.focus-list h3 {
  margin-bottom: 0.3rem;
  font-family: var(--font-sans);
  font-size: 1rem;
}

.focus-list p {
  margin: 0;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.55;
}

.home-contact {
  padding: clamp(2.25rem, 3.5vw, 2.75rem) 0;
}

.section.home-contact {
  padding: clamp(2.25rem, 3.5vw, 2.75rem) 0;
}

.cta-actions p {
  /* Was a hardcoded #5E5E5E, which is the light theme's --muted. The panel
     behind it is --surface-soft and does invert, so in dark mode this line
     rendered at 2.48:1 and the sentence stating availability, the single most
     important line in the funnel, was the least readable text on the page. */
  color: var(--muted);
}

.split,
.case-study-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.68fr) minmax(0, 1.32fr);
  gap: clamp(2.5rem, 7vw, 6rem);
  align-items: start;
}

/* The split's first column is fixed at roughly 367px, so raising the cap alone
   cannot help; the type has to come down for a sentence to fit. */
.split > div:first-child h2 {
  max-width: 26ch;
  font-size: var(--step-3);
  line-height: 1.18;
}

.stack,
.text-block {
  display: grid;
  gap: 1.2rem;
  min-width: 0;
}

.stack > *,
.text-block > * {
  margin-bottom: 0;
}

.text-block {
  max-width: var(--reading);
}

/* Every prose surface gets a measure. Uncapped lines ran 95-105 characters,
   which is where a page stops reading like a document. */
.text-block p,
.content-list li,
.project-summary,
.hero-copy,
.project-chapter-summary,
.section-head p,
.story-copy p {
  max-width: var(--reading);
}

.case-study-grid .text-block,
.case-study-grid .text-block p {
  max-width: 50ch;
}

.text-block p,
.split p {
  color: var(--muted);
}

/* The section heading is a sticky marker in the left column, so it stays
   beside the prose it names. It used to be capped at 9ch and set at up to
   3.25rem, which only worked while every heading was a single word: once a
   heading states a finding instead of a label, 46px type in a 242px column
   breaks to five characters a line. Sized for a sentence now: this column
   holds the claim, and the column beside it holds the evidence. */
.case-study-grid > h2 {
  position: sticky;
  top: 110px;
  max-width: 26ch;
  margin-bottom: 0;
  font-size: var(--step-2);
  line-height: 1.22;
  letter-spacing: -0.012em;
  text-wrap: pretty;
}

.content-list {
  display: grid;
  gap: 0.9rem;
  padding-left: 1.2rem;
  margin-block: 0;
  color: var(--muted);
}

.content-list li {
  padding-left: 0.3rem;
}

.content-list strong {
  color: var(--text);
}

.section-ink .content-list strong {
  color: var(--ink);
}

.callout {
  padding: 1.25rem 1.35rem;
  border-left: 4px solid var(--accent);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  color: var(--muted);
  background: var(--surface);
}

.architecture {
  display: grid;
  max-width: 820px;
  gap: 0;
  padding-left: 1.2rem;
  border-left: 2px solid var(--accent);
}

.arch-node {
  position: relative;
  padding: 1.15rem 1.25rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink);
  background: var(--surface);
  font-weight: 700;
}

.arch-node::before {
  content: "";
  position: absolute;
  top: 1.4rem;
  left: calc(-1.2rem - 6px);
  width: 10px;
  height: 10px;
  border: 2px solid var(--bg);
  border-radius: 50%;
  background: var(--accent);
}

.tinted .arch-node::before {
  border-color: var(--surface-soft);
}

.arch-node small {
  display: block;
  margin-top: 0.35rem;
  color: var(--muted);
  font-weight: 500;
  line-height: 1.55;
}

.arch-arrow {
  height: 1.5rem;
  overflow: hidden;
  color: transparent;
  font-size: 0;
}

.screenshot-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.1rem;
}

.screenshot-grid figure {
  overflow: hidden;
  margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.screenshot-grid a {
  display: block;
  overflow: hidden;
}

.screenshot-grid img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: contain;
  object-position: top left;
  transition: transform 240ms ease;
}

.screenshot-grid a:hover img {
  transform: scale(1.015);
}

.screenshot-grid figcaption {
  padding: 0.95rem 1rem;
  color: var(--muted);
  font-size: 0.86rem;
  line-height: 1.5;
}

.results-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(275px, 1fr));
  gap: 1rem;
}

.metric {
  padding: 1.35rem 1.4rem 1.5rem;
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  border-radius: 2px;
  background: var(--surface);
}

/* States the ledger convention once, where the reader meets the work. Set in
   the measurement face, not the prose face, because it is a count. */
/* The strongest claim on the site used to live on the second page. It sits in
   the hero now, because a link from an application lands here and nowhere
   else. Colour is inherited: the hero is an ink section, so a --text value
   would render dark on dark. */
.hero-ledger {
  max-width: 54ch;
  margin: 1.5rem 0 0;
  padding-left: 1rem;
  border-left: 3px solid currentColor;
  color: inherit;
  font-size: var(--step--1);
  line-height: 1.65;
}

.hero-ledger strong {
  font-weight: 500;
}

.hero-ledger a {
  white-space: nowrap;
}

/* Spends the reviewer's first three minutes for them rather than asking them
   to hunt. Sits directly under the ledger, where someone judging the work is
   already looking. */
.reading-order {
  max-width: 74ch;
  margin-top: clamp(2.5rem, 5vw, 3.75rem);
  padding-top: clamp(2rem, 4vw, 2.75rem);
  border-top: 1px solid var(--line-strong);
}

.reading-order h2 {
  max-width: 26ch;
  margin-bottom: 1.4rem;
}

.reading-order .content-list {
  margin-bottom: 1.4rem;
}

.reading-order .content-list strong {
  color: var(--ink);
  font-weight: 500;
}

.reading-order > p:last-child {
  color: var(--muted);
  font-size: var(--step--1);
}

/* ---------------------------------------------------------------------------
   Ledger of comparisons.

   Twenty results, each measured against a baseline. The units are not
   comparable to one another: ROC AUC, MAP@10, MRR, percentage points, SLA
   breaches per day. Only three of the twenty have a published confidence
   interval. So magnitude is not drawn anywhere in this table, because it
   cannot be drawn honestly, and direction is drawn everywhere, because
   direction is the one attribute all twenty genuinely share.

   The table is a table. Earlier drafts dressed it as a calibration
   certificate, with a serial number and an issue date, and that was the wrong
   instinct: a document that needs a costume to be believed is less trustworthy
   than one that does not, and the serial would have hashed the stylesheet
   rather than the measurements, which on a page about honesty is the one lie
   the thing could not survive.
   --------------------------------------------------------------------------- */
.ledger {
  margin: 0 0 clamp(3rem, 6vw, 4.5rem);
}

.ledger-head h2 {
  max-width: 26ch;
  margin-bottom: 0.85rem;
}

.ledger-head > p {
  max-width: 68ch;
  margin-bottom: 1.6rem;
  color: var(--muted);
}

.ledger-tally {
  display: flex;
  flex-wrap: wrap;
  gap: 0 clamp(1.75rem, 4vw, 3rem);
  margin: 0 0 2rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line-strong);
}

.ledger-tally div {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
}

.ledger-tally dt {
  order: 2;
  color: var(--muted);
  font-size: var(--step--1);
}

.ledger-tally dd {
  order: 1;
  margin: 0;
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--step-2);
  font-variant-numeric: tabular-nums;
}

.ledger-tally div[data-verdict="against"] dt,
.ledger-tally div[data-verdict="against"] dd {
  color: var(--against);
}

/* The table scrolls inside itself on narrow screens rather than forcing the
   page to scroll sideways. */
.ledger-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step--1);
  text-align: left;
}

.ledger-table thead th {
  padding: 0 0.9rem 0.7rem 0;
  border-bottom: 2px solid var(--ink);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.ledger-table tbody th,
.ledger-table td {
  padding: 0.85rem 0.9rem 0.85rem 0;
  border-bottom: 1px solid var(--line);
  font-weight: 400;
  vertical-align: baseline;
}

.ledger-table tbody th {
  color: var(--ink);
  font-weight: 500;
}

.ledger-table tbody th a {
  text-decoration-color: var(--line-strong);
}

.ledger-compared {
  color: var(--muted);
}

.ledger-figure,
.ledger-unit {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.ledger-unit {
  color: var(--muted);
  font-size: var(--step--2);
}

/* The direction column is the object. A reader scanning it sees seven filled
   marks without reading a single word, which is the honest summary of this
   portfolio and the reason the other thirteen are worth anything. */
.ledger-direction span {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.ledger-direction span::before {
  content: "";
  flex: none;
  width: 13px;
  height: 13px;
  border: 1px solid var(--line-strong);
}

tr[data-verdict="none"] .ledger-direction span::before {
  background: var(--line-strong);
}

tr[data-verdict="against"] .ledger-direction span::before {
  border-color: var(--against);
  background: var(--against);
}

tr[data-verdict="against"] .ledger-direction span {
  color: var(--against);
}

@media (max-width: 900px) {
  /* Unit folds into the figure cell's line and Compared is dropped: on a phone
     the useful columns are what it was, what it scored, and which way it went. */
  .ledger-table {
    display: block;
    overflow-x: auto;
  }

  .ledger-compared {
    display: none;
  }

  /* Keeps the project link at or above the 24px minimum target size. */
  .ledger-table tbody th a {
    display: inline-block;
    padding-block: 0.25rem;
  }
}

/* ---------------------------------------------------------------------------
   Verdict ledger.

   Every figure here that was measured against a baseline carries which way it
   came out. That is the whole device: a portfolio reporting only wins costs
   nothing to write, so the results that went the other way are what make the
   rest worth reading. Marking them makes them countable rather than buried in
   a paragraph, and the reader can audit the ratio by scanning.

   The palette has no hue to spend, so direction is carried by rule weight and
   ink: a result that counts against the build gets the heaviest rule on the
   page and the darkest label. Nothing else on the site is emphasised this way.
   --------------------------------------------------------------------------- */
.metric .verdict {
  margin: 0 0 0.95rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--line-strong);
  color: var(--soft);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.14em;
  line-height: 1;
  text-transform: uppercase;
}

.metric[data-verdict="against"] .verdict {
  border-top-width: 3px;
  border-top-color: var(--against);
  color: var(--against);
}

.metric[data-verdict="none"] .verdict {
  border-top-style: dashed;
}

.metric strong {
  display: block;
  margin-bottom: 0.7rem;
  color: var(--accent-dark);
  font-family: var(--font-mono);
  font-size: var(--step-2);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  line-height: 1;
  letter-spacing: -0.03em;
}

.metric span {
  color: var(--muted);
  font-size: 0.9rem;
}

.simple-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}

.simple-card {
  padding: 1.35rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.simple-card h2,
.simple-card h3 {
  font-size: 1.35rem;
}

.simple-card p {
  color: var(--muted);
}

.evidence-visual {
  display: grid;
  gap: 0.7rem;
  padding: 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.evidence-row {
  display: grid;
  grid-template-columns: 120px 1fr 72px;
  gap: 0.7rem;
  align-items: center;
  padding: 0.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg);
}

.evidence-row span {
  min-height: 12px;
  border-radius: 999px;
  background: var(--line);
}

.evidence-row span:nth-child(2) {
  background: rgba(23, 23, 23, 0.22);
}

.evidence-row span:nth-child(3) {
  background: rgba(23, 23, 23, 0.24);
}

.story-grid,
.value-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.7fr) minmax(0, 1.3fr);
  gap: clamp(3rem, 8vw, 8rem);
}

.story-intro h2,
.value-grid > div:first-child h2 {
  max-width: 26ch;
}

.story-copy {
  max-width: var(--reading);
}

.story-copy p {
  color: var(--muted);
  font-size: 1.06rem;
}

.career-timeline {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-top: clamp(3.5rem, 7vw, 6rem);
  border-top: 1px solid var(--line-strong);
}

.career-timeline article {
  padding: 1.6rem 1.5rem 0 0;
}

.career-timeline article + article {
  padding-left: 1.5rem;
  border-left: 1px solid var(--line);
}

.timeline-period,
.credential-status,
.contact-label {
  display: block;
  margin-bottom: 1rem;
  color: var(--accent-dark);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.career-timeline h3 {
  font-size: 1.3rem;
}

.career-timeline p {
  color: var(--muted);
  font-size: 0.92rem;
}

.value-list {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--line-strong);
}

.value-list article {
  display: grid;
  grid-template-columns: minmax(150px, 0.38fr) minmax(0, 1fr);
  gap: 1.5rem;
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--line);
}

.value-list h3,
.value-list p {
  margin: 0;
}

.value-list h3 {
  font-size: 1.12rem;
}

.value-list p {
  color: var(--muted);
}

.contact-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(320px, 0.8fr);
  gap: clamp(3rem, 8vw, 8rem);
  align-items: start;
}

.contact-focus h2 {
  max-width: 26ch;
}

.contact-focus > p {
  max-width: var(--reading);
  color: var(--muted);
  font-size: 1.05rem;
}

.contact-list {
  margin-top: 2rem;
}

.contact-card {
  display: grid;
  gap: 0;
  padding: 0 1.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

.contact-card > div {
  padding: 1.5rem 0;
}

.contact-card > div + div {
  border-top: 1px solid var(--line);
}

.contact-card strong,
.contact-card a {
  color: var(--ink);
  font-size: 1.02rem;
  font-weight: 700;
}

.contact-card p {
  margin: 0.3rem 0 0;
  color: var(--muted);
  font-size: 0.9rem;
}

.contact-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.1rem;
}

.contact-links a {
  color: var(--accent-dark);
  font-size: 0.92rem;
  text-decoration: none;
}

.credential-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}

.credential-card {
  min-height: 270px;
  padding: clamp(1.5rem, 3vw, 2rem);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.credential-card h2 {
  max-width: 26ch;
  margin-bottom: 0.8rem;
  font-size: clamp(1.55rem, 2.7vw, 2.2rem);
}

.credential-card p {
  color: var(--muted);
}

.credential-card .credential-focus {
  color: var(--ink);
  font-weight: 700;
}

.resume-contact {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.2rem;
  padding: 0;
  margin: 1.3rem 0 0;
  color: var(--light-muted);
  font-family: var(--font-mono);
  font-size: 0.76rem;
  list-style: none;
}

.resume-contact a {
  color: var(--light);
  font-weight: 700;
  text-decoration: none;
}

.resume-block + .resume-block {
  margin-top: 4rem;
}

.resume-block .hero-copy {
  color: var(--muted);
}

.resume-block > h2 {
  padding-bottom: 0.8rem;
  margin-bottom: 1.6rem;
  border-bottom: 1px solid var(--line-strong);
  color: var(--soft);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.11em;
  line-height: 1.4;
  text-transform: uppercase;
}

.skill-groups {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}

.skill-group {
  padding: 1.2rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.skill-group h3 {
  margin-bottom: 0.45rem;
  color: var(--accent-dark);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.skill-group p {
  margin: 0;
  color: var(--muted);
  font-size: 0.94rem;
}

.role {
  display: grid;
  gap: 0.45rem;
}

.role + .role {
  padding-top: 2.2rem;
  margin-top: 2.2rem;
  border-top: 1px solid var(--line);
}

.role-head,
.resume-project-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 1rem;
}

.role-head h3,
.resume-project h3 {
  margin: 0;
  font-size: 1.23rem;
}

.resume-project h3 a {
  color: var(--ink);
  text-decoration: none;
}

.resume-project h3 a:hover {
  color: var(--accent-dark);
}

.role-dates {
  color: var(--soft);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
}

.role-org {
  margin: 0;
  color: var(--accent-dark);
  font-weight: 700;
}

.role ul {
  display: grid;
  gap: 0.6rem;
  padding-left: 1.2rem;
  margin: 0.4rem 0 0;
  color: var(--muted);
}

.resume-projects {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}

.resume-project {
  display: grid;
  align-content: start;
  gap: 0.65rem;
  padding: 1.3rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.resume-project p {
  margin: 0;
  color: var(--muted);
  font-size: 0.93rem;
}

.edu-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem 2rem;
}

.edu-item {
  display: grid;
  gap: 0.25rem;
}

.edu-item h3 {
  margin: 0;
  font-size: 1.06rem;
}

.edu-item p {
  margin: 0;
  color: var(--muted);
  font-size: 0.92rem;
}

.site-footer {
  padding: 4rem 0 2rem;
  border-top: 1px solid var(--line-strong);
  color: var(--muted);
  background: var(--surface-soft);
}

.footer-grid {
  display: grid;
  grid-template-columns: minmax(260px, 1.35fr) minmax(160px, 0.65fr) minmax(160px, 0.65fr);
  gap: 2.5rem;
}

.footer-intro {
  max-width: 420px;
}

.footer-brand {
  color: var(--ink);
  font-size: 1.2rem;
  font-weight: 700;
  text-decoration: none;
}

.footer-intro p {
  margin: 0.55rem 0 0;
  color: var(--muted);
  font-size: 0.9rem;
}

.footer-nav,
.footer-social {
  display: grid;
  align-content: start;
  gap: 0.55rem;
}

.footer-nav a,
.footer-social a {
  width: fit-content;
  color: var(--muted);
  font-size: 0.88rem;
  font-weight: 600;
  text-decoration: none;
}

.footer-nav a:hover,
.footer-social a:hover {
  color: var(--ink);
}

.footer-meta {
  display: flex;
  grid-column: 1 / -1;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.75rem 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.7rem;
}

@media (max-width: 1000px) {
  .hero-grid {
    grid-template-columns: minmax(0, 1fr) minmax(340px, 0.75fr);
    gap: 3rem;
  }

  .experience-grid.principles {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .experience-grid.principles article:nth-child(3) {
    padding-left: 0;
    border-left: 0;
  }
}

@media (max-width: 900px) {
  .nav-toggle {
    display: inline-block;
    flex: 0 0 auto;
  }

  .nav-menu {
    position: fixed;
    top: 68px;
    right: 0;
    left: 0;
    z-index: 99;
    display: none;
    max-height: calc(100vh - 68px);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 1rem var(--gutter) 1.5rem;
    overflow-y: auto;
    border-bottom: 1px solid var(--line-strong);
    color: var(--inverse-fg);
    background: var(--inverse-bg);
    box-shadow: var(--shadow-lg);
  }

  .nav-menu[data-open] {
    display: flex;
  }

  /* The panel background is --inverse-bg, which is dark under the light theme
     and white under the dark one. These links were written when the panel was
     always dark: --light-muted gave 2.81:1 on the white panel and --light gave
     the current page 1:1, so the open menu was unreadable on a phone in dark
     mode. Everything here is now mixed from the panel's own text colour. */
  .nav-menu a {
    display: flex;
    width: 100%;
    min-height: 54px;
    align-items: center;
    padding: 0.75rem 0;
    border-bottom: 1px solid color-mix(in srgb, var(--inverse-fg) 20%, transparent);
    border-radius: 0;
    color: color-mix(in srgb, var(--inverse-fg) 74%, var(--inverse-bg));
    font-size: 1.05rem;
  }

  .nav-menu a:hover,
  .nav-menu a[aria-current="page"] {
    color: var(--inverse-fg);
    background: transparent;
  }

  .nav-menu .nav-cta,
  .nav-menu .nav-cta[aria-current="page"] {
    width: fit-content;
    min-height: 48px;
    padding: 0.65rem 1rem;
    margin: 1rem 0 0;
    border: 1px solid var(--button-bg);
    border-radius: var(--radius-sm);
    color: var(--button-fg);
    background: var(--button-bg);
    text-decoration: none;
  }

  .hero-grid,
  .section-head,
  .approach-grid,
  .cta-panel,
  .split,
  .case-study-grid,
  .story-grid,
  .value-grid,
  .contact-layout,
  .profile-grid {
    grid-template-columns: 1fr;
  }

  .profile-focus {
    padding-top: 2.25rem;
    padding-left: 0;
    border-top: 1px solid var(--line-strong);
    border-left: 0;
  }

  .hero-content {
    max-width: 760px;
  }

  .home-hero .hero-grid {
    grid-template-columns: 1fr;
    gap: 2.75rem;
  }

  .hero h1 {
    max-width: 26ch;
  }

  .proof-panel {
    max-width: 720px;
    transform: none;
  }

  .home-hero .proof-panel {
    justify-self: start;
  }

  .home-senior-grid {
    grid-template-columns: 1fr;
    gap: 3.25rem;
  }

  .selected-case {
    grid-template-areas:
      "number title proof"
      "number description proof"
      "number link proof";
    grid-template-columns: 38px minmax(0, 1fr) minmax(110px, 0.35fr);
    align-items: start;
  }

  .selected-case-proof {
    align-self: center;
  }

  .signal-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .signal-grid > div:nth-child(3) {
    padding-left: 0;
    border-top: 1px solid var(--line);
    border-left: 0;
  }

  .signal-grid > div:nth-child(4) {
    border-top: 1px solid var(--line);
  }

  .section-head {
    align-items: start;
  }

  .section-head h2 {
    max-width: 26ch;
  }

  .project-card.featured,
  .project-card.featured:nth-child(even) {
    grid-template-columns: 1fr;
  }

  .project-card.featured > div:first-child,
  .project-card.featured:nth-child(even) > div:first-child {
    grid-column: 1;
    grid-row: 1;
  }

  .project-card.featured > .media-frame,
  .project-card.featured:nth-child(even) > .media-frame {
    grid-column: 1;
    grid-row: 2;
    min-height: 0;
    aspect-ratio: 16 / 10;
    border: 0;
    border-top: 1px solid var(--line);
  }

  .project-chapter {
    grid-template-columns: 1fr;
    gap: 2.5rem;
    padding: 5rem 0;
  }

  .home-case.project-chapter {
    grid-template-columns: 1fr;
    gap: 2.75rem;
  }

  .project-chapter-copy,
  .project-chapter-preview {
    max-width: 720px;
  }

  .experience-grid {
    grid-template-columns: 1fr;
    border-top: 0;
  }

  .experience-grid article,
  .experience-grid article + article {
    padding: 1.5rem 0;
    border-top: 1px solid var(--line);
    border-left: 0;
  }

  .case-study-grid > h2 {
    position: static;
    max-width: 28ch;
  }

  .story-intro h2,
  .value-grid > div:first-child h2,
  .approach-grid > div:first-child h2 {
    max-width: 26ch;
  }

  .footer-grid {
    grid-template-columns: 1.3fr 0.7fr 0.7fr;
  }
}

@media (max-width: 700px) {
  .project-grid,
  .screenshot-grid,
  .simple-grid,
  .credential-grid,
  .resume-projects,
  .skill-groups,
  .edu-list {
    grid-template-columns: 1fr;
  }

  .project-card.featured h2,
  .project-card.featured h3 {
    font-size: var(--step-3);
  }

  .selected-case {
    grid-template-areas:
      "number title"
      ". description"
      ". proof"
      ". link";
    grid-template-columns: 30px minmax(0, 1fr);
    gap: 0.75rem 1rem;
  }

  .selected-case-proof {
    margin-top: 0.25rem;
  }

  .project-chapter-copy h3 {
    font-size: var(--step-4);
  }

  .principle-grid {
    grid-template-columns: 1fr;
  }

  .principle-grid article > span {
    margin-bottom: 1.4rem;
  }

  .experience-grid.principles {
    grid-template-columns: 1fr;
  }

  .experience-grid.principles article,
  .experience-grid.principles article:nth-child(3) {
    padding: 1.5rem 0;
    border-top: 1px solid rgba(255, 255, 255, 0.26);
    border-left: 0;
  }

  .career-timeline {
    grid-template-columns: 1fr;
  }

  .career-timeline article,
  .career-timeline article + article {
    padding: 1.5rem 0;
    border-top: 1px solid var(--line);
    border-left: 0;
  }

  .home-education {
    grid-template-columns: 1fr;
    gap: 1.25rem;
  }

  .value-list article {
    grid-template-columns: 1fr;
    gap: 0.5rem;
  }

  .footer-grid {
    grid-template-columns: 1fr 1fr;
  }

  .footer-intro {
    grid-column: 1 / -1;
  }
}

@media (max-width: 560px) {
  :root {
    --gutter: 1.1rem;
  }

  h1 {
    font-size: var(--step-5);
  }

  .nav-shell {
    min-height: 68px;
  }

  .brand strong {
    font-size: 0.94rem;
  }

  .nav-menu {
    top: 68px;
    max-height: calc(100vh - 68px);
  }

  .hero {
    padding: 4rem 0 3.75rem;
  }

  .home-hero {
    padding: 3rem 0;
  }

  .hero-grid {
    gap: 2.7rem;
  }

  .hero-links {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.7rem 1rem;
  }

  .hero-links li:nth-child(-n + 2) {
    grid-column: 1 / -1;
  }

  .hero-links li::before {
    display: none;
  }

  .hero-actions,
  .cta-actions .button-row {
    align-items: stretch;
    flex-direction: column;
  }

  .hero-actions .button,
  .cta-actions .button {
    width: 100%;
  }

  .home-hero .hero-actions .text-link {
    justify-content: center;
    margin-left: 0;
  }

  .proof-panel figcaption {
    padding: 1.1rem;
  }

  .proof-metrics div {
    padding-right: 0.55rem;
  }

  .proof-metrics div + div {
    padding-left: 0.55rem;
  }

  .proof-metrics dt {
    font-size: 0.58rem;
  }

  .proof-metrics dd {
    font-size: 1.2rem;
  }

  .hero-credibility div {
    padding-right: 0.5rem;
  }

  .hero-credibility div + div {
    padding-left: 0.5rem;
  }

  .hero-credibility dt {
    font-size: 0.56rem;
  }

  .hero-credibility dd {
    font-size: 0.76rem;
  }

  .hero-credibility {
    grid-template-columns: 1fr;
  }

  .hero-credibility div,
  .hero-credibility div + div {
    padding: 0.8rem 0;
    border-left: 0;
  }

  .hero-credibility div + div {
    border-top: 1px solid rgba(255, 255, 255, 0.22);
  }

  .home-case-facts div {
    grid-template-columns: 1fr;
    gap: 0.3rem;
  }

  .profile-record div {
    grid-template-columns: 1fr;
    gap: 0.35rem;
  }

  .signal-grid {
    grid-template-columns: 1fr;
  }

  .signal-grid > div,
  .signal-grid > div + div,
  .signal-grid > div:nth-child(3),
  .signal-grid > div:nth-child(4) {
    min-height: 0;
    padding: 1.35rem 0;
    border-top: 1px solid var(--line);
    border-left: 0;
  }

  .signal-grid > div:first-child {
    border-top: 0;
  }

  .section,
  .section.compact,
  .section-ink {
    padding: 4rem 0;
  }

  .section-head {
    gap: 1.5rem;
    margin-bottom: 2.3rem;
  }

  .page-title {
    padding: 4rem 0 3.5rem;
  }

  .page-title h1 {
    overflow-wrap: anywhere;
    font-size: var(--step-4);
  }

  .page-jump-links a {
    flex: 1 1 45%;
    justify-content: center;
    text-align: center;
  }

  .project-card,
  .project-card.featured > div:first-child {
    padding: 1.2rem;
  }

  .project-card.featured {
    border-radius: var(--radius);
  }

  .project-card.featured > .media-frame,
  .project-card.featured:nth-child(even) > .media-frame {
    border-radius: 0;
  }

  .outcome-list {
    gap: 0.7rem;
    grid-template-columns: 1fr;
  }

  .outcome-list li,
  .outcome-list li + li {
    display: grid;
    grid-template-columns: minmax(85px, auto) 1fr;
    gap: 0.65rem;
    align-items: baseline;
    padding: 0.45rem 0;
    border-left: 0;
  }

  .outcome-list li + li {
    border-top: 1px solid var(--line);
  }

  .outcome-list strong {
    margin: 0;
  }

  .more-projects-head {
    align-items: flex-start;
    flex-direction: column;
  }

  .compact-grid {
    grid-template-columns: 1fr;
  }

  .project-card.compact {
    min-height: 240px;
  }

  .home-credentials li {
    grid-template-columns: 1fr;
    gap: 0.25rem;
  }

  .home-senior-actions {
    align-items: stretch;
    flex-direction: column;
  }

  .home-senior-actions .button {
    width: 100%;
  }

  .project-chapter {
    gap: 2rem;
    padding: 4.25rem 0;
  }

  .project-preview-frame {
    padding: 0.75rem;
    border-radius: var(--radius-lg);
  }

  .project-chapter-preview figcaption {
    align-items: flex-start;
    flex-direction: column;
    gap: 0.25rem;
  }

  .project-chapter-links {
    align-items: stretch;
    flex-direction: column;
  }

  .project-chapter-links .button {
    width: 100%;
  }

  .button-row {
    align-items: stretch;
  }

  .button-row .button {
    flex: 1 1 auto;
  }

  .filter-chip {
    flex: 1 1 auto;
  }

  .cta-panel {
    padding: 1.5rem;
    border-radius: 0;
  }

  .evidence-row {
    grid-template-columns: 74px 1fr 42px;
  }

  .contact-card {
    padding-inline: 1.1rem;
  }

  .footer-grid {
    grid-template-columns: 1fr;
  }

  .footer-intro,
  .footer-meta {
    grid-column: auto;
  }

  .footer-meta {
    align-items: flex-start;
    flex-direction: column;
  }
}

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

  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}
