/* ============================================================
   console-portfolio — original implementation
   Visual family translated from the reference dossier:
   dark near-monochrome + single cold-blue emissive accent,
   HUD viewport frame, boot loader, cursor thread, pill nav,
   Oxanium / MuseoModerno / Geist Mono (all SIL OFL, self-hosted).
   All copy, names, assets are original.
   ============================================================ */

/* ---- Fonts (self-hosted OFL variable faces) ---- */
@font-face {
  font-family: "Oxanium";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("../fonts/oxanium.woff2") format("woff2");
}
@font-face {
  font-family: "MuseoModerno";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/museomoderno.woff2") format("woff2");
}
@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/geistmono.woff2") format("woff2");
}

/* ---- Design tokens ---- */
:root {
  --background: #000;
  --foreground: #fff;
  --color-white: #fff;
  --color-black: #000;
  --card-bg: #0a0a0a;
  --border: #1a1a1a;
  --blue-glow: #3b82f6;
  --blue-bright: #60a5fa;
  --gray-300: #eef0f3;
  --gray-400: #cfd4db;
  --gray-900: #0d1117;

  /* ---- Theme surfaces (dark = default). Overridden under
     html[data-theme="light"] near the foot of this file. The cold-blue
     accent (--blue-*) is deliberately shared across both themes. ---- */
  --nav-bg: rgba(0, 0, 0, 0.4);
  --nav-border: rgba(255, 255, 255, 0.1);
  --nav-shadow: rgba(0, 0, 0, 0.5);
  --nav-indicator: #fff;
  --nav-indicator-fg: #000;
  --hud-line: rgba(255, 255, 255, 0.2);
  --loader-bg: #000;
  --loader-fg: #fff;
  --chip-bg: #fff;                        /* work skill bubbles */
  --chip-fg: #000;
  --chip-glow: rgba(255, 255, 255, 0.22);
  --dot-inactive: rgba(255, 255, 255, 0.28);
  --surface-1: rgba(255, 255, 255, 0.015);  /* faint card fills */
  --surface-2: rgba(255, 255, 255, 0.02);
  --surface-3: rgba(255, 255, 255, 0.06);   /* inline code */
  --hair: rgba(255, 255, 255, 0.04);
  --scrim-0: rgba(0, 0, 0, 0.9);            /* mobile belief-copy vignette */
  --scrim-1: rgba(0, 0, 0, 0.8);
  --scrim-2: rgba(0, 0, 0, 0);
  --scrim-shadow: rgba(0, 0, 0, 0.85);
  --arrow-bg: rgba(10, 10, 10, 0.6);   /* carousel arrow chip */
  /* Generative-canvas ink (RGB triplet, read by main.js). Near-white in dark;
     dark slate in light so the ring / constellations stay legible. */
  --canvas-ink: 226, 234, 250;

  --font-oxanium: "Oxanium", "Oxanium Fallback", system-ui, sans-serif;
  --font-museo: "MuseoModerno", system-ui, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, monospace;

  --safe-area-top: max(10px, 40px);
  --safe-area-right: max(10px, 40px);
  --safe-area-bottom: max(10px, 40px);
  --safe-area-left: max(10px, 40px);
  --border-chamfer: 40px;
  --border-padding: 10px;
  --blur-md: 12px;
  --container-7xl: 80rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.75rem;

  --vh: 1vh;
  --content-height: calc(100 * var(--vh) - var(--safe-area-top) - var(--safe-area-bottom));

  --ease: cubic-bezier(0.4, 0, 0.2, 1);
}

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

html { -webkit-text-size-adjust: 100%; }

html { scroll-behavior: smooth; scrollbar-width: none; }
html::-webkit-scrollbar { display: none; }
body::-webkit-scrollbar { display: none; }

body {
  font-family: var(--font-oxanium);
  font-weight: 400;
  font-size: 16px;
  line-height: 24px;
  color: var(--foreground);
  background: var(--background);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Document itself is the scroller so captured scroll states advance
     and the aphoristic belief panels enter/reveal. */
  overflow-x: hidden;
  overflow-y: auto;
  min-height: 100vh;
  cursor: auto;
}
/* Home: gentle snap between full-height belief panels. Snap lives on the
   document (html) because the document — not an inner box — is the scroller. */
html.snap { scroll-snap-type: y proximity; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  html.snap { scroll-snap-type: none; }
}

/* ============================================================
   Run 004 fidelity repair — reference-derived composition contracts
   ============================================================ */

/* The thread is atmospheric in the reference. Keep it behind every readable
   surface and markedly quieter instead of drawing a rule through the copy. */
.cursor-thread { z-index: 1; opacity: 0.24; mix-blend-mode: screen; }
.cursor-thread svg { height: 5rem; filter: blur(0.35px); }
.pill-nav, .hud-frame { z-index: 50; }
main { position: relative; z-index: 2; }

/* Compact HUD/nav metrics visible in the target captures. */
.pill-nav-inner { padding: 0.4rem; }
.pill-indicator { height: calc(100% - 12px); top: 6px; }
.pill-nav a { padding: 0.5rem 1.4rem; font-size: 0.95rem; font-weight: 500; }

/* Final cascade guard for the run-005 measured route contracts. */
.cursor-thread { opacity: 0.12; }
.cursor-thread svg { width: 58vw; height: 3.5rem; }
.about-page .page-scroll {
  min-height: var(--content-height); width: min(74vw, 1080px); margin: 0 auto;
  display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(260px, .75fr);
  align-items: center; gap: clamp(4rem, 9vw, 9rem);
}
.about-page .about-wrap { max-width: 620px; padding: 0; margin: 0; }
.about-page .about-wrap h1 { font-weight: 300; font-size: clamp(2.2rem, 3.2vw, 3.2rem); letter-spacing: .02em; }
.about-page .about-body { max-width: 54ch; margin-top: 1rem; gap: .9rem; }
.about-page .about-body p { font-size: clamp(.78rem, .82vw, .9rem); line-height: 1.58; color: var(--gray-300); }
.about-page .philosophy { font-size: clamp(1.2rem, 1.75vw, 1.65rem); margin-top: 1.25rem; }
.about-page .interests { margin-top: 1rem; }
.about-page .socials { margin-top: 1rem; }
.about-page .portrait {
  position: relative; inset: auto; grid-column: 2; grid-row: 1;
  width: min(100%, 300px); margin: 0 auto; aspect-ratio: 1;
  border-radius: 0; mask-image: none; -webkit-mask-image: none;
}
.about-page .portrait img { object-fit: contain; }

@media (max-width: 820px) {
  .cursor-thread { display: none; }
  .about-page .page-scroll {
    width: auto; min-height: var(--content-height); margin: 0; padding: 4.5rem 2rem 2rem;
    display: flex; flex-direction: column; justify-content: flex-start; gap: 1.4rem;
  }
  .about-page .portrait { order: 0; width: 180px; height: 150px; aspect-ratio: auto; margin: 0 auto; }
  .about-page .about-wrap { order: 1; width: 100%; max-width: none; }
  .about-page .about-wrap > .mono-label, .about-page .about-wrap h1 { display: none; }
  .about-page .about-body { max-width: none; margin-top: 0; gap: .8rem; }
  .about-page .about-body p { font-size: .72rem; line-height: 1.55; }
  .about-page .philosophy { font-size: 1.05rem; margin-top: 1rem; }
  .about-page .interests { margin-top: .9rem; }
  .about-page .chip { font-size: .52rem; padding: .22rem .48rem; }
  .about-page .socials { margin-top: 1rem; }
}
.mono-label { font-size: 0.54rem; line-height: 1.2; letter-spacing: 0.16em; }

/* HOME: the reference's ring/cube is the persistent dominant geometry. The
   belief copy remains available, but becomes restrained edge choreography. */
.home .hero-canvas-wrap {
  position: fixed;
  top: 52%; left: 50%;
  transform: translate(-50%, -50%) scale(0.9);
  z-index: 1;
}
.home .hero .panel-inner, .home .hero-aside, .home .scroll-cue,
.home .panel:not(.hero) .panel-inner { z-index: 3; }
.home .hero h1 { font-size: clamp(2rem, 4.1vw, 3.7rem); font-weight: 300; letter-spacing: 0.01em; }
.home .hero h1 .role { font-size: 0.34em; letter-spacing: 0.02em; }
.home .panel:not(.hero) h2 { font-family: var(--font-museo); font-weight: 300; font-size: clamp(1.15rem, 2.7vw, 2.35rem); }
.home .panel:not(.hero) p { font-size: clamp(0.62rem, 0.8vw, 0.78rem); line-height: 1.45; max-width: 36ch; }
.home .panel:not(.hero) .panel-inner { max-width: 42rem; opacity: 0.72; }

/* WORK: a centered, bounded two-column résumé with a compact adjacent cluster. */
.work-page .page-scroll { min-height: var(--content-height); display: grid; place-items: start center; }
.work-page .work-wrap { width: min(76vw, 900px); min-height: 0; padding: 0; }
.work-page .xp-track { min-height: 330px; }
.work-page .xp-slide { grid-template-columns: minmax(0, 1.25fr) minmax(220px, .75fr); gap: clamp(2rem, 5vw, 5rem); }
.work-page .xp-role { font-size: clamp(1rem, 1.6vw, 1.35rem); font-weight: 500; }
.work-page .xp-company { font-size: 0.7rem; font-weight: 300; }
.work-page .xp-dates { font-size: 0.52rem; margin-top: 0.2rem; }
.work-page .xp-sub { margin: 1rem 0 0.55rem; }
.work-page .xp-info ul { gap: 0.38rem; }
.work-page .xp-info li { font-size: clamp(0.62rem, .72vw, .72rem); line-height: 1.42; padding-left: 0.8rem; max-width: 48ch; }
.work-page .skill-cluster { max-width: 255px; }
.work-page .skill-head { text-align: left; margin-bottom: 0.3rem; }
.work-page .car-arrow { width: 44px; height: 44px; font-size: 1.6rem; background: transparent; }
.work-page .car-dots { margin-top: 0.9rem; }
.work-page .car-dot { width: 7px; height: 7px; }
.work-page .car-dot.active { width: 20px; }

/* ABOUT: compact copy-plus-mark balance rather than an editorial long-form page. */
.about-page .page-scroll {
  min-height: var(--content-height);
  width: min(76vw, 900px);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.25fr .75fr;
  align-items: center;
  gap: clamp(3rem, 8vw, 7rem);
}
.about-page .about-wrap { max-width: 500px; padding: 0; margin: 0; }
.about-page .about-wrap h1 { font-weight: 300; font-size: clamp(1.8rem, 3vw, 2.8rem); letter-spacing: 0.02em; }
.about-page .about-body { max-width: 48ch; margin-top: 1rem; gap: 0.75rem; }
.about-page .about-body p { font-size: clamp(0.62rem, .72vw, .72rem); line-height: 1.48; }
.about-page .philosophy { font-size: clamp(1rem, 1.6vw, 1.35rem); margin-top: 1.25rem; }
.about-page .interests { margin-top: 1rem; }
.about-page .chip { font-size: 0.55rem; padding: 0.2rem 0.5rem; }
.about-page .socials { margin-top: 1rem; gap: 0.5rem; }
.about-page .socials a { width: 26px; height: 26px; }
.about-page .socials svg { width: 12px; height: 12px; }
.about-page .portrait {
  position: relative; inset: auto;
  grid-column: 2; grid-row: 1;
  width: min(100%, 230px); margin: 0 auto;
  aspect-ratio: 1 / 1;
  border-radius: 0; mask-image: none; -webkit-mask-image: none;
}
.about-page .portrait img { object-fit: contain; }

/* Explicit mobile templates: compact single-frame layouts, not desktop stacks. */
@media (max-width: 820px) {
  :root { --safe-area-top: 12px; --safe-area-right: 12px; --safe-area-bottom: 12px; --safe-area-left: 12px; }
  main { padding: var(--safe-area-top) var(--safe-area-right) var(--safe-area-bottom); }
  .home .hero-canvas-wrap { top: 52%; transform: translate(-50%, -50%) scale(0.46); }
  .home .hero .panel-inner { padding: 2.2rem 0 0 0.7rem; }
  .home .hero h1 { font-size: 1.45rem; }
  .home .panel:not(.hero) .panel-inner { max-width: 17rem; }
  .home .panel:not(.hero) h2 { font-size: 1.1rem; }
  .home .panel:not(.hero) p { font-size: 0.58rem; }

  .work-page .page-scroll { display: grid; min-height: var(--content-height); }
  .work-page .work-wrap { width: min(78vw, 300px); }
  .work-page .xp-track { min-height: 0; }
  .work-page .xp-slide { grid-template-columns: 1fr 0.72fr; gap: 0.75rem; align-items: center; }
  .work-page .xp-role { font-size: 0.82rem; }
  .work-page .xp-company { font-size: 0.54rem; }
  .work-page .xp-dates, .work-page .mono-label { font-size: 0.4rem; }
  .work-page .xp-sub { margin: 0.55rem 0 0.28rem; }
  .work-page .xp-info ul { gap: 0.2rem; }
  .work-page .xp-info li { font-size: 0.68rem; line-height: 1.48; padding-left: 0.8rem; }
  .work-page .skill-head { text-align: center; }
  .work-page .skill-cluster { width: 100%; max-width: 116px; aspect-ratio: 1; margin: 0 auto; }
  .work-page .car-arrow { width: 22px; height: 22px; }
  .work-page .car-prev { left: -24px; } .work-page .car-next { right: -24px; }
  .work-page .car-dots { margin-top: 0.45rem; }

  .about-page .page-scroll {
    width: min(78vw, 300px); min-height: var(--content-height);
    grid-template-columns: 1fr; grid-template-rows: auto auto;
    align-content: center; gap: 1.1rem;
  }
  .about-page .portrait { grid-column: 1; grid-row: 1; width: 112px; aspect-ratio: 3 / 2; }
  .about-page .about-wrap { grid-row: 2; }
  .about-page .about-wrap > .mono-label, .about-page .about-wrap h1 { display: none; }
  .about-page .about-body { margin-top: 0; gap: 0.45rem; }
  .about-page .about-body p { font-size: 0.72rem; line-height: 1.55; }
  .about-page .philosophy { font-size: 0.72rem; margin-top: 0.65rem; }
  .about-page .interests { margin-top: 0.55rem; }
  .about-page .interests-list { gap: 0.22rem; }
  .about-page .chip { font-size: 0.52rem; padding: 0.22rem 0.48rem; }
  .about-page .socials { margin-top: 0.55rem; }
}

b, strong { font-weight: 700; color: var(--foreground); }
a { color: inherit; text-decoration: none; }
::selection { background: var(--blue-glow); color: #fff; }

.font-museo { font-family: var(--font-museo); }
.font-mono { font-family: var(--font-mono); }
.mono-label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gray-400);
}

/* ============================================================
   Boot loader — audio-wave heartbeat + letter reveal + iris
   ============================================================ */
@keyframes heartbeat {
  0%, 100% { opacity: 0.5; transform: scaleY(0.8); }
  50% { opacity: 1; transform: scaleY(3.2); }
}

.loader-iris {
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  background: radial-gradient(circle at center, transparent 0%, var(--loader-bg) 0%);
  transition: background 0.9s var(--ease);
}
.loader-layer {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  background: var(--loader-bg);
  transition: opacity 0.6s var(--ease), visibility 0.6s var(--ease);
}
.audio-wave-heart rect { fill: var(--loader-fg); }
.loader-wordmark {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  /* sit clearly below the heartbeat equalizer so letters never overlap bars */
  padding-top: 9rem;
  pointer-events: none;
  font-family: var(--font-oxanium);
  font-weight: 300;
  letter-spacing: 0.05em;
  color: var(--loader-fg);
  font-size: 2.25rem;
  transition: opacity 0.6s var(--ease), visibility 0.6s var(--ease);
}
.loader-wordmark .letter {
  display: inline-block;
  opacity: 0;
  transform: translateY(6px);
}
/* TYPE-form terminal caret: a blinking block cursor that walks the text. */
.loader-caret {
  display: inline-block;
  width: 0.52ch;
  height: 1.02em;
  margin-left: 0.08em;
  background: var(--loader-fg);
  animation: caretBlink 0.9s steps(1) infinite;
}
@keyframes caretBlink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
@media (min-width: 768px) { .loader-wordmark { font-size: 3rem; } }
@media (min-width: 1024px) { .loader-wordmark { font-size: 3.75rem; } }

body.loaded .loader-layer,
body.loaded .loader-wordmark { opacity: 0; visibility: hidden; }
body.loaded .loader-iris { background: radial-gradient(circle at center, transparent 0%, var(--loader-bg) 140%); }

/* ============================================================
   HUD chamfered border frame
   ============================================================ */
.hud-frame {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 30;
  width: 100vw;
  height: 100vh;
  overflow: clip;
}
.hud-frame .hud-inner {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transform: scaleX(-1);
  transform-origin: center center;
}
.hud-frame svg { position: absolute; inset: 0; overflow: visible; max-width: 100%; max-height: 100%; }
.hud-frame path { stroke: var(--hud-line); }
.hud-corner {
  fill: none;
  stroke: var(--blue-glow);
  stroke-width: 1.5;
  opacity: 0.55;
  filter: drop-shadow(0 0 4px var(--blue-glow));
}

/* ============================================================
   Cursor thread — glowing sine wave
   ============================================================ */
.cursor-thread {
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  will-change: transform;
}
.cursor-thread svg { width: 100%; height: 8rem; }
@keyframes wave {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}
.cursor-thread .wave-a { animation: wave 2s ease-in-out infinite; }
.cursor-thread .wave-b { animation: wave 2s ease-in-out infinite reverse; }

/* ============================================================
   Floating pill nav
   ============================================================ */
.pill-nav {
  position: fixed;
  top: 0; left: 0;
  padding: 0.5rem;
  z-index: 50;
}
@media (min-width: 1280px) {
  .pill-nav { top: 1.5rem; right: 2rem; left: auto; padding: 0; }
}
.pill-nav-inner {
  position: relative;
  display: flex;
  align-items: center;
  background: var(--nav-bg);
  backdrop-filter: blur(var(--blur-md));
  -webkit-backdrop-filter: blur(var(--blur-md));
  border: 1px solid var(--nav-border);
  border-radius: 9999px;
  padding: 0.5rem;
  box-shadow: 0 25px 50px -12px var(--nav-shadow);
}
.pill-indicator {
  position: absolute;
  background: var(--nav-indicator);
  border-radius: 9999px;
  height: calc(100% - 16px);
  top: 8px;
  left: 0;
  z-index: 0;
  transition: left 0.4s var(--ease), width 0.4s var(--ease);
}
.pill-nav a {
  position: relative;
  padding: 0.5rem 1.5rem;
  border-radius: 9999px;
  font-family: var(--font-oxanium);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--foreground);
  transition: color 0.3s var(--ease);
  z-index: 10;
  white-space: nowrap;
}
.pill-nav a:hover { color: var(--foreground); }
/* The label the sliding white indicator currently sits under inverts to black.
   Driven off .indicated (updated on hover/place), never the static .active,
   so hovering a link can never strand both labels invisible. Placed after
   :hover so it wins the equal-specificity tie. */
.pill-nav a.indicated { color: var(--nav-indicator-fg); }

/* ============================================================
   Layout shell
   ============================================================ */
main {
  box-sizing: border-box;
  padding: var(--safe-area-top) var(--safe-area-right) var(--safe-area-bottom) var(--safe-area-left);
}

/* ============================================================
   HOME — scroll story of aphoristic panels
   ============================================================ */
/* .home-scroll is now a plain flow wrapper — the document is the scroller. */
.home-scroll { overflow-x: hidden; }

.panel {
  min-height: var(--content-height);
  scroll-snap-align: start;
  scroll-snap-stop: always;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 2rem clamp(0.5rem, 4vw, 4rem);
  position: relative;
}
.panel-inner { max-width: var(--container-7xl); width: 100%; margin: 0 auto; }
.panel[data-align="left"] .panel-inner { text-align: left; margin-left: 0; }
.panel[data-align="right"] .panel-inner { text-align: right; margin-right: 0; }

.panel h2 {
  font-family: var(--font-oxanium);
  font-weight: 600;
  line-height: 1.1;
  font-size: clamp(2rem, 6vw, 4rem);
  letter-spacing: -0.02em;
}
.panel h2 .line-2 { display: block; color: var(--gray-400); }
.panel p {
  margin-top: 1.5rem;
  max-width: 40ch;
  font-weight: 400;
  font-size: clamp(1rem, 1.6vw, 1.25rem);
  line-height: 1.625;
  color: var(--gray-300);
}
.panel[data-align="right"] p { margin-left: auto; }
.panel .mono-label { margin-bottom: 1.25rem; display: block; }

/* reveal state */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity 0.9s var(--ease), transform 0.9s var(--ease); }
.panel[data-dir="left"] .reveal { transform: translate(-40px, 0); }
.panel[data-dir="right"] .reveal { transform: translate(40px, 0); }
.reveal.in { opacity: 1; transform: translate(0, 0); }
/* The directional selectors above (0,3,0) out-specify plain `.reveal.in`
   (0,2,0), so without an equally-specific reset the ±40px offset was NEVER
   cleared — invisible on wide desktop but pushing right-/left-aligned content
   past the mobile viewport edge (clipped by overflow-x:hidden). Reset with a
   matching-specificity `.in` rule so the settled state truly lands at 0. */
.panel[data-dir="left"] .reveal.in,
.panel[data-dir="right"] .reveal.in { transform: translate(0, 0); }

/* Mobile: shrink the horizontal reveal offset so even a mid-transition frame
   stays inside the viewport, and let the belief headlines wrap instead of
   riding off the right edge on the narrowest phones. */
@media (max-width: 640px) {
  .panel { padding: 2rem clamp(0.75rem, 5vw, 1.5rem); }
  .panel-inner { max-width: 100%; }
  .panel[data-dir="left"] .reveal { transform: translate(-20px, 0); }
  .panel[data-dir="right"] .reveal { transform: translate(20px, 0); }
  .panel h2 { font-size: clamp(1.75rem, 8vw, 2.5rem); overflow-wrap: break-word; }
  .panel p { overflow-wrap: break-word; }
}

/* Hero panel — wordmark anchored top-left, generative object owns the center */
.hero { align-items: flex-start; justify-content: flex-start; text-align: left; }
.hero-canvas-wrap {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%) scale(0.5);
  z-index: 0;
  pointer-events: none;
}
@media (min-width: 768px) { .hero-canvas-wrap { transform: translate(-50%, -50%) scale(0.75); } }
@media (min-width: 1024px) { .hero-canvas-wrap { transform: translate(-50%, -50%) scale(1); } }
.hero-canvas-wrap canvas { display: block; }

.hero .panel-inner {
  position: relative;
  z-index: 2;
  text-align: left;
  margin: 0;
  max-width: none;
  padding-top: clamp(0.5rem, 3vh, 3rem);
}
.hero h1 {
  font-family: var(--font-oxanium);
  /* Reference wordmark is thin/airy and pure white — reserve bold for
     section headings, keep the largest type on the site light. */
  font-weight: 300;
  color: var(--color-white);
  text-transform: uppercase;
  line-height: 1.02;
  letter-spacing: 0.04em;
  font-size: 2rem;
  max-width: 90%;
  margin: 0;
}
.hero h1 .role {
  display: block;
  color: var(--gray-400);
  font-weight: 300;
  letter-spacing: 0.06em;
  font-size: 0.42em;
  margin-top: 0.4em;
}
@media (min-width: 768px) {
  .hero h1 { font-size: 3rem; max-width: none; letter-spacing: 0.03em; }
}
@media (min-width: 1024px) { .hero h1 { font-size: 5rem; } }
/* A restrained secondary line, echoing the reference's lower-right aside */
.hero-aside {
  position: absolute;
  right: clamp(1rem, 4vw, 4rem);
  bottom: clamp(4rem, 12vh, 8rem);
  z-index: 2;
  max-width: 26ch;
  text-align: right;
  color: var(--gray-400);
  font-weight: 400;
  font-size: clamp(0.85rem, 1.2vw, 1rem);
  line-height: 1.6;
}
@media (max-width: 767px) { .hero-aside { display: none; } }

.scroll-cue {
  position: absolute;
  bottom: 3rem; left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gray-400);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
}
.scroll-cue .bar { width: 1px; height: 40px; background: linear-gradient(to bottom, var(--blue-glow), transparent); }

/* CTA link */
.cta { font-weight: 700; border-bottom: 1px solid var(--blue-glow); padding-bottom: 2px; transition: color 0.2s var(--ease); }
.cta:hover { color: var(--blue-bright); }
.cta::after { content: " \2197"; color: var(--blue-glow); }

/* ============================================================
   WORK page — paginated experience carousel + skill-bubble cluster
   ============================================================ */
/* .page-scroll is now a plain flow wrapper — the document is the scroller. */
.page-scroll { overflow-x: hidden; }
.page-wrap { max-width: var(--container-7xl); margin: 0 auto; padding: clamp(4rem, 12vh, 9rem) clamp(0.5rem, 4vw, 3rem) 6rem; }

.work-wrap {
  max-width: var(--container-7xl);
  margin: 0 auto;
  min-height: var(--content-height);
  /* Anchor the experience block to the top third (reference), not vertically
     centred — kills the large empty upper band the critic flagged. */
  padding: clamp(4.5rem, 15vh, 9rem) clamp(0.5rem, 4vw, 2.5rem) 4rem;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}
/* Carousel shell */
.xp-carousel { position: relative; outline: none; }
.xp-track {
  position: relative;
  min-height: clamp(340px, 46vh, 470px);
}
.xp-slide {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(1.5rem, 4vw, 4rem);
  /* Top-align the columns so the role heading and the "Technical Skills"
     header share a baseline (reference), rather than floating mid-track. */
  align-items: start;
  opacity: 0;
  visibility: hidden;
  transform: translateY(14px);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
  pointer-events: none;
}
.xp-slide.active {
  position: relative;
  opacity: 1;
  visibility: visible;
  transform: none;
  pointer-events: auto;
}

/* Left — experience detail */
.xp-role { font-size: clamp(1.4rem, 3vw, 2.1rem); font-weight: 600; line-height: 1.1; }
.xp-company { color: var(--gray-300); font-weight: 500; margin-top: 0.25rem; }
.xp-dates { font-family: var(--font-mono); font-size: 0.78rem; color: var(--gray-400); letter-spacing: 0.05em; margin-top: 0.4rem; }
.xp-sub { display: block; margin: 1.75rem 0 0.9rem; }
.xp-info ul { list-style: none; display: grid; gap: 0.75rem; }
.xp-info li { position: relative; padding-left: 1.4rem; color: var(--gray-300); font-weight: 400; line-height: 1.55; max-width: 54ch; }
/* Reference uses a restrained chevron marker, not a blue diamond, keeping the
   list monochrome. */
.xp-info li::before { content: "\203A"; position: absolute; left: 0; top: -0.05em; color: var(--gray-400); font-weight: 400; font-size: 1.05em; line-height: 1.6; }

/* Right — Technical Skills floating bubble cluster */
.skill-panel { position: relative; }
.skill-head { display: block; text-align: right; margin-bottom: 0.75rem; }
.skill-cluster {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  max-width: 440px;
  margin-left: auto;
}
/* Bubbles are a real physics sandbox now (see initWork in main.js): each chip
   is a rigid circle under gravity, colliding with neighbours + walls and shoved
   by the cursor. JS sizes each circle (width/height) and drives its position via
   an inline `transform: translate(x,y)` every frame — no CSS animation. The
   translate(0,0) base is just a graceful pre-JS fallback (anchored top-left). */
.bubble {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  border-radius: 9999px;
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
  line-height: 1.05;
  padding: 0.4em 0.55em;
  /* JS sizes each circle to fit its label on one line — labels never wrap. */
  white-space: nowrap;
  will-change: transform;
}
/* Reference skill bubbles are a monochrome cluster of solid white chips with
   black text — no blue, no dark outlined variants. All bubble modifiers render
   as the same white chip; slight opacity variance keeps the cluster from
   reading as one flat blob without introducing colour. */
.bubble.solid,
.bubble.ghost,
.bubble.accent {
  background: var(--chip-bg);
  color: var(--chip-fg);
  font-weight: 600;
  border: 0;
  /* Crisp opaque chips with a soft halo so the cluster reads as solid floating
     bubbles at every breakpoint — not a dim node-graph. */
  box-shadow: 0 0 26px var(--chip-glow);
}
.bubble.ghost { background: var(--chip-bg); }

/* Arrows */
.car-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border);
  background: var(--arrow-bg);
  color: var(--gray-300);
  border-radius: 9999px;
  font-size: 1.4rem; line-height: 1;
  cursor: pointer;
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease), transform 0.25s var(--ease);
}
.car-arrow:hover { color: var(--foreground); border-color: var(--blue-glow); }
.car-prev { left: -4px; }
.car-next { right: -4px; }
@media (min-width: 1100px) {
  .car-prev { left: -92px; }
  .car-next { right: -92px; }
}

/* Pagination dots */
.car-dots { display: flex; justify-content: center; gap: 0.6rem; margin-top: clamp(1.75rem, 5vh, 3rem); }
.car-dot {
  width: 8px; height: 8px; border-radius: 9999px;
  background: var(--dot-inactive); border: 0; padding: 0; cursor: pointer;
  transition: background 0.25s var(--ease), width 0.25s var(--ease);
}
/* Active dot carries the single cold-blue accent so the blue system reaches
   the work route (previously blue lived only on the hero cube / about mark). */
.car-dot.active { background: var(--blue-glow); width: 22px; box-shadow: 0 0 10px rgba(59, 130, 246, 0.6); }

.chip {
  font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.05em;
  border: 1px solid var(--border); border-radius: 9999px; padding: 0.3rem 0.8rem;
  color: var(--gray-300); background: var(--surface-2);
}

@media (max-width: 820px) {
  .xp-track { min-height: 0; }
  .xp-slide { grid-template-columns: 1fr; gap: 2rem; }
  .skill-head { text-align: left; }
  .skill-cluster { margin: 0 auto; max-width: 340px; }
  .car-prev { left: 0; }
  .car-next { right: 0; }
}
/* Narrow phones: a taller cluster box gives the six circular bubbles room to
   spread vertically without colliding or clipping at the viewport edge. JS
   selects a matching portrait layout below this width. */
@media (max-width: 640px) {
  .skill-cluster { aspect-ratio: 4 / 5; max-width: 288px; margin-top: 0.5rem; }
}

@media (prefers-reduced-motion: reduce) {
  .bubble { animation: none !important; }
  .xp-slide { transition: opacity 0.2s linear; transform: none; }
}

/* ============================================================
   Run 005 repair — measured viewport occupancy and mobile templates
   ============================================================ */
.cursor-thread { opacity: 0.12; }
.cursor-thread svg { width: 58vw; height: 3.5rem; }

/* ------------------------------------------------------------
   Run 006 repair — restore the reference's one-idea-per-full-
   height-panel scroll story. Run 005 pinned every belief panel's
   inner content to `position: fixed; bottom` — so all five belief
   texts stacked on top of one another at every scroll position
   (the overlapping garble the critic flagged P0). Belief copy is
   put back into normal document flow: each .panel keeps its full
   --content-height, so only one aphorism is ever on screen, and
   the reveal-on-scroll observer presents them sequentially. The
   generative ring/cube stays fixed and centered behind the story,
   as in the reference (persistent across scroll states). */
.home .hero-canvas-wrap {
  top: 50%; left: 50%;
  transform: translate(-50%, -50%) scale(1);
}
.home .hero .panel-inner { padding: clamp(1.2rem, 5vh, 4rem) 0 0 0.8rem; }
.home .hero h1 { font-size: clamp(2.5rem, 4.5vw, 4.25rem); }
.home .hero-aside { font-size: 0.82rem; color: var(--gray-400); }

/* Belief panels: in-flow, full-height, alternating left/right. The copy sits
   to one side (≈36ch) so it reads beside — never on top of — the centered
   ring. pointer-events restored on the inner block so the CTA link works. */
.home .panel:not(.hero) { pointer-events: none; }
.home .panel:not(.hero) .panel-inner {
  position: static;
  pointer-events: auto;
  width: 100%;
  max-width: 36ch;
  margin: 0;
  padding: 0 clamp(1rem, 4vw, 4rem);
  opacity: 1;
}
.home .panel:not(.hero)[data-align="left"] .panel-inner { margin-right: auto; text-align: left; }
.home .panel:not(.hero)[data-align="right"] .panel-inner { margin-left: auto; text-align: right; }
.home .panel:not(.hero) h2 {
  font-family: var(--font-museo);
  font-weight: 600;
  font-size: clamp(1.5rem, 3.2vw, 2.6rem);
  line-height: 1.12;
  letter-spacing: -0.01em;
  color: var(--foreground);
}
.home .panel:not(.hero) p { font-size: clamp(.82rem, .95vw, .98rem); color: var(--gray-300); }

/* Closing wordmark — the reference's full-bleed centered scroll-ending
   wordmark. Original three-beat process line, large and centered. */
.home .panel.closing { pointer-events: none; }
.home .panel.closing .panel-inner {
  position: static;
  width: 100%;
  max-width: none;
  margin: 0 auto;
  padding: 0 clamp(1rem, 4vw, 4rem);
  text-align: center;
  opacity: 1;
}
.home .panel.closing h2 {
  font-family: var(--font-museo);
  font-weight: 600;
  font-size: clamp(2.25rem, 7vw, 5rem);
  line-height: 1.04;
  letter-spacing: -0.015em;
  color: var(--foreground);
  text-align: center;
}

/* Reference desktop routes occupy roughly two-thirds of the framed width. */
.work-page .work-wrap { width: min(72vw, 1080px); }
.work-page .xp-track { min-height: 380px; }
.work-page .xp-slide { grid-template-columns: minmax(0, 1.15fr) minmax(270px, .85fr); gap: clamp(3rem, 7vw, 7rem); }
.work-page .xp-role { font-size: clamp(1.35rem, 1.7vw, 1.7rem); }
.work-page .xp-company { font-size: .86rem; }
.work-page .xp-dates { font-size: .66rem; }
.work-page .xp-info li { font-size: clamp(.78rem, .82vw, .88rem); line-height: 1.5; }
/* Center the cluster within its column so the bubbles sit away from the right
   HUD frame edge (where the faint cursor thread's tail read as node-graph
   connectors), matching the reference's free-floating white bubble cluster. */
.work-page .skill-cluster { max-width: 380px; margin: 0 auto; }

.about-page .page-scroll {
  width: min(74vw, 1080px);
  grid-template-columns: minmax(0, 1.25fr) minmax(260px, .75fr);
  gap: clamp(4rem, 9vw, 9rem);
}
.about-page .about-wrap { max-width: 620px; }
.about-page .about-wrap h1 { font-size: clamp(2.2rem, 3.2vw, 3.2rem); }
.about-page .about-body p { font-size: clamp(.78rem, .82vw, .9rem); line-height: 1.58; color: var(--gray-300); }
.about-page .philosophy { font-size: clamp(1.2rem, 1.75vw, 1.65rem); }
.about-page .portrait { width: min(100%, 300px); }

@media (max-width: 820px) {
  .cursor-thread { display: none; }
  .home .hero-canvas-wrap { top: 52%; transform: translate(-50%, -50%) scale(.58); }
  .home .hero .panel-inner { padding: 3.6rem 0 0 1rem; }
  .home .hero h1 { font-size: 2rem; line-height: 1.02; }
  .home .hero h1 .role { font-size: .34em; }
  .home .panel:not(.hero) .panel-inner {
    position: static; width: 100%; padding: 0 1.5rem; max-width: 22rem;
  }
  .home .panel:not(.hero) h2 { font-size: 1.5rem; }
  .home .panel:not(.hero) p { font-size: .78rem; line-height: 1.5; }
  .home .panel.closing .panel-inner { max-width: none; padding: 0 1.25rem; }
  .home .panel.closing h2 { font-size: clamp(1.9rem, 11vw, 2.6rem); }

  /* Mobile work follows the reference's vertical résumé then skill cluster. */
  .work-page .page-scroll { place-items: stretch; }
  .work-page .work-wrap { width: auto; margin: 0; padding: 4.8rem 2rem 2.5rem; justify-content: flex-start; }
  .work-page .xp-track { min-height: 600px; }
  .work-page .xp-slide { grid-template-columns: 1fr; gap: 1.35rem; align-content: start; }
  .work-page .xp-role { font-size: 1.1rem; }
  .work-page .xp-company { font-size: .74rem; }
  .work-page .xp-dates, .work-page .mono-label { font-size: .58rem; }
  .work-page .xp-info li { font-size: .68rem; line-height: 1.48; padding-left: .8rem; }
  .work-page .xp-info ul { gap: .42rem; }
  .work-page .skill-head { text-align: left; }
  .work-page .skill-cluster { width: 220px; max-width: 68vw; aspect-ratio: 1; margin: .25rem auto 0; }
  .work-page .car-prev { left: -.8rem; }
  .work-page .car-next { right: -.8rem; }

  /* Mobile about is graphic-first, then a full-width readable text column. */
  .about-page .page-scroll {
    width: auto; margin: 0; padding: 4.5rem 2rem 2rem;
    display: flex; flex-direction: column; justify-content: flex-start; gap: 1.4rem;
  }
  .about-page .portrait { order: 0; width: 180px; height: 150px; aspect-ratio: auto; margin: 0 auto; }
  .about-page .about-wrap { order: 1; width: 100%; max-width: none; }
  .about-page .about-wrap > .mono-label, .about-page .about-wrap h1 { display: none; }
  .about-page .about-body { max-width: none; gap: .8rem; }
  .about-page .about-body p { font-size: .72rem; line-height: 1.55; }
  .about-page .philosophy { font-size: 1.05rem; margin-top: 1rem; }
  .about-page .interests { margin-top: .9rem; }
  .about-page .chip { font-size: .52rem; padding: .22rem .48rem; }
  .about-page .socials { margin-top: 1rem; }
}

@media (max-width: 420px) {
  .work-page .work-wrap, .about-page .page-scroll { padding-left: 1.55rem; padding-right: 1.55rem; }
  .work-page .xp-track { min-height: 620px; }
}

/* ============================================================
   ABOUT page
   ============================================================ */
.about-wrap { max-width: var(--container-7xl); margin: 0 auto; padding: clamp(4rem, 12vh, 9rem) clamp(0.5rem, 4vw, 3rem) 6rem; position: relative; }
.about-wrap h1 {
  font-family: var(--font-oxanium); font-weight: 700; text-transform: uppercase;
  font-size: clamp(2.5rem, 7vw, 5rem); line-height: 1;
}
.about-body { max-width: 54ch; margin-top: 2rem; display: grid; gap: 1.5rem; }
.about-body p { color: var(--gray-300); font-weight: 400; line-height: 1.7; font-size: clamp(1rem, 1.6vw, 1.15rem); }
.philosophy {
  font-family: var(--font-museo); font-weight: 300; color: var(--foreground);
  font-size: clamp(1.5rem, 4vw, 2.5rem); line-height: 1.25; margin-top: 2.5rem; max-width: 22ch;
}
.interests { margin-top: 2.5rem; }
.interests .mono-label { display: block; margin-bottom: 0.75rem; }
.interests-list { display: flex; flex-wrap: wrap; gap: 0.5rem; }

.socials { margin-top: 3rem; display: flex; gap: 1rem; align-items: center; }
.socials a {
  width: 44px; height: 44px; border: 1px solid var(--border); border-radius: 9999px;
  display: inline-flex; align-items: center; justify-content: center; color: var(--gray-300);
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease), transform 0.25s var(--ease);
}
.socials a:hover { color: var(--foreground); border-color: var(--blue-glow); transform: translateY(-2px); }
.socials svg { width: 20px; height: 20px; }

.portrait {
  position: absolute;
  bottom: 0; right: clamp(0.5rem, 4vw, 3rem);
  width: clamp(220px, 32vw, 400px);
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  overflow: hidden;
  /* keep the cold-blue emissive readable (no grayscale) so the mark anchors
     the right side instead of dissolving into the page black */
  filter: contrast(1.05) brightness(1.08) drop-shadow(0 0 30px rgba(59, 130, 246, 0.22));
  opacity: 1;
  mask-image: linear-gradient(to top, transparent, #000 22%);
  -webkit-mask-image: linear-gradient(to top, transparent, #000 22%);
  pointer-events: none;
}
.portrait img, .portrait svg { width: 100%; height: 100%; object-fit: cover; display: block; }
.portrait canvas { width: 100%; height: 100%; display: block; }
/* Zodiac panel: no photo mask/clip — let the full constellation show, keep the
   cold-blue emissive glow as its halo. */
.portrait--zodiac {
  mask-image: none;
  -webkit-mask-image: none;
  overflow: visible;
  filter: drop-shadow(0 0 34px rgba(59, 130, 246, 0.28));
}
@media (max-width: 900px) {
  .portrait { position: relative; right: auto; margin: 3rem auto 0; mask-image: none; -webkit-mask-image: none; }
}

/* ============================================================
   Reduced motion
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .audio-wave-heart rect { animation: none !important; transform: scaleY(1.6) !important; }
  .cursor-thread { display: none !important; }
  .cursor-thread .wave-a, .cursor-thread .wave-b { animation: none !important; }
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
  .home-scroll, .page-scroll { scroll-snap-type: none; scroll-behavior: auto; }
  .loader-layer, .loader-wordmark, .loader-iris { transition: opacity 0.2s linear; }
  * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; }
}

/* Cascade guard: these atmosphere/nav rules intentionally follow the base
   component declarations above. */
.cursor-thread { z-index: 1; opacity: 0.24; mix-blend-mode: screen; }
.cursor-thread svg { height: 5rem; filter: blur(0.35px); }
.pill-nav, .hud-frame { z-index: 50; }
.pill-nav-inner { padding: 0.4rem; }
.pill-indicator { height: calc(100% - 12px); top: 6px; }
.pill-nav a { padding: 0.5rem 1.4rem; font-size: 0.95rem; font-weight: 500; }

/* ============================================================
   Run 007 repair — work skill-cluster balance + mobile safe-zone
   ============================================================ */
/* WORK split (run 008): anchor the experience block to the TOP THIRD and
   top-align the two columns so the role heading and the "Technical Skills"
   label share a baseline — killing the large empty upper band the critic
   flagged (the run-007 vertical-centre left ~40% dead space above). The JS
   sizes each white bubble to its label (no wrap, no collision), and the ~10
   bubbles now read at the reference's dense constellation. */
.work-page .work-wrap { padding-top: clamp(4rem, 18vh, 10rem); }
.work-page .xp-slide { align-items: start; }
.work-page .skill-panel {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}
.work-page .skill-head { text-align: center; margin-bottom: 0.85rem; }
.work-page .skill-cluster {
  position: relative;
  width: 100%;
  max-width: 380px;
  aspect-ratio: 1 / 1;
  margin: 0 auto;
}

/* Slightly widen the belief column so display aphorisms settle on 2–3 lines
   rather than four short fragments. */
@media (min-width: 768px) {
  .home .panel:not(.hero) .panel-inner { max-width: 42ch; }
}

/* MOBILE: the persistent particle ring stays centred, so belief copy is given
   a soft vignette scrim + text-shadow (a clear text safe-zone) — it never
   dissolves into the generative object the way the flat centred copy did. */
@media (max-width: 767px) {
  .home .panel:not(.hero) .panel-inner,
  .home .panel.closing .panel-inner {
    padding: 1.15rem 1.3rem;
    border-radius: 16px;
    background: radial-gradient(120% 100% at 50% 50%,
      var(--scrim-0) 0%, var(--scrim-1) 44%, var(--scrim-2) 100%);
    -webkit-backdrop-filter: blur(2.5px);
    backdrop-filter: blur(2.5px);
    text-shadow: 0 1px 14px var(--scrim-shadow);
  }
  /* a touch more room for the mobile skill cluster */
  .work-page .skill-cluster { width: 250px; max-width: 74vw; }
}
@media (max-width: 767px) and (prefers-reduced-motion: reduce) {
  .home .panel:not(.hero) .panel-inner,
  .home .panel.closing .panel-inner { backdrop-filter: none; -webkit-backdrop-filter: none; }
}

/* ============================================================
   Run 009 — reference-faithful home scroll DECK
   ------------------------------------------------------------
   The home page becomes VIEWPORT-LOCKED: the document no longer
   scrolls (body is fixed at one viewport); an inner scroller
   (#scroller) mandatory-snaps one full-height panel at a time,
   un-skippable. Each panel's content is parked off-screen and
   slides in (per data-dir) with a per-letter heading stagger when
   its section becomes active — and replays on every re-entry.
   The generative object is now a PERSISTENT fixed element behind
   the whole deck, dispersing/refocusing with scroll (see main.js).
   This section is last in source order so it wins the cascade over
   the earlier document-scroll (runs 004–008) home rules.
   ============================================================ */

/* Viewport-lock the home route; the inner box is the only scroller. */
body.home {
  height: calc(var(--vh, 1vh) * 100);
  overflow: hidden;
}
.home main { height: 100%; overflow: hidden; }
.home #scroller {
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  scroll-snap-type: y mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.home #scroller::-webkit-scrollbar { display: none; }

/* Each panel is exactly one scroller viewport, hard-snapping. */
.home .panel {
  height: 100%;
  min-height: 100%;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

/* The generative object persists behind every panel (fixed, centered) and is
   what morphs between sections — instead of scrolling away with the hero. */
.home .hero-canvas-wrap {
  position: fixed;
  top: 50%; left: 50%;
  z-index: 0;
}

/* Zodiac constellation layer — full-viewport canvas behind the deck. Sits
   below `main` (z-index 2), so it shows through the transparent panels while
   the belief copy renders on top. */
.constellation-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

/* Neutralize the old one-shot IntersectionObserver reveal on home — the deck
   controller drives entrance instead, on `.panel.active`. */
.home .reveal { opacity: 1; transform: none; transition: none; }

/* Belief + closing content is parked off-screen until its panel is active. */
.home .panel:not(.hero) .panel-inner,
.home .panel.closing .panel-inner {
  opacity: 0;
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  will-change: transform, opacity;
}
/* Park off-screen per direction. Use matching translate() function lists (never
   the `none` keyword as the animated endpoint) so every engine interpolates the
   slide smoothly rather than snapping/stalling. */
.home .panel[data-dir="left"] .panel-inner { transform: translate(-100vw, 0); }
.home .panel[data-dir="right"] .panel-inner { transform: translate(100vw, 0); }
.home .panel[data-dir="up"] .panel-inner,
.home .panel.closing .panel-inner { transform: translate(0, 14vh); }
.home .panel.active .panel-inner { opacity: 1; transform: translate(0, 0); }

/* Per-letter heading stagger. Letters rise + fade, sequenced by --i, layered on
   top of the container slide. Fires only while the panel is active. */
.home .panel .word { display: inline-block; white-space: nowrap; }
.home .panel .char {
  display: inline-block;
  opacity: 0;
  transform: translate(0, 0.55em);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}
.home .panel.active .char {
  opacity: 1;
  transform: translate(0, 0);
  transition-delay: calc(var(--i) * 24ms + 0.12s);
}

/* Reduced motion: everything settled, no slide, no stagger. The object holds
   its focused state (main.js pins focus = 1). */
@media (prefers-reduced-motion: reduce) {
  .home #scroller { scroll-snap-type: none; scroll-behavior: auto; }
  .home .panel:not(.hero) .panel-inner,
  .home .panel.closing .panel-inner,
  .home .panel .char {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ============================================================
   Blog — index + article (same visual family as about/work:
   dark near-monochrome, single cold-blue accent, mono eyebrows)
   ============================================================ */

/* Both blog routes scroll normally top-to-bottom, clearing the fixed nav. */
.blog-page .page-scroll,
.article-page .page-scroll {
  min-height: var(--content-height);
  width: min(88vw, 1080px);
  margin: 0 auto;
  padding: clamp(6rem, 12vh, 9rem) 0 5rem;
}
.article-page .page-scroll { width: min(88vw, 760px); }

/* Shared eyebrow: mono, letterspaced, cold-blue */
.eyebrow {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gray-400);
}
.eyebrow--accent { color: var(--blue-bright); }

/* ---- Index header ---- */
.blog-head { max-width: 40ch; }
.blog-head h1 {
  font-weight: 300;
  font-size: clamp(2.2rem, 4.2vw, 3.4rem);
  letter-spacing: 0.01em;
  line-height: 1.06;
  margin-top: 0.9rem;
}
.blog-head h1 b { font-weight: 500; color: var(--blue-bright); }
.blog-head .lede {
  margin-top: 1.1rem;
  max-width: 52ch;
  color: var(--gray-400);
  font-size: clamp(0.9rem, 1.1vw, 1.05rem);
  line-height: 1.6;
}

/* ---- Index grid + cards ---- */
.post-grid {
  margin-top: clamp(2.4rem, 5vw, 3.6rem);
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1rem;
}
.post-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface-1);
  transition: border-color 0.28s var(--ease), transform 0.28s var(--ease), background 0.28s var(--ease);
}
.post-card:hover {
  border-color: var(--blue-glow);
  transform: translateY(-3px);
  background: rgba(59, 130, 246, 0.04);
}
/* Thumbnail: a small console/diagram per article, monochrome + cold-blue */
.post-thumb {
  aspect-ratio: 320 / 168;
  background: #08080a;
  border-bottom: 1px solid var(--border);
  overflow: hidden;
}
.post-thumb svg { display: block; width: 100%; height: 100%; }
.post-body {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  flex: 1;
  padding: 1.25rem 1.4rem 1.4rem;
}
.post-card h3 {
  font-family: var(--font-oxanium);
  font-weight: 500;
  font-size: clamp(1.05rem, 1.6vw, 1.28rem);
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--foreground);
}
.post-card .post-meta {
  margin-top: auto;
  font-family: var(--font-mono);
  font-size: 0.56rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gray-400);
}

/* ---- Article: back bar + header ---- */
.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gray-400);
  transition: color 0.2s var(--ease);
}
.back-link:hover { color: var(--foreground); }

.article-head { margin-top: 1.8rem; border-bottom: 1px solid var(--border); padding-bottom: 1.6rem; }
.article-meta { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; }
.article-head h1 {
  font-weight: 300;
  font-size: clamp(1.9rem, 4vw, 3rem);
  line-height: 1.08;
  letter-spacing: 0.005em;
  margin-top: 1rem;
  color: var(--foreground);
}
.byline {
  margin-top: 1.2rem;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  font-size: 0.82rem;
  color: var(--gray-400);
}
.byline .avatar {
  width: 34px; height: 34px; border-radius: 9999px; flex: none;
  display: grid; place-items: center;
  font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.02em;
  color: #cfe0ff;
  background: linear-gradient(135deg, rgba(96,165,250,0.35), rgba(59,130,246,0.08));
  border: 1px solid rgba(96,165,250,0.35);
}
.byline b { color: var(--gray-300); font-weight: 500; }

/* ---- Article body prose ---- */
.article-body { margin-top: 2.2rem; }
.article-body > p {
  color: var(--gray-300);
  font-size: clamp(0.98rem, 1.05vw, 1.08rem);
  line-height: 1.72;
  margin-top: 1.25rem;
}
.article-body > p:first-child { margin-top: 0; }
.article-body h2 {
  font-family: var(--font-oxanium);
  font-weight: 500;
  font-size: clamp(1.35rem, 2.2vw, 1.75rem);
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--foreground);
  margin-top: 2.8rem;
  scroll-margin-top: 6rem;
}
.article-body h3 {
  font-family: var(--font-oxanium);
  font-weight: 500;
  font-size: 1.05rem;
  color: var(--foreground);
  margin-top: 1.8rem;
}
.article-body a {
  color: var(--blue-bright);
  border-bottom: 1px solid rgba(96, 165, 250, 0.35);
  transition: border-color 0.2s var(--ease);
}
.article-body a:hover { border-bottom-color: var(--blue-bright); }
.article-body b, .article-body strong { color: var(--foreground); font-weight: 600; }
.article-body em { color: var(--gray-300); font-style: italic; }
.article-body ul { margin: 1.2rem 0 0; padding-left: 1.1rem; display: grid; gap: 0.6rem; }
.article-body li {
  color: var(--gray-300);
  font-size: clamp(0.92rem, 1vw, 1.02rem);
  line-height: 1.62;
  padding-left: 0.3rem;
}
.article-body li::marker { color: var(--blue-glow); }
.article-body code {
  font-family: var(--font-mono);
  font-size: 0.82em;
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.08em 0.36em;
  color: var(--gray-300);
}

/* Pull quote */
.article-pull {
  margin: 2rem 0 0;
  padding: 0.2rem 0 0.2rem 1.4rem;
  border-left: 2px solid var(--blue-glow);
}
.article-pull p {
  font-family: var(--font-museo);
  font-weight: 300;
  font-size: clamp(1.2rem, 2vw, 1.55rem);
  line-height: 1.32;
  color: var(--foreground);
}

/* Code / console figures */
.code-figure { margin: 1.8rem 0 0; }
.code-figure .code-bar {
  display: flex; align-items: center; gap: 0.5rem;
  background: #0d0d0d;
  border: 1px solid var(--border);
  border-bottom: none;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 0.55rem 0.9rem;
}
.code-figure .code-bar .dot { width: 8px; height: 8px; border-radius: 9999px; background: #2a2a2a; }
.code-figure .code-bar .path {
  margin-left: 0.4rem;
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.06em; color: var(--gray-400);
}
.code-figure pre {
  margin: 0;
  overflow-x: auto;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  padding: 1rem 1.1rem;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  line-height: 1.7;
  color: #d7dde3;
}
.code-figure pre .cm { color: #5f6b73; }
.code-figure pre .kw { color: #7aa2ff; }
.code-figure pre .fn { color: #6fd6b0; }
.code-figure pre .st { color: #e0a44b; }

/* Info panel figure (ported from the console blocks) */
.panel-figure {
  margin: 1.8rem 0 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface-1);
  overflow: hidden;
}
.panel-figure .panel-bar {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.6rem 0.95rem;
  border-bottom: 1px solid var(--border);
  font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--gray-400);
}
.panel-figure .panel-bar .tag { margin-left: auto; color: var(--blue-bright); }
.panel-figure .row {
  display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; align-items: baseline;
  padding: 0.6rem 0.95rem;
  border-top: 1px solid var(--hair);
  font-size: 0.86rem;
}
.panel-figure .row:first-of-type { border-top: none; }
.panel-figure .row .k {
  font-family: var(--font-mono); font-size: 0.64rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--blue-bright); min-width: 8.5rem;
}
.panel-figure .row .v { color: var(--gray-300); }
.panel-figure .flow {
  padding: 0.9rem 0.95rem;
  display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center;
  font-family: var(--font-mono); font-size: 0.72rem; color: var(--gray-300);
}
.panel-figure .flow .node {
  border: 1px solid var(--border); border-radius: 4px; padding: 0.28rem 0.55rem; background: var(--surface-2);
}
.panel-figure .flow .node.crit { border-color: var(--blue-glow); color: var(--foreground); }
.panel-figure .flow .arr { color: var(--blue-glow); }

figcaption {
  margin-top: 0.7rem;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.04em;
  line-height: 1.5;
  color: var(--gray-400);
}

/* Outro CTA */
.article-outro {
  margin-top: 3rem;
  padding-top: 1.8rem;
  border-top: 1px solid var(--border);
}
.article-outro p { color: var(--gray-300); font-size: 1rem; line-height: 1.7; }
.article-outro .cta { margin-top: 0.6rem; display: inline-block; }

/* Related, at the foot of an article */
.related { margin-top: 3rem; }
.related .eyebrow { display: block; margin-bottom: 1.1rem; }
.related-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 0.9rem; }
.related-card {
  display: block;
  padding: 1.1rem 1.2rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  transition: border-color 0.25s var(--ease), transform 0.25s var(--ease);
}
.related-card:hover { border-color: var(--blue-glow); transform: translateY(-2px); }
.related-card h4 {
  font-family: var(--font-oxanium); font-weight: 500; font-size: 0.98rem; line-height: 1.25;
  color: var(--foreground); margin-top: 0.5rem;
}

@media (max-width: 820px) {
  .blog-page .page-scroll,
  .article-page .page-scroll { width: auto; padding-left: 1.55rem; padding-right: 1.55rem; }
  .post-grid { grid-template-columns: 1fr; }
  .panel-figure .row .k { min-width: 0; }
}

/* ============================================================
   PROJECTS — live, in-browser product demos
   ------------------------------------------------------------
   Three interactive case-study widgets (Voilae try-on, modr
   vision, AdFlow inspector) ported from their own build. Their
   component CSS below is authored against a small set of local
   design tokens; the .projects-page scope remaps those tokens to
   this site's cold-blue palette (accent silver/teal → cold blue,
   focus → blue-glow) so the demos read as part of this portfolio
   rather than a transplant. The procedurally-drawn pixel-art
   canvases keep their own deep-navy scenes — that navy reads as a
   warm panel against the pure-black page and its blue accents.
   ============================================================ */
.projects-page {
  --brand-teal: var(--blue-bright);          /* primary accent → cold blue */
  --brand-teal-bright: #cfe0ff;              /* bright ice-blue (glows/hovers) */
  --brand-pink: #7aa2ff;
  --line: #1b2236;                            /* hairline, faintly navy */
  --line-soft: rgba(255, 255, 255, 0.06);
  --fill-4: rgba(255, 255, 255, 0.04);
  --fill-8: rgba(255, 255, 255, 0.08);
  --border-10: rgba(255, 255, 255, 0.10);
  --focus: var(--blue-glow);
  --surface-primary: #000;
  --surface-secondary: #0d1020;
  --surface-raised: #141830;
  --text-primary: #fff;
  --text-subdued: rgba(255, 255, 255, 0.62);
  --text-secondary: #9aa0b4;
  /* "Screen" chrome (telemetry consoles + omnibar dots). Overridden in light
     so the readout panels flip; the pixel-art render viewports keep their own
     deep-navy scenes drawn on the <canvas>. */
  --screen-panel: linear-gradient(180deg, #0a1a25, #06121b);
  --screen-dot: #223440;
  --body: 0.9rem;
  --lg: 1rem;
  --xl: 1.06rem;
  --dur: 0.16s;
}

/* ---- page shell + section framing (this site's idiom) ---- */
.projects-page .page-scroll {
  min-height: var(--content-height);
  width: min(90vw, 1100px);
  margin: 0 auto;
  padding: clamp(6rem, 12vh, 9rem) 0 5rem;
}
.projects-intro { max-width: 52ch; }
.projects-intro h1 {
  font-weight: 300;
  font-size: clamp(2.2rem, 4.2vw, 3.4rem);
  letter-spacing: 0.01em;
  line-height: 1.06;
  margin-top: 0.9rem;
  color: var(--foreground);
}
.projects-intro h1 b { font-weight: 500; color: var(--blue-bright); }
.projects-intro .lede {
  margin-top: 1.1rem;
  max-width: 62ch;
  color: var(--gray-400);
  font-size: clamp(0.9rem, 1.1vw, 1.05rem);
  line-height: 1.6;
}

/* ---- project carousel (echoes the work route: arrows + counter + dots) ---- */
.proj-carousel { position: relative; margin-top: clamp(2.6rem, 5vw, 3.6rem); outline: none; }
.proj-nav {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding-bottom: 1.3rem; border-bottom: 1px solid var(--border);
}
.proj-counter { font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.18em; color: var(--gray-400); }
.proj-arrows { display: flex; gap: 0.6rem; }
.proj-carousel .car-arrow { position: static; top: auto; transform: none; width: 40px; height: 40px; font-size: 1.35rem; }
.proj-carousel .car-arrow:hover { transform: translateY(-1px); }
.proj-track { position: relative; padding-top: clamp(2rem, 4vw, 3rem); }
.proj-slide { display: none; }
.proj-slide.active { display: block; animation: proj-in 0.45s var(--ease) both; }
@keyframes proj-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.proj-carousel .project { margin-top: 0; padding-top: 0; border-top: 0; }
.proj-carousel .car-dots { margin-top: clamp(2rem, 4vw, 3rem); }
@media (prefers-reduced-motion: reduce) { .proj-slide.active { animation: none; } }

.project {
  margin-top: clamp(3.5rem, 7vw, 5.5rem);
  padding-top: clamp(2.4rem, 5vw, 3.4rem);
  border-top: 1px solid var(--border);
}
.project-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem 1rem; }
.project-tag {
  font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--gray-400);
}
.project-tag.accent { color: var(--blue-bright); }
.project h2 {
  font-family: var(--font-oxanium); font-weight: 500;
  font-size: clamp(1.5rem, 2.6vw, 2.1rem); line-height: 1.12;
  letter-spacing: 0.005em; color: var(--foreground); margin-top: 0.9rem; max-width: 24ch;
}
.project h2 b { color: var(--blue-bright); font-weight: 500; }
.project .lede {
  margin-top: 0.85rem; max-width: 72ch; color: var(--gray-400);
  font-size: clamp(0.9rem, 1.02vw, 1.02rem); line-height: 1.62;
}
.project .lede strong { color: var(--foreground); font-weight: 500; }
.project .lede code {
  font-family: var(--font-mono); font-size: 0.85em;
  background: var(--surface-3); border: 1px solid var(--border);
  border-radius: 4px; padding: 0.06em 0.34em; color: var(--gray-300);
}
.project-links { margin-top: 1rem; display: flex; flex-wrap: wrap; gap: 1.4rem; }
.demo-wrap { margin-top: clamp(1.8rem, 3.5vw, 2.6rem); }

@media (max-width: 820px) {
  .projects-page .page-scroll { width: auto; padding-left: 1.55rem; padding-right: 1.55rem; }
}

/* ---------- Buttons (corner-bracket action + arrow link) --------------- */
.projects-page .btn {
  --corner: var(--brand-teal);
  position: relative; display: inline-flex; align-items: center; gap: 14px;
  padding: 14px 16px 14px 20px; border: 0; border-radius: 0;
  background: transparent; color: var(--text-primary);
  font-family: inherit; font-size: var(--body); font-weight: 400; line-height: 1;
  transition: color var(--dur) ease;
}
.projects-page .btn::before {
  content: ""; position: absolute; inset: 0; background: var(--fill-4);
  z-index: -1; transition: transform var(--dur) ease, background var(--dur) ease;
}
.projects-page .btn .corner {
  position: absolute; width: 8px; height: 8px;
  border-color: var(--corner); border-style: solid; border-width: 0;
  transition: border-color var(--dur) ease;
}
.projects-page .btn .corner.tl { top: 0; left: 0; border-top-width: 1px; border-left-width: 1px; }
.projects-page .btn .corner.tr { top: 0; right: 0; border-top-width: 1px; border-right-width: 1px; }
.projects-page .btn .corner.bl { bottom: 0; left: 0; border-bottom-width: 1px; border-left-width: 1px; }
.projects-page .btn .corner.br { bottom: 0; right: 0; border-bottom-width: 1px; border-right-width: 1px; }
.projects-page .btn .icon-box {
  display: grid; place-items: center; width: 26px; height: 26px;
  background: var(--fill-8); color: var(--brand-teal);
  transition: background var(--dur) ease, color var(--dur) ease;
}
.projects-page .btn .icon-box svg { width: 13px; height: 13px; }
.projects-page .btn:hover { color: var(--text-primary); }
.projects-page .btn:hover::before { transform: scale(0.97, 0.96); background: var(--fill-8); }
.projects-page .btn:hover .corner { border-color: var(--brand-teal-bright); }
.projects-page .btn:hover .icon-box { background: var(--brand-teal); color: var(--surface-primary); }
.projects-page .btn[disabled] { opacity: 0.6; cursor: default; }

.projects-page .arrow-link {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--text-primary); font-size: var(--body);
}
.projects-page .arrow-link svg {
  width: 12px; height: 12px; color: var(--brand-teal);
  transition: transform var(--dur) ease;
}
.projects-page .arrow-link:hover { color: var(--text-primary); }
.projects-page .arrow-link:hover svg { transform: translate(2px, -2px); }

/* ---------- Console mockup (procedural, no images) --------------------- */
.projects-page .console {
  position: relative; border: 1px solid var(--line); border-radius: 10px;
  background: var(--screen-panel);
  box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.8);
  font-family: var(--font-mono); font-size: 12.5px; color: var(--text-subdued);
  overflow: hidden;
}
.projects-page .console-bar {
  display: flex; align-items: center; gap: 8px; padding: 10px 14px;
  border-bottom: 1px solid var(--line); background: rgba(255, 255, 255, 0.02);
}
.projects-page .console-bar .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--screen-dot); }
.projects-page .console-bar .title { margin-left: 8px; color: var(--text-secondary); font-size: 12px; }
.projects-page .console-body { padding: 16px 18px; display: flex; flex-direction: column; gap: 12px; }
.projects-page .console-row {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px;
  border: 1px solid var(--line); border-radius: 6px; background: rgba(255, 255, 255, 0.015);
}
.projects-page .console-row .k { color: var(--brand-teal); }
.projects-page .console-row .v { color: var(--text-subdued); }
.projects-page .tag { margin-left: auto; font-size: 11px; padding: 2px 8px; border-radius: 4px; letter-spacing: 0.04em; }
.projects-page .tag--blocked { color: #7ef0c0; background: rgba(56, 220, 150, 0.12); border: 1px solid rgba(56, 220, 150, 0.25); }
.projects-page .tag--critical { color: #ff9d9d; background: rgba(255, 90, 90, 0.12); border: 1px solid rgba(255, 90, 90, 0.28); }
.projects-page .tag--open { color: var(--brand-teal); background: rgba(96, 165, 250, 0.12); border: 1px solid rgba(96, 165, 250, 0.28); }

/* =====================================================================
   Voilae try-on demo
   ===================================================================== */
.tryon { display: grid; grid-template-columns: minmax(0, 360px) minmax(0, 1fr); gap: clamp(24px, 4vw, 56px); align-items: start; }
.tryon-viewport {
  position: relative; width: 100%; aspect-ratio: 3 / 4;
  border: 1px solid var(--line); border-radius: 10px; overflow: hidden;
  background: #06121b; box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.8);
  user-select: none; outline: none;
}
.tryon-viewport:focus-visible { box-shadow: 0 0 0 2px var(--focus), 0 30px 80px -30px rgba(0, 0, 0, 0.8); }
.tryon[data-state="result"] .tryon-viewport { cursor: ew-resize; }
.tryon-cv { position: absolute; inset: 0; width: 100%; height: 100%; image-rendering: pixelated; image-rendering: crisp-edges; }
.tryon-clip { position: absolute; inset: 0; }
.tryon[data-state="idle"] .tryon-clip { clip-path: none !important; }
.tryon-divider {
  position: absolute; top: 0; bottom: 0; width: 2px; background: rgba(255, 255, 255, 0.9);
  transform: translateX(-1px); opacity: 0; pointer-events: none; transition: opacity var(--dur) ease;
}
.tryon-handle {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 38px; height: 38px; display: flex; align-items: center; justify-content: center;
  border-radius: 50%; background: #fff; color: #06121b; font-size: 15px; font-weight: 500;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
}
.tryon[data-state="result"] .tryon-divider { opacity: 1; }
.tryon-vtag {
  position: absolute; top: 12px; z-index: 2; font-family: var(--font-mono); font-size: 10px;
  letter-spacing: 0.14em; text-transform: uppercase; padding: 4px 10px; border-radius: 999px;
  opacity: 0; transition: opacity var(--dur) ease;
}
.tryon-vtag--after { left: 12px; color: #06121b; background: var(--brand-teal-bright); }
.tryon-vtag--before { right: 12px; color: #06121b; background: #fff; }
.tryon[data-state="result"] .tryon-vtag { opacity: 1; }
.tryon-scan {
  position: absolute; inset: 0; z-index: 3; opacity: 0; pointer-events: none;
  background: linear-gradient(rgba(6, 18, 27, 0.55), rgba(6, 18, 27, 0.55)); transition: opacity var(--dur) ease;
}
.tryon-scan::before {
  content: ""; position: absolute; left: 18%; right: 18%; top: 14%; bottom: 18%;
  border: 1.5px dashed var(--brand-teal); border-radius: 8px; animation: tryon-pulse 1.1s ease-in-out infinite;
}
.tryon-scan::after {
  content: ""; position: absolute; left: 0; right: 0; height: 2px; top: 0;
  background: linear-gradient(90deg, transparent, var(--brand-teal-bright), transparent);
  box-shadow: 0 0 14px 2px rgba(207, 224, 247, 0.5); animation: tryon-scanline 1.4s linear infinite;
}
.tryon[data-state="loading"] .tryon-scan { opacity: 1; }
@keyframes tryon-scanline { 0% { top: 8%; } 100% { top: 88%; } }
@keyframes tryon-pulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }
.tryon-hint {
  position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 3;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em; color: var(--text-primary);
  background: rgba(6, 18, 27, 0.72); border: 1px solid var(--border-10); padding: 7px 13px; border-radius: 999px;
  backdrop-filter: blur(4px); white-space: nowrap; opacity: 0; transition: opacity var(--dur) ease;
}
.tryon[data-state="idle"] .tryon-hint { opacity: 1; }
.tryon-panel { display: flex; flex-direction: column; gap: 18px; }
.tryon-product { display: flex; flex-direction: column; gap: 3px; }
.tryon-brand { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--brand-teal); }
.tryon-name { font-size: var(--xl); font-weight: 500; letter-spacing: -0.01em; color: var(--text-primary); }
.tryon-sub { font-size: 13px; color: var(--text-subdued); }
.tryon-thumbs { display: flex; flex-wrap: wrap; gap: 10px; }
.tryon-thumb {
  width: 58px; height: 58px; padding: 0; border: 1px solid var(--line); border-radius: 8px;
  overflow: hidden; background: var(--fill-4); cursor: pointer;
  transition: border-color var(--dur) ease, transform var(--dur) ease, box-shadow var(--dur) ease;
}
.tryon-thumb img, .tryon-thumb canvas { display: block; width: 100%; height: 100%; object-fit: cover; image-rendering: pixelated; image-rendering: crisp-edges; }
.tryon-thumb canvas { background: linear-gradient(180deg, #0d1020, #080a14); }
.tryon-thumb:hover { transform: translateY(-2px); border-color: var(--border-10); }
.tryon-thumb[aria-selected="true"] { border-color: var(--brand-teal); box-shadow: 0 0 0 1px var(--brand-teal), 0 0 18px -4px var(--brand-teal); }
.tryon-tel { margin-top: 2px; }
.tryon-tel .console-body { gap: 8px; padding: 14px 16px; }
.tryon-actions { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.tryon-next { display: none; background: none; border: 0; cursor: pointer; font: inherit; padding: 0; }
.tryon[data-state="result"] .tryon-next { display: inline-flex; }
.tryon-report { font-family: var(--font-mono); font-size: 12px; line-height: 1.5; color: var(--brand-teal-bright); margin: 0; min-height: 1.5em; }
.tryon-report strong { color: var(--text-primary); font-weight: 500; }
.tryon-foot { font-size: 12.5px; line-height: 1.5; color: var(--text-subdued); margin: 0; }
.tryon-foot a { color: var(--brand-teal); text-decoration: underline; text-underline-offset: 2px; }
@media (max-width: 980px) {
  .tryon { grid-template-columns: 1fr; gap: 28px; }
  .tryon-stage { max-width: 340px; margin: 0 auto; width: 100%; }
}
@media (prefers-reduced-motion: reduce) { .tryon-scan::before, .tryon-scan::after { animation: none; } }

/* =====================================================================
   modr vision demo
   ===================================================================== */
.scan { display: flex; flex-direction: column; gap: 28px; }
.scan-body { display: grid; grid-template-columns: minmax(0, 400px) minmax(0, 1fr); gap: clamp(24px, 4vw, 56px); align-items: start; }
.scan-modes { display: inline-flex; gap: 4px; padding: 4px; border: 1px solid var(--line); border-radius: 999px; background: var(--fill-4); align-self: start; }
.scan-mode {
  font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.03em; color: var(--text-subdued);
  background: none; border: 0; cursor: pointer; padding: 8px 16px; border-radius: 999px;
  transition: color var(--dur) ease, background var(--dur) ease;
}
.scan-mode:hover { color: var(--text-primary); }
.scan-mode[aria-selected="true"] { color: #06121b; background: var(--brand-teal-bright); }
.scan[data-mode="part"] [data-scan-panel="diagram"], .scan[data-mode="diagram"] [data-scan-panel="part"] { display: none; }
.scan[data-mode="diagram"] .scan-box { display: none; }
.scan[data-mode="part"] .scan-dboxes { display: none; }
.scan-viewport {
  position: relative; width: 100%; aspect-ratio: 4 / 3; border: 1px solid var(--line);
  border-radius: 10px; overflow: hidden; background: #06121b; box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.8); user-select: none;
}
.scan-cv { position: absolute; inset: 0; width: 100%; height: 100%; image-rendering: pixelated; image-rendering: crisp-edges; }
.scan-box {
  position: absolute; z-index: 3; border: 1.5px solid var(--brand-teal-bright); border-radius: 4px;
  box-shadow: 0 0 0 1px rgba(6, 18, 27, 0.6), 0 0 16px -2px var(--brand-teal);
  opacity: 0; transform: scale(1.04); transition: opacity var(--dur) ease, transform var(--dur) ease; pointer-events: none;
}
.scan[data-state="result"] .scan-box { opacity: 1; transform: scale(1); }
.scan[data-verdict="low"] .scan-box { border-style: dashed; border-color: #e6a23c; box-shadow: 0 0 0 1px rgba(6, 18, 27, 0.6), 0 0 16px -2px rgba(230, 162, 60, 0.8); }
.scan-boxlabel {
  position: absolute; left: -1.5px; top: -21px; font-family: var(--font-mono); font-size: 10px;
  letter-spacing: 0.04em; white-space: nowrap; padding: 3px 7px; border-radius: 4px; color: #06121b; background: var(--brand-teal-bright);
}
.scan[data-verdict="low"] .scan-boxlabel { background: #e6a23c; }
.scan-reticle {
  position: absolute; inset: 0; z-index: 4; opacity: 0; pointer-events: none;
  background: linear-gradient(rgba(6, 18, 27, 0.5), rgba(6, 18, 27, 0.5)); transition: opacity var(--dur) ease;
}
.scan-reticle::before {
  content: ""; position: absolute; left: 14%; right: 14%; top: 12%; bottom: 16%;
  border: 1.5px dashed var(--brand-teal); border-radius: 8px; animation: tryon-pulse 1.1s ease-in-out infinite;
}
.scan-reticle::after {
  content: ""; position: absolute; left: 0; right: 0; height: 2px; top: 0;
  background: linear-gradient(90deg, transparent, var(--brand-teal-bright), transparent);
  box-shadow: 0 0 14px 2px rgba(207, 224, 247, 0.5); animation: tryon-scanline 1.4s linear infinite;
}
.scan[data-state="loading"] .scan-reticle { opacity: 1; }
.scan-hint {
  position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 3;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em; color: var(--text-primary);
  background: rgba(6, 18, 27, 0.72); border: 1px solid var(--border-10); padding: 7px 13px; border-radius: 999px;
  backdrop-filter: blur(4px); white-space: nowrap; opacity: 0; transition: opacity var(--dur) ease;
}
.scan[data-state="idle"] .scan-hint { opacity: 1; }
.scan-panel { display: flex; flex-direction: column; gap: 18px; }
.scan-product { display: flex; flex-direction: column; gap: 3px; }
.scan-brand { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--brand-teal); }
.scan-name { font-size: var(--xl); font-weight: 500; letter-spacing: -0.01em; color: var(--text-primary); }
.scan-sub { font-size: 13px; color: var(--text-subdued); }
.scan-thumbs { display: flex; flex-wrap: wrap; gap: 10px; }
.scan-thumb {
  width: 64px; height: 48px; padding: 0; border: 1px solid var(--line); border-radius: 8px;
  overflow: hidden; background: #0b0e1c; cursor: pointer;
  transition: border-color var(--dur) ease, transform var(--dur) ease, box-shadow var(--dur) ease;
}
.scan-thumb canvas { display: block; width: 100%; height: 100%; object-fit: cover; image-rendering: pixelated; image-rendering: crisp-edges; }
.scan-thumb:hover { transform: translateY(-2px); border-color: var(--border-10); }
.scan-thumb[aria-selected="true"] { border-color: var(--brand-teal); box-shadow: 0 0 0 1px var(--brand-teal), 0 0 18px -4px var(--brand-teal); }
.scan-meter { display: flex; flex-direction: column; gap: 7px; }
.scan-meter-head {
  display: flex; align-items: baseline; justify-content: space-between; font-family: var(--font-mono);
  font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-subdued);
}
.scan-meter-head .val { font-size: 15px; color: var(--text-primary); letter-spacing: 0; }
.scan-meter-track { position: relative; height: 8px; border-radius: 999px; background: var(--fill-4); overflow: hidden; }
.scan-meter-track::after {
  content: ""; position: absolute; left: 60%; top: -2px; bottom: -2px; width: 1px;
  background: repeating-linear-gradient(180deg, var(--border-10) 0 3px, transparent 3px 6px);
}
.scan-meter-fill { height: 100%; width: 0; border-radius: 999px; background: var(--brand-teal-bright); transition: width 0.25s ease; }
.scan-meter-fill[data-low="true"] { background: #e6a23c; }
.scan-verdict { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em; color: var(--text-subdued); display: inline-flex; align-items: center; gap: 8px; }
.scan-verdict::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--text-subdued); }
.scan-verdict--high { color: var(--brand-teal-bright); }
.scan-verdict--high::before { background: var(--brand-teal-bright); }
.scan-verdict--low { color: #e6a23c; }
.scan-verdict--low::before { background: #e6a23c; }
.scan-tel .console-body { gap: 8px; padding: 14px 16px; }
.scan-actions { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.scan-next { display: none; background: none; border: 0; cursor: pointer; font: inherit; padding: 0; }
.scan[data-state="result"] .scan-next { display: inline-flex; }
.scan-report { font-family: var(--font-mono); font-size: 12px; line-height: 1.5; color: var(--brand-teal-bright); margin: 0; min-height: 3em; }
.scan[data-verdict="low"] .scan-report { color: #f0c07a; }
.scan-report strong { color: var(--text-primary); font-weight: 500; }
.scan-foot { font-size: 12.5px; line-height: 1.5; color: var(--text-subdued); margin: 0; }
.scan-foot a { color: var(--brand-teal); text-decoration: underline; text-underline-offset: 2px; }
.scan-dboxes { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.scan-dbox {
  position: absolute; border: 1.5px solid rgba(207, 224, 247, 0.55); border-radius: 3px;
  background: rgba(122, 162, 255, 0.08); opacity: 0; transform: scale(1.06);
  transition: opacity 0.28s ease, transform 0.28s ease, border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}
.scan-dboxes.is-shown .scan-dbox { opacity: 1; transform: scale(1); }
.scan-dboxes.is-shown .scan-dbox:nth-child(1) { transition-delay: 0.05s; }
.scan-dboxes.is-shown .scan-dbox:nth-child(2) { transition-delay: 0.14s; }
.scan-dboxes.is-shown .scan-dbox:nth-child(3) { transition-delay: 0.23s; }
.scan-dboxes.is-shown .scan-dbox:nth-child(4) { transition-delay: 0.32s; }
.scan-dboxes.is-shown .scan-dbox:nth-child(5) { transition-delay: 0.41s; }
.scan-dbox-label {
  position: absolute; left: -1.5px; top: -17px; min-width: 15px; text-align: center;
  font-family: var(--font-mono); font-size: 10px; line-height: 15px; height: 15px; padding: 0 3px;
  border-radius: 3px; color: #06121b; background: rgba(207, 224, 247, 0.7);
}
.scan-dbox.is-lit { border-color: var(--brand-teal-bright); background: rgba(122, 162, 255, 0.2); box-shadow: 0 0 14px -2px var(--brand-teal); }
.scan-dbox.is-lit .scan-dbox-label { background: var(--brand-teal-bright); }
.scan-dbox.is-dim { opacity: 0.28; }
.scan-steps { list-style: none; margin: 0; padding: 0; display: none; flex-direction: column; gap: 8px; }
.scan-steps.is-shown { display: flex; animation: scan-fade 0.4s ease both; }
.scan-step {
  display: flex; gap: 12px; align-items: flex-start; padding: 10px 12px; border: 1px solid var(--line);
  border-radius: 8px; background: var(--fill-4); cursor: default; outline: none;
  transition: border-color var(--dur) ease, background var(--dur) ease;
}
.scan-step:hover, .scan-step:focus-visible { border-color: var(--brand-teal); background: rgba(122, 162, 255, 0.08); }
.scan-step-n {
  flex: none; width: 20px; height: 20px; border-radius: 50%; font-family: var(--font-mono);
  font-size: 11px; line-height: 20px; text-align: center; color: var(--brand-teal-bright); background: rgba(122, 162, 255, 0.14);
}
.scan-step-t { font-size: 13px; line-height: 1.5; color: var(--text-primary); }
.scan-gloss {
  display: none; flex-direction: column; gap: 6px; padding: 14px 16px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--fill-4);
}
.scan-gloss.is-shown { display: flex; animation: scan-fade 0.4s ease both; }
@keyframes scan-fade { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.scan-gloss-row { display: flex; gap: 10px; align-items: baseline; font-size: 12.5px; line-height: 1.45; color: var(--text-subdued); }
.scan-gloss-k { flex: none; width: 18px; font-family: var(--font-mono); font-size: 11px; color: var(--brand-teal); }
.scan-gloss-v strong { color: var(--text-primary); font-weight: 500; }
@media (max-width: 980px) {
  .scan-body { grid-template-columns: 1fr; gap: 28px; }
  .scan-stage { max-width: 420px; margin: 0 auto; width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .scan-reticle::before, .scan-reticle::after { animation: none; }
  .scan-dbox { transition: opacity 0.01s, border-color 0.15s ease, background 0.15s ease; }
  .scan-steps.is-shown, .scan-gloss.is-shown { animation: none; }
}

/* =====================================================================
   AdFlow demo
   ===================================================================== */
.adflow { display: grid; grid-template-columns: minmax(0, 420px) minmax(0, 1fr); gap: clamp(24px, 4vw, 56px); align-items: start; }
.adflow-browser { border: 1px solid var(--line); border-radius: 10px; overflow: hidden; background: #06121b; box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.8); }
.adflow-omni { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-bottom: 1px solid var(--line); background: rgba(255, 255, 255, 0.02); }
.adflow-omni .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--screen-dot); }
.adflow-url {
  margin-left: 6px; font-family: var(--font-mono); font-size: 11px; color: var(--text-secondary);
  background: var(--fill-4); border: 1px solid var(--line); padding: 3px 12px; border-radius: 999px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.adflow-viewport { position: relative; width: 100%; aspect-ratio: 4 / 3; overflow: hidden; background: #06121b; user-select: none; }
.adflow[data-state="idle"] .adflow-viewport { cursor: pointer; }
.adflow-cv { position: absolute; inset: 0; width: 100%; height: 100%; image-rendering: pixelated; image-rendering: crisp-edges; }
.adflow-slotlabel {
  position: absolute; top: 11%; right: 3%; z-index: 3; font-family: var(--font-mono); font-size: 9px;
  letter-spacing: 0.14em; text-transform: uppercase; color: #6b7690;
}
.adflow[data-state="idle"] .adflow-slotlabel, .adflow[data-state="loading"] .adflow-slotlabel { color: #8b95ad; }
.adflow-scan {
  position: absolute; inset: 0; z-index: 4; opacity: 0; pointer-events: none;
  background: linear-gradient(rgba(6, 18, 27, 0.28), rgba(6, 18, 27, 0.28)); transition: opacity var(--dur) ease;
}
.adflow-scan::after {
  content: ""; position: absolute; left: 0; right: 0; height: 2px; top: 0;
  background: linear-gradient(90deg, transparent, var(--brand-teal-bright), transparent);
  box-shadow: 0 0 14px 2px rgba(207, 224, 247, 0.5); animation: tryon-scanline 1.4s linear infinite;
}
.adflow[data-state="loading"] .adflow-scan { opacity: 1; }
.adflow-hint {
  position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%); z-index: 5;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em; color: var(--text-primary);
  background: rgba(6, 18, 27, 0.72); border: 1px solid var(--border-10); padding: 7px 13px; border-radius: 999px;
  backdrop-filter: blur(4px); white-space: nowrap; opacity: 0; transition: opacity var(--dur) ease;
}
.adflow[data-state="idle"] .adflow-hint, .adflow[data-state="loading"] .adflow-hint { opacity: 1; }
.adflow-panel { display: flex; flex-direction: column; gap: 16px; }
.adflow-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.adflow-brand { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--brand-teal); }
.adflow-count { font-family: var(--font-mono); font-size: 12px; color: var(--text-subdued); }
.adflow-flow {
  display: flex; flex-direction: column; gap: 5px; min-height: 60px; max-height: 264px;
  overflow-y: auto; overflow-x: hidden; padding-right: 3px; scrollbar-width: thin; scrollbar-color: var(--border-10) transparent;
}
.adflow-flow::-webkit-scrollbar { width: 6px; }
.adflow-flow::-webkit-scrollbar-thumb { background: var(--border-10); border-radius: 3px; }
.adflow-flow::-webkit-scrollbar-track { background: transparent; }
.adflow-req {
  display: flex; align-items: center; gap: 10px; padding: 8px 12px; border: 1px solid var(--line);
  border-left: 3px solid var(--text-subdued); border-radius: 6px; background: var(--fill-4);
  opacity: 0; transform: translateX(-7px); transition: opacity 0.3s ease, transform 0.3s ease;
}
.adflow-req.is-in { opacity: 1; transform: none; }
.adflow-req-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--text-subdued); }
.adflow-req-main { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.adflow-req-vendor { font-size: 13px; font-weight: 500; color: var(--text-primary); line-height: 1.3; }
.adflow-req-meta { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-subdued); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.adflow-req-price { font-family: var(--font-mono); font-size: 11px; color: var(--text-secondary); }
.adflow-reqtag { margin-left: 0; flex: none; }
.adflow-req-ms { flex: none; font-family: var(--font-mono); font-size: 11px; color: var(--text-subdued); min-width: 40px; text-align: right; }
.adflow-req.is-win { border-left-color: var(--brand-teal-bright); background: rgba(56, 220, 150, 0.06); box-shadow: inset 0 0 0 1px rgba(56, 220, 150, 0.15); }
.adflow-req.is-issue { border-left-color: #F59E0B; background: rgba(245, 158, 11, 0.06); box-shadow: inset 0 0 0 1px rgba(245, 158, 11, 0.18); }
.adflow-tel .console-body { gap: 8px; padding: 14px 16px; }
.adflow-ai { display: flex; flex-direction: column; gap: 14px; }
.adflow-report { font-family: var(--font-mono); font-size: 12px; line-height: 1.65; color: var(--text-subdued); margin: 0; }
.adflow-report:empty { display: none; }
.adflow-report strong { color: var(--text-primary); font-weight: 500; }
.adflow-cursor {
  display: inline-block; width: 7px; height: 13px; margin-left: 1px; vertical-align: text-bottom;
  background: var(--brand-teal-bright); animation: adflow-blink 0.9s step-end infinite;
}
@keyframes adflow-blink { 50% { opacity: 0; } }
.adflow-foot { font-size: 12.5px; line-height: 1.5; color: var(--text-subdued); margin: 0; }
.adflow-foot a { color: var(--brand-teal); text-decoration: underline; text-underline-offset: 2px; }
@media (max-width: 980px) {
  .adflow { grid-template-columns: 1fr; gap: 28px; }
  .adflow-stage { max-width: 440px; margin: 0 auto; width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .adflow-scan::after { animation: none; }
  .adflow-req { transition: opacity 0.01s; }
  .adflow-cursor { animation: none; }
}

/* Pill-nav: five tabs fit narrow phones without overflowing the frame. */
@media (max-width: 540px) {
  .pill-nav a { padding: 0.45rem 0.8rem; font-size: 0.8rem; }
}

/* ============================================================
   Theme control — segmented light / dark / auto
   ------------------------------------------------------------
   Three icon buttons injected by theme.js at the LEADING end of
   the pill nav (opposite the tabs). "Auto" follows the visitor's
   local time of day. The button matching the current mode is
   filled, mirroring the tab indicator so the control reads as
   part of the same nav system.
   ============================================================ */
.theme-seg {
  position: relative;
  z-index: 10;
  display: inline-flex;
  align-items: center;
  flex: none;
  gap: 2px;
  margin-right: 0.5rem;
  padding-right: 0.5rem;
  border-right: 1px solid var(--nav-border);   /* divider from the tabs */
}
.theme-opt {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 9999px;
  background: transparent;
  color: var(--gray-400);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.25s var(--ease), background 0.25s var(--ease);
}
.theme-opt:hover { color: var(--foreground); }
.theme-opt:focus-visible { outline: 2px solid var(--blue-glow); outline-offset: 2px; }
.theme-opt.is-active { color: var(--nav-indicator-fg); background: var(--nav-indicator); }
.theme-opt svg { width: 15px; height: 15px; display: block; }
@media (max-width: 540px) {
  .theme-seg { gap: 0; margin-right: 0.3rem; padding-right: 0.3rem; }
  .theme-opt { width: 26px; height: 26px; }
  .theme-opt svg { width: 14px; height: 14px; }
}

/* ============================================================
   LIGHT THEME — token overrides. Dark is the default (bare :root
   above); this block only takes effect under html[data-theme="light"],
   so the dark experience is byte-for-byte unchanged. The cold-blue
   accent (--blue-*) is intentionally shared by both themes.
   ============================================================ */
html[data-theme="light"] {
  --background: #f4f5f7;
  --foreground: #10131a;
  --color-white: #10131a;   /* hero wordmark ink */
  --color-black: #ffffff;
  --card-bg: #ffffff;
  --border: #dcdfe6;
  --gray-300: #2b3038;      /* primary body copy */
  --gray-400: #586074;      /* muted / secondary */
  --gray-900: #eef0f3;

  --nav-bg: rgba(255, 255, 255, 0.6);
  --nav-border: rgba(16, 19, 26, 0.12);
  --nav-shadow: rgba(16, 19, 26, 0.14);
  --nav-indicator: #10131a;
  --nav-indicator-fg: #ffffff;
  --hud-line: rgba(16, 19, 26, 0.16);
  --loader-bg: #f4f5f7;
  --loader-fg: #10131a;
  --chip-bg: #10131a;
  --chip-fg: #f4f5f7;
  --chip-glow: rgba(16, 19, 26, 0.16);
  --dot-inactive: rgba(16, 19, 26, 0.22);
  --surface-1: rgba(16, 19, 26, 0.02);
  --surface-2: rgba(16, 19, 26, 0.035);
  --surface-3: rgba(16, 19, 26, 0.06);
  --hair: rgba(16, 19, 26, 0.07);
  --scrim-0: rgba(244, 245, 247, 0.92);
  --scrim-1: rgba(244, 245, 247, 0.82);
  --scrim-2: rgba(244, 245, 247, 0);
  --scrim-shadow: rgba(244, 245, 247, 0.9);
  --arrow-bg: rgba(16, 19, 26, 0.04);
  --canvas-ink: 40, 52, 78;   /* dark slate ink for the generative art */
}

/* Code figures are miniature "code editors" — like a syntax-highlighted
   screenshot, they read best kept dark in either theme. */
html[data-theme="light"] .code-figure pre { background: #0e0f13; color: #d7dde3; }
html[data-theme="light"] .code-figure .code-bar { background: #14151a; }

/* Blog thumbnails — schematic console/diagram SVGs. Their palette is inline
   as SVG presentation attributes; CSS wins over those, so the theme recolors
   them by value: dark panels → light, dark neutral strokes → light neutral,
   light "pop" shapes → dark ink, neutral text → readable slate. The cold-blue
   accents (#3b82f6 / #60a5fa / #8fc0ff) are shared and left untouched. */
html[data-theme="light"] .post-thumb { background: #eef1f5; }
html[data-theme="light"] .post-thumb svg [fill="#0a0a0d"],
html[data-theme="light"] .post-thumb svg [fill="#08080a"],
html[data-theme="light"] .post-thumb svg [fill="#0d0d10"],
html[data-theme="light"] .post-thumb svg [fill="#2a2a2e"] { fill: #ffffff; }
html[data-theme="light"] .post-thumb svg [fill="#0d1526"] { fill: #e7eefb; }
html[data-theme="light"] .post-thumb svg [stroke="#1c1c22"],
html[data-theme="light"] .post-thumb svg [stroke="#26262c"],
html[data-theme="light"] .post-thumb svg [stroke="#33343a"],
html[data-theme="light"] .post-thumb svg [stroke="#26323f"],
html[data-theme="light"] .post-thumb svg [stroke="#243043"],
html[data-theme="light"] .post-thumb svg [stroke="#53545c"],
html[data-theme="light"] .post-thumb svg [stroke="#0a0a0d"] { stroke: #c6ccd5; }
html[data-theme="light"] .post-thumb svg [fill="#6b6f76"],
html[data-theme="light"] .post-thumb svg [fill="#53545c"],
html[data-theme="light"] .post-thumb svg [fill="#7a7d84"],
html[data-theme="light"] .post-thumb svg [fill="#8a8f96"],
html[data-theme="light"] .post-thumb svg [fill="#33343a"] { fill: #5a6472; }
html[data-theme="light"] .post-thumb svg [fill="#d7dde3"],
html[data-theme="light"] .post-thumb svg [fill="#eef0f3"] { fill: #2b3038; }
html[data-theme="light"] .post-thumb svg [stroke="#f4f7fc"] { stroke: #2b3038; }
html[data-theme="light"] .post-thumb svg [fill="#6b8bb5"] { fill: #4a6fa5; }
/* Panels filled by a gradient (the "Evaluation" vignette) can't be matched by
   value — override the gradient-filled rect to the light panel colour. */
html[data-theme="light"] .post-thumb svg [fill="url(#evGlow)"] { fill: #ffffff; }

/* Projects page: remap its scoped tokens so the case-study text, controls and
   telemetry "screens" invert with the theme. The interactive pixel-art render
   viewports keep their own deep-navy scenes drawn on the <canvas> — they read
   as device screenshots, so they stay dark in both themes. */
html[data-theme="light"] .projects-page {
  --line: #dcdfe6;
  --line-soft: rgba(16, 19, 26, 0.08);
  --fill-4: rgba(16, 19, 26, 0.04);
  --fill-8: rgba(16, 19, 26, 0.08);
  --border-10: rgba(16, 19, 26, 0.12);
  --text-primary: #10131a;
  --text-subdued: rgba(16, 19, 26, 0.66);
  --text-secondary: #586074;
  --screen-panel: #ffffff;
  --screen-dot: #c6ccd5;
}
/* Demo "device" frames: the pixel-art scenes inside now paint light in light
   mode (see tryon.js / scan.js), and the AdFlow scene was always a light news
   page — so lighten the surrounding browser/viewport chrome to match, and
   soften the deep drop-shadows that were tuned against a black page. */
html[data-theme="light"] .adflow-browser { background: #ffffff; }
html[data-theme="light"] .adflow-omni { background: #f1f3f7; }
html[data-theme="light"] .adflow-viewport,
html[data-theme="light"] .tryon-viewport,
html[data-theme="light"] .scan-viewport { background: #e7ecf2; }
html[data-theme="light"] .projects-page .console,
html[data-theme="light"] .adflow-browser,
html[data-theme="light"] .tryon-viewport,
html[data-theme="light"] .scan-viewport {
  box-shadow: 0 20px 50px -28px rgba(16, 19, 26, 0.35);
}
html[data-theme="light"] .adflow-slotlabel { color: #7a8299; }
/* Garment / part swatch thumbnails — their own backdrop (a dark gradient on the
   try-on <canvas>, a dark fill behind the scan parts) must flip too. The scan
   thumbnails paint transparent now (see scan.js), so the element bg shows. */
html[data-theme="light"] .tryon-thumb canvas { background: linear-gradient(180deg, #e9ecf2, #d6dbe5); }
html[data-theme="light"] .scan-thumb { background: #e7ecf2; }

/* Portrait sits on light now — keep its cold-blue emissive but ease the
   brightness lift that was tuned for a black backdrop. */
html[data-theme="light"] .portrait {
  filter: contrast(1.02) drop-shadow(0 0 26px rgba(59, 130, 246, 0.22));
}
