/* ============================================================
   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;

  --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: 28px; height: 28px; font-size: 1rem; 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: #fff; }
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%, #000 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: #000;
  transition: opacity 0.6s var(--ease), visibility 0.6s var(--ease);
}
.audio-wave-heart rect { fill: #fff; }
.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: #fff;
  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);
}
@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%, #000 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: rgba(255, 255, 255, 0.2); }
.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: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(var(--blur-md));
  -webkit-backdrop-filter: blur(var(--blur-md));
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 9999px;
  padding: 0.5rem;
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
}
.pill-indicator {
  position: absolute;
  background: #fff;
  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: rgba(255, 255, 255, 0.95);
  transition: color 0.3s var(--ease);
  z-index: 10;
  white-space: nowrap;
}
.pill-nav a:hover { color: #fff; }
/* 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: #000; }

/* ============================================================
   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: #fff;
  color: #000;
  font-weight: 600;
  border: 0;
  /* Crisp opaque white chips with a soft white halo so the cluster reads as
     solid floating bubbles at every breakpoint — not a dim node-graph. */
  box-shadow: 0 0 26px rgba(255, 255, 255, 0.22);
}
.bubble.ghost { background: #fff; }

/* 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: rgba(10, 10, 10, 0.6);
  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: #fff; border-color: var(--blue-glow); }
.car-prev { left: -4px; }
.car-next { right: -4px; }
@media (min-width: 1100px) {
  .car-prev { left: -56px; }
  .car-next { right: -56px; }
}

/* 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: rgba(255, 255, 255, 0.28); 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: rgba(255, 255, 255, 0.02);
}

@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: #fff;
}
.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: #fff;
  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: #fff;
  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: #fff; 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%,
      rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.8) 44%, rgba(0, 0, 0, 0) 100%);
    -webkit-backdrop-filter: blur(2.5px);
    backdrop-filter: blur(2.5px);
    text-shadow: 0 1px 14px rgba(0, 0, 0, 0.85);
  }
  /* 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;
  }
}
