/* ============================================================
   DESIGN TOKENS — terminal-brutalist
   Near-black canvas, one electric accent, hard grid lines,
   oversized display type against small mono labels.
   ============================================================ */

:root {
  /* --- surface ramp: near-black, never pure #000 --- */
  --bg:            #08080a;
  --bg-raised:     #0e0e11;
  --bg-sunken:     #050506;
  --surface:       #131317;
  --surface-hover: #1a1a20;

  /* --- rule / border ramp --- */
  --line:          #1e1e24;
  --line-strong:   #2c2c35;
  --line-faint:    #141418;

  /* --- text ramp --- */
  --text:          #f2f2f0;
  --text-dim:      #8b8b96;
  --text-faint:    #55555f;

  /* --- the one accent --- */
  --accent:        #00ff9c;
  --accent-dim:    #00c979;
  --accent-deep:   #007a4a;
  --accent-bright: #00ff9c;
  --accent-glow:   rgba(0, 255, 156, 0.18);
  --accent-wash:   rgba(0, 255, 156, 0.06);

  /* --- theme-aware paint used by overlays, images, and canvases --- */
  --card-featured:       #08080a;
  --portrait-outline:    transparent;
  --canvas-bg:           #08080a;
  --canvas-star:         #fff8e7;
  --field-dot:           #aab4b0;
  --field-active:        #00ff9c;
  --field-link:          #00ff9c;
  --mask-opaque:         #000000;
  --media-black:         #000000;
  --overlay-text:        #f2f2f0;
  --overlay-text-dim:    #8b8b96;
  --overlay-line:        #2c2c35;
  --lightbox-caption:    #8b8b96;
  --scrim-contact:       rgba(5, 5, 6, 0.88);
  --scrim-reel:          rgba(4, 4, 6, 0.86);
  --scrim-lightbox:      rgba(5, 5, 6, 0.94);
  --scrim-palette:       rgb(5 5 6 / 82%);
  --graph-panel:         rgba(8, 8, 10, 0.78);
  --graph-panel-border:  rgba(255, 255, 255, 0.16);
  --shadow-cursor:       rgba(8, 8, 10, 0.55);
  --shadow-graph-inset:  rgba(0, 0, 0, 0.58);
  --shadow-graph-panel:  rgba(0, 0, 0, 0.32);
  --shadow-modal:        rgba(0, 0, 0, 0.55);
  --shadow-palette:      rgb(0 0 0 / 70%);
  --panel-highlight:     rgb(255 255 255 / 2%);
  --shadow-case-study:   rgba(5, 5, 6, 0.65);
  --inset-highlight:     rgba(255, 255, 255, 0.03);
  --shadow-reel-title:   rgba(5, 5, 6, 0.9);

  /* --- status tones --- */
  --tone-live:     #00ff9c;
  --tone-building: #ffc857;
  --tone-shipped:  #7aa2ff;
  --tone-archived: #55555f;

  /* --- type --- */
  --font-display: 'Archivo', 'Arial Black', 'Helvetica Neue', sans-serif;
  --font-body:    'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono:    'JetBrains Mono', 'SF Mono', 'Consolas', ui-monospace, monospace;

  /* fluid display scale */
  /* 14vw made "AND BUILDING" wrap onto a second line, giving a 3-line headline
     that pushed the hero CTAs below the fold. 10.5vw keeps it on one line. */
  --fs-mega:  clamp(2.75rem, 10.5vw, 10rem);
  --fs-h1:    clamp(2.6rem, 7.5vw, 6.5rem);
  --fs-h2:    clamp(2rem, 5vw, 4rem);
  --fs-h3:    clamp(1.35rem, 2.6vw, 2rem);
  --fs-body:  clamp(1rem, 1.05vw, 1.125rem);
  --fs-lead:  clamp(1.125rem, 1.6vw, 1.5rem);
  --fs-mono:  clamp(0.68rem, 0.85vw, 0.8rem);
  --fs-small: 0.8125rem;

  --lh-tight: 0.9;
  --lh-snug:  1.15;
  --lh-body:  1.65;

  --tracking-mono: 0.18em;
  --tracking-tight: -0.03em;
  --tracking-mega: -0.045em;

  /* --- space --- */
  --gutter:  clamp(1.25rem, 4vw, 4rem);
  /* Was clamp(6rem, 14vh, 11rem): 126px top AND bottom on a 900px screen, so
     252px of empty space between every section. Roughly halved. */
  --section: clamp(3rem, 7vh, 5.5rem);
  --stack-s: 0.75rem;
  --stack-m: 1.5rem;
  --stack-l: 3rem;
  --stack-xl: 6rem;

  --maxw: 1560px;
  --measure: 62ch;

  /* --- motion --- */
  --ease-out:  cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --dur-fast: 180ms;
  --dur:      420ms;
  --dur-slow: 900ms;

  --z-canvas: 0;
  --z-content: 10;
  --z-nav: 60;
  --z-cursor: 9999;
  --z-preloader: 10000;
}

/* Crisp paper and ink, with an accessible electric blue for text/rules and a
   separate brighter blue for bloom and canvas points. */
:root[data-theme='light'] {
  color-scheme: light;

  --bg:            #fbfcff;
  --bg-raised:     #f3f7ff;
  --bg-sunken:     #eaf0fb;
  --surface:       #f7f9fd;
  --surface-hover: #edf3ff;

  --line:          #d5deeb;
  --line-strong:   #aebbd0;
  --line-faint:    #e7edf5;

  --text:          #0b1020;
  --text-dim:      #46516a;
  --text-faint:    #596579;

  --accent:        #0054d1;
  --accent-dim:    #0047b8;
  --accent-deep:   #003c99;
  --accent-bright: #00a8ff;
  --accent-glow:   rgba(0, 168, 255, 0.24);
  --accent-wash:   rgba(0, 84, 209, 0.08);

  --tone-live:     #0054d1;
  --tone-building: #805500;
  --tone-shipped:  #3949ab;
  --tone-archived: #596579;

  --card-featured:       #edf4ff;
  --portrait-outline:    #15233f;
  --canvas-bg:           #f4f8ff;
  --canvas-star:         #213047;
  --field-dot:           #68758a;
  --field-active:        #00a8ff;
  --field-link:          #0054d1;
  --overlay-text:        #ffffff;
  --overlay-text-dim:    #dbe6f6;
  --overlay-line:        #91a0b8;
  --lightbox-caption:    #dbe6f6;
  --scrim-contact:       rgba(9, 17, 35, 0.76);
  --scrim-reel:          rgba(9, 17, 35, 0.82);
  --scrim-lightbox:      rgba(9, 17, 35, 0.88);
  --scrim-palette:       rgb(9 17 35 / 76%);
  --graph-panel:         rgba(251, 252, 255, 0.9);
  --graph-panel-border:  rgba(21, 35, 63, 0.24);
  --shadow-cursor:       rgba(11, 16, 32, 0.35);
  --shadow-graph-inset:  rgba(0, 84, 209, 0.1);
  --shadow-graph-panel:  rgba(20, 44, 84, 0.18);
  --shadow-modal:        rgba(9, 17, 35, 0.24);
  --shadow-palette:      rgb(9 17 35 / 28%);
  --panel-highlight:     rgb(255 255 255 / 68%);
  --shadow-case-study:   rgba(9, 17, 35, 0.22);
  --inset-highlight:     rgba(255, 255, 255, 0.72);
  --shadow-reel-title:   rgba(5, 10, 22, 0.82);
}

/* Respect the setting, but keep the site legible and complete. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 1ms;
    --dur: 1ms;
    --dur-slow: 1ms;
  }
}

/* ============================================================
   RESET / BASE
   ============================================================ */

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

html {
  background: var(--bg);
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  font-feature-settings: 'kern' 1, 'liga' 1, 'calt' 1;
}

body.is-locked { overflow: hidden; }

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 800;
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}

p { margin: 0; text-wrap: pretty; }
a { color: inherit; text-decoration: none; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img, svg, canvas { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: none; padding: 0; }

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

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

/* ============================================================
   SHARED PRIMITIVES
   ============================================================ */

.shell {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* small mono label — the workhorse of this design */
.mono {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--text-faint);
  font-weight: 500;
}

.mono--accent { color: var(--accent); }

/* section header: [ 02 ] ——— SELECTED WORK */
.section-head {
  display: flex;
  align-items: baseline;
  gap: 1.25rem;
  padding-block: 1rem;
  border-top: 1px solid var(--line);
  margin-bottom: var(--stack-l);
}

.section-head__index {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  color: var(--accent);
  flex-shrink: 0;
}

.section-head__title {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--text-dim);
}

.section-head__rule {
  flex: 1;
  height: 1px;
  background: var(--line-strong);
}

.section {
  position: relative;
  padding-block: var(--section);
  z-index: var(--z-content);
}

.lead {
  font-size: var(--fs-lead);
  line-height: 1.45;
  color: var(--text-dim);
  max-width: var(--measure);
}

/* status pill */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--line-strong);
  border-radius: 100px;
  color: var(--text-dim);
  white-space: nowrap;
}

.pill::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

.pill[data-tone='live']     { color: var(--tone-live);     border-color: color-mix(in srgb, var(--tone-live) 35%, transparent); }
.pill[data-tone='building'] { color: var(--tone-building); border-color: color-mix(in srgb, var(--tone-building) 35%, transparent); }
.pill[data-tone='shipped']  { color: var(--tone-shipped);  border-color: color-mix(in srgb, var(--tone-shipped) 35%, transparent); }
.pill[data-tone='archived'] { color: var(--tone-archived); }

.pill[data-tone='live']::before {
  animation: pulse-dot 2s var(--ease-in-out) infinite;
}

@keyframes pulse-dot {
  0%, 100% { opacity: 1;   box-shadow: 0 0 0 0 var(--accent-glow); }
  50%      { opacity: 0.5; box-shadow: 0 0 0 5px transparent; }
}

/* tech tag */
.tag {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  color: var(--text-faint);
  padding: 0.25rem 0.55rem;
  border: 1px solid var(--line);
  border-radius: 3px;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}

.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

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

/* ============================================================
   LAYOUT — divyansh-site
   ============================================================ */

/* ---------- cursor system (elements injected by cursor.js) ---------- */
.cursor-dot,
.cursor-ring,
.cursor-trail {
  position: fixed;
  top: 0; left: 0;
  pointer-events: none;
  z-index: var(--z-cursor);
  will-change: transform;
}

/* No centring margins here — cursor.js already offsets by half in its
   translate3d (px - 3 / rx - 16). Adding a negative margin on top of that
   double-centred the elements, putting the dot 3px and the ring 16px
   up-and-left of the real pointer. */
.cursor-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

.cursor-ring {
  width: 32px; height: 32px;
  border: 1.5px solid var(--accent);
  border-radius: 50%;
  /* No mix-blend-mode: difference — it inverts the accent to magenta over the
     white display type. A dark outer shadow keeps the ring readable on both
     the near-black background and the light headline instead. */
  box-shadow: 0 0 0 1px var(--shadow-cursor), 0 0 12px var(--accent-glow);
  display: grid;
  place-items: center;
  transition: width var(--dur-fast) var(--ease-out),
              height var(--dur-fast) var(--ease-out),
              border-radius var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}

.cursor-ring__label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  color: var(--accent);
  opacity: 0;
  white-space: nowrap;
  transition: opacity var(--dur-fast) var(--ease-out);
}

.cursor-ring.is-view .cursor-ring__label { opacity: 1; }

.cursor-trail {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--accent);
}

html.has-custom-cursor,
html.has-custom-cursor * { cursor: none !important; }

/* ---------- preloader (injected by preloader.js) ---------- */
.preloader {
  position: fixed;
  inset: 0;
  z-index: var(--z-preloader);
  display: grid;
  place-items: center;
  background: var(--bg-sunken);
}

.preloader__cols {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
}

.preloader__col {
  background: var(--bg-sunken);
  will-change: transform;
}

.preloader__readout {
  position: relative;
  z-index: 2;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  color: var(--text-dim);
  text-align: left;
  min-width: 15rem;
  display: grid;
  gap: 0.5rem;
}

.preloader__line { opacity: 0; }
.preloader__line.is-on { opacity: 1; color: var(--accent); }

.preloader__pct {
  position: absolute;
  bottom: var(--gutter);
  right: var(--gutter);
  z-index: 2;
  font-family: var(--font-mono);
  font-size: clamp(3rem, 10vw, 7rem);
  font-weight: 700;
  color: var(--line-strong);
  line-height: 1;
}

.preloader__bar {
  position: absolute;
  bottom: 0; left: 0;
  height: 1px;
  width: 0%;
  background: var(--accent);
  z-index: 2;
}

/* ============================================================
   NAV
   ============================================================ */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: var(--z-nav);
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur) var(--ease-out),
              background-color var(--dur) var(--ease-out);
}

.nav.is-stuck {
  border-bottom-color: var(--line);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
}

.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--stack-m);
  height: 68px;
}

.nav__brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  font-weight: 700;
  flex-shrink: 0;
}

.nav__mark {
  width: 10px; height: 10px;
  background: var(--accent);
  border-radius: 2px;
  animation: mark-breathe 3.2s var(--ease-in-out) infinite;
}

@keyframes mark-breathe {
  0%, 100% { transform: rotate(0deg)  scale(1);    border-radius: 2px; }
  50%      { transform: rotate(45deg) scale(0.82); border-radius: 50%; }
}

.nav__links {
  display: flex;
  gap: clamp(1rem, 2.4vw, 2.4rem);
}

.nav__link {
  position: relative;
  color: var(--text-dim);
  padding-block: 0.4rem;
  transition: color var(--dur-fast) var(--ease-out);
}

.nav__link::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--dur) var(--ease-out);
}

.nav__link:hover { color: var(--text); }
.nav__link:hover::after,
.nav__link.is-active::after { transform: scaleX(1); transform-origin: left; }
.nav__link.is-active { color: var(--accent); }

.nav__cta {
  border: 1px solid var(--line-strong);
  padding: 0.55rem 1rem;
  border-radius: 100px;
  color: var(--text);
  white-space: nowrap;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}

.nav__cta:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
}

.nav__toggle { display: none; }

.nav__progress {
  height: 1px;
  width: 0%;
  background: var(--accent);
  transition: width 80ms linear;
}

/* ============================================================
   HERO
   ============================================================ */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  /* Overridden further down by the CONTENT HIERARCHY PASS rule — change the
     padding there, not here. */
  padding-block: 6.5rem 4rem;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
}

.hero__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: var(--z-canvas);
}

.hero__inner {
  position: relative;
  z-index: var(--z-content);
  width: 100%;
}

.hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1rem, 3vw, 2.5rem);
  padding-bottom: 1.5rem;
  margin-bottom: clamp(1.5rem, 4vh, 3rem);
  border-bottom: 1px solid var(--line);
}

.hero__title {
  font-size: var(--fs-mega);
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-mega);
  font-weight: 900;
  text-transform: uppercase;
  margin-bottom: clamp(1.5rem, 4vh, 3rem);
}

.hero__line {
  display: block;
  width: max-content;
  max-width: 100%;
  white-space: nowrap;
}

.hero__letter,
.hero__glyph { display: inline-block; }

.hero__letter--space { width: 0.27em; }

.hero__glyph {
  transform: translate3d(var(--lean-x, 0), var(--lean-y, 0), 0) rotate(var(--lean-r, 0deg));
  transform-origin: 50% 88%;
  transition: transform 150ms var(--ease-out);
}

.hero__line--accent {
  --hero-fill: 0;
  color: transparent;
  -webkit-text-stroke: 1.5px var(--accent);
  text-stroke: 1.5px var(--accent);
}

.hero__line--accent[data-hero-split='true'] {
  -webkit-text-stroke: 0;
  text-stroke: 0;
}

.hero__line--accent .hero__letter { --letter-fill: 0%; }

.hero__line--accent .hero__glyph {
  color: transparent;
  -webkit-text-fill-color: transparent;
  -webkit-text-stroke: 1.5px var(--accent);
  text-stroke: 1.5px var(--accent);
  background: linear-gradient(
    90deg,
    var(--accent) 0,
    var(--accent) var(--letter-fill),
    transparent var(--letter-fill),
    transparent 100%
  );
  -webkit-background-clip: text;
  background-clip: text;
}

.hero__body {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 5vw, 5rem);
  align-items: start;
}

.hero__statement {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: var(--tracking-tight);
  max-width: 22ch;
}

.hero__statement em {
  font-style: normal;
  color: var(--accent);
}

.hero__sub {
  color: var(--text-dim);
  max-width: 48ch;
  font-size: var(--fs-body);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: var(--stack-m);
}

/* buttons */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  font-weight: 500;
  padding: 0.85rem 1.4rem;
  border-radius: 100px;
  border: 1px solid transparent;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
  will-change: transform;
}

.btn svg { transition: transform var(--dur) var(--ease-out); }
.btn:hover svg { transform: translateX(4px); }

.btn--primary { background: var(--accent); color: var(--bg); }
.btn--primary:hover { background: var(--text); }

.btn--ghost { border-color: var(--line-strong); color: var(--text); }
.btn--ghost:hover { border-color: var(--accent); color: var(--accent); }

/* metrics rail */
.metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  margin-top: clamp(2rem, 6vh, 4.5rem);
}

.metric {
  background: var(--bg);
  padding: clamp(1rem, 2vw, 1.6rem);
  transition: background-color var(--dur) var(--ease-out);
}

.metric:hover { background: var(--bg-raised); }

.metric__value {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 3.6vw, 3.1rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: var(--tracking-tight);
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  margin-bottom: 0.5rem;
}

.metric__label {
  display: block;
  font-size: var(--fs-small);
  color: var(--text);
  margin-bottom: 0.15rem;
}

.metric__context {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.08em;
  color: var(--text-faint);
}

/* Absolutely positioned at the hero's bottom-right, which is exactly where the
   last metric cell's context line ends — "Global Goals Run, Balkalakaar" ran
   straight under "SCROLL" at 1600, 1440, 1280, 1024, 820 and 768px. It only
   looked fine at a few widths by luck of where the text happened to wrap.
   The hero now reserves a band for the cue (see .hero padding-bottom), so the
   two can never share space regardless of how the metrics wrap. */
.hero__scroll {
  position: absolute;
  bottom: 1.25rem;
  right: var(--gutter);
  display: flex;
  align-items: center;
  gap: 0.75rem;
  z-index: var(--z-content);
}

.hero__scroll-line {
  width: 46px; height: 1px;
  background: var(--line-strong);
  position: relative;
  overflow: hidden;
}

.hero__scroll-line::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--accent);
  transform: translateX(-100%);
  animation: scroll-sweep 2.2s var(--ease-in-out) infinite;
}

@keyframes scroll-sweep {
  0%   { transform: translateX(-100%); }
  60%  { transform: translateX(100%); }
  100% { transform: translateX(100%); }
}

/* ============================================================
   MARQUEE
   ============================================================ */
.marquee {
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  padding-block: 1.1rem;
  background: var(--bg-raised);
}

.marquee__track {
  display: flex;
  gap: 3rem;
  white-space: nowrap;
  will-change: transform;
}

.marquee__item {
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 2.4vw, 2rem);
  font-weight: 800;
  letter-spacing: var(--tracking-tight);
  text-transform: uppercase;
  color: var(--text-faint);
  display: inline-flex;
  align-items: center;
  gap: 3rem;
}

.marquee__item::after {
  content: '';
  width: 8px; height: 8px;
  background: var(--accent);
  border-radius: 50%;
  flex-shrink: 0;
}

/* ============================================================
   SECTION SHARED
   ============================================================ */
.section--tight { padding-block: clamp(2.25rem, 4.5vh, 3.5rem); }
.section__lead { margin-bottom: var(--stack-l); }

/* ============================================================
   WORK GRID
   ============================================================ */
.work {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}

.card {
  position: relative;
  grid-column: span 4;
  background: var(--bg);
  padding: clamp(1.5rem, 2.4vw, 2.4rem);
  display: flex;
  flex-direction: column;
  gap: var(--stack-s);
  min-height: 300px;
  overflow: hidden;
  transform-style: preserve-3d;
  transition: background-color var(--dur) var(--ease-out);
  will-change: transform;
  /* .work draws its 1px card-to-card hairlines by showing its own
     background through a 1px grid gap. The scroll-linked ambient tilt
     (work-card-scroll in scroll.css) rotates each card up to ~1.25deg,
     which briefly pulls one corner in past its own grid cell edge and
     exposes a sliver of that background — reads as a stray line
     cutting into the card's corner. This solid (0-blur) halo, small
     enough not to bleed into an adjacent card across the 1px gap,
     rotates with the card and covers that sliver without touching the
     animation itself. */
  box-shadow: 0 0 0 6px var(--bg);
}

.card--featured { grid-column: span 6; min-height: 400px; background: var(--card-featured); }

.card:hover { background: var(--bg-raised); }

/* pointer-tracking sheen, positioned by motion.js via --mx/--my */
.card::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(
    380px circle at var(--mx, 50%) var(--my, 50%),
    var(--accent-wash),
    transparent 65%
  );
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
  pointer-events: none;
}

.card:hover::before { opacity: 1; }

/* top accent rule that draws in on hover */
.card::after {
  content: '';
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease-out);
}

.card:hover::after { transform: scaleX(1); }

.card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}

/* The title side needs min-width: 0 to let flexbox actually shrink it
   instead of both siblings fighting over space — without it, a long
   title (Reportcards — A Learning Centre) pushes card__index into too
   little room and wraps "02 / 2026" onto two lines, while short titles
   in the same row leave it on one, so the top rule above each card in
   the row sits at a different height. flex-shrink: 0 + nowrap on the
   index side is the actual fix; min-width: 0 just lets it work. */
.card__head > :first-child { min-width: 0; }

.card__index {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  color: var(--text-faint);
  flex-shrink: 0;
  white-space: nowrap;
}

.card__kind {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}

.card__name {
  font-size: var(--fs-h3);
  font-weight: 800;
  letter-spacing: var(--tracking-tight);
  margin-top: 0.4rem;
  text-wrap: balance;
  /* Reserve room for 2 lines always, not just when a title happens to
     wrap — otherwise a short 1-line name (Arun Silver) and a longer
     2-line one (Reportcards — A Learning Centre) start their blurb/
     desc at different heights in the same card row, reading as
     misaligned even though the card boxes themselves are equal. */
  min-height: calc(2 * 1.2em);
}

.card--featured .card__name { font-size: clamp(1.7rem, 3.2vw, 2.6rem); }

.card__blurb {
  color: var(--accent);
  font-size: var(--fs-small);
  font-weight: 500;
}

.card__desc {
  color: var(--text-dim);
  font-size: var(--fs-small);
  line-height: 1.6;
  max-width: 56ch;
}

.card__detail {
  color: var(--text-faint);
  font-size: var(--fs-small);
  line-height: 1.6;
  max-width: 56ch;
  padding-top: var(--stack-s);
  border-top: 1px solid var(--line);
}

.card__outcomes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  margin-top: auto;
  padding-top: var(--stack-m);
}

.card__outcome {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.06em;
  color: var(--text-dim);
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.card__outcome::before {
  content: '';
  width: 4px; height: 4px;
  background: var(--accent);
  transform: rotate(45deg);
  flex-shrink: 0;
}

.card__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding-top: var(--stack-m);
}

.card:hover .tag { color: var(--text-dim); border-color: var(--line-strong); }

/* ============================================================
   CONSTELLATION GRAPH
   ============================================================ */
.graph {
  position: relative;
  border: 1px solid var(--line);
  background:
    linear-gradient(var(--line-faint) 1px, transparent 1px) 0 0 / 44px 44px,
    linear-gradient(90deg, var(--line-faint) 1px, transparent 1px) 0 0 / 44px 44px,
    var(--bg-raised);
  height: clamp(440px, 68vh, 720px);
  overflow: hidden;
}

.graph__canvas { width: 100%; height: 100%; }

.graph__panel {
  position: absolute;
  left: clamp(1rem, 2vw, 2rem);
  bottom: clamp(1rem, 2vw, 2rem);
  max-width: min(360px, calc(100% - 4rem));
  padding: 1.15rem 1.3rem;
  background: color-mix(in srgb, var(--bg-sunken) 88%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  pointer-events: none;
}

.graph__panel-title {
  font-size: 1.15rem;
  font-weight: 800;
  margin: 0.4rem 0 0.35rem;
  letter-spacing: var(--tracking-tight);
}

.graph__panel-body {
  font-size: var(--fs-small);
  color: var(--text-dim);
  line-height: 1.55;
}

/* ============================================================
   ABOUT / STORY
   ============================================================ */
.about {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(2rem, 6vw, 6rem);
  align-items: start;
}

.about__title {
  font-size: var(--fs-h2);
  font-weight: 900;
  letter-spacing: var(--tracking-mega);
  line-height: 1.05;
  margin-bottom: var(--stack-m);
  text-transform: uppercase;
}

.about__title em {
  font-style: normal;
  color: transparent;
  -webkit-text-stroke: 1.2px var(--accent);
}

.story { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }

.story__item {
  background: var(--bg);
  padding: clamp(1.25rem, 2vw, 1.9rem);
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1.25rem;
  transition: background-color var(--dur) var(--ease-out);
}

.story__item:hover { background: var(--bg-raised); }

.story__act {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  color: var(--accent);
  padding-top: 0.3rem;
}

.story__title {
  font-size: 1.05rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
  letter-spacing: var(--tracking-tight);
}

.story__body {
  font-size: var(--fs-small);
  color: var(--text-dim);
  line-height: 1.65;
}

/* ============================================================
   PRINCIPLES
   ============================================================ */
.principles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}

.principle {
  background: var(--bg);
  padding: clamp(1.25rem, 2vw, 1.9rem);
  position: relative;
  transition: background-color var(--dur) var(--ease-out);
}

.principle:hover { background: var(--bg-raised); }

.principle__num {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  color: var(--text-faint);
  display: block;
  margin-bottom: 0.9rem;
}

.principle:hover .principle__num { color: var(--accent); }

.principle__title {
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  margin-bottom: 0.55rem;
  text-wrap: balance;
}

.principle__body {
  font-size: var(--fs-small);
  color: var(--text-dim);
  line-height: 1.6;
}

/* ============================================================
   TIMELINE
   ============================================================ */
.timeline { border-top: 1px solid var(--line); }

.job {
  display: grid;
  grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
  gap: clamp(1rem, 4vw, 4rem);
  padding-block: clamp(1.75rem, 3.5vh, 2.75rem);
  border-bottom: 1px solid var(--line);
  position: relative;
  transition: background-color var(--dur) var(--ease-out);
}

.job::before {
  content: '';
  position: absolute;
  left: calc(var(--gutter) * -1);
  right: calc(var(--gutter) * -1);
  top: 0; bottom: 0;
  background: var(--bg-raised);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
  z-index: -1;
}

.job:hover::before { opacity: 1; }

.job__meta { display: grid; gap: 0.4rem; align-content: start; }

.job__period {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  color: var(--accent);
}

.job__location {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.1em;
  color: var(--text-faint);
  text-transform: uppercase;
}

.job__org {
  font-size: clamp(1.4rem, 2.8vw, 2.1rem);
  font-weight: 800;
  letter-spacing: var(--tracking-tight);
  line-height: 1.1;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.job--highlight .job__org { color: var(--accent); }

.job__role {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  color: var(--text-dim);
  text-transform: uppercase;
  margin: 0.5rem 0 1rem;
}

.job__bullets { display: grid; gap: 0.6rem; }

.job__bullet {
  font-size: var(--fs-small);
  color: var(--text-dim);
  line-height: 1.6;
  padding-left: 1.15rem;
  position: relative;
  max-width: 68ch;
}

.job__bullet::before {
  content: '';
  position: absolute;
  left: 0; top: 0.62em;
  width: 5px; height: 1px;
  background: var(--accent);
}

/* ============================================================
   SKILLS / CREDENTIALS
   ============================================================ */
.stack-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.25fr);
  gap: clamp(1.5rem, 3.5vw, 3rem);
  align-items: start;
}

.skills { display: grid; gap: var(--stack-m); }

.skill-group { border-top: 1px solid var(--line); padding-top: var(--stack-m); }

.skill-group__name {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.9rem;
  display: block;
}

.skill-group__items { display: flex; flex-wrap: wrap; gap: 0.45rem; }

.skill-chip {
  font-size: var(--fs-small);
  color: var(--text-dim);
  padding: 0.4rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: 100px;
  transition: color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}

.skill-chip:hover {
  color: var(--bg);
  background: var(--accent);
  border-color: var(--accent);
}

.credentials { display: grid; gap: var(--stack-m); }

.credentials__block {
  border: 1px solid var(--line);
  padding: clamp(1.15rem, 2vw, 1.6rem);
  background: var(--bg-raised);
}

.credentials__block .mono { display: block; margin-bottom: 0.85rem; }

.edu__degree {
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  margin-bottom: 0.3rem;
}

.edu__school { font-size: var(--fs-small); color: var(--accent); margin-bottom: 0.15rem; }
.edu__period { font-family: var(--font-mono); font-size: 0.65rem; letter-spacing: 0.1em; color: var(--text-faint); margin-bottom: 0.8rem; }
.edu__note { font-size: var(--fs-small); color: var(--text-dim); line-height: 1.6; }

.cert-list { display: grid; gap: 0.85rem; }

.cert {
  display: grid;
  gap: 0.15rem;
  padding-left: 1rem;
  position: relative;
}

.cert::before {
  content: '';
  position: absolute;
  left: 0; top: 0.55em;
  width: 5px; height: 5px;
  border: 1px solid var(--accent);
  transform: rotate(45deg);
}

.cert__name { font-size: var(--fs-small); color: var(--text); font-weight: 500; }
.cert__issuer { font-family: var(--font-mono); font-size: 0.65rem; letter-spacing: 0.08em; color: var(--text-faint); }

.cert__note {
  font-size: 0.7rem;
  line-height: 1.5;
  color: var(--text-faint);
  margin-top: 0.3rem;
  padding-left: 0.6rem;
  border-left: 1px solid var(--line-strong);
}

.interest { margin-bottom: 1rem; }
.interest:last-child { margin-bottom: 0; }
.interest__title { font-size: var(--fs-small); font-weight: 600; color: var(--accent); margin-bottom: 0.25rem; }
.interest__body { font-size: var(--fs-small); color: var(--text-dim); line-height: 1.6; }

/* ============================================================
   CONTACT
   ============================================================ */
.contact {
  border-top: 1px solid var(--line);
  background:
    radial-gradient(1000px 420px at 50% 118%, var(--accent-wash), transparent 70%),
    var(--bg);
}

.contact__headline {
  font-size: var(--fs-h1);
  font-weight: 900;
  letter-spacing: var(--tracking-mega);
  text-transform: uppercase;
  line-height: 1;
  margin-bottom: var(--stack-m);
}

.contact__lead { margin-bottom: var(--stack-l); }

.contact__email {
  display: inline-flex;
  flex-direction: column;
  gap: 0.5rem;
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 4vw, 3rem);
  font-weight: 800;
  letter-spacing: var(--tracking-tight);
  word-break: break-all;
  padding-bottom: 0.6rem;
  border-bottom: 2px solid var(--line-strong);
  transition: color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
  will-change: transform;
}

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

.contact__email-hint {
  font-size: 0.65rem;
  color: var(--text-faint);
  transition: color var(--dur-fast) var(--ease-out);
}

.contact__email.is-copied { color: var(--accent); border-bottom-color: var(--accent); }
.contact__email.is-copied .contact__email-hint { color: var(--accent); }

.contact__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: var(--stack-l);
}

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

.social {
  display: flex;
  flex-wrap: wrap;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  margin-top: var(--stack-xl);
}

.social__item { flex: 1 1 180px; }

.social__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  background: var(--bg);
  padding: 1.15rem 1.3rem;
  height: 100%;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  color: var(--text-dim);
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}

.social__link:hover { background: var(--accent); color: var(--bg); }
.social__link svg { flex-shrink: 0; transition: transform var(--dur) var(--ease-out); }
.social__link:hover svg { transform: translate(3px, -3px); }

/* ============================================================
   FOOTER
   ============================================================ */
.footer {
  border-top: 1px solid var(--line);
  padding-block: 1.5rem;
  background: var(--bg-sunken);
}

.footer__inner {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: space-between;
  align-items: center;
}

/* ============================================================
   REVEAL BASE STATES
   (reveal.js flips these; if JS fails, content must still show —
    so the hidden state is applied by JS adding .reveal-armed)
   ============================================================ */
[data-reveal].reveal-armed { opacity: 0; }
[data-reveal].reveal-armed[data-reveal='up']   { transform: translateY(28px); }
[data-reveal].reveal-armed[data-reveal='line'] { transform: scaleX(0); transform-origin: left; opacity: 1; }
[data-reveal].reveal-armed[data-reveal='mask'] { clip-path: inset(0 100% 0 0); opacity: 1; }

[data-reveal].is-revealed {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 0 0);
  transition: opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out),
              clip-path var(--dur-slow) var(--ease-out);
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 1080px) {
  .card { grid-column: span 6; }
  .card--featured { grid-column: span 6; }
  .about { grid-template-columns: 1fr; }
  .stack-grid { grid-template-columns: 1fr; }
  .hero__body { grid-template-columns: 1fr; }
}

@media (max-width: 760px) {
  .nav__links,
  .nav__cta { display: none; }

  .nav__links.is-open {
    display: flex;
    position: fixed;
    inset: 68px 0 auto 0;
    flex-direction: column;
    gap: 0;
    background: var(--bg-sunken);
    border-bottom: 1px solid var(--line);
    padding: var(--gutter);
  }

  .nav__links.is-open .nav__link {
    padding-block: 1rem;
    border-bottom: 1px solid var(--line);
    font-size: 1rem;
  }

  .nav__toggle {
    display: grid;
    gap: 5px;
    padding: 0.5rem;
    margin-right: -0.5rem;
  }

  .nav__toggle span {
    display: block;
    width: 22px; height: 1.5px;
    background: var(--text);
    transition: transform var(--dur) var(--ease-out), opacity var(--dur) var(--ease-out);
  }

  .nav__toggle[aria-expanded='true'] span:first-child { transform: translateY(3.25px) rotate(45deg); }
  .nav__toggle[aria-expanded='true'] span:last-child  { transform: translateY(-3.25px) rotate(-45deg); }

  .card,
  .card--featured { grid-column: span 12; min-height: 0; }

  .job { grid-template-columns: 1fr; gap: 1rem; }
  .story__item { grid-template-columns: 1fr; gap: 0.5rem; }
  .hero { min-height: auto; padding-block: 7rem 3rem; }
  .hero__scroll { display: none; }
  .footer__inner { justify-content: flex-start; gap: 0.5rem; flex-direction: column; align-items: flex-start; }
  .graph { height: 60vh; }
}


/* ============================================================
   EXTENDED PORTFOLIO SECTIONS
   ============================================================ */
.hero__body:has(.hero__portrait) {
  /* Give the portrait its own column spanning both rows, instead of letting it
     start a tall third row that pushed the hero CTAs below the fold. */
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr) auto;
}

.hero__portrait {
  --portrait-ground: clamp(2rem, 6vh, 4.5rem);
  --portrait-contact: rgba(0, 0, 0, 0.76);
  position: relative;
  grid-column: 3;
  grid-row: 1 / span 2;
  justify-self: end;
  align-self: end;
  /* The source is now cropped tight to the subject, so it can carry real size —
     at 19vw he read as a letterboxed thumbnail. */
  width: clamp(275px, 31vw, 480px);
  max-width: 100%;
  /* Sized by width alone, he ran past the bottom of the window — 96px cut off at
     1440x900 and far more on a short laptop window, so the photo looked sliced
     across the face. Capping against the viewport height keeps him whole above
     the fold; svh so mobile browser chrome is accounted for. */
  max-height: clamp(205px, 36svh, 520px);
  margin-top: clamp(0.5rem, 1.5vh, 1.25rem);
  isolation: isolate;
  transform: translate3d(0, var(--portrait-ground), 0);
}

/* The portrait's base lands on the metrics rule; this compact shadow makes the
   contact legible on both ink-black and paper-white surfaces. */
.hero__portrait::after {
  content: '';
  position: absolute;
  z-index: 0;
  left: 19%;
  right: 19%;
  bottom: -8px;
  height: 18px;
  border-radius: 50%;
  background: radial-gradient(
    ellipse at center,
    var(--portrait-contact) 0 18%,
    color-mix(in srgb, var(--accent) 24%, transparent) 46%,
    transparent 74%
  );
  filter: blur(4px);
  pointer-events: none;
}

/* Speech bubble: sits above his head, points down at him. */
.hero__portrait-bubble {
  position: absolute;
  bottom: calc(100% - 0.5rem);
  left: 50%;
  z-index: 3;
  padding: 0.5rem 0.8rem;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: var(--bg-raised);
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, 6px) scale(0.9);
  transition: opacity 160ms var(--ease-out), transform 220ms var(--ease-out);
}
.hero__portrait-bubble::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  width: 8px;
  height: 8px;
  border: 1px solid var(--accent);
  border-top: 0;
  border-left: 0;
  background: var(--bg-raised);
  transform: translate(-50%, -55%) rotate(45deg);
}
.hero__portrait-bubble.is-on {
  opacity: 1;
  transform: translate(-50%, 0) scale(1);
}
.hero__portrait-bubble[data-tone="ouch"] {
  border-color: var(--tone-building);
  color: var(--tone-building);
  animation: portrait-shake 320ms var(--ease-out);
}
.hero__portrait-bubble[data-tone="ouch"]::after { border-color: var(--tone-building); }

@keyframes portrait-shake {
  0%, 100% { transform: translate(-50%, 0) scale(1) rotate(0deg); }
  25% { transform: translate(-50%, 0) scale(1.04) rotate(-3deg); }
  75% { transform: translate(-50%, 0) scale(1.04) rotate(3deg); }
}

.hero__portrait.is-poked .hero__portrait-image { animation: portrait-flinch 320ms var(--ease-out); }
@keyframes portrait-flinch {
  0%, 100% { transform: translate3d(0, 0, 0); }
  35% { transform: translate3d(0, 5px, 0) scale(0.985); }
}

@media (prefers-reduced-motion: reduce) {
  .hero__portrait-bubble { transition: none; animation: none; }
  .hero__portrait-bubble[data-tone] { animation: none; }
  .hero__portrait.is-poked .hero__portrait-image { animation: none; }
  .hero__glyph { transition: none; }
  .hero__scroll-line::after { animation: none; transform: none; }
}

.hero__portrait-glow {
  position: absolute;
  inset: 8% -22% -6%;
  z-index: -1;
  background: radial-gradient(circle at 50% 58%, var(--accent-glow), transparent 70%);
  filter: blur(34px);
  pointer-events: none;
}

.hero__portrait-stage {
  --portrait-parallax-scale: 1;
  --portrait-parallax-x: 0px;
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  max-height: inherit;
  transform: translate3d(var(--portrait-parallax-x), 0, 0) scale(var(--portrait-parallax-scale));
  transform-origin: 50% 100%;
  will-change: transform;
}

.hero__portrait-image {
  width: 100%;
  /* Fills the height cap without distorting; bottom-anchored so he stands on the
     baseline of the hero rather than floating with a gap beneath him. */
  height: auto;
  max-height: inherit;
  object-fit: contain;
  object-position: bottom center;
  transform: translate3d(0, 0, 0);
  transition: transform 180ms var(--ease-out);
  will-change: transform;
}

:root[data-theme='light'] .hero__portrait-image {
  filter:
    drop-shadow(1px 0 0 var(--portrait-outline))
    drop-shadow(-1px 0 0 var(--portrait-outline))
    drop-shadow(0 1px 0 var(--portrait-outline))
    drop-shadow(0 -1px 0 var(--portrait-outline));
}

:root[data-theme='light'] .hero__portrait { --portrait-contact: rgba(11, 16, 32, 0.3); }

.apps-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
}

.app-shot-card { min-width: 0; }
.app-shot { display: block; width: 100%; text-align: left; }

.browser-frame {
  display: block;
  overflow: hidden;
  border: 1px solid var(--line-strong);
  background: var(--bg-raised);
  transition: border-color var(--dur-fast) var(--ease-out), transform var(--dur) var(--ease-out);
}

.app-shot:hover .browser-frame { border-color: var(--accent-deep); transform: translateY(-3px); }

.browser-frame__bar {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  min-height: 34px;
  padding: 0.45rem 0.7rem;
  border-bottom: 1px solid var(--line);
}

.browser-frame__dots { display: flex; gap: 5px; }
.browser-frame__dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--line-strong); }
.browser-frame__dots i:first-child { background: var(--accent-deep); }

.browser-frame__url {
  grid-column: 2;
  justify-self: center;
  min-width: 0;
  max-width: min(280px, 70%);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border: 1px solid var(--line);
  border-radius: 100px;
  padding: 0.15rem 0.75rem;
  color: var(--text-faint);
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.06em;
}

.browser-frame__image {
  display: block;
  width: 100%;
  /* height:auto is required — without it the img's HTML height attribute wins and
     aspect-ratio is ignored, which rendered these 16:10 captures in a 0.64 portrait
     box and cropped the app UI down to an empty strip. */
  height: auto;
  aspect-ratio: 8 / 5;
  object-fit: cover;
  object-position: top center;
}

.app-shot-card__caption { display: grid; gap: 0.3rem; padding-top: 0.9rem; }
.app-shot-card__caption p { color: var(--text-dim); font-size: var(--fs-small); }

.writing-essays {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  border: 1px solid var(--line);
  background: var(--line);
}

.writing-card {
  min-width: 0;
  padding: clamp(1.4rem, 2.5vw, 2.4rem);
  background: var(--bg);
  transition: background-color var(--dur) var(--ease-out);
}

.writing-card:hover { background: var(--bg-raised); }
.writing-card__meta, .draft__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.writing__words { flex-shrink: 0; color: var(--accent); font-family: var(--font-mono); font-size: 0.65rem; letter-spacing: 0.12em; }
.writing-card__title { margin: var(--stack-m) 0 var(--stack-s); font-size: var(--fs-h3); }
.writing-card__excerpt { color: var(--text-dim); font-size: var(--fs-small); line-height: 1.7; }

.writing__subhead, .design-block__head {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: var(--stack-l) 0 var(--stack-m);
}

.draft-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border-top: 1px solid var(--line); }
.draft { min-width: 0; padding: 1.25rem 0; border-bottom: 1px solid var(--line); }
.draft:nth-child(odd) { padding-right: clamp(1rem, 3vw, 3rem); border-right: 1px solid var(--line); }
.draft:nth-child(even) { padding-left: clamp(1rem, 3vw, 3rem); }
.draft__title { font-size: 1rem; letter-spacing: -0.01em; }
.draft__note { display: inline-flex; margin-top: 0.65rem; }
.draft__excerpt { margin-top: 0.65rem; color: var(--text-faint); font-size: var(--fs-small); line-height: 1.6; }
.writing__cta, .design__cta { margin-top: var(--stack-l); }

.design-block + .design-block { margin-top: var(--stack-xl); }
.design-stills { columns: 3; column-gap: 1rem; }

.design-still {
  position: relative;
  display: block;
  width: 100%;
  margin: 0 0 1rem;
  break-inside: avoid;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--bg-raised);
  text-align: left;
}

.design-still img { width: 100%; height: auto; }
.design-still__scrim {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  padding: 1rem;
  background: linear-gradient(to top, color-mix(in srgb, var(--accent-deep) 72%, transparent), transparent 68%);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}
.design-still__scrim .mono { color: var(--overlay-text); }
.design-still:hover .design-still__scrim, .design-still:focus-visible .design-still__scrim { opacity: 1; }

.reel-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1rem; }
.reel-tile {
  position: relative;
  display: grid;
  place-items: center;
  min-width: 0;
  aspect-ratio: 9 / 16;
  overflow: hidden;
  border: 1px solid var(--accent-deep);
  background: linear-gradient(145deg, var(--accent-wash), transparent 48%), var(--bg-raised);
  transition: border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}
.reel-tile:hover { border-color: var(--accent); background-color: var(--surface); }
.reel-tile__play { display: grid; place-items: center; width: 3.5rem; height: 3.5rem; padding-left: 0.2rem; border: 1px solid var(--accent); border-radius: 50%; color: var(--accent); }
.reel-tile__title { position: absolute; left: 0.8rem; right: 0.8rem; bottom: 0.8rem; color: var(--text-dim); overflow-wrap: anywhere; }
.reel-tile__index { position: absolute; top: 0.8rem; right: 0.8rem; color: var(--accent); }
.reel-tile.is-playing { display: block; }
.reel-tile__frame { display: block; width: 100%; height: 100%; border: 0; }

.lightbox[hidden] { display: none; }
.lightbox {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-nav) + 10);
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: var(--scrim-lightbox);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.lightbox__stage { display: grid; place-items: center; gap: 0.75rem; max-width: min(92vw, 1400px); max-height: 88vh; }
.lightbox__image { max-width: 100%; max-height: calc(88vh - 3rem); width: auto; height: auto; object-fit: contain; }
.lightbox__caption { max-width: 80ch; color: var(--lightbox-caption); text-align: center; }
.lightbox__close { position: absolute; top: max(1rem, var(--gutter)); right: max(1rem, var(--gutter)); background: var(--bg); }

.vault {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: clamp(2rem, 6vw, 6rem);
  align-items: start;
  min-width: 0;
}
.vault__note { margin-top: var(--stack-m); }
.vault__metrics { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; margin-top: var(--stack-l); border: 1px solid var(--line); background: var(--line); }
.vault-metric { min-width: 0; }
.vault-metric .metric__value { font-size: clamp(1.7rem, 3vw, 2.8rem); }
.vault-metric .metric__label { overflow-wrap: anywhere; }
.vault-tree { min-width: 0; max-width: 100%; overflow: hidden; padding: clamp(1.1rem, 2.5vw, 2rem); border: 1px solid var(--line-strong); background: linear-gradient(var(--line-faint) 1px, transparent 1px) 0 0 / 100% 32px, var(--bg-sunken); font-family: var(--font-mono); font-size: clamp(0.72rem, 1vw, 0.86rem); }
.vault-tree__root { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 0.8rem; color: var(--text-faint); }
.vault-tree__all { flex: 0 0 auto; padding: 0.25rem 0.45rem; border: 1px solid var(--line-strong); color: var(--text-faint); cursor: pointer; }
.vault-tree__all:hover, .vault-tree__all[aria-pressed='true'] { border-color: var(--accent-deep); color: var(--accent); background: var(--accent-wash); }
.vault-tree__row { display: grid; grid-template-columns: auto minmax(7.5rem, auto) minmax(0, 1fr); gap: 0.65rem; align-items: baseline; width: 100%; min-width: 0; padding: 0.45rem 0.35rem; border-inline-start: 2px solid transparent; text-align: start; cursor: pointer; transition: color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out); }
.vault-tree__row:hover { background: var(--surface-hover); }
.vault-tree__row[aria-pressed='true'] { border-inline-start-color: var(--branch-color, var(--accent)); background: var(--accent-wash); }
.vault-tree__joint, .vault-tree__note { min-width: 0; color: var(--text-faint); }
.vault-tree__note { overflow-wrap: anywhere; }
.vault-tree__name { min-width: 0; color: var(--branch-color, var(--accent)); }
.vault-tree.is-typing .vault-tree__row { opacity: 0; transform: translateX(-8px); }
.vault-tree.is-typing.is-typed .vault-tree__row { opacity: 1; transform: none; transition: opacity var(--dur-fast) var(--ease-out) var(--tree-delay), transform var(--dur-fast) var(--ease-out) var(--tree-delay), color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out); }
@media (max-width: 1080px) {
  .hero__portrait { grid-column: 1; grid-row: auto; justify-self: end; width: min(260px, 58vw); }
  .writing-essays { grid-template-columns: 1fr; }
  .design-stills { columns: 2; }
  .reel-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .vault { grid-template-columns: 1fr; }
}

@media (max-width: 760px) {
  .hero__portrait { justify-self: center; width: min(220px, 66vw); }
  .apps-grid, .draft-list { grid-template-columns: 1fr; }
  .draft:nth-child(odd), .draft:nth-child(even) { padding-inline: 0; border-right: 0; }
  .design-stills { columns: 1; }
  .reel-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.65rem; }
  .vault__metrics { grid-template-columns: 1fr; }
  .lightbox { padding: 4.5rem 1rem 1rem; }
  .lightbox__close { top: 0.8rem; right: 0.8rem; }
}

@media (prefers-reduced-motion: reduce) {
  .hero__portrait-image, .browser-frame, .design-still__scrim { transition: none; }
  .app-shot:hover .browser-frame { transform: none; }
  .vault-tree.is-typing .vault-tree__row { opacity: 1; transform: none; transition: none; }
}

.vault__summary { min-width: 0; }

/* ---------- reel thumbnails (Drive poster frames) ---------- */
.reel-tile__thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.62;
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}

.reel-tile:hover .reel-tile__thumb { opacity: 0.9; transform: scale(1.04); }

/* keep the play glyph and labels above the poster */
.reel-tile__play,
.reel-tile__title,
.reel-tile__index { position: relative; z-index: 2; }
.reel-tile__title, .reel-tile__index { position: absolute; }

.reel-tile__play {
  background: color-mix(in srgb, var(--bg-sunken) 62%, transparent);
  backdrop-filter: blur(3px);
}

.reel-tile__title {
  color: var(--overlay-text);
  text-shadow: 0 1px 6px var(--shadow-reel-title);
}

/* Section titles are real <h2> elements for correct heading order. The base
   heading reset applies the display face at weight 800, so restate the mono
   treatment here to keep them looking exactly as before. */
h2.section-head__title {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  font-weight: 500;
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--text-dim);
  line-height: 1;
}

/* ⌘K trigger in the nav — the palette is the site's signature interaction,
   so it needs to be discoverable rather than hidden behind a shortcut. */
.nav__palette {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--line-strong);
  border-radius: 5px;
  color: var(--text-faint);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.nav__palette:hover { color: var(--accent); border-color: var(--accent); }
@media (max-width: 760px) { .nav__palette { display: none; } }

.nav__theme {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--line-strong);
  border-radius: 5px;
  color: var(--text-faint);
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}

.nav__theme:hover,
.nav__theme[aria-pressed='true'] {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-wash);
}

/* Icon-only, matching the sound toggle beside it. The label is kept in the DOM
   for assistive tech and hidden at every width. */
.nav__theme { min-width: 32px; justify-content: center; padding-inline: 0.4rem; }
.nav__theme-icon { display: inline-flex; align-items: center; color: var(--accent); }
.nav__theme-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

@media (max-width: 760px) {
  .nav__theme { min-width: 44px; min-height: 44px; padding: 0.35rem; }
}

/* ---------- interactive second-brain graph ---------- */
.vault-graph {
  grid-column: 1 / -1;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  margin: var(--stack-l) 0 0;
  display: grid;
  justify-items: stretch;
  gap: 0.9rem;
}

.vault-graph__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-width: 0;
  color: var(--text-faint);
}

.vault-graph__status { color: var(--accent); text-align: end; }

.vault-graph__canvas {
  width: 100%;
  max-width: 100%;
  height: clamp(28rem, 50vw, 40rem);
  border: 1px solid var(--line-strong);
  background: var(--bg-sunken);
  border-radius: 2px;
  contain: paint;
}

.vault-graph__caption {
  justify-self: center;
  color: var(--text-faint);
  text-align: center;
  max-width: 62ch;
}

@media (max-width: 600px) {
  .vault-tree__row { grid-template-columns: auto minmax(0, 1fr); gap: 0.15rem 0.55rem; }
  .vault-tree__note { grid-column: 2; line-height: 1.45; }
  .vault-graph__head { align-items: flex-start; flex-direction: column; gap: 0.35rem; }
  .vault-graph__status { text-align: start; }
  .vault-graph__canvas { height: clamp(24rem, 112vw, 30rem); }
}
/* ============ SOCIAL RAIL ============
   Fixed on the right of the landing page. Mirrors the chapter rail on the left,
   so the two read as a pair of margins rather than stray furniture. Hidden on
   narrow screens where there is no gutter — the footer already carries the links. */
.social-rail {
  position: fixed;
  top: 50%;
  right: clamp(0.5rem, 1.6vw, 1.4rem);
  z-index: calc(var(--z-nav) - 2);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  transform: translateY(-50%);
}

.social-rail::after {
  content: '';
  width: 1px;
  height: clamp(2rem, 7vh, 4rem);
  margin-top: 0.5rem;
  background: linear-gradient(to bottom, var(--line-strong), transparent);
}

.social-rail__link {
  position: relative;
  display: grid;
  place-items: center;
  width: 2.35rem;
  height: 2.35rem;
  border: 1px solid transparent;
  border-radius: 50%;
  color: var(--text-dim);
  transition: color 180ms var(--ease-out), border-color 180ms var(--ease-out),
              background 180ms var(--ease-out), transform 180ms var(--ease-out);
}

.social-rail__link:hover,
.social-rail__link:focus-visible {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
  transform: translateY(-2px);
}

/* Label slides out to the left so it never pushes past the viewport edge. */
.social-rail__tip {
  position: absolute;
  right: calc(100% + 0.5rem);
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--line-strong);
  background: var(--bg-raised);
  color: var(--text-dim);
  font-size: 0.6rem;
  letter-spacing: var(--tracking-mono);
  white-space: nowrap;
  opacity: 0;
  transform: translateX(6px);
  pointer-events: none;
  transition: opacity 160ms var(--ease-out), transform 160ms var(--ease-out);
}

.social-rail__link:hover .social-rail__tip,
.social-rail__link:focus-visible .social-rail__tip {
  opacity: 1;
  transform: translateX(0);
}

@media (max-width: 1100px) { .social-rail { display: none; } }
@media (prefers-reduced-motion: reduce) {
  .social-rail__link, .social-rail__tip { transition: none; }
}

/* ============ SUBSTACK CTA ============
   Sits right after Writing. One row, one action — deliberately short so it reads
   as a punctuation mark between sections rather than another block to scroll. */
.subscribe {
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 2vw, 1.6rem);
  padding: clamp(1rem, 2.4vw, 1.5rem) clamp(1.1rem, 2.6vw, 1.8rem);
  border: 1px solid var(--line-strong);
  background: var(--bg-raised);
  color: var(--text);
  transition: border-color var(--dur) var(--ease-out),
              background var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-out);
}

.subscribe:hover,
.subscribe:focus-visible {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 7%, var(--bg-raised));
  transform: translateY(-2px);
}

.subscribe__mark {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 2.8rem;
  height: 2.8rem;
  border: 1px solid var(--accent);
  border-radius: 50%;
  color: var(--accent);
}

.subscribe__text { display: grid; gap: 0.25rem; min-width: 0; }

.subscribe__title {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 2vw, 1.5rem);
  font-weight: 800;
  letter-spacing: var(--tracking-tight);
  line-height: 1.15;
}

.subscribe__note {
  color: var(--accent);
  font-size: 0.68rem;
  letter-spacing: var(--tracking-mono);
}

.subscribe__go {
  flex: 0 0 auto;
  margin-left: auto;
  padding: 0.55rem 0.95rem;
  border: 1px solid var(--accent);
  border-radius: 100px;
  color: var(--accent);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  white-space: nowrap;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}

.subscribe:hover .subscribe__go { background: var(--accent); color: var(--bg); }

@media (max-width: 620px) {
  .subscribe { flex-wrap: wrap; }
  .subscribe__go { margin-left: 0; width: 100%; text-align: center; }
}

@media (prefers-reduced-motion: reduce) {
  .subscribe, .subscribe__go { transition: none; }
  .subscribe:hover { transform: none; }
}

/* ============ VOLUNTEERING ============
   Two entries carry the weight; the other eleven sit in a compact list. Thirteen
   full cards would have been another 3,000px of page. */
.volunteer {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 2.4vw, 2rem);
  margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
}

.volunteer__card {
  padding: clamp(1.1rem, 2.4vw, 1.8rem);
  border: 1px solid var(--line);
  background: var(--bg-raised);
}

.volunteer__org {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2vw, 1.6rem);
  font-weight: 800;
  letter-spacing: var(--tracking-tight);
  line-height: 1.1;
}

.volunteer__role { color: var(--text); margin-top: 0.15rem; }

.volunteer__meta {
  margin-top: 0.4rem;
  color: var(--text-faint);
  font-size: 0.66rem;
  letter-spacing: var(--tracking-mono);
}

.volunteer__points {
  display: grid;
  gap: 0.55rem;
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
  list-style: none;
}

.volunteer__points li {
  position: relative;
  padding-left: 1rem;
  color: var(--text-dim);
  font-size: 0.92rem;
  line-height: 1.55;
}

.volunteer__points li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 5px;
  height: 1px;
  background: var(--accent);
}

.volunteer-list { list-style: none; border-top: 1px solid var(--line); }

.volunteer-list__row {
  display: grid;
  /* The last two columns must be fixed. As `auto` they sized to their own text,
     so "1 YR 4 MOS" and "6 MOS" produced different column widths on every row and
     the org/role columns never lined up down the list. */
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.2fr) 11.5rem 6rem;
  gap: clamp(0.6rem, 2vw, 1.6rem);
  align-items: baseline;
  text-align: left;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--line);
  transition: background var(--dur-fast) var(--ease-out);
}

.volunteer-list__row:hover { background: var(--bg-raised); }

.volunteer-list__org { font-weight: 600; color: var(--text); }
.volunteer-list__role { color: var(--text-dim); }
.volunteer-list__period,
.volunteer-list__len { color: var(--text-faint); font-size: 0.66rem; letter-spacing: var(--tracking-mono); }
.volunteer-list__len { text-align: right; }

@media (max-width: 860px) {
  .volunteer { grid-template-columns: minmax(0, 1fr); }
  .volunteer-list__row { grid-template-columns: minmax(0, 1fr) auto; row-gap: 0.2rem; }
  .volunteer-list__role { grid-column: 1 / -1; }
  .volunteer-list__len { display: none; }
}

/* ---------- journey photo strips ---------- */
.journeys { display: grid; gap: clamp(1.5rem, 3vw, 2.5rem); margin-top: clamp(1.5rem, 3vw, 2.5rem); }
/* Grid items default to min-width:auto, so the strip refused to shrink and pushed
   the whole document to 3783px on a 390px phone instead of scrolling internally. */
.journey, .journeys > * { min-width: 0; }
.journeys[hidden] { display: none; }

.journey__name {
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 2vw, 1.5rem);
  font-weight: 800;
  letter-spacing: var(--tracking-tight);
}
.journey__meta { color: var(--accent); font-size: 0.66rem; letter-spacing: var(--tracking-mono); }
.journey__blurb { color: var(--text-dim); margin-top: 0.3rem; }

/* Horizontal strip, same pattern as the reels — keeps a long set of photos to
   one screen instead of stacking into thousands of pixels. */
.journey__strip {
  display: grid;
  min-width: 0;
  max-width: 100%;
  grid-template-columns: none;
  grid-auto-flow: column;
  grid-auto-columns: clamp(200px, 22vw, 300px);
  gap: clamp(0.6rem, 1.4vw, 1rem);
  margin-top: 1rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: 0.75rem;
}
.journey__strip > * { scroll-snap-align: start; }
.journey__strip::-webkit-scrollbar { height: 6px; }
.journey__strip::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 3px; }

/* <figure> keeps the UA default margin of 16px 40px, which indented the first
   photo of every strip by 40px and made the two journeys look misaligned. */
.journey__shot { margin: 0; border: 1px solid var(--line); background: var(--bg-raised); }
.journey__shot img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
.journey__shot figcaption {
  padding: 0.5rem 0.6rem;
  border-top: 1px solid var(--line);
  color: var(--text-faint);
  font-size: 0.62rem;
  letter-spacing: var(--tracking-mono);
}

/* ============ HERO ON SHORT WINDOWS ============
   The hero is a full viewport tall, but its own content (meta row, two-line
   title, statement, sub, buttons, metrics rail, portrait) is taller than a short
   laptop window — so the bottom of the portrait fell below the fold and the face
   was sliced off. Measured 89px past the fold at 1440x650.

   Shrinking the photo further just makes him a thumbnail, so tighten the hero
   itself instead. Nothing is hidden; only spacing and type scale down, and only
   below 820px of viewport height so tall windows are untouched. */
@media (max-height: 820px) {
  .hero { padding-block: 5.25rem 2.25rem; }
  .hero__meta { padding-bottom: 1rem; margin-bottom: 1.25rem; }
  .hero__title { font-size: clamp(2.2rem, 6.4vw, 4.4rem); margin-bottom: 1.25rem; }
  .hero__body { gap: clamp(1.25rem, 3.5vw, 3rem); }
  .hero__portrait { max-height: clamp(210px, 41svh, 440px); margin-top: 0.4rem; }
}

@media (max-height: 720px) {
  .hero { padding-block: 4.75rem 1.5rem; }
  .hero__meta { padding-bottom: 0.75rem; margin-bottom: 0.9rem; }
  .hero__title { font-size: clamp(1.9rem, 5.4vw, 3.4rem); margin-bottom: 0.9rem; }
  .hero__statement { font-size: clamp(1.05rem, 2.2vw, 1.5rem); }
  .hero__sub { font-size: 0.92rem; }
  .hero__portrait { max-height: clamp(185px, 33svh, 360px); margin-top: 0.2rem; }
}

@media (max-height: 640px) {
  .hero { padding-block: 4.5rem 1.1rem; }
  .hero__title { font-size: clamp(1.7rem, 4.6vw, 2.8rem); margin-bottom: 0.7rem; }
  .hero__portrait { max-height: clamp(160px, 27svh, 300px); }
}

/* ============ TOUCH TARGETS ============
   Several controls were 18-28px tall — fine for a mouse, too small for a thumb.
   Padding rather than height so nothing shifts visually on desktop; the extra
   area is invisible but tappable. Applied only on coarse pointers. */
@media (pointer: coarse) {
  .nav__brand,
  .page-back,
  .vault-tree__all,
  .footer a,
  .page-nav a {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }

  .nav__toggle {
    width: 44px;
    height: 44px;
    place-items: center;
  }

  /* Clickable branch rows in the vault tree need real height too. */
  .vault-tree__row {
    min-height: 44px;
    align-items: center;
  }
}

/* ============ WORK: THE REST ============
   Six cards lead; the remaining projects sit as a compact list. Each still has
   its own page, so nothing is hidden, it just stops costing a full card. */
/* ---------- work filters ----------
   Eighteen projects is past the point where a flat list reads. These chips
   scroll horizontally on a phone rather than wrapping into three rows. */
.work-filters {
  display: flex;
  gap: 0.5rem;
  margin: clamp(1rem, 2.4vw, 1.75rem) 0 clamp(1rem, 2vw, 1.5rem);
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 0.25rem;
}
.work-filters::-webkit-scrollbar { display: none; }
.work-filters:empty { display: none; }

.work-filter {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.8rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: transparent;
  color: var(--text-faint);
  font-size: 0.66rem;
  letter-spacing: var(--tracking-mono);
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}
.work-filter:hover,
.work-filter:focus-visible { color: var(--accent); border-color: var(--accent); }

.work-filter[aria-selected='true'] {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-wash);
}

.work-filter__count {
  font-size: 0.6rem;
  opacity: 0.65;
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  .work-filter { transition: none; }
}

.work-more { margin-top: clamp(1.5rem, 3vw, 2.5rem); }

.work-more__label {
  color: var(--text-faint);
  font-size: 0.66rem;
  letter-spacing: var(--tracking-mono);
  margin-bottom: 0.75rem;
}

.work-more__list { list-style: none; border-top: 1px solid var(--line); }

.work-more__link {
  display: grid;
  grid-template-columns: 2.5rem minmax(0, 1fr) minmax(0, 1.3fr) minmax(0, 0.85fr) 3.5rem;
  gap: clamp(0.6rem, 2vw, 1.5rem);
  align-items: baseline;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--line);
  color: var(--text-dim);
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}

.work-more__link:hover { background: var(--bg-raised); color: var(--text); }
.work-more__index { color: var(--accent); font-size: 0.66rem; letter-spacing: var(--tracking-mono); }
.work-more__name { font-weight: 600; color: var(--text); }
.work-more__blurb { color: var(--text-dim); }
.work-more__year { color: var(--text-faint); font-size: 0.66rem; text-align: right; }

@media (max-width: 1000px) {
  .work-more__link { grid-template-columns: 2.2rem minmax(0, 1fr) 3.2rem; row-gap: 0.25rem; }
  .work-more__blurb, .work-more__stack { grid-column: 2 / -1; }
}

/* ---------- volunteering toggle ---------- */
.volunteer-toggle {
  margin-top: 1rem;
  padding: 0.7rem 1.1rem;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: var(--tracking-mono);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.volunteer-toggle:hover { border-color: var(--accent); color: var(--accent); }
.volunteer-list[hidden] { display: none; }

/* ============ SUBSTACK BAND SPACING ============
   The band is a self-contained object, but it was wearing full section padding
   on top of the neighbouring sections' own: 167px of dead space above it and
   130px below. It sits close to the writing it belongs to now. */
#subscribe { padding-block: 0; }
.section:has(+ #subscribe) { padding-bottom: clamp(1.75rem, 3.5vw, 3rem); }
#subscribe + .section { padding-top: clamp(1.75rem, 3.5vw, 3rem); }

/* ============ PRINCIPLES AS A TIMELINE ============
   Six items in an auto-fit grid left an orphan on a second row. One horizontal
   run instead: a rule across the top, a marker per principle, text beneath.
   Scrolls sideways on narrow screens so it always stays a single line. */
.principles {
  position: relative;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  grid-template-columns: none;
  gap: clamp(1rem, 2vw, 2rem);
  padding-top: 2.4rem;
  background: none;
  border: 0;
}

/* the rail */
.principles::before {
  content: '';
  position: absolute;
  top: 0.72rem;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, var(--line-strong), var(--line-strong) 92%, transparent);
}

.principle {
  position: relative;
  padding: 0;
  background: none;
  min-width: 0;
}

.principle:hover { background: none; }

/* the marker sitting on the rail */
.principle::before {
  content: '';
  position: absolute;
  top: -1.92rem;
  left: 0;
  width: 9px;
  height: 9px;
  border: 1px solid var(--accent);
  border-radius: 50%;
  background: var(--bg);
  transition: background var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}

.principle:hover::before { background: var(--accent); transform: scale(1.25); }

.principle__num { margin-bottom: 0.5rem; }
.principle__title { font-size: clamp(0.95rem, 1.1vw, 1.05rem); }
.principle__body { font-size: 0.88rem; }

/* Below the point where six columns stay readable, it becomes a swipeable rail
   rather than collapsing back into rows. */
@media (max-width: 1100px) {
  .principles {
    grid-auto-columns: clamp(210px, 40vw, 280px);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    padding-bottom: 0.75rem;
    scrollbar-width: thin;
    scrollbar-color: var(--line-strong) transparent;
  }
  .principles > * { scroll-snap-align: start; }
  .principles::-webkit-scrollbar { height: 6px; }
  .principles::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 3px; }
}

@media (prefers-reduced-motion: reduce) {
  .principle::before { transition: none; }
}

/* The marker filled on hover but the words stayed dim, so only the dot
   responded. The whole principle lights now, and its neighbours step back so
   the one you are reading is clearly the one selected. */
.principle__title,
.principle__body {
  transition: color var(--dur-fast) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
}

.principle:hover .principle__title { color: var(--accent); }
.principle:hover .principle__body { color: var(--text); }

@media (prefers-reduced-motion: reduce) {
  .principle__title, .principle__body { transition: none; }
}

.work-more__stack {
  color: var(--text-faint);
  font-size: 0.62rem;
  letter-spacing: var(--tracking-mono);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The toggle read as a disabled label: faint text, faint border, no colour.
   It hides eleven real entries, so it has to look like the control it is. */
.volunteer-toggle {
  border-color: var(--accent);
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  font-weight: 700;
}
.volunteer-toggle::after { content: ' \2193'; }
.volunteer-toggle[aria-expanded="true"]::after { content: ' \2191'; }
.volunteer-toggle:hover { background: var(--accent); color: var(--bg); }

/* ---------- footer navigation ----------
   The footer was three lines of text with nowhere to go. Same destinations as
   the header, so reaching the bottom is not a dead end. */
.footer__link {
  position: relative;
  color: var(--text-dim);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  transition: color var(--dur-fast) var(--ease-out);
}

.footer__link::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -3px;
  width: 100%;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--dur) var(--ease-out);
}

.footer__link:hover { color: var(--accent); }
.footer__link:hover::after { transform: scaleX(1); transform-origin: left; }

@media (prefers-reduced-motion: reduce) {
  .footer__link, .footer__link::after { transition: none; }
}

/* ============ SECOND BRAIN LAYOUT ============
   The tree sat top-right and the graph far below, so nothing suggested that
   clicking a branch filters the map. They sit side by side now: intro and stats
   run across the top, then the tree next to the graph it controls. That also
   closes the dead space that opened under the stats. */
.vault {
  grid-template-columns: minmax(260px, 24rem) minmax(0, 1fr);
  gap: clamp(1.25rem, 2.5vw, 2.5rem);
  align-items: start;
}

.vault__summary {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(1.25rem, 3vw, 3rem);
  align-items: center;
}

/* the eyebrow spans, the prose and the metrics sit beside each other */
.vault__summary > .mono { grid-column: 1 / -1; }
.vault__summary .lead { margin: 0; }
.vault__metrics { margin-top: 0; }

.vault-tree { grid-column: 1; align-self: stretch; }
.vault-graph { grid-column: 2; margin-top: 0; }

/* the tree is the control for the map, so say so */
.vault-tree::after {
  content: 'CLICK A BRANCH TO FILTER THE MAP';
  display: block;
  padding: 0.75rem 1rem 0;
  color: var(--text-faint);
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: var(--tracking-mono);
}

@media (max-width: 1100px) {
  .vault { grid-template-columns: minmax(0, 1fr); }
  .vault__summary { grid-template-columns: minmax(0, 1fr); }
  .vault-tree, .vault-graph { grid-column: 1; }
}

/* .hero__body:has(.hero__portrait) forces three columns and sits outside any
   media query, so it outranked the single-column mobile rule on specificity.
   The portrait's column collapsed to zero and the photo vanished on phones. */
@media (max-width: 1080px) {
  .hero__body:has(.hero__portrait) { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- open source rows ----------
   Only two of the builds are public. They should be findable at a glance rather
   than sitting in the list looking like everything else. */
.work-more__row--oss { position: relative; }

/* No vertical marker: Audio Splitter and Hotkey HQ are adjacent rows, so any
   full-height bar merged into one line that read as cutting through the rule
   between them. The accent name and the OSS badge carry it instead. */

.work-more__row--oss .work-more__name { color: var(--accent); }

.work-more__oss {
  margin-left: 0.5rem;
  padding: 0.1rem 0.35rem;
  border: 1px solid var(--accent);
  border-radius: 2px;
  color: var(--accent);
  font-size: 0.55rem;
  letter-spacing: var(--tracking-mono);
  vertical-align: middle;
}

.work-more__row--oss:hover { background: color-mix(in srgb, var(--accent) 7%, transparent); }

/* ============ FOOTER ============
   Was a single flat row of links over three lines of text. Now a real closing
   block: who this is and what to do next on the left, then the sections and the
   outbound links as their own columns. */
.footer__top {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  padding-block: clamp(2rem, 4.5vw, 3.5rem);
  border-bottom: 1px solid var(--line);
}

.footer__brand { display: grid; align-content: start; gap: 1rem; }

.footer__wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  font-weight: 700;
  letter-spacing: var(--tracking-mono);
  color: var(--text);
}

.footer__mark {
  width: 10px;
  height: 10px;
  background: var(--accent);
  border-radius: 2px;
}

.footer__statement {
  max-width: 30ch;
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 1.9vw, 1.6rem);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: var(--tracking-tight);
  color: var(--text);
}

.footer__statement em { color: var(--accent); font-style: normal; }

.footer__cta {
  justify-self: start;
  padding: 0.7rem 1.1rem;
  border: 1px solid var(--accent);
  border-radius: 100px;
  color: var(--accent);
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}

.footer__cta:hover { background: var(--accent); color: var(--bg); }

.footer__col { display: grid; align-content: start; gap: 0.55rem; }

.footer__col-title {
  margin-bottom: 0.35rem;
  color: var(--text-faint);
  font-size: 0.6rem;
  letter-spacing: var(--tracking-mono);
}

.footer__out { opacity: 0; transition: opacity var(--dur-fast) var(--ease-out); }
.footer__link:hover .footer__out { opacity: 1; }

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

@media (max-width: 900px) {
  .footer__top { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .footer__brand { grid-column: 1 / -1; }
}

@media (max-width: 560px) {
  .footer__top { grid-template-columns: minmax(0, 1fr); }
}

/* On a phone the hero stacks, so the portrait lands last and ran 125px past the
   fold - the same sliced-face problem, just on a narrow screen. Cap it against
   the viewport height so he arrives whole. */
@media (max-width: 1080px) {
  /* Shrinking him further was not the fix - the hero's own stacked content is
     taller than a phone screen, so he was landing below the fold no matter his
     size. He moves up instead, directly under the headline, where he is seen
     whole before the reader scrolls. */
  .hero__portrait {
    order: -1;
    justify-self: center;
    width: min(215px, 54vw);
    max-height: min(28svh, 240px);
    margin-top: 0;
    margin-bottom: 0.5rem;
  }
}

/* ---------- stack hierarchy ----------
   Fifty-odd chips with no hierarchy told a reader nothing. The daily drivers
   lead and read louder; the rest stay available without competing. */
.skill-group--core .skill-chip {
  border-color: var(--accent);
  color: var(--accent);
}

.marquee__updated {
  position: absolute;
  right: 0.55rem;
  bottom: 0.18rem;
  color: var(--text-faint);
  font-size: 0.52rem;
  letter-spacing: 0.08em;
  pointer-events: none;
}

.skill-group--core .skill-group__name { color: var(--text); }

.skill-group__note {
  display: block;
  margin-top: 0.2rem;
  color: var(--text-faint);
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
}

/* ============ CONTENT HIERARCHY PASS ============ */

/* The identity statement is the display, while the former headline is context. */
.hero {
  /* 1.5rem left no room for the absolutely positioned .hero__scroll cue, so
     "SCROLL" sat on the metrics grid's bottom-right corner and ran straight
     through "Global Goals Run, Balkalakaar" at 1600, 1440, 1366, 1280, 1024,
     820 and 768px. It only looked right at a handful of widths, by luck of
     where the metric text happened to wrap. This reserves the cue its own band.
     Note this rule overrides the earlier .hero padding-block — edit it here. */
  padding-block: 5.25rem 4rem;
}

.hero__meta {
  padding-bottom: 0.75rem;
  margin-bottom: clamp(0.75rem, 1.6vh, 1.25rem);
}

.hero__eyebrow {
  margin-bottom: 0.65rem;
  color: var(--text-faint);
  font-size: 0.68rem;
  letter-spacing: var(--tracking-mono);
}

.hero__title {
  max-width: 100%;
  margin-bottom: clamp(0.9rem, 1.8vh, 1.35rem);
  font-size: clamp(3.15rem, 5vw, 4.75rem);
  line-height: 0.88;
}

.hero__body:has(.hero__portrait) {
  grid-template-columns: minmax(0, 1fr) minmax(220px, 330px);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: center;
}

.hero__copy { min-width: 0; }
.hero__sub { max-width: 58ch; }

.hero__portrait {
  grid-column: 2;
  grid-row: 1;
  width: min(100%, 310px);
  max-height: min(25svh, 235px);
  margin: 0;
  transform: none;
}

.metrics {
  margin-top: clamp(0.75rem, 1.7vh, 1.1rem);
}

.metric { padding: clamp(0.65rem, 1.2vw, 0.9rem); }
.metric__value { margin-bottom: 0.3rem; font-size: clamp(1.55rem, 2.4vw, 2.2rem); }
.metric__label { font-size: 0.76rem; }
.metric__context { font-size: 0.58rem; }

/* One flagship, then three peers. */
.card--hero {
  grid-column: 1 / -1;
  min-height: 0;
  padding: clamp(1.75rem, 3.4vw, 3.2rem);
  background: var(--card-featured);
}

.card--hero .card__name { font-size: clamp(2rem, 4vw, 3.6rem); }
.card--hero .card__desc,
.card--hero .card__detail { max-width: 82ch; }

.card--lead { grid-column: span 4; min-height: 430px; }

.card__outcomes--hero {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  padding-top: 0;
  border: 1px solid var(--line);
  background: var(--line);
}

.card__outcomes--hero .card__outcome {
  display: grid;
  align-content: start;
  gap: 0.25rem;
  min-height: 6rem;
  padding: 1rem;
  background: var(--bg);
}

.card__outcomes--hero .card__outcome::before { display: none; }

.card__outcome-value {
  color: var(--accent);
  font-family: var(--font-display);
  font-size: clamp(1.8rem, 3.4vw, 3rem);
  line-height: 1;
}

.card__outcome-copy { color: var(--text-dim); }

.card__evidence {
  display: grid;
  gap: 0.3rem;
  width: max-content;
  max-width: 100%;
  margin-top: 0.15rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--accent);
  background: var(--accent-wash);
}

.card__evidence-value {
  color: var(--accent);
  font-family: var(--font-display);
  font-size: clamp(1.7rem, 2.8vw, 2.5rem);
  line-height: 1;
}

.card__evidence-label { color: var(--text-dim); }

/* Product captures sit in a desktop-device shell, with purpose under caption. */
.device-frame {
  display: block;
  padding: 0.55rem 0.55rem 0;
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  background: var(--bg-raised);
  box-shadow: 0 18px 42px color-mix(in srgb, var(--shadow-modal) 45%, transparent);
  transition: border-color var(--dur-fast) var(--ease-out), transform var(--dur) var(--ease-out);
}

.device-frame__screen { border-radius: 8px 8px 3px 3px; }
.device-frame__base {
  display: block;
  width: 34%;
  height: 6px;
  margin-inline: auto;
  border-radius: 0 0 8px 8px;
  background: var(--line-strong);
}

.app-shot:hover .browser-frame { transform: none; }
.app-shot:hover .device-frame { border-color: var(--accent-deep); transform: translateY(-3px); }

.app-shot-card__purpose {
  margin-top: 0.35rem;
  padding-top: 0.55rem;
  border-top: 1px solid var(--line);
  color: var(--text);
  font-weight: 600;
}

.writing__thesis {
  max-width: 72ch;
  margin-bottom: clamp(1.25rem, 3vw, 2.25rem);
}

/* Native Substack form plus the original profile link as a separate fallback. */
.subscribe__form {
  display: flex;
  flex: 1 1 340px;
  min-width: 240px;
}

.subscribe__input {
  width: 100%;
  min-width: 0;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--line-strong);
  border-right: 0;
  border-radius: 0;
  outline: 0;
  background: var(--bg-sunken);
  color: var(--text);
  font: inherit;
}

.subscribe__input::placeholder {
  color: var(--text-faint);
  font-family: var(--font-mono);
  font-size: 0.64rem;
  letter-spacing: var(--tracking-mono);
}

.subscribe__input:focus { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }

.subscribe__submit {
  flex: 0 0 auto;
  padding: 0.7rem 1rem;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--bg);
  font-weight: 700;
  letter-spacing: var(--tracking-mono);
  cursor: pointer;
}

.subscribe__submit:hover,
.subscribe__submit:focus-visible { background: var(--text); border-color: var(--text); }

.subscribe__go { margin-left: 0; }
.subscribe:hover .subscribe__go { background: transparent; color: var(--accent); }
.subscribe__go:hover,
.subscribe__go:focus-visible { background: var(--accent) !important; color: var(--bg) !important; }

/* A real note sits beside the graph controls instead of leaving the claim abstract. */
.vault__sidebar {
  grid-column: 1;
  display: grid;
  gap: 1rem;
  min-width: 0;
}

.vault-note {
  min-width: 0;
  padding: clamp(1rem, 2vw, 1.4rem);
  border: 1px solid var(--line-strong);
  background: var(--bg-raised);
  box-shadow: inset 3px 0 0 var(--accent);
}

.vault-note__head {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--line);
  color: var(--text-faint);
}

.vault-note__title {
  margin: 1rem 0 0.75rem;
  font-size: clamp(1.1rem, 1.8vw, 1.45rem);
}

.vault-note__body { display: grid; gap: 0.7rem; color: var(--text-dim); font-size: 0.88rem; line-height: 1.6; }
.vault-note__body ul { display: grid; gap: 0.3rem; padding-left: 1.1rem; }
.vault-note__wikilink {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  background: var(--accent-wash);
}
.vault-note__tag { color: var(--accent); font-family: var(--font-mono); font-size: 0.78rem; }

@media (max-width: 1080px) {
  .hero__body:has(.hero__portrait) { grid-template-columns: minmax(0, 1fr); }
  .hero__portrait { grid-column: 1; grid-row: auto; }
  .card--hero { grid-column: 1 / -1; }
  .card--lead { grid-column: span 6; }
  .vault__sidebar, .vault-graph { grid-column: 1; }
}

@media (max-width: 760px) {
  .hero { padding-block: 6rem 1.5rem; }
  .hero__title { font-size: clamp(1.8rem, 8vw, 2.5rem); line-height: 0.92; }
  .hero__portrait { width: min(190px, 50vw); max-height: min(22svh, 190px); }
  .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .card--lead { grid-column: span 12; min-height: 0; }
  .card__outcomes--hero { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 620px) {
  .subscribe__text { flex: 1 1 calc(100% - 4rem); }
  .subscribe__form { flex-basis: 100%; min-width: 0; }
  .subscribe__go { width: 100%; text-align: center; }
}

@media (prefers-reduced-motion: reduce) {
  .device-frame { transition: none; }
  .app-shot:hover .device-frame { transform: none; }
  .nav__mark,
  .pill[data-tone='live']::before { animation: none; }
}

/* One product, four screens - so its line sits above the grid, not under every card. */
.apps__lead {
  grid-column: 1 / -1;
  max-width: 62ch;
  margin-bottom: clamp(1rem, 2vw, 1.75rem);
  color: var(--text-dim);
}
.apps__lead a { color: var(--accent); }
.apps__lead a:hover { text-decoration: underline; }

/* An abstract principle lands harder with one real instance under it. */
.principle__example {
  margin-top: 0.65rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--line);
  color: var(--accent);
  font-size: 0.62rem;
  line-height: 1.5;
  letter-spacing: 0.02em;
}

/* ============ PORTRAIT: BIGGER, AND STANDING ON THE LINE ============
   After the hero was restructured he had shrunk to 225px and sat 197px above the
   hero's lower edge, which read as floating. He is scaled up and pushed down to
   meet the rule he stands on. */
@media (min-width: 1081px) {
  .hero__portrait {
    width: clamp(300px, 34vw, 540px);
    max-height: clamp(260px, 46svh, 600px);
    align-self: end;
    margin-top: 0;
    /* Sit on the hero's bottom edge rather than hovering above it. The hero has
       overflow:hidden, so a small overshoot grounds him without spilling. */
    margin-bottom: calc(var(--hero-pad-bottom, 4rem) * -1);
  }
}

@media (min-width: 1081px) and (max-height: 820px) {
  .hero__portrait { max-height: clamp(230px, 42svh, 470px); }
}

@media (min-width: 1081px) and (max-height: 700px) {
  .hero__portrait { max-height: clamp(190px, 34svh, 360px); }
}

/* ============ MARQUEE, REFINED ============
   It was one uniform wall of huge uppercase text, so a live signal and a standing
   principle read exactly the same. Smaller now, with live items labelled and in
   accent while the principles sit back. */
.marquee__item {
  font-size: clamp(0.8rem, 1.35vw, 1.05rem);
  font-weight: 700;
  letter-spacing: 0.06em;
  gap: 0.55rem;
  color: var(--text-faint);
}

/* the dot becomes a separator between items, not a bullet on each */
.marquee__item::after {
  width: 4px;
  height: 4px;
  margin-inline: 2.25rem;
  background: var(--line-strong);
  opacity: 0.8;
}

.marquee__item--live { color: var(--text-dim); }
.marquee__item--live::after { background: var(--accent); }

.marquee__label {
  padding: 0.15rem 0.45rem;
  border: 1px solid var(--accent-deep);
  border-radius: 2px;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.58rem;
  font-weight: 600;
  letter-spacing: var(--tracking-mono);
  white-space: nowrap;
}

.marquee__value { white-space: nowrap; }
.marquee__item--live .marquee__value { color: var(--text); }

.marquee { padding-block: 0.85rem; }

/* ============================================================
   NATIVE SCROLL-LINKED MOTION

   Everything in the feature query is progressive enhancement. Browsers
   without Scroll-driven Animations keep the existing reveal, rail and counter
   behaviour. None of these transforms participates in layout.
   ============================================================ */

@property --rail-fill {
  syntax: '<number>';
  inherits: true;
  initial-value: 0;
}

@property --vault-assembly {
  syntax: '<number>';
  inherits: false;
  initial-value: 1;
}

@property --metric-progress {
  syntax: '<number>';
  inherits: false;
  initial-value: 1;
}

@keyframes work-card-scroll {
  0% {
    transform: perspective(900px) translate3d(0, 7px, 0) rotateZ(-1.25deg)
      rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
  }
  46% {
    transform: perspective(900px) translate3d(0, -4px, 0) rotateZ(0.7deg)
      rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
  }
  72% {
    transform: perspective(900px) translate3d(0, -1px, 0) rotateZ(-0.2deg)
      rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
  }
  100% {
    transform: perspective(900px) translate3d(0, 5px, 0) rotateZ(1.1deg)
      rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
  }
}

@keyframes work-row-scroll {
  0% { transform: translate3d(0, 3px, 0) rotate(-0.45deg); }
  50% { transform: translate3d(0, -2px, 0) rotate(0.25deg); }
  100% { transform: translate3d(0, 2px, 0) rotate(0.4deg); }
}

@keyframes section-rule-draw {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

@keyframes chapter-rail-fill {
  from { --rail-fill: 0; }
  to { --rail-fill: 1; }
}

@keyframes vault-graph-assemble {
  from { --vault-assembly: 0; }
  to { --vault-assembly: 1; }
}

@keyframes metric-scroll-count {
  from { --metric-progress: 0; }
  to { --metric-progress: 1; }
}

@supports (animation-timeline: view()) and (animation-timeline: scroll()) {
  .card {
    animation: work-card-scroll 1ms linear both;
    animation-timeline: view(block);
    animation-range: entry 0% exit 100%;
  }

  .work-more__link {
    animation: work-row-scroll 1ms linear both;
    animation-timeline: view(block);
    animation-range: entry 0% exit 100%;
    transform-origin: center;
    will-change: transform;
  }

  .section-head__rule {
    animation: section-rule-draw 1ms linear both;
    animation-timeline: view(block);
    animation-range: entry 0% cover 32%;
    transform-origin: left center;
    will-change: transform;
  }

  /* JS measures the chapter boundaries only when layout changes. The browser
     samples the root timeline and interpolates the fill on every scroll. */
  .chapter-rail {
    animation: chapter-rail-fill 1ms linear both;
    animation-timeline: scroll(root block);
    animation-range: var(--rail-range-start, 0%) var(--rail-range-end, 100%);
  }

  .vault-graph__canvas {
    --vault-assembly: 0;
    animation: vault-graph-assemble 1ms linear both;
    animation-timeline: view(block);
    animation-range: entry 0% cover 55%;
  }

  /* Text formatting cannot be expressed reliably with CSS counters (prefixes,
     suffixes and Indian compact notation vary per item). CSS owns progress;
     motion.js reads this property from its existing shared frame scheduler. */
  /* Removed: tying the metric count to root scroll froze the numbers at a
     fraction of their real value, because the metrics sit at the top of the
     page. They count on entry in motion.js instead. */
}

@media (prefers-reduced-motion: reduce) {
  .card,
  .work-more__link,
  .section-head__rule,
  .chapter-rail,
  .vault-graph__canvas,
  .metrics [data-count-to] {
    animation: none !important;
  }

  .card,
  .work-more__link,
  .section-head__rule {
    transform: none !important;
    will-change: auto;
  }

  .chapter-rail { --rail-fill: 1; }
  .vault-graph__canvas { --vault-assembly: 1; }
  .metrics [data-count-to] { --metric-progress: 1; }
}

@import url('./mark.css');

.cinema-counter {
  position: fixed;
  left: var(--gutter);
  bottom: var(--gutter);
  z-index: calc(var(--z-nav) - 1);
  max-width: calc(100vw - (var(--gutter) * 2));
  padding: 0.75rem 0.85rem;
  border: 1px solid var(--line-strong);
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tracking-mono);
  line-height: 1.65;
  pointer-events: none;
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
  contain: layout paint;
}

.cinema-counter.is-hero-visible {
  opacity: 0;
  transform: translate3d(0, 0.5rem, 0);
}

.cinema-counter__index,
.cinema-counter__title {
  overflow: hidden;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

.cinema-counter__index,
.cinema-counter__bar { color: var(--accent); }

.cinema-counter__progress {
  display: flex;
  gap: 0.75rem;
  white-space: nowrap;
}

@supports (position: sticky) {
  .cinema-sticky-head {
    position: sticky;
    top: 68px;
    z-index: 2;
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: var(--gutter);
    background: color-mix(in srgb, var(--bg) 94%, transparent);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    will-change: transform;
  }
}

.cinema-navigation-progress {
  position: fixed;
  top: 0;
  left: 0;
  z-index: calc(var(--z-preloader) + 1);
  width: 100%;
  height: 2px;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  transform: translate3d(-100%, 0, 0);
}

.cinema-navigation-progress::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--accent);
  box-shadow: 0 0 14px var(--accent-glow);
  transform: scaleX(0.35);
  transform-origin: left;
}

.cinema-navigation-progress.is-active {
  opacity: 1;
  animation: cinema-progress var(--dur-slow) var(--ease-out) infinite;
}

@keyframes cinema-progress {
  0% { transform: translate3d(-100%, 0, 0); }
  65% { transform: translate3d(35%, 0, 0); }
  100% { transform: translate3d(100%, 0, 0); }
}

.cinema-transition-wipe {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-preloader) + 2);
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--accent);
  pointer-events: none;
  contain: paint;
  view-transition-name: cinema-wipe;
}

.cinema-transition-wipe__chapter {
  color: var(--bg);
  font-family: var(--font-display);
  font-size: clamp(3rem, 13vw, 11rem);
  font-weight: 900;
  letter-spacing: var(--tracking-mega);
  line-height: 0.85;
  text-transform: uppercase;
}

::view-transition-group(root),
::view-transition-group(cinema-title),
::view-transition-group(cinema-wipe) {
  animation-duration: 200ms;
  animation-timing-function: var(--ease-in-out);
}

::view-transition-group(cinema-wipe) { z-index: 3; }
::view-transition-group(cinema-title) { z-index: 4; }

::view-transition-old(root) { animation: cinema-old 200ms linear both; }
::view-transition-new(root) { animation: cinema-new 200ms linear both; }

::view-transition-old(cinema-wipe) { display: none; }
::view-transition-new(cinema-wipe) {
  animation: cinema-wipe 200ms var(--ease-in-out) both;
}

::view-transition-old(cinema-title),
::view-transition-new(cinema-title) {
  height: 100%;
  animation-duration: 200ms;
  animation-timing-function: var(--ease-out);
}

@keyframes cinema-old {
  0%, 46% { opacity: 1; }
  47%, 100% { opacity: 0; }
}

@keyframes cinema-new {
  0%, 53% { opacity: 0; }
  54%, 100% { opacity: 1; }
}

@keyframes cinema-wipe {
  0% { clip-path: inset(0 100% 0 0); }
  46%, 54% { clip-path: inset(0 0 0 0); }
  100% { clip-path: inset(0 0 0 100%); }
}

@media (max-width: 899px) {
  .cinema-counter { display: none; }
  .cinema-sticky-head {
    position: static;
    margin-inline: 0;
    padding-inline: 0;
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    transform: none !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cinema-counter { transition: none; }
  .cinema-sticky-head {
    position: static;
    margin-inline: 0;
    padding-inline: 0;
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    transform: none !important;
  }
  .cinema-navigation-progress,
  .cinema-transition-wipe { display: none; }
  .cinema-navigation-progress.is-active { animation: none; transform: none; }
  ::view-transition-group(root),
  ::view-transition-group(cinema-title),
  ::view-transition-group(cinema-wipe),
  ::view-transition-old(root),
  ::view-transition-new(root),
  ::view-transition-old(cinema-wipe),
  ::view-transition-new(cinema-wipe),
  ::view-transition-old(cinema-title),
  ::view-transition-new(cinema-title) { animation-duration: 1ms; }
}

/* The counter's rows were inline, so the section title ran straight into the
   progress bar and overlapped it. Lay them out as explicit stacked rows. */
.cinema-counter {
  display: grid;
  gap: 0.25rem;
  min-width: 13rem;
  line-height: 1.35;
}

.cinema-counter__index,
.cinema-counter__title,
.cinema-counter__progress { display: block; }

.cinema-counter__title { max-width: 18rem; color: var(--text); }

.cinema-counter__progress {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 0.15rem;
}

/* Quieter counter: smaller, dimmer, and it fades back when scrolling stops.
   Previously it sat at full contrast permanently and competed with the content. */
.cinema-counter {
  padding: 0.55rem 0.7rem;
  font-size: 0.62rem;
  border-color: var(--line);
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: blur(6px);
  opacity: 0.6;
  transition: opacity 420ms var(--ease-out);
}

.cinema-counter.is-idle { opacity: 0.18; }
.cinema-counter:hover { opacity: 0.95; }

.cinema-counter__title { color: var(--text-dim); font-size: 0.6rem; }
.cinema-counter__index { color: var(--text-faint); }
.cinema-counter__bar { color: var(--accent-deep); letter-spacing: -0.06em; }
.cinema-counter__percent { color: var(--text-faint); }

@media (prefers-reduced-motion: reduce) {
  .cinema-counter { transition: none; }
}

/* ============ COUNTER: PRESENT ONLY WHILE SCROLLING ============
   It used to sit there permanently and merely dim to 18% when idle, which still
   left a box parked over the page. It now rides in while you scroll and folds
   away into the left gutter the moment you stop, leaving a 3px accent tick as
   the only trace. Hovering the gutter brings it back. */
.cinema-counter {
  transform-origin: left bottom;
  transition:
    opacity 260ms var(--ease-out),
    transform 320ms var(--ease-out),
    clip-path 320ms var(--ease-out);
  clip-path: inset(0 0 0 0);
}

.cinema-counter.is-idle {
  opacity: 0;
  transform: translate3d(calc(-100% - var(--gutter)), 0, 0);
  clip-path: inset(0 100% 0 0);
}

/* the trace left behind, so the reader knows where it went */
.cinema-counter.is-idle::after {
  content: '';
  position: absolute;
  left: calc(100% + var(--gutter));
  bottom: 0;
  width: 3px;
  height: 100%;
  background: var(--accent);
  opacity: 0.5;
}

/* pointer-events are off on the counter itself, so the gutter hotspot revives it */
.cinema-counter { pointer-events: none; }
.cinema-counter.is-idle:hover { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .cinema-counter { transition: opacity 120ms linear; }
  .cinema-counter.is-idle { transform: none; clip-path: none; opacity: 0; }
  .cinema-counter.is-idle::after { display: none; }
}

.palette {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-preloader) - 1);
  color: var(--text);
  font-family: var(--font-body);
}
.palette[hidden] { display: none; }
.palette__scrim {
  display: grid;
  width: 100%;
  height: 100%;
  place-items: start center;
  padding: min(14vh, 8rem) 1rem 1rem;
  overflow-y: auto;
  background: var(--scrim-palette);
  opacity: 0;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  transition: opacity var(--dur-fast) var(--ease-out);
}
.palette.is-open .palette__scrim { opacity: 1; }
.palette__panel {
  display: flex;
  flex-direction: column;
  width: min(100%, 40rem);
  max-height: calc(100dvh - min(14vh, 8rem) - 1rem);
  overflow: hidden;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  background: var(--bg-sunken);
  box-shadow: 0 2rem 7rem var(--shadow-palette), 0 0 0 1px var(--panel-highlight);
  opacity: 0;
  transform: scale(0.96) translateY(-0.5rem);
  transform-origin: 50% 15%;
  transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur) var(--ease-spring);
}
.palette.is-open .palette__panel { opacity: 1; transform: scale(1) translateY(0); }
.palette__terminal {
  flex: 0 1 auto;
  min-height: 0;
  max-height: min(38vh, 20rem);
  padding: 1rem 1.2rem;
  overflow: auto;
  border-bottom: 1px solid var(--line-strong);
  background: var(--bg);
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  line-height: 1.55;
  letter-spacing: 0.02em;
  overflow-wrap: anywhere;
  scrollbar-color: var(--line-strong) transparent;
  scrollbar-width: thin;
}
.palette__terminal[hidden], .palette__results[hidden] { display: none; }
.palette__terminal-entry + .palette__terminal-entry { margin-top: 1rem; }
.palette__terminal-command {
  display: flex;
  min-width: 0;
  gap: 0.6rem;
  color: var(--text);
  font-weight: 700;
}
.palette__terminal-echo-prompt { flex: none; color: var(--accent); }
.palette__terminal-line {
  margin-top: 0.28rem;
  margin-left: 1.15rem;
  white-space: pre-wrap;
}
.palette__terminal-line[data-terminal-kind="heading"],
.palette__terminal-line[data-terminal-kind="status"] { color: var(--accent); }
.palette__terminal-line[data-terminal-kind="error"] { color: var(--tone-building); }
.palette__terminal-line[data-terminal-kind="project"],
.palette__terminal-line[data-terminal-kind="writing"],
.palette__terminal-line[data-terminal-kind="help"] { color: var(--text-dim); }
.palette__search {
  flex: none;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.85rem;
  min-height: 4.5rem;
  padding: 0 1.2rem;
  border-bottom: 1px solid var(--line-strong);
  cursor: text;
}
.palette__prompt {
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 1.25rem;
  font-weight: 700;
  animation: palette-blink 1s steps(1, end) infinite;
}
.palette__input {
  width: 100%;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  caret-color: var(--accent);
}
.palette__input::placeholder { color: var(--text-faint); opacity: 1; }
.palette__key {
  padding: 0.25rem 0.42rem;
  border: 1px solid var(--line-strong);
  border-radius: 3px;
  background: var(--bg-raised);
  color: var(--text-faint);
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.1em;
}
.palette__results {
  flex: 1 1 auto;
  min-height: 0;
  max-height: min(55vh, 27rem);
  overflow-y: auto;
  padding: 0.5rem 0;
  scrollbar-color: var(--line-strong) transparent;
  scrollbar-width: thin;
}
.palette__group {
  padding: 0.75rem 1.2rem 0.35rem;
  color: var(--text-faint);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: var(--tracking-mono);
  transition: color var(--dur-fast) var(--ease-out);
}
.palette__group:has(+ .palette__option.is-active) { color: var(--accent); }
.palette__option {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 1rem;
  min-height: 3.8rem;
  padding: 0.62rem 1.2rem 0.62rem calc(1.2rem - 2px);
  border-left: 2px solid transparent;
  cursor: pointer;
  opacity: 0;
  animation: palette-row-in 240ms var(--ease-out) forwards;
  animation-delay: var(--palette-delay, 0ms);
}
.palette__option.is-active { border-left-color: var(--accent); background: var(--accent-wash); }
.palette__option-text { display: grid; min-width: 0; gap: 0.18rem; }
.palette__title, .palette__subtitle { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.palette__title { color: var(--text); font-size: 0.92rem; font-weight: 600; }
.palette__title mark { background: transparent; color: var(--accent); font-weight: 700; }
.palette__subtitle { color: var(--text-faint); font-size: 0.75rem; }
.palette__option-group {
  color: var(--text-faint);
  font-family: var(--font-mono);
  font-size: 0.57rem;
  letter-spacing: 0.12em;
  transition: color var(--dur-fast) var(--ease-out);
}
.palette__option.is-active .palette__option-group { color: var(--accent); }
.palette__empty {
  padding: 3rem 1.2rem;
  color: var(--text-faint);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  text-align: center;
}
.palette__footer {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 2.75rem;
  padding: 0.65rem 1.2rem;
  border-top: 1px solid var(--line-strong);
  color: var(--text-faint);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.palette__status { flex: none; color: var(--accent-dim); font-weight: 700; }

@keyframes palette-blink {
  0%, 48% { opacity: 1; }
  49%, 100% { opacity: 0.2; }
}
@keyframes palette-row-in {
  from { opacity: 0; transform: translateY(0.3rem); }
  to { opacity: 1; transform: translateY(0); }
}

@media (max-width: 40rem) {
  .palette__scrim { align-items: end; padding: 0; }
  .palette__panel {
    width: 100%;
    max-height: min(88dvh, 46rem);
    border-width: 1px 0 0;
    border-radius: 0;
    transform: translateY(1rem);
    transform-origin: 50% 100%;
  }
  .palette__terminal { max-height: 36dvh; padding-inline: 1rem; }
  .palette.is-open .palette__panel { transform: translateY(0); }
  .palette__results { max-height: calc(min(88dvh, 46rem) - 7.25rem); }
  .palette__search { min-height: 4.25rem; padding-inline: 1rem; }
  .palette__option { padding-right: 1rem; padding-left: calc(1rem - 2px); }
  .palette__group, .palette__footer { padding-inline: 1rem; }
  .palette__hint { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

@media (prefers-reduced-motion: reduce) {
  .palette__scrim, .palette__panel { transition: none; }
  .palette__panel, .palette.is-open .palette__panel { transform: none; }
  .palette__prompt, .palette__option { animation: none; }
  .palette__option { opacity: 1; }
}

/* "Ctrl" needs more room than the ⌘ glyph, so let the trigger size to its label. */
.nav__palette { gap: 0.35rem; white-space: nowrap; }
.nav__palette-mod { font-size: 0.95em; letter-spacing: 0.02em; }

.behind-trigger {
  position: fixed;
  right: max(0.75rem, env(safe-area-inset-right));
  bottom: max(0.75rem, env(safe-area-inset-bottom));
  z-index: calc(var(--z-nav) - 1);
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 36px;
  padding: 0.45rem 0.65rem;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  background: color-mix(in srgb, var(--bg-raised) 92%, transparent);
  color: var(--text-dim);
  box-shadow: 0 10px 30px var(--shadow-modal);
  cursor: pointer;
  font-size: 0.58rem;
  letter-spacing: 0.1em;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}

.behind-trigger kbd {
  padding: 0.12rem 0.28rem;
  border: 1px solid currentColor;
  border-radius: 3px;
  font: inherit;
}

.behind-trigger:hover,
.behind-trigger:focus-visible,
.behind-trigger[aria-pressed='true'] {
  border-color: var(--accent);
  background: var(--bg-raised);
  color: var(--accent);
}

[data-behind-section] { position: relative; }

.behind-note {
  position: absolute;
  top: clamp(0.75rem, 1.8vw, 1.5rem);
  right: max(0.75rem, calc((100vw - var(--maxw)) / 2 + 0.75rem));
  z-index: calc(var(--z-content) + 2);
  display: grid;
  width: min(15rem, 22vw);
  gap: 0.25rem;
  padding: 0.55rem 0.65rem 0.6rem 0.85rem;
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  background: color-mix(in srgb, var(--bg-raised) 94%, transparent);
  box-shadow: 0 9px 24px var(--shadow-modal);
  color: var(--text-dim);
  font-family: var(--font-mono);
  opacity: 0;
  pointer-events: none;
  transform: translateY(7px);
}

.behind-note::before {
  content: '';
  position: absolute;
  top: 1rem;
  right: 100%;
  width: clamp(1rem, 3vw, 3rem);
  height: 1px;
  background: linear-gradient(to left, var(--accent), transparent);
}

.behind-note__eyebrow {
  color: var(--accent);
  font-size: 0.52rem;
  letter-spacing: 0.14em;
}

.behind-note__fact {
  font-size: clamp(0.5rem, 0.58vw, 0.62rem);
  letter-spacing: 0.055em;
  line-height: 1.45;
}

[data-behind-label='hero'] { top: 8.75rem; }
[data-behind-label='subscribe'] {
  top: calc(100% + 0.6rem);
  right: auto;
  left: max(0.75rem, calc((100vw - var(--maxw)) / 2 + 0.75rem));
}
[data-behind-label='subscribe']::before {
  right: auto;
  left: 100%;
  background: linear-gradient(to right, var(--accent), transparent);
}
[data-behind-label='work'] { top: 4.5rem; }

.behind-active .behind-note {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 260ms var(--ease-out), transform 360ms var(--ease-out);
  transition-delay: min(calc(var(--behind-index) * 22ms), 220ms);
}

@media (max-width: 899px), (any-hover: none) {
  .behind-trigger,
  .behind-note { display: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .behind-trigger,
  .behind-note,
  .behind-active .behind-note {
    transition: none !important;
    transform: none !important;
  }
}

@media print {
  .behind-trigger,
  .behind-note { display: none !important; }
}

.keys-overlay {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-preloader) - 10);
}

.keys-overlay__scrim {
  display: grid;
  min-height: 100%;
  place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

.keys-overlay__panel {
  width: min(46rem, 100%);
  max-height: min(46rem, calc(100svh - 2rem));
  overflow: auto;
  border: 1px solid var(--line-strong);
  border-top: 2px solid var(--accent);
  border-radius: 6px;
  background: var(--bg-raised);
  box-shadow: 0 24px 80px var(--shadow-palette);
  color: var(--text);
}

.keys-overlay__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: clamp(1rem, 3vw, 1.75rem);
  border-bottom: 1px solid var(--line);
}

.keys-overlay__head h2 {
  margin-top: 0.4rem;
  font-size: clamp(1.6rem, 5vw, 3.1rem);
}

.keys-overlay__close {
  min-width: 44px;
  min-height: 38px;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  color: var(--text-dim);
  cursor: pointer;
}

.keys-overlay__close:hover,
.keys-overlay__close:focus-visible { border-color: var(--accent); color: var(--accent); }

.keys-overlay__description {
  margin: 0;
  padding: 1rem clamp(1rem, 3vw, 1.75rem);
  border-bottom: 1px solid var(--line);
  color: var(--text-dim);
  line-height: 1.55;
}

.keys-overlay__list {
  margin: 0;
  padding: 0 clamp(1rem, 3vw, 1.75rem) 1rem;
}

.keys-overlay__list > div {
  display: grid;
  grid-template-columns: minmax(8.5rem, 0.72fr) 1.5fr;
  gap: 1rem;
  align-items: center;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--line-faint);
}

.keys-overlay__list dt,
.keys-overlay__list dd { margin: 0; }

.keys-overlay__list kbd {
  display: inline-block;
  max-width: 100%;
  padding: 0.25rem 0.42rem;
  border: 1px solid var(--line-strong);
  border-bottom-color: var(--text-faint);
  border-radius: 4px;
  background: var(--bg-sunken);
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  line-height: 1.35;
  white-space: normal;
}

.keys-overlay__list dd { color: var(--text-dim); font-size: 0.9rem; }

.nav__sound {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  min-height: 30px;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--line-strong);
  border-radius: 5px;
  color: var(--text-faint);
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}

.nav__sound:hover,
.nav__sound:focus-visible,
.nav__sound[aria-pressed='true'] {
  border-color: var(--accent);
  background: var(--accent-wash);
  color: var(--accent);
}

/* Icon-only. The text label stays in the DOM for assistive tech but is never
   shown - "SOUND OFF" next to a speaker glyph was saying the same thing twice
   and taking up a third of the header. */
.nav__sound { min-width: 32px; padding-inline: 0.4rem; }
.nav__sound-icon { display: inline-flex; align-items: center; color: var(--accent); }
.nav__sound-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

@media (max-width: 1180px) and (min-width: 761px) {
  .nav__sound-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .nav__sound { padding-inline: 0.4rem; }
}

@media (max-width: 760px) {
  .nav__inner { gap: clamp(0.3rem, 2.1vw, 0.75rem); }
  .nav__sound { min-width: 44px; min-height: 44px; padding: 0.3rem; }
  .nav__sound-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .nav__sound-icon { min-width: 0; }
  .keys-overlay__scrim { padding: 0.75rem; }
  .keys-overlay__list > div { grid-template-columns: minmax(6.5rem, 0.8fr) 1.4fr; gap: 0.75rem; }
}

@media (max-width: 430px) {
  .keys-overlay__list > div { grid-template-columns: 1fr; gap: 0.3rem; }
}

@media (prefers-reduced-motion: reduce) {
  .keys-overlay *,
  .nav__sound { transition: none !important; }
}

@media print {
  .keys-overlay,
  .nav__sound { display: none !important; }
}

/* ---------- nav control cluster: Ctrl K, sound, theme ----------
   These were three separately-built buttons sitting side by side, each with its
   own border, and they read as three mismatched boxes no matter how the heights
   were equalised. They are one segmented control now: a single border around the
   group, hairline dividers between segments, no borders on the buttons
   themselves. keys.css loads after layout.css in every bundle, so this wins
   without !important. */
.nav__tools {
  display: inline-flex;
  align-items: stretch;
  height: 30px;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  overflow: hidden;
  background: transparent;
}

.nav__tools > button {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  margin: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--text-faint);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}

/* Hairline between segments, never before the first one. */
.nav__tools > button + button { border-left: 1px solid var(--line-strong); }

.nav__palette { padding: 0 0.7rem; gap: 0.3rem; }
.nav__sound,
.nav__theme { width: 34px; padding: 0; }

.nav__tools > button:hover,
.nav__tools > button:focus-visible {
  color: var(--accent);
  background: var(--accent-wash);
}
/* The group border lights up as a whole on hover, so the cluster reacts as one
   object rather than one segment flashing on its own. */
.nav__tools:hover,
.nav__tools:focus-within { border-color: var(--accent); }

/* "On" is a quiet fill inside its segment. It used to take a full accent border
   while the segment beside it stayed grey, which is what made two controls in
   the same cluster look like different components. */
.nav__tools > button[aria-pressed='true'] {
  color: var(--accent);
  background: var(--accent-wash);
}

.nav__sound-icon,
.nav__theme-icon { display: inline-flex; align-items: center; justify-content: center; min-width: 0; }

@media (max-width: 760px) {
  /* No keyboard to press Ctrl K with, so the group drops to two segments.
     This needs the descendant selector: layout.css hides .nav__palette at
     specificity (0,1,0), which `.nav__tools > button { display: inline-flex }`
     at (0,1,1) silently overrode — the shortcut reappeared on phones. */
  .nav__tools > .nav__palette { display: none; }
  .nav__tools { height: 40px; }
  .nav__sound,
  .nav__theme { width: 44px; }
}

@media (prefers-reduced-motion: reduce) {
  .nav__tools,
  .nav__tools > button { transition: none; }
}

/* Detail pages only — shared tokens and homepage primitives come from tokens.css/layout.css. */
.detail-page { overflow-x: hidden; }
.detail-page main { min-height: 100svh; padding-top: 68px; }
.detail-page .nav__toggle { display: none; }
.page-back { display: inline-block; margin-top: clamp(2rem, 6vw, 5rem); font-family: var(--font-mono); font-size: var(--fs-mono); font-weight: 700; letter-spacing: var(--tracking-mono); text-transform: uppercase; color: var(--accent); }
.page-hero { padding-block: clamp(3rem, 9vw, 8rem) clamp(3rem, 7vw, 6rem); border-bottom: 1px solid var(--line); }
.page-hero__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.8rem 1.5rem; margin-bottom: clamp(1.5rem, 4vw, 3rem); }
.page-hero h1 { max-width: 13ch; font-family: var(--font-display); font-size: clamp(3.25rem, 10vw, 9rem); font-weight: 900; line-height: 0.9; letter-spacing: var(--tracking-mega); overflow-wrap: anywhere; text-transform: uppercase; }
.page-hero__lead { max-width: 38ch; margin-top: clamp(1.5rem, 4vw, 3rem); font-family: var(--font-display); font-size: var(--fs-h3); font-weight: 600; line-height: 1.25; color: var(--accent); }
.page-body { padding-block: clamp(3rem, 8vw, 7rem); }
.prose { width: min(100%, 68ch); color: var(--text-dim); font-size: clamp(1rem, 1.5vw, 1.15rem); line-height: 1.82; }
.prose > * + * { margin-top: 1.4em; }
.prose h2, .prose h3 { margin-top: 2.4em; font-family: var(--font-display); font-weight: 800; line-height: 1.15; color: var(--text); }
.prose h2 { font-size: var(--fs-h3); }
.prose h3 { font-size: var(--fs-lead); }
.prose ul, .prose ol { display: grid; gap: 0.55rem; padding-left: 1.35rem; }
.prose ul { list-style: square; }
.prose ol { list-style: decimal; }
.prose li::marker, .prose strong { color: var(--accent); }
.prose blockquote { padding: 0.5rem 0 0.5rem clamp(1rem, 3vw, 2rem); border-left: 2px solid var(--accent); color: var(--text); font-family: var(--font-display); font-size: var(--fs-lead); font-weight: 600; line-height: 1.45; }
.prose a { color: var(--accent); text-decoration: underline; text-underline-offset: 0.2em; }
.prose__note { padding: 1rem; border: 1px solid var(--line); font-family: var(--font-mono); font-size: var(--fs-mono); letter-spacing: var(--tracking-mono); text-transform: uppercase; color: var(--text-faint); }
.page-section, .related, .page-nav { margin-top: clamp(4rem, 10vw, 9rem); }
.page-screens__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(1rem, 3vw, 2.5rem); }
.page-shot { min-width: 0; }
.page-shot figcaption { display: grid; gap: 0.5rem; padding-top: 1rem; color: var(--text-dim); }
.page-shot img { width: 100%; height: auto; }
.related__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1px; padding: 1px; background: var(--line); }
.related__item { display: grid; gap: 0.7rem; min-width: 0; padding: clamp(1.25rem, 4vw, 2.5rem); background: var(--bg); transition: background-color var(--dur) var(--ease-out); }
.related__item:hover { background: var(--bg-raised); }
.related__item strong { font-family: var(--font-display); font-size: var(--fs-lead); color: var(--text); }
.related__item span { color: var(--text-dim); line-height: 1.6; }
.page-substack { margin-top: clamp(2.5rem, 6vw, 5rem); }
.page-nav { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1px; padding: 1px; background: var(--line); }
.page-nav__link { display: grid; gap: 0.6rem; min-width: 0; padding: clamp(1.25rem, 4vw, 2.5rem); background: var(--bg); transition: background-color var(--dur) var(--ease-out); }
.page-nav__link:hover { background: var(--bg-raised); }
.page-nav__link strong { overflow-wrap: anywhere; font-family: var(--font-display); font-size: var(--fs-lead); }
.page-nav__link--next { text-align: right; }
@media (max-width: 900px) { .detail-page .nav__links { display: none; } .page-screens__grid { grid-template-columns: 1fr; } }
@media (max-width: 620px) { .detail-page .nav__cta { display: none; } .page-hero h1 { font-size: clamp(2.75rem, 16vw, 5rem); } .related__grid, .page-nav { grid-template-columns: 1fr; } .page-nav__link--next { text-align: left; } }
