/* hjadmz · Landing page
   ---------------------------------------------------------------------------
   Brand law observed here:
     · FCA — Function precedes Convenience precedes Aesthetics
     · Minimum viable complexity — every rule justifies its existence
     · No raw hex outside tokens.css. Every color is a token.
     · Two type families. Four radii. Five duration tokens, overdamped,
       zero overshoot.
     · The wordmark is the only mark. Role is body content, never welded to it.
     · Italic is reserved for the Soli Deo Gloria corner mark. Nothing else.
   --------------------------------------------------------------------------- */

/* ─── Fonts · self-hosted, subset, woff2 ─────────────────────────────────── */
/* Subset from the brand kit TTFs: latin + the punctuation this page actually
   uses. 1.14 MiB of TTF became 94.2 KiB of WOFF2. Zero third-party requests —
   no font CDN, no analytics, no trackers. */

@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/Inter-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/Inter-Medium.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/Inter-SemiBold.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../assets/fonts/JetBrainsMono-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../assets/fonts/JetBrainsMono-Medium.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}

/* ─── Reset ──────────────────────────────────────────────────────────────── */

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

/* The HTML hidden state must win over component display rules. This also
   keeps script-enhanced controls inert in browsers that lack their API. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* sticky header height + breathing room, so #anchors don't land under it */
  scroll-padding-top: 6.5rem;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: var(--line-height-body);
  color: var(--color-text);
  background-color: var(--color-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-synthesis: none;
  font-synthesis-weight: none;
  overflow-wrap: break-word;
}

h1, h2, h3, h4, p, figure, blockquote, dl, dd, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
button { font: inherit; color: inherit; }
:where(input, button, textarea, select) { font: inherit; }

/* Underlines always present on prose links; nav/utility links opt out
   explicitly (they read as controls, not as prose references). */
a {
  color: var(--color-text-link);
  text-decoration: underline;
  text-underline-offset: 0.15em;
  transition: color var(--duration-quick) var(--ease-default);
}
a:hover { color: var(--color-text-link-hover); }

:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-ring);
  outline-offset: var(--focus-ring-offset);
  border-radius: var(--radius-sm);
}

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

/* ─── Local layout tokens ────────────────────────────────────────────────── */

:root {
  --shell:      68rem;   /* content measure — wide enough for the work index */
  --gutter:     var(--space-6);
  --rule:       1px solid var(--color-border-subtle);
  --rule-firm:  1px solid var(--color-border);
  --header-h:   4rem;      /* canonical 64px sticky bar */
}

@media (min-width: 48em) {
  :root { --gutter: var(--space-10); }
}

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-left: max(var(--gutter), env(safe-area-inset-left));
  padding-right: max(var(--gutter), env(safe-area-inset-right));
}

.mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums lining-nums;
}

.eyebrow {
  font-family: var(--font-mono);
  font-weight: var(--weight-medium);
  font-size: var(--step--1);
  line-height: 1.2;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.faint { color: var(--color-text-faint); }


/* ─── Skip link ──────────────────────────────────────────────────────────── */

.skip {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  z-index: var(--z-toast);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  color: var(--color-text);
  border: var(--rule-firm);
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-size: var(--step--1);
  transform: translateY(calc(-100% - var(--space-4)));
  transition: transform var(--duration-quick) var(--ease-out);
}
.skip:focus-visible { transform: translateY(0); }

/* ─── Header ─────────────────────────────────────────────────────────────── */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: var(--color-bg);
  background: color-mix(in srgb, var(--color-bg) 88%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--color-border-subtle);
}

@supports not ((-webkit-backdrop-filter: blur(12px)) or (backdrop-filter: blur(12px))) {
  .site-header { background: var(--color-bg); }
}

.header-inner {
  min-height: var(--header-h);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: var(--space-6);
  row-gap: var(--space-2);
  padding-block: var(--space-2);
}
.header-inner > * {
  min-width: 0;
}

.brand {
  display: inline-flex;
  align-items: center;
  color: var(--color-mark);
  text-decoration: none;
  flex: 0 0 auto;
  border-radius: var(--radius-sm);
}
/* The inline mark is the tight-bbox wordmark: ink only, no baked-in padding.
   Clear space (brand law: 1× cap-height) is CSS's job here, which is what lets
   the same asset sit correctly in a 64px header and a footer. */
.brand svg { height: 1.0625rem; width: auto; }
.brand { padding: calc(1.0625rem * 0.753); margin: calc(-1.0625rem * 0.753); }
.brand:hover { color: var(--color-mark); }
.brand, .brand svg { transition: none; }   /* the mark is static, period */

.site-nav {
  display: none;
  margin-inline-start: auto;
  align-items: center;
  justify-content: flex-end;
  flex: 1 1 auto;
  flex-wrap: wrap;
  min-width: 0;
  max-width: 100%;
  gap: var(--space-1);
}

.nav-link {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--step--1);
  color: var(--color-text-muted);
  text-decoration: none;
  transition: color var(--duration-quick) var(--ease-default),
              background-color var(--duration-quick) var(--ease-default);
}
.nav-link:hover { color: var(--color-text); background: var(--color-surface-raised); }
.nav-link[aria-current="true"] { color: var(--color-text); }
.nav-link .n {
  font-family: var(--font-mono);
  font-size: 0.75rem;      /* 12px — the floor, not 0.75em of 14px */
  color: var(--color-text-faint);
  font-variant-numeric: tabular-nums;
}
.nav-link[aria-current="true"] .n { color: var(--color-text-link); }

/* Native navigation is the small-screen and no-script baseline. The dropdown
   is aligned with the shell edge beyond the following theme button. */
.mobile-menu {
  position: relative;
  display: block;
  flex: 0 0 auto;
  margin-inline-start: auto;
}
.mobile-menu-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-width: 2.75rem;
  min-height: 2.75rem;
  padding: var(--space-2) var(--space-3);
  list-style: none;
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  line-height: 1.2;
  cursor: pointer;
  transition: color var(--duration-quick) var(--ease-default),
              border-color var(--duration-quick) var(--ease-default),
              background-color var(--duration-quick) var(--ease-default);
}
.mobile-menu-toggle::-webkit-details-marker { display: none; }
.mobile-menu-toggle::marker { content: ""; }
.mobile-menu-toggle:hover,
.mobile-menu[open] > .mobile-menu-toggle {
  color: var(--color-text);
  border-color: var(--color-border);
  background: var(--color-surface-raised);
}
.mobile-menu-toggle svg {
  width: 1rem;
  height: 1rem;
  flex: 0 0 auto;
}
.mobile-menu-links {
  position: absolute;
  top: calc(100% + var(--space-2));
  inset-inline-end: calc(-2.75rem - var(--space-6));
  z-index: var(--z-dropdown);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  width: min(18rem, calc(100vw - var(--gutter) - var(--gutter)));
  max-width: calc(100vw - var(--gutter) - var(--gutter));
  max-height: calc(100vh - var(--header-h) - var(--space-4));
  padding: var(--space-2);
  overflow-y: auto;
  overscroll-behavior: contain;
  border: var(--rule-firm);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-md);
}
@supports (height: 100dvh) {
  .mobile-menu-links {
    max-height: calc(100dvh - var(--header-h) - var(--space-4));
  }
}
.mobile-menu-link {
  display: flex;
  align-items: center;
  min-width: 0;
  min-height: 2.75rem;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  line-height: 1.3;
  overflow-wrap: anywhere;
  text-decoration: none;
  transition: color var(--duration-quick) var(--ease-default),
              background-color var(--duration-quick) var(--ease-default);
}
.mobile-menu-link:hover {
  color: var(--color-text);
  background: var(--color-surface-raised);
}

.header-tools {
  display: flex;
  flex: 0 0 auto;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-inline-start: 0;
}

/* The palette shortcut remains active in JavaScript everywhere; its opener is
   redundant beside the complete native menu on narrow/touch-first layouts. */
#palette-open { display: none; }

@media (min-width: 56.25em) {
  .site-nav { display: flex; }
  .mobile-menu { display: none; }
  .header-tools { margin-inline-start: var(--space-4); }
  #palette-open { display: inline-flex; }
}

/* ─── Buttons ────────────────────────────────────────────────────────────── */

.btn {
  --btn-bg: transparent;
  --btn-fg: var(--color-text);
  --btn-edge: var(--color-border);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  min-height: 2.75rem;              /* Fitts — comfortable target on touch */
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-edge);
  border-radius: var(--radius-sm);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--duration-quick) var(--ease-default),
              border-color var(--duration-quick) var(--ease-default),
              color var(--duration-quick) var(--ease-default);
}
.btn:hover { --btn-edge: var(--color-text); }

.btn-primary {
  --btn-bg: var(--color-text);
  --btn-fg: var(--color-bg);
  --btn-edge: var(--color-text);
}
.btn-primary:hover {
  --btn-bg: var(--color-text-muted);
  --btn-edge: var(--color-text-muted);
  --btn-fg: var(--color-bg);
}

/* Icon-only utilities in the header */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 2.75rem;      /* 44px — the tap-target floor */
  min-width: 2.75rem;
  padding-inline: var(--space-2);
  background: transparent;
  color: var(--color-text-muted);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color var(--duration-quick) var(--ease-default),
              border-color var(--duration-quick) var(--ease-default),
              background-color var(--duration-quick) var(--ease-default);
}
.icon-btn:hover {
  color: var(--color-text);
  border-color: var(--color-border);
  background: var(--color-surface-raised);
}
.icon-btn svg { width: 1rem; height: 1rem; }

.kbd-hint {
  display: none;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  padding-inline: var(--space-1);
}
@media (min-width: 35em) { .kbd-hint { display: inline; } }

/* Inline code is the mono face, never the browser's default fixed font —
   that would put a third family on the page. */
code {
  font-family: var(--font-mono);
  font-size: 0.9em;      /* optical correction: JetBrains Mono runs large */
}

kbd {
  font-family: var(--font-mono);
  font-size: 0.75rem;   /* 12px — the type floor, never below */
  line-height: 1;
  padding: 0.25em 0.4em;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-raised);
  color: var(--color-text-muted);
  white-space: nowrap;
}

/* ─── Section scaffolding · the spec-sheet grammar ───────────────────────── */

.section { padding-block: var(--space-16); border-top: var(--rule); }
@media (min-width: 48em) { .section { padding-block: var(--space-20); } }

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-6);
  margin-bottom: var(--space-8);
  padding-bottom: var(--space-4);
  border-bottom: var(--rule);
}
.section-head h2 {
  min-width: 0;
  font-size: var(--step-2);
  font-weight: var(--weight-semi);
  line-height: var(--line-height-heading);
  letter-spacing: var(--tracking-tight);
}
.section-num {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-text-faint);
  letter-spacing: var(--tracking-wide);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.section-lead {
  max-width: var(--max-width-prose);
  color: var(--color-text-muted);
  margin-bottom: var(--space-10);
}

/* ─── Hero ───────────────────────────────────────────────────────────────── */

.hero { padding-block: var(--space-16) var(--space-12); }
@media (min-width: 48em) { .hero { padding-block: var(--space-24) var(--space-16); } }

.hero .eyebrow { display: block; margin-bottom: var(--space-6); }

.hero h1 {
  font-size: var(--step-4);
  font-weight: var(--weight-semi);
  line-height: var(--line-height-tight);
  letter-spacing: var(--tracking-tight);
  max-width: 20ch;
  text-wrap: balance;
}
@media (min-width: 64em) { .hero h1 { font-size: var(--step-5); } }

.hero h1 .line-2 {
  display: block;
  color: var(--color-text-muted);
}

.hero-lead {
  margin-top: var(--space-6);
  max-width: 54ch;
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--color-text-muted);
  text-wrap: pretty;
}

.hero-actions {
  margin-top: var(--space-8);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* Availability — a live fact, so it gets a live-looking indicator. */
.status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-6);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-text-muted);
}
.status .dot {
  width: 0.4375rem;
  height: 0.4375rem;
  border-radius: var(--radius-full);
  background: var(--color-success);
  flex: 0 0 auto;
}

/* Spec strip — the datasheet header row. */
.spec-strip {
  margin-top: var(--space-12);
  border-top: var(--rule-firm);
  display: grid;
  grid-template-columns: 1fr;
}
@media (min-width: 40em) { .spec-strip { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 56.25em) { .spec-strip { grid-template-columns: repeat(4, 1fr); } }

.spec {
  padding: var(--space-4) 0;
  border-bottom: var(--rule);
}
@media (min-width: 40em) {
  .spec { padding: var(--space-5) var(--space-5) var(--space-5) 0; }
  .spec + .spec { border-left: var(--rule); padding-left: var(--space-5); }
}
@media (min-width: 40em) and (max-width: 56.1875em) {
  .spec:nth-child(odd) { border-left: 0; padding-left: 0; }
}

.spec dt {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--color-text-faint);
  margin-bottom: var(--space-2);
}
.spec dd { margin: 0; font-size: var(--step--1); color: var(--color-text); }

.work-provenance {
  margin-top: 0;
  margin-bottom: var(--space-12);
}

/* ─── FCA gate · the interactive operating system ────────────────────────── */

.fca {
  border: var(--rule-firm);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  overflow: hidden;
}

.fca-input-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-5);
  border-bottom: var(--rule);
  background: var(--color-surface-raised);
}
.fca-input-row label {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--color-text-muted);   /* faint is 4.34:1 on the raised surface */
  flex: 0 0 auto;
}
.fca-input {
  flex: 1 1 16rem;
  min-width: 0;
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  color: var(--color-text);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: var(--step-0);   /* ≥16px, or iOS Safari zooms on focus and stays */
}
.fca-input::placeholder { color: var(--color-text-faint); }

.gates { display: grid; grid-template-columns: 1fr; }
@media (min-width: 48em) { .gates { grid-template-columns: repeat(3, 1fr); } }

.gate {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-6);
  border-bottom: var(--rule);
  text-align: left;
  background: transparent;
  border-inline: 0;
  border-top: 0;
  cursor: pointer;
  transition: background-color var(--duration-quick) var(--ease-default);
}
@media (min-width: 48em) {
  .gate { border-bottom: 0; }
  .gate + .gate { border-left: var(--rule); }
}
.gate:hover { background: var(--color-surface-raised); }
.gate:focus-visible { outline-offset: calc(-1 * var(--focus-ring-width)); }

.gate-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.gate-name {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-text-faint);
}
.gate-title {
  display: block;
  font-size: var(--step-0);
  font-weight: var(--weight-semi);
  line-height: var(--line-height-heading);
  color: var(--color-text);
}
.gate-desc {
  display: block;
  font-size: var(--step-0);
  color: var(--color-text-muted);
  line-height: 1.5;
}

/* The switch: a real checkbox underneath, so it is keyboard- and
   screen-reader-native. The visual is a track and a knob. */
.switch {
  position: relative;
  width: 2.25rem;
  height: 1.25rem;
  border-radius: var(--radius-full);
  background: var(--color-text-faint);   /* ≥4.5:1 — the off state must be visible */
  flex: 0 0 auto;
  transition: background-color var(--duration-quick) var(--ease-default);
}
.switch::after {
  content: "";
  position: absolute;
  top: 0.1875rem; left: 0.1875rem;
  width: 0.875rem; height: 0.875rem;
  border-radius: var(--radius-full);
  background: var(--color-bg);
  transition: transform var(--duration-quick) var(--ease-overdamp);
}
.gate[aria-pressed="true"] .switch { background: var(--color-success); }
.gate[aria-pressed="true"] .switch::after { transform: translateX(1rem); }

.fca-verdict {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3) var(--space-4);
  padding: var(--space-5) var(--space-6);
  border-top: var(--rule-firm);
  background: var(--color-surface-raised);
  min-height: 4.5rem;
}
.verdict-flag {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
.verdict-flag[data-state="pass"] { color: var(--color-success); background: var(--color-success-subtle); }
.verdict-flag[data-state="warn"] { color: var(--color-warning); background: var(--color-warning-subtle); }
.verdict-flag[data-state="fail"] { color: var(--color-error);   background: var(--color-error-subtle); }
.verdict-flag[data-state="idle"] { color: var(--color-text-muted); background: transparent; border: 1px solid var(--color-border-subtle); }

.verdict-text { flex: 1 1 20rem; font-size: var(--step--1); color: var(--color-text); }
.verdict-text .subject { font-weight: var(--weight-semi); }

/* ─── Work index ─────────────────────────────────────────────────────────── */

.featured-grid {
  display: grid;
  grid-template-columns: 1fr;
  align-items: start;
  gap: var(--space-5);
  margin-bottom: var(--space-8);
}
@media (min-width: 64em) {
  .featured-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.featured-card {
  min-width: 0;
  overflow: hidden;
  border: var(--rule-firm);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text);
  text-decoration: none;
  transition: border-color var(--duration-quick) var(--ease-default),
              background-color var(--duration-quick) var(--ease-default);
}
.featured-card:hover {
  color: var(--color-text);
  border-color: var(--color-text-muted);
  background: var(--color-surface-raised);
}
.featured-card img {
  width: 100%;
  height: auto;
  aspect-ratio: auto;
  object-fit: contain;
  border-bottom: var(--rule);
  background: var(--color-surface-raised);
}
.featured-caption {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: end;
  gap: var(--space-3) var(--space-5);
  padding: var(--space-4) var(--space-5);
  font-size: var(--step--1);
}
.featured-caption strong {
  display: block;
  font-size: var(--step-0);
  font-weight: var(--weight-semi);
}
.featured-caption small {
  display: block;
  margin-top: var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--step--1);
}

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

.work-item { border-bottom: var(--rule); }

/* Native details/summary keeps disclosure behavior available without JS. The
   h3 inside summary preserves the document outline. */
.work-details { display: block; }
.work-summary {
  display: block;
  list-style: none;
  cursor: pointer;
}
.work-summary::-webkit-details-marker { display: none; }
.work-summary::marker { content: ""; }
.work-summary:focus-visible {
  outline-offset: calc(-1 * var(--focus-ring-width));
}

.work-row {
  display: grid;
  grid-template-columns: 2.5rem 1fr auto;
  align-items: baseline;
  gap: var(--space-3) var(--space-4);
  width: 100%;
  margin: 0;
  padding: var(--space-5) var(--space-2);
  background: transparent;
  font: inherit;
  text-align: left;
  /* Canonical row hover: an 8px indent over 200ms, overdamped.
     No colour wash, no scale, no shadow lift. */
  transition: padding-left var(--duration-exit) var(--ease-overdamp);
}
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .work-summary:hover .work-row { padding-left: calc(var(--space-2) + var(--space-2)); }
}

@media (min-width: 53.75em) {
  .work-row {
    grid-template-columns: 2.5rem minmax(0, 1.6fr) minmax(0, 1fr) 7rem 1.5rem;
  }
}

.work-idx {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-text-faint);
  font-variant-numeric: tabular-nums;
}
.work-title {
  font-size: var(--step-1);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
  line-height: var(--line-height-heading);
  color: var(--color-text);
}
.work-kind { font-size: var(--step--1); color: var(--color-text-muted); }
.work-year {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-text-faint);
  font-variant-numeric: tabular-nums;
}
.work-kind, .work-year { display: none; }
@media (min-width: 53.75em) { .work-kind, .work-year { display: block; } }

.work-chev {
  justify-self: end;
  color: var(--color-text-faint);
  transition: transform var(--duration-moderate) var(--ease-overdamp);
}
.work-chev svg { width: 0.875rem; height: 0.875rem; }
.work-details[open] .work-chev { transform: rotate(90deg); }

/* Details owns visibility; no script-driven open-then-collapse layout shift. */
.work-panel { display: block; padding: 0 var(--space-2) var(--space-8); }

@media (min-width: 53.75em) {
  .work-panel { padding-left: calc(2.5rem + var(--space-4)); }
}

.work-body {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: 1fr;
}
@media (min-width: 53.75em) { .work-body { grid-template-columns: minmax(0, 1fr) 16rem; gap: var(--space-10); } }

.work-body > .prose p { max-width: var(--max-width-prose); color: var(--color-text-muted); }
.work-body > .prose p + p { margin-top: var(--space-4); }
.work-body strong { color: var(--color-text); font-weight: var(--weight-semi); }

.facts { border-top: var(--rule); }
.fact {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-4);
  padding: var(--space-3) 0;
  border-bottom: var(--rule);
  font-size: var(--step--1);
}
.fact dt {
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-faint);
  flex: 0 0 auto;
}
.fact dd { min-width: 0; margin: 0; text-align: right; color: var(--color-text); }

.tags { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-5); }
.tag {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-text-muted);
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-sm);
  white-space: nowrap;
}

/* ─── Stack ──────────────────────────────────────────────────────────────── */

.stack-grid {
  display: grid;
  gap: 0;
  grid-template-columns: 1fr;
  border-top: var(--rule-firm);
}
@media (min-width: 40em) { .stack-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64em) { .stack-grid { grid-template-columns: repeat(3, 1fr); } }

.stack-group { padding: var(--space-6) 0; border-bottom: var(--rule); }
@media (min-width: 40em) {
  .stack-group { padding: var(--space-6) var(--space-6) var(--space-6) 0; }
  .stack-group + .stack-group { border-left: var(--rule); padding-left: var(--space-6); }
}
@media (min-width: 40em) and (max-width: 63.9375em) {
  .stack-group:nth-child(odd) { border-left: 0; padding-left: 0; }
}
@media (min-width: 64em) {
  .stack-group:nth-child(3n+1) { border-left: 0; padding-left: 0; }
}

.stack-group h3 {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--color-text-faint);
  margin-bottom: var(--space-4);
}
.stack-group li {
  font-size: var(--step--1);
  color: var(--color-text);
  padding-block: var(--space-1);
}

/* ─── Working principles ────────────────────────────────────────────────── */

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

.ledger-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-1) var(--space-8);
  padding: var(--space-5) 0;
  border-bottom: var(--rule);
}
@media (min-width: 48em) {
  .ledger-row { grid-template-columns: 15rem minmax(0, 1fr); gap: var(--space-8); align-items: baseline; }
}

.ledger-name {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  color: var(--color-text);
}
.ledger-meaning { font-size: var(--step-0); color: var(--color-text-muted); line-height: 1.55; }

/* ─── Now ────────────────────────────────────────────────────────────────── */

.now { border-top: var(--rule-firm); }
.now-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-1) var(--space-8);
  padding: var(--space-4) 0;
  border-bottom: var(--rule);
}
@media (min-width: 40em) { .now-row { grid-template-columns: 9rem minmax(0, 1fr); align-items: baseline; } }

.now-key {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--color-text-faint);
}
.now-val { font-size: var(--step-0); color: var(--color-text); }

/* ─── Contact ────────────────────────────────────────────────────────────── */

.contact-grid {
  display: grid;
  gap: var(--space-10);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 53.75em) { .contact-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 22rem); gap: var(--space-16); } }

.contact-lines { border-top: var(--rule-firm); }
.contact-line {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-4);
  padding: var(--space-4) 0;
  border-bottom: var(--rule);
  font-size: var(--step--1);
}
.contact-line dt {
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--color-text-faint);
}
.contact-line dd { min-width: 0; margin: 0; text-align: right; overflow-wrap: anywhere; }
/* Same reasoning as the footer nav: standalone targets, so 24px minimum. */
.contact-line a,
.now-val a,
.work-body a {
  display: inline-flex;
  align-items: center;
  min-height: 1.5rem;
}


.note {
  font-size: var(--step--1);
  color: var(--color-text-muted);
  line-height: 1.6;
  border-left: 1px solid var(--color-border);
  padding-left: var(--space-5);
}
.note p + p { margin-top: var(--space-3); }

/* ─── Footer ─────────────────────────────────────────────────────────────── */

.site-footer {
  border-top: var(--rule-firm);
  padding-block: var(--space-12) var(--space-10);
  margin-top: var(--space-8);
}
.footer-inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  justify-content: space-between;
  align-items: flex-start;
}
/* The colophon needs its measure; without a basis the nav squeezes it and the
   lines break mid-phrase. */
.footer-inner > :first-child { flex: 1 1 30rem; min-width: 0; }
.footer-links { flex: 0 1 auto; }
.footer-mark { color: var(--color-mark); margin-bottom: var(--space-5); }
.footer-mark svg { height: 0.9375rem; width: auto; }

.colophon {
  margin-top: var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-text-faint);
  line-height: 1.7;
  max-width: 56ch;
}

/* The one sanctioned italic on the entire site. */
.sdg {
  font-family: var(--font-body);
  font-style: italic;
  font-size: var(--step--1);
  color: var(--color-text-muted);
}

.footer-links { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); }
/* WCAG 2.2 SC 2.5.8: these are navigation targets, not inline prose links,
   so the inline exception does not apply — they get a real 24px+ box. */
.footer-links a {
  display: inline-flex;
  align-items: center;
  min-height: 1.5rem;
  padding-inline: var(--space-2);
  margin-inline: calc(var(--space-2) * -1);
  font-size: var(--step--1);
  color: var(--color-text-muted);
  text-decoration: none;
}
.footer-links a:hover { color: var(--color-text); text-decoration: underline; text-underline-offset: 0.15em; }

/* ─── Command palette ────────────────────────────────────────────────────── */

.palette::backdrop {
  background: rgb(2 6 23 / 0.45);
  background: color-mix(in srgb, var(--color-text) 40%, transparent);
}

.palette {
  width: calc(100vw - 2rem);
  max-width: 34rem;
  max-height: calc(100vh - 2rem);
  padding: 0;
  margin: 1rem auto;
  border: var(--rule-firm);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.palette:not([open]) { display: none; }

@supports (height: 100dvh) {
  .palette { max-height: min(26rem, calc(100dvh - 2rem)); }
}

@media (prefers-reduced-motion: no-preference) {
  .palette[open] { animation: palette-in var(--duration-enter) var(--ease-overdamp); }
  .palette[open]::backdrop { animation: fade-in var(--duration-enter) var(--ease-out); }
}
@keyframes palette-in {
  from { opacity: 0; transform: translateY(-0.5rem); }
  to   { opacity: 1; transform: none; }
}
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

.palette-search {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: var(--rule);
  flex: 0 0 auto;
}
.palette-search:focus-within {
  outline: var(--focus-ring-width) solid var(--color-ring);
  outline-offset: calc(-1 * var(--focus-ring-width));
}
.palette-search svg { width: 1rem; height: 1rem; color: var(--color-text-faint); flex: 0 0 auto; }
.palette-search input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--color-text);
  font-size: var(--step-0);
  padding: 0;
}
.palette-search input:focus { outline: none; }
.palette-search input::placeholder { color: var(--color-text-faint); }

.palette-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  margin: calc(var(--space-2) * -1);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
  flex: 0 0 auto;
}
.palette-close:hover { color: var(--color-text); background: var(--color-surface-raised); }
.palette-close svg { width: 1rem; height: 1rem; }

.palette-list { overflow-y: auto; padding: var(--space-2); flex: 1 1 auto; }

.palette-group {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--color-text-faint);
  padding: var(--space-3) var(--space-3) var(--space-2);
}

.palette-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text);
  font-size: var(--step--1);
  text-align: left;
  cursor: pointer;
}
.palette-item[data-active="true"] { background: var(--color-surface-raised); }
.palette-item .pi-icon { color: var(--color-text-faint); display: flex; flex: 0 0 auto; }
.palette-item .pi-icon svg { width: 0.9375rem; height: 0.9375rem; }
.palette-item .pi-label { flex: 1 1 auto; min-width: 0; }
.palette-item .pi-hint {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-text-faint);
  flex: 0 0 auto;
}

.palette-empty {
  padding: var(--space-8) var(--space-5);
  text-align: center;
  font-size: var(--step--1);
  color: var(--color-text-faint);
}

.palette-foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  padding: var(--space-3) var(--space-5);
  border-top: var(--rule);
  font-size: var(--step--1);
  color: var(--color-text-faint);
  flex: 0 0 auto;
}
.palette-foot span { display: inline-flex; align-items: center; gap: var(--space-2); }

@media (pointer: coarse) {
  .palette-foot { display: none; }
}

/* ─── Toast ──────────────────────────────────────────────────────────────── */

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--space-8) + env(safe-area-inset-bottom, 0px));
  max-width: calc(100vw - 2rem);
  transform: translate(-50%, 1rem);
  z-index: var(--z-toast);
  padding: var(--space-3) var(--space-5);
  border: var(--rule-firm);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: var(--shadow-md);
  font-size: var(--step--1);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--duration-quick) var(--ease-out),
              transform var(--duration-moderate) var(--ease-overdamp);
}
.toast[data-show="true"] { opacity: 1; transform: translate(-50%, 0); }

/* ─── Scroll reveal ──────────────────────────────────────────────────────── */
/* Overdamped, zero overshoot, tiny travel. Content is fully present in the
   DOM and readable without JS — this only softens arrival. */

@media (prefers-reduced-motion: no-preference) {
  .reveal { opacity: 0; }
  .reveal[data-seen="true"] {
    opacity: 1;
    transition: opacity var(--duration-slow) var(--ease-out);
  }
}
/* If JS never runs, nothing may stay hidden. */
.no-js .reveal { opacity: 1; }

/* Controls that only mean something with scripting are not offered without it.
   A dead button is worse than an absent one. */
.no-js #theme-toggle,
.no-js #palette-open,
.no-js .header-tools,
.no-js #copy-link,
.no-js .fca { display: none; }

/* With scripting unavailable the theme button is absent, so the menu already
   sits at the shell edge and must not reserve that button's width. */
.no-js .mobile-menu-links { inset-inline-end: 0; }

.fca-fallback {
  display: none;
  max-width: var(--max-width-prose);
  padding: var(--space-5);
  border: var(--rule-firm);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-muted);
}
.no-js .fca-fallback { display: block; }

/* ─── Print ──────────────────────────────────────────────────────────────── */

@media print {
  .site-header, .palette, .toast, .hero-actions, .skip, .work-chev { display: none !important; }
  /* Print the whole portfolio, whatever the accordion state was on screen. */
  .work-details:not([open]) > .work-panel { display: block !important; }
  .reveal { opacity: 1 !important; }
  .section { border-top: 1px solid var(--color-border); padding-block: 1.5rem; }
  h1, h2, h3 { break-after: avoid; page-break-after: avoid; }
  .stack-group, .ledger-row, .now-row, .fact {
    break-inside: avoid;
    page-break-inside: avoid;
  }
  a { text-decoration: underline; }
  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: var(--step--1);
    color: var(--color-text-muted);
  }
}

@media (prefers-contrast: more) {
  :root { --color-border-subtle: var(--color-border); }
}

@media (forced-colors: active) {
  .nav-link[aria-current="true"] { text-decoration: underline; }
  .palette-item[data-active="true"] {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }
  .switch {
    border: 1px solid ButtonText;
    background: Canvas;
  }
  .switch::after { background: ButtonText; }
  .gate[aria-pressed="true"] .switch { outline: 2px solid Highlight; }
  .status .dot { border: 1px solid ButtonText; }
}

/* Dated stamp — anything time-sensitive says when it was true, so the reader
   can judge it. Biographical facts never go in copy that claims to last. */
.stamp {
  display: block;
  margin-top: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-text-faint);
}
