/* ==========================================================================
   Calvin Yang — site.css

   One stylesheet for every page. It is split into cascade layers, and a
   layer can only override the layers listed before it:

     tokens      design decisions: color, type, space, motion
     base        element defaults
     layout      page width, sections, grids
     components  anything with a class name
     pages       layouts used by a single page type
     utilities   single-purpose helpers

   Colors use light-dark(), so each token carries both themes. The active
   theme comes from color-scheme: the OS preference by default, or
   <html data-theme="light|dark"> once the visitor presses the toggle.
   A block that sets `color-scheme: dark` (the instrument panels) gets the
   dark palette in both themes without any extra rules.
   ========================================================================== */

@layer tokens, base, layout, components, pages, utilities;

/* --- fonts ---------------------------------------------------------------- */
/* Latin subsets, self-hosted; licenses in fonts/LICENSE.md. */
@font-face {
  font-family: "Unbounded";
  src: url("../fonts/unbounded-800.woff2") format("woff2");
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Geist";
  src: url("../fonts/geist-variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Martian Mono";
  src: url("../fonts/martian-mono-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Martian Mono";
  src: url("../fonts/martian-mono-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
/* Stand-in while Unbounded loads, scaled so "CALVIN YANG." sets to the same
   width (Arial Black is ~86% as wide), so the nameplate does not jump when
   the real font swaps in. */
@font-face {
  font-family: "Unbounded Fallback";
  src: local("Arial Black"), local("ArialMT-Black"), local("Arial Bold"), local("Arial");
  size-adjust: 117%;
}

/* ==========================================================================
   1. TOKENS
   ========================================================================== */
@layer tokens {
  :root {
    color-scheme: light dark;

    /* --- color: light "bench" / dark "scope" ----------------------------- */
    --bg: light-dark(#f1f0ea, #0b0c0b);
    --bg-raised: light-dark(#f9f8f4, #131513);
    --bg-sunken: light-dark(#e6e5dd, #070807);
    --ink: light-dark(#121412, #ecede6);
    --ink-2: light-dark(#3b403a, #c4c8bf);
    --muted: light-dark(#5a6058, #9aa095);
    --rule: light-dark(#d5d4cb, #262a25);
    --rule-strong: light-dark(#85897e, #5e6459);
    --grid-line: light-dark(rgb(18 20 18 / 0.055), rgb(236 237 230 / 0.05));

    /* copper: coils, links, emphasis. -ink is the small-text-safe shade */
    --accent: light-dark(#e4531b, #ff6a2b);
    --accent-ink: light-dark(#b23c0b, #ff8551);
    --on-accent: light-dark(#121412, #0b0c0b);
    /* signal: live state, highlights, selection (a fill, never thin text on paper) */
    --signal: light-dark(#d2f53c, #c9f31d);
    --on-signal: #121412;
    --led: light-dark(#3d9a17, #c9f31d);

    --primary: light-dark(#121412, #c9f31d);
    --on-primary: light-dark(#f1f0ea, #0b0c0b);
    --focus: light-dark(#b23c0b, #c9f31d);
    /* plots and screenshots are white; they sit on a white plate in both themes */
    --plate: #ffffff;
    --shadow: 0 18px 40px -24px light-dark(rgb(18 20 18 / 0.45), rgb(0 0 0 / 0.8));

    /* --- type ------------------------------------------------------------ */
    --font-display: "Unbounded", "Unbounded Fallback", "Arial Black", system-ui, sans-serif;
    --font-body: "Geist", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-mono: "Martian Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

    --fs-label: 0.6875rem;                              /* 11px mono caps */
    --fs-small: 0.875rem;                               /* 14px */
    --fs-body: 1.0625rem;                               /* 17px */
    --fs-lede: clamp(1.125rem, 1rem + 0.45vw, 1.3125rem);
    --fs-h3: clamp(1.25rem, 1.05rem + 0.7vw, 1.625rem);
    --fs-h2: clamp(1.875rem, 1.2rem + 2.8vw, 3.5rem);
    --fs-h1: clamp(2.25rem, 1.1rem + 4.9vw, 5.5rem);
    --fs-readout: clamp(1.5rem, 1.1rem + 1.4vw, 2.5rem);

    /* --- space (4px base) ------------------------------------------------ */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;
    --space-7: 48px;
    --space-8: 64px;
    --space-9: 96px;
    --section-pad: clamp(56px, 2.5rem + 4vw, 112px);

    /* --- layout ---------------------------------------------------------- */
    --max: 1320px;
    --gutter: clamp(16px, 4vw, 40px);
    --header-h: 64px;

    /* --- motion: three durations, two curves, nothing else ---------------- */
    --t-fast: 150ms;
    --t-base: 300ms;
    --t-slow: 600ms;
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  }

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

/* ==========================================================================
   2. BASE
   ========================================================================== */
@layer base {
  *,
  *::before,
  *::after { box-sizing: border-box; }

  html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    scroll-padding-top: calc(var(--header-h) + 24px);
    background: var(--bg);
  }

  body {
    margin: 0;
    min-height: 100svh;
    background: var(--bg);
    color: var(--ink);
    font: 400 var(--fs-body) / 1.6 var(--font-body);
    font-synthesis: none;
    text-rendering: optimizeLegibility;
    -webkit-font-smoothing: antialiased;
    overflow-x: clip;
  }

  img,
  svg,
  video,
  canvas,
  iframe { display: block; max-width: 100%; }
  img { height: auto; }

  h1, h2, h3, h4, h5, h6 { margin: 0; line-height: 1.1; text-wrap: balance; }
  p, ul, ol, dl, dd, figure, blockquote { margin: 0; }
  p { text-wrap: pretty; }

  a {
    color: inherit;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.22em;
  }
  a:hover { text-decoration-color: var(--accent); }

  button { font: inherit; color: inherit; }
  strong { font-weight: 650; }
  code { font-family: var(--font-mono); font-size: 0.86em; letter-spacing: -0.02em; }

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

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

  [hidden] { display: none !important; }
}

/* ==========================================================================
   3. LAYOUT
   ========================================================================== */
@layer layout {
  .wrap {
    width: min(100% - 2 * var(--gutter), var(--max));
    margin-inline: auto;
  }

  .section { padding-block: var(--section-pad); }
  .section + .section { border-top: 1px solid var(--rule); }
  .section--sunken { background: var(--bg-sunken); }

  /* A dark "instrument" block in both themes. */
  .panel {
    color-scheme: dark;
    background: var(--bg-raised);
    color: var(--ink);
  }

  /* Flow spacing: children of .flow get consistent vertical rhythm. */
  .flow > * + * { margin-top: var(--flow, 1em); }
}

/* ==========================================================================
   4. COMPONENTS
   ========================================================================== */
@layer components {
  /* --- skip link & scroll progress ---------------------------------------- */
  .skip-link {
    position: fixed;
    top: 8px;
    left: 8px;
    z-index: 100;
    padding: 12px 16px;
    background: var(--primary);
    color: var(--on-primary);
    font: 500 var(--fs-small) / 1 var(--font-mono);
    text-decoration: none;
    transform: translateY(-150%);
  }
  .skip-link:focus { transform: none; }

  .progress {
    position: fixed;
    inset: 0 0 auto;
    z-index: 60;
    height: 2px;
    background: var(--accent);
    transform: scaleX(var(--p, 0));
    transform-origin: 0 50%;
    pointer-events: none;
  }
  @supports (animation-timeline: scroll()) {
    .progress {
      animation: progress-grow linear both;
      animation-timeline: scroll(root);
    }
  }
  @keyframes progress-grow {
    from { transform: scaleX(0); }
    to { transform: scaleX(1); }
  }

  /* --- labels: small mono caps, the site's "instrument" voice -------------- */
  .label {
    font: 400 var(--fs-label) / 1.45 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .label--accent { color: var(--accent-ink); }
  .label--ink { color: var(--ink); }

  /* --- header --------------------------------------------------------------- */
  .site-header {
    position: sticky;
    top: 0;
    z-index: 50;
    border-bottom: 1px solid var(--rule);
    background: color-mix(in srgb, var(--bg) 90%, transparent);
    backdrop-filter: saturate(1.3) blur(14px);
    -webkit-backdrop-filter: saturate(1.3) blur(14px);
    view-transition-name: site-header;
  }
  .site-header__inner {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    height: var(--header-h);
  }

  .brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin-right: auto;
    font: 600 15px / 1 var(--font-body);
    letter-spacing: -0.01em;
    text-decoration: none;
  }
  .brand__mark { width: 22px; height: 22px; color: var(--accent); flex: none; }

  .nav__list {
    display: flex;
    align-items: center;
    gap: 2px;
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .nav__link {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 40px;
    padding: 0 10px;
    color: var(--ink-2);
    font: 400 var(--fs-label) / 1 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
  }
  .nav__num { color: var(--muted); font-size: 0.9em; }
  .nav__link::after {
    content: "";
    position: absolute;
    right: 10px;
    bottom: 8px;
    left: 10px;
    height: 1px;
    background: currentColor;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--t-base) var(--ease-out);
  }
  .nav__link:hover,
  .nav__link[aria-current] { color: var(--ink); }
  .nav__link:hover::after,
  .nav__link[aria-current]::after { transform: scaleX(1); }

  .icon-btn {
    display: inline-grid;
    place-items: center;
    width: 40px;
    height: 40px;
    flex: none;
    padding: 0;
    border: 1px solid var(--rule);
    background: transparent;
    color: var(--ink);
    cursor: pointer;
    transition: border-color var(--t-fast), background-color var(--t-fast);
  }
  .icon-btn:hover { border-color: var(--ink); }
  .icon-btn svg { width: 18px; height: 18px; }

  /* Both controls need JS, so they only appear once it is running.
     The theme toggle shows the theme you would switch *to*. */
  .theme-toggle,
  .menu-btn { display: none; }
  .js .theme-toggle { display: inline-grid; }
  .theme-toggle .icon-sun { display: none; }
  :root[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
  :root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

  .menu-btn {
    width: auto;
    padding: 0 12px;
    gap: 8px;
    font: 400 var(--fs-label) / 1 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }

  @media (max-width: 760px) {
    .js .menu-btn { display: inline-flex; align-items: center; }
    .js .nav {
      position: absolute;
      top: 100%;
      right: 0;
      left: 0;
      padding: var(--space-2) var(--gutter) var(--space-5);
      border-bottom: 1px solid var(--rule);
      background: var(--bg);
      display: none;
    }
    .js .site-header.is-open .nav { display: block; }
    .js .nav__list { flex-direction: column; align-items: stretch; gap: 0; }
    .js .nav__link { min-height: 48px; font-size: 12px; border-bottom: 1px solid var(--rule); }
    .js .nav__link::after { display: none; }
    .brand__name { display: none; }
  }
  @media (max-width: 760px) and (min-width: 380px) {
    .brand__name { display: inline; }
  }

  /* --- buttons & links ------------------------------------------------------ */
  .btn-row { display: flex; flex-wrap: wrap; gap: var(--space-3); }

  .btn {
    --btn-bg: transparent;
    --btn-fg: var(--ink);
    --btn-border: var(--rule-strong);
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    min-height: 48px;
    padding: 0 20px;
    border: 1px solid var(--btn-border);
    background: var(--btn-bg);
    color: var(--btn-fg);
    font: 500 12px / 1 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--t-fast), color var(--t-fast), border-color var(--t-fast);
  }
  .btn:hover { --btn-border: var(--ink); }
  .btn__icon { display: inline-block; transition: transform var(--t-base) var(--ease-out); }

  /* Primary: solid, with a clipped corner. The notch is painted in the
     surface color, so blocks with another background set --surface. */
  .btn--primary {
    --btn-bg: var(--primary);
    --btn-fg: var(--on-primary);
    --btn-border: var(--primary);
  }
  .btn--primary::after {
    content: "";
    position: absolute;
    top: -1px;
    right: -1px;
    width: 12px;
    height: 12px;
    background: var(--surface, var(--bg));
    clip-path: polygon(0 0, 100% 0, 100% 100%);
  }
  .btn--primary:hover {
    --btn-bg: var(--accent);
    --btn-fg: var(--on-accent);
    --btn-border: var(--accent);
  }
  .btn--lg { min-height: 56px; padding: 0 24px; font-size: 13px; }
  .btn--email { text-transform: none; letter-spacing: 0; font-size: 14px; }

  .link-arrow {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 10px 0 8px;
    border-bottom: 1px solid currentColor;
    font: 500 12px / 1 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
    transition: color var(--t-fast);
  }
  .link-arrow:hover { color: var(--accent-ink); }
  .link-arrow__icon { display: inline-block; transition: transform var(--t-base) var(--ease-out); }

  @media (hover: hover) {
    .btn:hover .btn__icon--right,
    .link-arrow:hover .link-arrow__icon { transform: translateX(4px); }
    .btn:hover .btn__icon--down { transform: translateY(3px); }
    .btn:hover .btn__icon--up-right { transform: translate(3px, -3px); }
    .btn:hover .btn__icon--left { transform: translateX(-4px); }
  }

  /* [↗] marks a link that leaves the site. */
  .ext {
    font-family: var(--font-mono);
    font-size: 0.8em;
    letter-spacing: 0;
    color: var(--muted);
    white-space: nowrap;
  }

  /* --- chips, status, LEDs -------------------------------------------------- */
  .chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 0;
    list-style: none;
  }
  .chips li {
    padding: 6px 9px;
    border: 1px solid var(--rule);
    color: var(--ink-2);
    font: 400 var(--fs-label) / 1.2 var(--font-mono);
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }

  .status {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    color: var(--ink);
  }
  .led {
    width: 8px;
    height: 8px;
    flex: none;
    border-radius: 50%;
    background: var(--led);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--led) 22%, transparent);
  }

  /* --- frames: crop-mark brackets around media ------------------------------ */
  .frame { position: relative; display: block; }
  .frame::before {
    --len: 14px;
    --w: 1.5px;
    --c: var(--bracket, var(--ink));
    content: "";
    position: absolute;
    inset: -7px;
    z-index: 3;
    pointer-events: none;
    background:
      linear-gradient(var(--c), var(--c)) top left / var(--len) var(--w),
      linear-gradient(var(--c), var(--c)) top left / var(--w) var(--len),
      linear-gradient(var(--c), var(--c)) top right / var(--len) var(--w),
      linear-gradient(var(--c), var(--c)) top right / var(--w) var(--len),
      linear-gradient(var(--c), var(--c)) bottom left / var(--len) var(--w),
      linear-gradient(var(--c), var(--c)) bottom left / var(--w) var(--len),
      linear-gradient(var(--c), var(--c)) bottom right / var(--len) var(--w),
      linear-gradient(var(--c), var(--c)) bottom right / var(--w) var(--len);
    background-repeat: no-repeat;
    transition: transform var(--t-base) var(--ease-out);
  }
  .frame__media {
    display: block;
    overflow: hidden;
    background: var(--bg-sunken);
  }
  .frame__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: var(--pos, 50% 50%);
    transition: transform var(--t-slow) var(--ease-out);
  }
  .frame__tag {
    position: absolute;
    bottom: 0;
    left: 0;
    z-index: 2;
    max-width: calc(100% - 24px);
    padding: 6px 9px;
    background: var(--ink);
    color: var(--bg);
    font: 400 var(--fs-label) / 1.35 var(--font-mono);
    letter-spacing: 0.05em;
    text-transform: uppercase;
  }
  @media (hover: hover) {
    a.frame:hover::before,
    .frame:has(a:hover)::before { transform: scale(0.985); --bracket: var(--accent); }
    a.frame:hover .frame__media img { transform: scale(1.03); }
  }

  /* A white backing for plots and screenshots, in both themes. */
  .plate { background: var(--plate); }
  .plate img { object-fit: contain; }

  /* --- readouts: a measured value with its unit and meaning ---------------- */
  .readouts {
    display: grid;
    grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr));
    border-top: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
  }
  .readout {
    display: flex;
    flex-direction: column-reverse;
    justify-content: flex-end;
    gap: 8px;
    padding: 14px 12px 14px 0;
  }
  .readout + .readout { padding-left: 12px; border-left: 1px solid var(--rule); }
  .readout dt {
    font: 400 var(--fs-label) / 1.45 var(--font-mono);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .readout dd {
    font: 800 var(--fs-readout) / 1 var(--font-display);
    letter-spacing: -0.03em;
    white-space: nowrap;
  }
  .unit {
    margin-left: 0.2em;
    font: 400 0.42em / 1 var(--font-mono);
    letter-spacing: 0;
    color: var(--muted);
  }
  @media (max-width: 560px) {
    .readouts { grid-template-columns: 1fr; }
    .readout {
      flex-direction: row-reverse;
      align-items: baseline;
      justify-content: space-between;
      gap: 16px;
      padding: 12px 0;
    }
    .readout + .readout { padding-left: 0; border-left: 0; border-top: 1px solid var(--rule); }
    .readout dt { text-align: right; max-width: 20ch; }
  }

  /* --- spec: a datasheet-style key/value list -------------------------------- */
  .spec { border-top: 1px solid var(--rule-strong); }
  .spec > div {
    display: grid;
    grid-template-columns: minmax(88px, 1fr) minmax(0, 2.4fr);
    gap: var(--space-4);
    padding: 11px 0;
    border-bottom: 1px solid var(--rule);
  }
  .spec dt {
    font: 400 var(--fs-label) / 1.6 var(--font-mono);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .spec dd { font-size: var(--fs-small); line-height: 1.5; }

  /* --- section heading ------------------------------------------------------ */
  .section-head {
    display: grid;
    gap: var(--space-4);
    margin-bottom: clamp(32px, 5vw, 64px);
  }
  .section-head__index {
    display: flex;
    align-items: center;
    gap: var(--space-3);
  }
  .section-head__index b { font-weight: 500; color: var(--accent-ink); }
  .section-head__rule { flex: 1; height: 1px; background: var(--rule); }
  .section-title {
    max-width: 20ch;
    font: 800 var(--fs-h2) / 1.04 var(--font-display);
    letter-spacing: -0.035em;
  }
  .section-sub { max-width: 58ch; color: var(--ink-2); font-size: var(--fs-lede); line-height: 1.55; }

  /* A highlighter stroke, drawn in when the heading scrolls into view. */
  .mark {
    padding: 0 0.06em;
    background: linear-gradient(var(--signal), var(--signal)) 0 58% / 100% 72% no-repeat;
    color: var(--on-signal);
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
  }

  /* --- ticked lists --------------------------------------------------------- */
  .ticks { padding: 0; list-style: none; }
  .ticks li { position: relative; padding-left: 22px; color: var(--ink-2); }
  .ticks li + li { margin-top: 10px; }
  .ticks li::before {
    content: "→";
    position: absolute;
    left: 0;
    color: var(--accent);
    font-family: var(--font-mono);
    font-size: 0.85em;
    line-height: 1.9;
  }

  /* --- figures -------------------------------------------------------------- */
  .figure figcaption {
    display: flex;
    gap: var(--space-3);
    margin-top: var(--space-3);
    color: var(--muted);
    font-size: var(--fs-small);
    line-height: 1.5;
  }
  .figure__num {
    flex: none;
    padding-top: 2px;
    color: var(--accent-ink);
    font: 400 var(--fs-label) / 1.45 var(--font-mono);
    letter-spacing: 0.05em;
    text-transform: uppercase;
  }
  .figure .frame__media { aspect-ratio: var(--ratio, 4 / 3); }
  .figure--contain .frame__media { background: var(--plate); }
  .figure--contain img { object-fit: contain; padding: clamp(6px, 1.2vw, 14px); }

  .gallery {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(20px, 3vw, 32px) clamp(16px, 2.4vw, 28px);
  }
  .gallery--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .gallery .figure--wide { grid-column: 1 / -1; }
  @media (max-width: 700px) {
    .gallery,
    .gallery--3 { grid-template-columns: 1fr; }
  }

  /* --- video: thumbnail first, player on click ------------------------------- */
  .video-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(20px, 3vw, 32px) clamp(16px, 2.4vw, 28px);
  }
  @media (max-width: 700px) { .video-grid { grid-template-columns: 1fr; } }

  .video__screen {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: #000;
  }
  .video__play {
    display: block;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
  }
  .video__play img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--t-slow) var(--ease-out), opacity var(--t-base);
  }
  .video__play:focus-visible { outline-offset: -4px; }
  .video__icon {
    position: absolute;
    top: 50%;
    left: 50%;
    display: grid;
    place-items: center;
    width: 60px;
    height: 60px;
    border: 1px solid rgb(255 255 255 / 0.7);
    border-radius: 50%;
    background: rgb(11 12 11 / 0.55);
    transform: translate(-50%, -50%);
    transition: transform var(--t-base) var(--ease-out), background-color var(--t-fast);
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
  }
  .video__icon::before {
    content: "";
    margin-left: 4px;
    border-top: 9px solid transparent;
    border-bottom: 9px solid transparent;
    border-left: 15px solid #fff;
  }
  @media (hover: hover) {
    .video__play:hover img { transform: scale(1.03); }
    .video__play:hover .video__icon { transform: translate(-50%, -50%) scale(1.1); background: var(--accent); }
  }
  .video__screen iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
  .video__meta {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-4);
    margin-top: var(--space-3);
  }
  .video__title { font-weight: 550; font-size: var(--fs-small); line-height: 1.4; }
  .video__out {
    flex: none;
    font: 400 var(--fs-label) / 1 var(--font-mono);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--muted);
  }
  .video__out:hover { color: var(--accent-ink); }

  /* --- the coil instrument (home hero) -------------------------------------- */
  .instrument {
    --surface: var(--bg-raised);
    --bracket: var(--muted);
    border: 1px solid var(--rule);
  }
  .instrument__bar,
  .instrument__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: 0 var(--space-4);
  }
  .instrument__bar { min-height: 52px; border-bottom: 1px solid var(--rule); }
  .instrument__foot { min-height: 44px; border-top: 1px solid var(--rule); }
  .instrument__stage {
    position: relative;
    aspect-ratio: 900 / 340;
    background:
      linear-gradient(var(--grid-line) 1px, transparent 1px) 0 0 / 30px 30px,
      linear-gradient(90deg, var(--grid-line) 1px, transparent 1px) 0 0 / 30px 30px,
      var(--bg);
  }
  .instrument__stage canvas { width: 100%; height: 100%; }
  .instrument__btn {
    display: none; /* shown once JS can drive it */
    align-items: center;
    gap: 10px;
    min-height: 36px;
    padding: 0 12px;
    border: 1px solid var(--rule-strong);
    background: transparent;
    color: var(--ink);
    font: 500 var(--fs-label) / 1 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    transition: background-color var(--t-fast), color var(--t-fast), border-color var(--t-fast);
  }
  .js .instrument__btn { display: inline-flex; }
  .instrument__btn:hover { border-color: var(--signal); }
  .instrument__btn[aria-pressed="true"] {
    border-color: var(--signal);
    background: var(--signal);
    color: var(--on-signal);
  }
  .instrument__btn-icon { width: 9px; height: 9px; background: currentColor; clip-path: polygon(0 0, 100% 50%, 0 100%); }
  .instrument__btn[aria-pressed="true"] .instrument__btn-icon { clip-path: none; }
  .instrument__readouts { display: flex; gap: var(--space-4); }
  .instrument__led { display: inline-flex; align-items: center; gap: 7px; }
  .instrument__led::before {
    content: "";
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--rule-strong);
    transition: background-color var(--t-fast), box-shadow var(--t-fast);
  }
  .instrument__led.is-on { color: var(--ink); }
  .instrument__led.is-on::before { background: var(--accent); box-shadow: 0 0 10px var(--accent); }
  .instrument__clock { font-variant-numeric: tabular-nums; }
  .instrument__note {
    padding: var(--space-3) var(--space-4) var(--space-4);
    border-top: 1px solid var(--rule);
    color: var(--muted);
    font-size: 13px;
    line-height: 1.5;
  }
  .instrument__btn { white-space: nowrap; }
  @media (max-width: 480px) {
    .instrument__fig { display: none; }
  }

  /* --- source-code link ------------------------------------------------------ */
  .repo-link {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 2px 14px;
    padding: 14px 16px;
    border: 1px solid var(--rule-strong);
    text-decoration: none;
    transition: border-color var(--t-fast), background-color var(--t-fast);
  }
  .repo-link:hover { border-color: var(--ink); background: var(--bg-raised); }
  .repo-link svg { width: 22px; height: 22px; fill: currentColor; grid-row: span 2; }
  .repo-link__label { font: 400 var(--fs-label) / 1.4 var(--font-mono); letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); }
  .repo-link__name { font: 500 var(--fs-small) / 1.35 var(--font-mono); overflow-wrap: anywhere; }
  .repo-link .ext { grid-row: 1 / span 2; grid-column: 3; }

  /* --- wiring schematic -------------------------------------------------------- */
  .circuit-wrap {
    color-scheme: dark;
    --surface: var(--bg-raised);
    padding: clamp(14px, 3vw, 32px);
    border: 1px solid var(--rule);
    background:
      linear-gradient(var(--grid-line) 1px, transparent 1px) 0 0 / 32px 32px,
      linear-gradient(90deg, var(--grid-line) 1px, transparent 1px) 0 0 / 32px 32px,
      var(--bg-raised);
    color: var(--ink);
  }
  .circuit { width: 100%; height: auto; }
  .circuit text { font-family: var(--font-mono); fill: var(--muted); }
  .circuit .part-name { font-size: 15px; font-weight: 500; fill: var(--ink); letter-spacing: 0.02em; }
  .circuit .part-sub { font-size: 11px; letter-spacing: 0.08em; }
  .circuit .pin-label { font-size: 11px; letter-spacing: 0.04em; }
  .circuit .port-label { font-size: 11px; font-weight: 500; fill: var(--signal); }
  .circuit .rail-label { font-size: 12px; font-weight: 500; letter-spacing: 0.06em; }
  .circuit .rail-5v { fill: var(--accent); }
  .circuit .screen-line { font-size: 12px; fill: var(--signal); }
  .circuit .part-box { fill: var(--bg); stroke: var(--rule-strong); stroke-width: 1; }
  .circuit .chip { fill: color-mix(in srgb, var(--signal) 6%, transparent); stroke: color-mix(in srgb, var(--signal) 30%, transparent); }
  .circuit .screen { fill: #050605; stroke: color-mix(in srgb, var(--signal) 30%, transparent); }
  .circuit .wire { fill: none; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
  .circuit .n-5v { stroke: var(--accent); }
  .circuit .n-gnd { stroke: var(--muted); }
  .circuit .n-sig { stroke: var(--signal); }
  .circuit .node { fill: var(--bg-raised); stroke-width: 1.4; }
  .circuit .node-5v { stroke: var(--accent); }
  .circuit .node-gnd { stroke: var(--muted); }
  .circuit .node-sig { stroke: var(--signal); }
  .circuit .part { cursor: pointer; }
  .circuit .part .hit { fill: transparent; }
  .circuit .part:focus { outline: none; }
  .circuit .part:focus-visible .part-box { stroke: var(--focus); stroke-width: 2.5; }
  .circuit :is(.part-box, .part-name, .part-sub, .wire, .node, .pin-label, .port-label, .chip, .screen, .screen-line) {
    transition: opacity var(--t-base), stroke-width var(--t-base);
  }
  /* Selecting a part keeps its nets bright and dims everything else. */
  .circuit[data-focus] .part:not(.is-lit) :is(.part-box, .part-name, .part-sub, .chip, .screen, .screen-line) { opacity: 0.3; }
  .circuit[data-focus] :is(.wire, .node, .pin-label, .port-label):not(.is-lit) { opacity: 0.14; }
  .circuit .part.is-lit .part-box { stroke: var(--ink); }
  .circuit .wire.is-lit { stroke-width: 2.6; }
  /* Current flows only along the lit nets, so nothing moves on its own. */
  @media (prefers-reduced-motion: no-preference) {
    .circuit .n-sig.is-lit { stroke-dasharray: 5 9; animation: circuit-flow 0.6s linear infinite; }
  }
  @keyframes circuit-flow { to { stroke-dashoffset: -28; } }

  .circuit-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 22px;
    margin-top: var(--space-4);
    padding: var(--space-4) 0 0;
    border-top: 1px solid var(--rule);
    list-style: none;
  }
  .circuit-legend li { display: flex; align-items: center; gap: 9px; }
  .circuit-legend i { width: 20px; height: 2px; background: var(--muted); }
  .circuit-legend .k-5v i { background: var(--accent); }
  .circuit-legend .k-sig i { background: var(--signal); }
  .circuit-hint { margin-top: var(--space-3); }
  .circuit-hint__pan { display: none; }
  /* A wiring diagram does not survive being squeezed to phone width, so it
     keeps a readable size and pans sideways instead. */
  @media (max-width: 760px) {
    .circuit-scroll { overflow-x: auto; overscroll-behavior-x: contain; }
    .circuit-scroll .circuit { min-width: 640px; }
    .circuit-hint__pan { display: inline; }
  }

  /* --- résumé (markup generated by tools/sync_resume.py) --------------------- */
  .resume-shell { border: 1px solid var(--rule-strong); background: var(--bg-raised); --surface: var(--bg-raised); }
  .resume-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--rule);
  }
  .resume-bar .btn { min-height: 42px; padding: 0 16px; }
  .resume-doc { padding: clamp(20px, 4vw, 56px); }
  .resume-doc-head { padding-bottom: var(--space-5); }
  .resume-doc-head h3 {
    font: 800 clamp(1.75rem, 1.2rem + 2vw, 2.75rem) / 1 var(--font-display);
    letter-spacing: -0.03em;
  }
  .resume-contact {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 18px;
    margin-top: var(--space-3);
    padding: 0;
    list-style: none;
    color: var(--ink-2);
    font-size: var(--fs-small);
  }
  .resume-block {
    display: grid;
    grid-template-columns: 160px minmax(0, 1fr);
    gap: var(--space-5);
    padding-block: var(--space-5);
    border-top: 1px solid var(--rule);
  }
  .resume-block > h4 {
    font: 400 var(--fs-label) / 1.8 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--accent-ink);
  }
  .resume-entry + .resume-entry { margin-top: var(--space-5); }
  .resume-entry-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 4px 16px;
  }
  .resume-entry-head h5 { font-size: 1.0625rem; font-weight: 600; line-height: 1.35; }
  .resume-when {
    font: 400 var(--fs-label) / 1.4 var(--font-mono);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
    white-space: nowrap;
  }
  .resume-where { margin-top: 2px; color: var(--ink-2); font-size: var(--fs-small); }
  .resume-entry ul { margin: 10px 0 0; padding-left: 18px; color: var(--ink-2); }
  .resume-entry li + li { margin-top: 6px; }
  .resume-entry li::marker { color: var(--accent); }
  .resume-skills { display: grid; gap: var(--space-3); }
  .resume-skills > div { display: grid; grid-template-columns: 170px minmax(0, 1fr); gap: var(--space-4); }
  .resume-skills dt { font: 400 var(--fs-label) / 1.8 var(--font-mono); letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); }
  .resume-summary { color: var(--ink-2); }
  @media (max-width: 720px) {
    .resume-block,
    .resume-skills > div { grid-template-columns: 1fr; gap: var(--space-2); }
  }

  /* --- next project (generated) ---------------------------------------------- */
  .next-project {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: var(--space-5);
    padding: clamp(28px, 4vw, 48px) 0;
    border-top: 1px solid var(--ink);
    border-bottom: 1px solid var(--rule);
    text-decoration: none;
  }
  .next-project__title {
    display: block;
    margin-top: var(--space-3);
    font: 800 clamp(1.5rem, 1rem + 2.4vw, 3rem) / 1.05 var(--font-display);
    letter-spacing: -0.03em;
    transition: color var(--t-fast);
  }
  .next-project__arrow {
    font: 400 clamp(1.5rem, 1rem + 2vw, 2.5rem) / 1 var(--font-mono);
    transition: transform var(--t-base) var(--ease-out);
  }
  @media (hover: hover) {
    .next-project:hover .next-project__title { color: var(--accent-ink); }
    .next-project:hover .next-project__arrow { transform: translateX(8px); }
  }

  /* --- footer: an engineering-drawing title block (generated) ---------------- */
  .site-footer {
    padding-block: var(--space-7) var(--space-6);
    border-top: 1px solid var(--rule);
  }
  .title-block {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    border: 1px solid var(--rule-strong);
  }
  .title-block > div {
    display: grid;
    gap: 4px;
    padding: 10px 12px;
    border-right: 1px solid var(--rule);
  }
  .title-block > div:last-child { border-right: 0; }
  .title-block dt {
    font: 400 10px / 1.3 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .title-block dd { font-size: var(--fs-small); line-height: 1.35; overflow-wrap: anywhere; }
  .title-block__wide { grid-column: span 2; }
  .site-footer__note { margin-top: var(--space-4); }
  @media (max-width: 900px) {
    .title-block { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .title-block > div { border-bottom: 1px solid var(--rule); }
    .title-block > div:nth-child(2n) { border-right: 0; }
    .title-block__wide { grid-column: 1 / -1; border-bottom: 0; }
  }

  /* --- reveal on scroll (only when JS is running and motion is welcome) ---- */
  @media (prefers-reduced-motion: no-preference) {
    .js .reveal {
      opacity: 0;
      transform: translateY(18px);
      transition: opacity var(--t-slow) var(--ease-out), transform var(--t-slow) var(--ease-out);
      transition-delay: var(--delay, 0ms);
    }
    .js .reveal.is-in { opacity: 1; transform: none; }
    .js .mark {
      background-size: 0% 72%;
      transition: background-size var(--t-slow) var(--ease-out) 250ms;
    }
    .js .is-in .mark { background-size: 100% 72%; }
    /* Highlighted text is dark in both themes. On the dark page it must never
       appear before its highlight does, so there is no draw-in there. */
    :root.js[data-theme="dark"] .mark { background-size: 100% 72%; transition: none; }
  }
}

/* ==========================================================================
   5. PAGES
   ========================================================================== */
@layer pages {
  /* --- home: hero ------------------------------------------------------------ */
  .hero {
    position: relative;
    isolation: isolate;
    padding-block: clamp(20px, 3vw, 36px) clamp(40px, 5vw, 72px);
    overflow: clip;
  }
  .hero::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
      linear-gradient(var(--grid-line) 1px, transparent 1px) 0 0 / 24px 24px,
      linear-gradient(90deg, var(--grid-line) 1px, transparent 1px) 0 0 / 24px 24px;
    -webkit-mask-image: linear-gradient(#000 30%, transparent 92%);
    mask-image: linear-gradient(#000 30%, transparent 92%);
    pointer-events: none;
  }
  .hero__inner { container-type: inline-size; }
  .hero__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px 24px;
    padding-bottom: var(--space-3);
    border-bottom: 1px solid var(--rule);
  }
  .hero__coords { color: var(--muted); }

  /* The name spans the full width at any size. In Unbounded ExtraBold at this
     tracking, "CALVIN" + "YANG." measure 8.35em, so 11.2% of the container
     leaves room for the gap that space-between opens up. */
  .nameplate {
    display: flex;
    justify-content: space-between;
    gap: 0.2em;
    margin: clamp(18px, 3cqi, 44px) 0 clamp(28px, 4cqi, 56px);
    font: 800 clamp(2.25rem, 10.3vw, 9.25rem) / 0.84 var(--font-display);
    font-size: 11.2cqi;
    letter-spacing: -0.045em;
    text-transform: uppercase;
    white-space: nowrap;
  }
  .nameplate__word { display: block; }
  .nameplate__word + .nameplate__word { --i: 1; }
  .nameplate__dot { color: var(--accent); }

  .hero__grid {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: clamp(28px, 5vw, 80px);
    align-items: end;
  }
  .hero__statement {
    margin-top: var(--space-3);
    font: 600 clamp(1.625rem, 1.1rem + 1.7vw, 2.5rem) / 1.08 var(--font-body);
    letter-spacing: -0.03em;
  }
  .hero__lede { margin-top: var(--space-4); max-width: 46ch; color: var(--ink-2); font-size: var(--fs-lede); line-height: 1.55; }
  .hero__intro .btn-row { margin-top: var(--space-6); }

  .facts {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    margin-top: clamp(40px, 6vw, 80px);
    border-top: 1px solid var(--ink);
  }
  .fact {
    display: flex;
    flex-direction: column-reverse;
    justify-content: flex-end;
    gap: 10px;
    padding: var(--space-4) var(--space-4) 0 0;
  }
  .fact + .fact { padding-left: var(--space-4); border-left: 1px solid var(--rule); }
  .fact dd { font: 800 var(--fs-readout) / 1 var(--font-display); letter-spacing: -0.035em; white-space: nowrap; }
  .fact dt {
    max-width: 26ch;
    font: 400 var(--fs-label) / 1.5 var(--font-mono);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--muted);
  }

  @media (max-width: 900px) {
    .hero__grid { grid-template-columns: minmax(0, 1fr); }
    .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .fact:nth-child(3) { padding-left: 0; border-left: 0; }
    .fact:nth-child(n + 3) { margin-top: var(--space-4); border-top: 1px solid var(--rule); }
  }

  /* --- home: selected work --------------------------------------------------- */
  .work {
    display: grid;
    gap: clamp(28px, 4vw, 64px);
    padding-block: clamp(28px, 4vw, 48px);
    border-top: 1px solid var(--ink);
  }
  .work--feature { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); align-items: start; }
  /* 16:9 trims the thin letterbox bars the V3 bench frame grab carries. */
  .work__media .frame__media { aspect-ratio: 16 / 9; }
  .work__inset {
    position: absolute;
    right: clamp(-14px, -1vw, -8px);
    bottom: -28px;
    z-index: 4;
    width: 36%;
    padding: 6px 6px 0;
    border: 1px solid var(--rule-strong);
    background: var(--plate);
    box-shadow: var(--shadow);
    color: #3b403a;
  }
  .work__inset img { width: 100%; aspect-ratio: 932 / 536; object-fit: cover; }
  .work__inset span {
    display: block;
    padding: 6px 2px;
    font: 400 10px / 1.3 var(--font-mono);
    letter-spacing: 0.05em;
    text-transform: uppercase;
  }
  .work__body { --flow: var(--space-4); }
  .work__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; }
  .work__meta b { font-weight: 500; color: var(--ink); }
  .work__title {
    margin-top: var(--space-3);
    font: 800 clamp(1.625rem, 1rem + 2vw, 2.75rem) / 1.05 var(--font-display);
    letter-spacing: -0.03em;
  }
  .work__title a { text-decoration: none; }
  .work__title a:hover { color: var(--accent-ink); }
  .work__kicker { font: 600 var(--fs-h3) / 1.2 var(--font-body); letter-spacing: -0.02em; }
  .work__body > p:not(.work__meta, .work__kicker) { max-width: 54ch; color: var(--ink-2); }
  .work__body .readouts { margin-top: var(--space-5); }
  .work__body .link-arrow { margin-top: var(--space-5); }

  .work--panel {
    --surface: var(--bg-raised);
    --bracket: var(--muted);
    grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
    margin-block: clamp(20px, 3vw, 40px);
    padding: clamp(20px, 4vw, 48px);
    border: 1px solid var(--rule);
  }
  .work--panel .figure .frame__media { aspect-ratio: 1050 / 675; }
  .checklist { margin-top: var(--space-5); padding: 0; list-style: none; border-top: 1px solid var(--rule); }
  .checklist li {
    display: grid;
    grid-template-columns: 22px minmax(0, 1fr) auto;
    gap: var(--space-3);
    padding: 12px 0;
    border-bottom: 1px solid var(--rule);
  }
  .checklist__tick { color: var(--signal); font-family: var(--font-mono); }
  .checklist strong { display: block; font-weight: 600; font-size: 15px; }
  .checklist p { color: var(--muted); font-size: 13px; margin-top: 2px; }
  .checklist__state { padding-top: 2px; }
  .work__foot { margin-top: var(--space-4); color: var(--ink-2); font-size: var(--fs-small); }

  .work-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(28px, 4vw, 56px);
    padding-top: clamp(28px, 4vw, 48px);
    border-top: 1px solid var(--ink);
  }
  .work-card { --flow: var(--space-4); }
  .work-card .frame__media { aspect-ratio: 16 / 10; }
  .work-card .frame { margin-bottom: var(--space-5); }
  .work-card .readouts { --cols: 2; margin-top: var(--space-5); }

  @media (max-width: 900px) {
    .work--feature,
    .work--panel,
    .work-grid { grid-template-columns: minmax(0, 1fr); }
    .work__inset { width: 42%; bottom: -20px; }
  }
  /* On a phone the inset would cover the photo's caption. */
  @media (max-width: 600px) {
    .work__inset { display: none; }
  }

  /* --- home: about ------------------------------------------------------------ */
  .about {
    display: grid;
    grid-template-columns: minmax(0, 6fr) minmax(0, 6fr);
    gap: clamp(32px, 6vw, 96px);
    align-items: start;
  }
  .about__title {
    font: 800 clamp(2rem, 1.2rem + 3.2vw, 4rem) / 1.02 var(--font-display);
    letter-spacing: -0.04em;
  }
  .about__copy { --flow: var(--space-4); }
  .about__copy > p { color: var(--ink-2); }
  .about__copy > p:first-child { color: var(--ink); font-size: var(--fs-lede); line-height: 1.5; }
  .about__copy .spec { margin-top: var(--space-6); }
  @media (max-width: 900px) { .about { grid-template-columns: minmax(0, 1fr); } }

  /* --- home: experience -------------------------------------------------------- */
  .timeline { padding: 0; list-style: none; border-top: 1px solid var(--ink); }
  .timeline__item {
    display: grid;
    grid-template-columns: minmax(150px, 3fr) minmax(0, 9fr);
    gap: var(--space-5);
    padding-block: clamp(22px, 3vw, 36px);
    border-bottom: 1px solid var(--rule);
  }
  .timeline__when { padding-top: 6px; }
  .timeline__title { font: 600 var(--fs-h3) / 1.2 var(--font-body); letter-spacing: -0.02em; }
  .timeline__org { margin-top: 4px; color: var(--accent-ink); font-size: var(--fs-small); font-weight: 500; }
  .timeline .ticks { margin-top: var(--space-4); max-width: 68ch; }
  .timeline .readouts { --cols: 2; max-width: 460px; margin-top: var(--space-5); }
  @media (max-width: 720px) {
    .timeline__item { grid-template-columns: minmax(0, 1fr); gap: var(--space-2); }
  }

  /* --- home: capabilities table ------------------------------------------------ */
  .caps { width: 100%; border-collapse: collapse; border-top: 1px solid var(--ink); }
  .caps th,
  .caps td { padding: 18px 16px 18px 0; border-bottom: 1px solid var(--rule); text-align: left; vertical-align: top; }
  .caps thead th {
    padding-block: 10px;
    font: 400 var(--fs-label) / 1.4 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .caps tbody th { width: 28%; font: 600 1.125rem / 1.3 var(--font-body); letter-spacing: -0.01em; }
  .caps__num { display: block; margin-bottom: 4px; color: var(--accent-ink); font: 400 var(--fs-label) / 1 var(--font-mono); }
  .caps td { color: var(--ink-2); }
  .caps td:last-child { width: 24%; padding-right: 0; font-size: var(--fs-small); }
  @media (max-width: 760px) {
    .caps thead { display: none; }
    .caps tr { display: grid; padding: 16px 0; border-bottom: 1px solid var(--rule); }
    .caps th,
    .caps td { width: auto !important; padding: 0; border: 0; }
    .caps td { margin-top: 8px; }
  }

  /* --- home: contact ------------------------------------------------------------ */
  .contact { --surface: var(--bg-raised); }
  .contact__title {
    font: 800 clamp(2.25rem, 1rem + 5.4vw, 6.25rem) / 0.98 var(--font-display);
    letter-spacing: -0.045em;
  }
  .contact__title a { text-decoration-thickness: 3px; text-underline-offset: 0.12em; text-decoration-color: var(--accent); }
  .contact__title a:hover { color: var(--accent); }
  .contact__grid {
    display: grid;
    grid-template-columns: minmax(0, 6fr) minmax(0, 6fr);
    gap: var(--space-6);
    align-items: end;
    margin-top: clamp(32px, 5vw, 64px);
    padding-top: var(--space-5);
    border-top: 1px solid var(--rule);
  }
  .contact__text { max-width: 52ch; color: var(--ink-2); font-size: var(--fs-lede); line-height: 1.55; }
  .contact__actions { display: grid; gap: var(--space-4); justify-items: start; }
  .contact__links { display: flex; flex-wrap: wrap; gap: 4px 20px; padding: 0; list-style: none; }
  .contact__links a {
    display: inline-flex;
    gap: 6px;
    padding: 8px 0;
    font: 400 12px / 1 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
  }
  .contact__links a:hover { color: var(--accent); }
  @media (max-width: 800px) { .contact__grid { grid-template-columns: minmax(0, 1fr); } }

  /* --- case studies --------------------------------------------------------------- */
  .cs-hero { padding-block: clamp(20px, 3vw, 36px) clamp(32px, 5vw, 56px); }
  .crumbs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px 24px;
    padding-bottom: var(--space-3);
    border-bottom: 1px solid var(--rule);
  }
  .crumbs a { text-decoration: none; color: var(--ink); }
  .crumbs a:hover { color: var(--accent-ink); }
  .cs-kicker { margin-top: clamp(28px, 5vw, 56px); }
  .cs-title {
    margin-top: var(--space-4);
    max-width: 16ch;
    font: 800 var(--fs-h1) / 0.98 var(--font-display);
    letter-spacing: -0.045em;
    overflow-wrap: break-word;
  }
  .cs-intro {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: clamp(28px, 5vw, 80px);
    margin-top: clamp(24px, 4vw, 48px);
    align-items: start;
  }
  .cs-lede { color: var(--ink-2); font-size: var(--fs-lede); line-height: 1.55; max-width: 60ch; }
  .cs-intro .chips { margin-top: var(--space-5); }
  .cs-intro .repo-link { margin-top: var(--space-4); }
  @media (max-width: 860px) { .cs-intro { grid-template-columns: minmax(0, 1fr); } }

  .cs-media { margin-top: clamp(32px, 5vw, 64px); }
  .cs-media .frame__media { aspect-ratio: var(--ratio, 16 / 9); max-height: 82svh; }
  /* A plot on a white plate is too bright at full bleed, especially in the
     dark theme, and its labels get oversized. Keep it at reading size. */
  .cs-media.figure--contain { max-width: 1000px; margin-inline: auto; }
  .cs-media.figure--contain .frame__media { max-height: none; }

  .cs-layout {
    display: grid;
    grid-template-columns: 200px minmax(0, 1fr);
    gap: clamp(32px, 6vw, 96px);
    padding-block: clamp(40px, 6vw, 80px) var(--section-pad);
  }
  .cs-toc { position: sticky; top: calc(var(--header-h) + 32px); align-self: start; }
  .cs-toc ol { margin-top: var(--space-3); padding: 0; list-style: none; border-top: 1px solid var(--rule); }
  .cs-toc a {
    display: flex;
    gap: 10px;
    padding: 9px 0;
    border-bottom: 1px solid var(--rule);
    color: var(--muted);
    font: 400 var(--fs-label) / 1.4 var(--font-mono);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    text-decoration: none;
    transition: color var(--t-fast);
  }
  .cs-toc a:hover,
  .cs-toc a[aria-current] { color: var(--ink); }
  .cs-toc a[aria-current] span { color: var(--accent-ink); }
  @media (max-width: 960px) {
    .cs-layout { grid-template-columns: minmax(0, 1fr); }
    .cs-toc { display: none; }
  }

  .cs-body { max-width: 780px; }
  .cs-section { --flow: var(--space-4); }
  .cs-section + .cs-section { margin-top: clamp(44px, 5vw, 72px); padding-top: clamp(28px, 3.5vw, 44px); border-top: 1px solid var(--rule); }
  .cs-section h2 {
    margin-top: var(--space-3);
    font: 800 clamp(1.5rem, 1rem + 1.9vw, 2.5rem) / 1.08 var(--font-display);
    letter-spacing: -0.035em;
  }
  .cs-section h3 { margin-top: var(--space-6); font: 600 var(--fs-h3) / 1.25 var(--font-body); letter-spacing: -0.02em; }
  .cs-section > p { color: var(--ink-2); max-width: 68ch; }
  .cs-section > p strong { color: var(--ink); }
  .cs-section > .readouts,
  .cs-section > .gallery,
  .cs-section > .video-grid,
  .cs-section > .figure,
  .cs-section > .circuit-wrap { margin-top: var(--space-6); }
  .cs-section > .ticks { margin-top: var(--space-5); }

  .version {
    --flow: var(--space-4);
    margin-top: var(--space-7);
    padding-top: var(--space-5);
    border-top: 1px solid var(--rule-strong);
  }
  .version__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 6px 24px;
  }
  .version__head h3 { margin: 4px 0 0; }
  .version > p { color: var(--ink-2); max-width: 68ch; }
  .version > .gallery,
  .version > .video-grid { margin-top: var(--space-5); }

  .cs-body > .next-project { margin-top: clamp(56px, 7vw, 96px); }

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

  /* --- 404 -------------------------------------------------------------------------- */
  .lost { position: relative; isolation: isolate; padding-block: clamp(48px, 10vw, 140px); overflow: clip; }
  .lost__code {
    position: absolute;
    top: 50%;
    right: -0.04em;
    z-index: -1;
    font: 800 clamp(10rem, 32vw, 30rem) / 0.8 var(--font-display);
    letter-spacing: -0.06em;
    color: transparent;
    -webkit-text-stroke: 1px var(--rule);
    transform: translateY(-50%);
    pointer-events: none;
    user-select: none;
  }
  .lost h1 {
    max-width: 14ch;
    margin-top: var(--space-5);
    font: 800 var(--fs-h1) / 1 var(--font-display);
    letter-spacing: -0.045em;
  }
  .lost p:not(.label) { margin-top: var(--space-5); max-width: 46ch; color: var(--ink-2); font-size: var(--fs-lede); }
  .lost .btn-row { margin-top: var(--space-7); }

  /* --- nameplate entrance ------------------------------------------------------------- */
  @media (prefers-reduced-motion: no-preference) {
    .js .nameplate__word {
      animation: word-rise var(--t-slow) var(--ease-out) backwards;
      animation-delay: calc(var(--i, 0) * 90ms + 60ms);
    }
    .js .hero__meta,
    .js .hero__grid,
    .js .facts { animation: fade-up var(--t-slow) var(--ease-out) backwards; animation-delay: 220ms; }
  }
  @keyframes word-rise {
    from { clip-path: inset(0 0 100% 0); transform: translateY(0.25em); }
    to { clip-path: inset(-20% -5% -20% -5%); transform: none; }
  }
  @keyframes fade-up {
    from { opacity: 0; transform: translateY(14px); }
  }
}

/* ==========================================================================
   6. UTILITIES
   ========================================================================== */
@layer utilities {
  .sr-only {
    position: absolute !important;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }
  .mt-5 { margin-top: var(--space-5); }
  .mt-6 { margin-top: var(--space-6); }
}

/* Page transitions between pages of this site (Chromium and Safari; other
   browsers simply navigate). js/head.js names the shared project image and
   title so they travel from the home page into the case study and back. */
@view-transition { navigation: auto; }
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 300ms; animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
::view-transition-group(project-image),
::view-transition-group(project-title) { animation-duration: 420ms; animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1); }
::view-transition-old(project-title),
::view-transition-new(project-title) { height: 100%; object-fit: contain; object-position: left top; }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* Reduced motion: every transition and animation ends immediately. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}

/* Printing from the home page prints only the résumé. */
@media print {
  :root { color-scheme: light; }
  .site-header,
  .progress,
  .skip-link,
  .hero,
  .site-footer,
  main > .section:not(#resume),
  #resume .section-head,
  .resume-bar { display: none !important; }
  @page { margin: 14mm 16mm; }
  body { background: #fff; color: #000; font-size: 10pt; line-height: 1.4; }
  #resume { padding: 0; border: 0; }
  .resume-shell { border: 0; background: #fff; }
  .resume-doc { padding: 0; }
  .resume-doc-head { padding-bottom: 8pt; }
  .resume-doc-head h3 { font-size: 22pt; }
  .resume-contact { margin-top: 4pt; font-size: 9pt; }
  .resume-block { grid-template-columns: 110px minmax(0, 1fr); gap: 12pt; padding-block: 8pt; }
  .resume-entry + .resume-entry { margin-top: 8pt; }
  .resume-entry-head h5 { font-size: 10.5pt; }
  .resume-where { font-size: 9pt; }
  .resume-entry ul { margin-top: 3pt; }
  .resume-entry li + li { margin-top: 1pt; }
  .resume-skills { gap: 4pt; }
  .resume-entry { break-inside: avoid; }
  .ext { display: none; }
}
