/* ============================================================
   3D PORTFOLIO — STYLE
   Theme colors change per zone via the --accent variable (JS).
   ============================================================ */

:root {
  --bg: #05010f;
  --text: #e8e6f3;
  --text-dim: #9d98b8;
  --accent: #8b5cf6;
  --glass: rgba(255, 255, 255, 0.04);
  --glass-border: rgba(255, 255, 255, 0.1);
  --font-main: 'Space Grotesk', sans-serif;
  --font-mono: 'JetBrains Mono', monospace;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-main);
  overflow-x: hidden;
  cursor: none;
}

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

.mono { font-family: var(--font-mono); }

/* ---------- Loader ---------- */
#loader {
  position: fixed; inset: 0; z-index: 100;
  background: var(--bg);
  display: flex; align-items: center; justify-content: center;
  transition: opacity 0.5s ease, visibility 0.5s;
}
#loader.done { opacity: 0; visibility: hidden; }
.loader-inner { text-align: center; }
.loader-ring {
  width: 64px; height: 64px; margin: 0 auto 24px;
  border: 2px solid var(--glass-border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.loader-text { font-family: var(--font-mono); font-size: 12px; letter-spacing: 3px; color: var(--text-dim); }
.dots::after { content: ''; animation: dots 1.2s steps(4) infinite; }
@keyframes dots { 0% { content: ''; } 25% { content: '.'; } 50% { content: '..'; } 75% { content: '...'; } }

/* ---------- Canvas ---------- */
#bg { position: fixed; inset: 0; z-index: 0; display: block; }

/* ---------- Progress bar ---------- */
#progress-bar {
  position: fixed; top: 0; left: 0; z-index: 60;
  width: 100%; height: 3px;
  background: linear-gradient(90deg, var(--accent), #fff);
  transform-origin: left;
  transform: scaleX(0);
}

/* ---------- Top bar ---------- */
#topbar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  display: flex; justify-content: space-between; align-items: center;
  gap: 16px;
  padding: 24px 40px;
}
/* the type blends against whatever scrolls under it; the CV chip does not,
   so it keeps its true accent colour instead of inverting */
.logo, .zone-label, #header-nav { mix-blend-mode: difference; }
.logo {
  font-family: var(--font-mono); font-weight: 700; font-size: 20px;
  color: #fff; text-decoration: none; letter-spacing: 1px;
  white-space: nowrap;
}
.topbar-right { display: flex; align-items: center; gap: 18px; min-width: 0; }
.zone-label {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 3px;
  color: #fff; opacity: 0.7; white-space: nowrap;
}

/* Mission-control nav: centered in the topbar, hidden while the site is
   loading / the launch countdown plays, then revealed by main.js and kept
   on screen for the whole journey. */
#header-nav {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  display: flex; gap: 8px;
  opacity: 0; pointer-events: none;
}
#header-nav.nav-visible { opacity: 1; pointer-events: auto; }
#header-nav a {
  position: relative;
  font-size: 11px; letter-spacing: 2px;
  color: #fff; opacity: 0.6;
  text-decoration: none;
  padding: 8px 16px;
  background-image: linear-gradient(var(--accent), var(--accent));
  background-repeat: no-repeat;
  background-position: 50% calc(100% - 2px);
  background-size: 0% 1px;
  transition: opacity 0.25s ease, letter-spacing 0.3s ease,
              background-size 0.35s cubic-bezier(0.22, 1, 0.36, 1),
              text-shadow 0.3s ease;
}
/* brackets slide in from the sides on hover — targeting-reticle style */
#header-nav a::before,
#header-nav a::after {
  position: absolute; top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-mono); font-size: 12px;
  color: var(--accent);
  opacity: 0;
  transition: opacity 0.3s ease, transform 0.3s ease;
}
#header-nav a::before { content: '['; left: 2px; transform: translateY(-50%) translateX(-6px); }
#header-nav a::after  { content: ']'; right: 2px; transform: translateY(-50%) translateX(6px); }
#header-nav a:hover {
  opacity: 1;
  letter-spacing: 3px;
  text-shadow: 0 0 14px var(--accent);
  background-size: calc(100% - 24px) 1px;
}
#header-nav a:hover::before,
#header-nav a:hover::after { opacity: 1; transform: translateY(-50%) translateX(0); }
/* the link whose section is currently on screen keeps a lit underline */
#header-nav a.nav-active {
  opacity: 1;
  background-size: calc(100% - 24px) 1px;
}

/* ---------- Side nav dots ---------- */
#dots-nav {
  position: fixed; right: 28px; top: 50%; transform: translateY(-50%);
  z-index: 50; display: flex; flex-direction: column; gap: 18px;
}
.dot {
  width: 10px; height: 10px; border-radius: 50%;
  border: 1px solid var(--text-dim);
  background: transparent;
  position: relative;
  transition: all 0.35s cubic-bezier(0.68, -0.55, 0.27, 1.55);
}
.dot:hover, .dot.active {
  background: var(--accent); border-color: var(--accent);
  transform: scale(1.5);
  box-shadow: 0 0 14px var(--accent);
}
.dot::before {
  content: attr(data-label);
  position: absolute; right: 22px; top: 50%; transform: translateY(-50%) translateX(8px);
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 2px;
  color: var(--text); white-space: nowrap;
  opacity: 0; pointer-events: none;
  transition: all 0.3s ease;
}
.dot:hover::before { opacity: 1; transform: translateY(-50%) translateX(0); }

/* ---------- Left social rail ---------- */
#social-rail {
  position: fixed; left: 26px; top: 50%; transform: translateY(-50%);
  z-index: 50;
  display: flex; flex-direction: column; align-items: center; gap: 16px;
}
.social-dot {
  position: relative;
  width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--glass-border);
  color: var(--accent);
  background: rgba(5, 1, 15, 0.4);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: all 0.35s cubic-bezier(0.68, -0.55, 0.27, 1.55);
}
.social-dot svg { width: 17px; height: 17px; fill: currentColor; }
.social-dot:hover {
  border-color: var(--accent);
  background: var(--accent);
  color: #fff;
  transform: scale(1.18);
  box-shadow: 0 0 22px var(--accent);
}
.social-dot::after {
  content: attr(data-label);
  position: absolute; left: 52px; top: 50%;
  transform: translateY(-50%) translateX(-8px);
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 2px;
  color: var(--text); white-space: nowrap;
  opacity: 0; pointer-events: none;
  transition: all 0.3s ease;
}
.social-dot:hover::after { opacity: 1; transform: translateY(-50%) translateX(0); }
.social-rail-line {
  width: 1px; height: 56px; margin-top: 6px;
  background: linear-gradient(to bottom, var(--accent), transparent);
}

/* ---------- Custom cursor ---------- */
#cursor {
  position: fixed; z-index: 99; pointer-events: none;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent);
  transform: translate(-50%, -50%);
  transition: background 0.3s;
}
#cursor-ring {
  position: fixed; z-index: 99; pointer-events: none;
  width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid var(--accent);
  transform: translate(-50%, -50%);
  transition: width 0.25s, height 0.25s, opacity 0.25s, border-color 0.3s;
  opacity: 0.6;
}
#cursor-ring.grow { width: 64px; height: 64px; opacity: 1; }
@media (hover: none) {
  #cursor, #cursor-ring { display: none; }
  body { cursor: auto; }
  /* nothing hovers on touch — the flip is bound to tap instead (main.js) */
  .cert-flip-hint { font-size: 0; }
  .cert-flip-hint::after {
    content: 'TAP TO REVEAL ⟲';
    font-size: 8px; letter-spacing: 2px;
  }
}

/* ---------- Sections ---------- */
#content { position: relative; z-index: 10; }

.section {
  min-height: 100vh;
  display: flex; flex-direction: column; justify-content: center;
  padding: 120px 5vw;
  position: relative;
}
.section-inner { max-width: 1650px; width: 100%; margin: 0 auto; position: relative; z-index: 1; }
.section-inner.wide { max-width: 1750px; }

/* Giant ghost number watermark filling the empty edges of each zone */
.section[data-num]::before {
  content: attr(data-num);
  position: absolute;
  top: 50%; right: -2vw;
  transform: translateY(-50%);
  font-family: var(--font-mono);
  font-size: 26vw; font-weight: 700; line-height: 1;
  color: transparent;
  -webkit-text-stroke: 2px rgba(255, 255, 255, 0.055);
  pointer-events: none; user-select: none;
  z-index: 0;
}
.section[data-num]:nth-child(even)::before { right: auto; left: -2vw; }

.section-num {
  font-size: 12px; letter-spacing: 4px; color: var(--accent);
  margin-bottom: 12px;
}
.section-title {
  font-size: clamp(2.4rem, 6vw, 4.5rem);
  font-weight: 700; letter-spacing: -1px;
  margin-bottom: 48px;
}
.section-title.big { font-size: clamp(2.6rem, 7vw, 5.5rem); margin-bottom: 28px; }
.accent { color: var(--accent); }

.gradient-text {
  background: linear-gradient(120deg, var(--accent), #fff 60%, var(--accent));
  background-size: 200% auto;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: shine 4s linear infinite;
}
@keyframes shine { to { background-position: 200% center; } }

.lead { font-size: 1.25rem; color: var(--text); line-height: 1.7; }
p { color: var(--text-dim); line-height: 1.8; }

/* ---------- Hero photo ---------- */
.hero-photo {
  position: static;
  width: 292px;
  margin: 0 auto 36px;
  z-index: 5;
  opacity: 0;
}
/* Cutout photo rising out of a glowing portal, rings orbiting behind */
.hero-photo-frame {
  position: relative;
  transition: transform 0.15s ease-out;
  will-change: transform;
}
.photo-orb {
  position: absolute; left: 50%; bottom: -2%;
  width: 105%; aspect-ratio: 1;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--accent) 42%, transparent) 0%,
    color-mix(in srgb, var(--accent) 14%, transparent) 45%,
    transparent 70%);
  filter: blur(6px);
  animation: orbPulse 4s ease-in-out infinite;
}
@keyframes orbPulse { 0%, 100% { opacity: 0.7; } 50% { opacity: 1; } }
.photo-ring {
  position: absolute; left: 50%; bottom: -6%;
  width: 100%; aspect-ratio: 1;
  margin-left: -50%;
  border-radius: 50%;
  border: 1px dashed color-mix(in srgb, var(--accent) 65%, transparent);
  animation: ringSpin 26s linear infinite;
}
.photo-ring-2 {
  width: 118%; bottom: -12%;
  margin-left: -59%;
  border-style: solid;
  opacity: 0.35;
  animation-duration: 44s;
  animation-direction: reverse;
}
@keyframes ringSpin { to { transform: rotate(360deg); } }
.hero-photo-frame img {
  position: relative; z-index: 2;
  display: block; width: 100%; height: auto;
  filter: drop-shadow(0 0 26px color-mix(in srgb, var(--accent) 50%, transparent)) contrast(1.04);
  /* Feather only the very bottom edge. The old cutout tapered to a waist, so
     fading its last 20% read as "dissolving into the void"; the current
     portrait is widest and most solid down there, and fading it that early
     made the background sculpture look like it was passing through him. */
  mask-image: linear-gradient(to bottom, #000 94%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, #000 94%, transparent 100%);
}

.hero-photo-tag {
  position: absolute; z-index: 3; left: 50%; bottom: 2%;
  transform: translateX(-50%);
  display: flex; gap: 16px; align-items: center; white-space: nowrap;
  padding: 10px 20px; border-radius: 999px;
  background: rgba(5, 1, 15, 0.55);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  font-size: 9px; letter-spacing: 1.5px; color: #fff;
}
.status-dot { color: var(--accent); animation: blink 1.4s step-end infinite; }

/* ---------- Hero ---------- */
.hero-inner { text-align: left; }
.eyebrow { font-size: 13px; letter-spacing: 5px; color: var(--accent); margin-bottom: 24px; }
.hero-name { font-size: clamp(3.4rem, 11vw, 8.5rem); font-weight: 700; line-height: 0.98; letter-spacing: -2px; }
.hero-name .line { display: block; }
.hero-tagline { margin: 28px 0 24px; font-size: 1.1rem; color: var(--text-dim); min-height: 1.8em; }
/* reserve two lines where the longest typewriter role wraps —
   otherwise the whole page reflows on every cycle and jitters the scroll */
@media (max-width: 1250px) {
  .hero-tagline { min-height: 3.6em; }
}
.caret { color: var(--accent); animation: blink 0.9s step-end infinite; }
@keyframes blink { 50% { opacity: 0; } }

/* meta chips: location / school / availability */
.hero-meta { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 36px; }
.meta-chip {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 10px; letter-spacing: 2px; color: var(--text);
  padding: 10px 18px; border-radius: 999px;
  border: 1px solid var(--glass-border);
  background: var(--glass);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: border-color 0.3s ease, color 0.3s ease, transform 0.3s ease;
}
.meta-chip:hover { border-color: var(--accent); color: #fff; transform: translateY(-2px); }
.meta-chip-live { color: #7dffa8; border-color: rgba(125, 255, 168, 0.35); }
.pulse-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: #7dffa8; box-shadow: 0 0 10px #7dffa8;
  animation: pulseDot 1.6s ease-in-out infinite;
}
@keyframes pulseDot { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.5); opacity: 0.55; } }

.hero-cta { display: flex; gap: 18px; flex-wrap: wrap; }

/* quick-hit stats under the CTAs */
.hero-stats {
  display: flex; gap: 18px; align-items: baseline; flex-wrap: wrap;
  margin-top: 44px;
  font-size: 10px; letter-spacing: 2px; color: var(--text-dim);
}
.hero-stats b { color: var(--accent); font-size: 1.5rem; font-weight: 600; margin-right: 7px; text-shadow: 0 0 18px var(--accent); }
.hs-sep { opacity: 0.3; }

/* tag chips floating around the hero photo */
.float-chip {
  position: absolute; z-index: 3;
  font-size: 9px; letter-spacing: 2px; color: #fff; white-space: nowrap;
  padding: 8px 14px; border-radius: 999px;
  background: rgba(5, 1, 15, 0.55);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 0 20px -6px var(--accent);
}
.fc-1 { top: 16%; left: -14%; animation: chipFloat 5.2s ease-in-out infinite; }
.fc-2 { top: 44%; right: -18%; animation: chipFloat 6.4s ease-in-out 0.8s infinite; }
.fc-3 { top: 72%; left: -10%; animation: chipFloat 5.8s ease-in-out 1.6s infinite; }
.fc-4 { top: 78%; right: -16%; animation: chipFloat 6.1s ease-in-out 2.3s infinite; }
.fc-5 { top: 2%;  right: -8%;  animation: chipFloat 5.5s ease-in-out 3.1s infinite; }
@keyframes chipFloat { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-12px); } }
.btn {
  display: inline-block; text-decoration: none;
  font-family: var(--font-mono); font-size: 13px; letter-spacing: 2px;
  padding: 16px 32px; border-radius: 999px;
  transition: all 0.35s ease;
}
.btn-solid { background: var(--accent); color: #fff; border: 1px solid var(--accent); }
.btn-solid:hover { box-shadow: 0 0 30px var(--accent); transform: translateY(-3px); }
.btn-ghost { background: transparent; color: var(--text); border: 1px solid var(--glass-border); }
.btn-ghost:hover { border-color: var(--accent); color: var(--accent); transform: translateY(-3px); }
.btn-big { font-size: 16px; padding: 20px 44px; margin: 32px 0; }

/* CV button: same pill language as the other CTAs, tinted with the live zone
   accent and swept by a scanline on hover so it reads as "retrieve artifact".
   Used in the hero CTA row and the contact console. */
.btn-cv {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--text);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.btn-cv::before {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 22%,
    color-mix(in srgb, var(--accent) 34%, transparent) 50%, transparent 78%);
  transform: translateX(-130%);
  transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
}
.btn-cv > * { position: relative; z-index: 1; }
.btn-cv svg {
  width: 15px; height: 15px; flex-shrink: 0;
  fill: none; stroke: var(--accent); stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
  transition: stroke 0.35s ease;
}
.btn-cv .cv-arrow { font-size: 12px; color: var(--accent); font-weight: 400; transition: transform 0.35s ease, color 0.35s ease; }
.btn-cv:hover {
  color: #fff;
  border-color: var(--accent);
  transform: translateY(-3px);
  box-shadow: 0 0 30px -8px var(--accent);
}
.btn-cv:hover::before { transform: translateX(130%); }
.btn-cv:hover svg { stroke: #fff; }
.btn-cv:hover .cv-arrow { color: #fff; transform: translate(3px, -3px); }
/* contact console: sits beside COPY EMAIL, so it matches that button's metrics */
.cv-inline { font-size: 12px; padding: 16px 26px; }

/* Header CV chip: compact twin of .btn-cv for the top bar */
.cv-chip {
  display: inline-flex; align-items: center; gap: 7px;
  text-decoration: none; white-space: nowrap;
  font-size: 10px; font-weight: 500; letter-spacing: 2px;
  color: #fff;
  padding: 8px 15px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: background 0.35s ease, border-color 0.35s ease,
              box-shadow 0.35s ease, transform 0.35s ease;
}
.cv-chip svg {
  width: 13px; height: 13px; flex-shrink: 0;
  fill: none; stroke: var(--accent); stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
  transition: stroke 0.35s ease;
}
.cv-chip:hover {
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 0 22px -4px var(--accent);
  transform: translateY(-2px);
}
.cv-chip:hover svg { stroke: #fff; }

.scroll-hint {
  position: absolute; bottom: 36px; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  font-size: 10px; letter-spacing: 3px; color: var(--text-dim);
}
.scroll-line {
  width: 1px; height: 48px;
  background: linear-gradient(to bottom, var(--accent), transparent);
  animation: scrollPulse 1.8s ease-in-out infinite;
}
@keyframes scrollPulse { 0%, 100% { transform: scaleY(0.4); opacity: 0.4; } 50% { transform: scaleY(1); opacity: 1; } }

/* ---------- About ---------- */
.about-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 64px; align-items: start; }
.about-text p { margin-bottom: 20px; }

/* Stats: editorial list rows, no boxes */
.about-stats { border-top: 1px solid var(--glass-border); }
.stat-line {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 22px 8px;
  border-bottom: 1px solid var(--glass-border);
  transition: all 0.35s ease;
}
.stat-line:hover {
  border-bottom-color: var(--accent);
  padding-left: 18px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.03));
}
.stat-value { font-size: 2.6rem; font-weight: 700; color: var(--accent); line-height: 1; }
.stat-label { font-size: 12px; letter-spacing: 3px; color: var(--text-dim); text-transform: uppercase; }

/* Status log: terminal-style "currently focused on" panel */
.about-now {
  margin-top: 56px;
  padding: 28px 30px;
  border: 1px solid var(--glass-border);
  border-radius: 18px;
  background: var(--glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.about-now-head {
  display: flex; align-items: center; gap: 10px;
  font-size: 11px; letter-spacing: 3px; color: var(--text);
  margin-bottom: 20px;
}
.about-now-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: #7dffa8; box-shadow: 0 0 10px #7dffa8;
  animation: pulseDot 1.6s ease-in-out infinite;
}
.about-now-tag { color: var(--text-dim); opacity: 0.8; }
.about-now-lines { display: flex; flex-direction: column; gap: 14px; }
.about-now-line {
  display: flex; align-items: baseline; gap: 10px;
  font-size: 12px; letter-spacing: 1.5px; color: var(--text-dim);
}
.about-now-line b { color: var(--text); font-weight: 500; letter-spacing: 1px; }
.about-now-fill {
  flex: 1; min-width: 24px;
  border-bottom: 1px dotted rgba(255, 255, 255, 0.18);
  transform: translateY(-3px);
}
.about-now-open b { color: var(--accent); }

/* Build process: scanning timeline + four-card breakdown */
.about-process { margin-top: 56px; }
.process-eyebrow { font-size: 11px; letter-spacing: 3px; color: var(--accent); margin-bottom: 10px; }
.process-title { font-size: clamp(1.3rem, 2.4vw, 1.7rem); margin-bottom: 40px; }

/* the sweeping line: ticks mark each step, a scanner ball travels across on loop */
.process-track { position: relative; height: 46px; margin: 0 4px 22px; }
.process-line {
  position: absolute; top: 50%; left: 0; right: 0; height: 1px;
  background: repeating-linear-gradient(to right,
    rgba(255, 255, 255, 0.3) 0 6px, transparent 6px 12px);
}
.process-scanner {
  position: absolute; top: 50%; left: 0;
  width: 12px; height: 12px; margin: -6px 0 0 -6px;
  border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 16px var(--accent), 0 0 0 4px color-mix(in srgb, var(--accent) 20%, transparent);
  will-change: left, opacity;
}
.process-tick {
  position: absolute; top: 50%; transform: translate(-50%, -50%);
  width: 1px; height: 22px; background: rgba(255, 255, 255, 0.35);
}
.process-tick b {
  position: absolute; top: -28px; left: 50%; transform: translateX(-50%);
  font-size: 11px; letter-spacing: 2px; color: var(--accent); font-weight: 500;
}

.process-grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--glass-border);
}
/* shared indicator bar that slides beneath whichever card is currently active,
   tracking the scanner ball 1:1 so the two never fall out of sync */
.process-fill {
  position: absolute; top: -1px; left: 0; width: 25%; height: 2px;
  background: var(--accent); box-shadow: 0 0 12px var(--accent);
  will-change: left, opacity;
}
.process-card {
  padding: 26px 24px; border-right: 1px solid var(--glass-border);
  transition: background 0.4s ease;
}
.process-card:last-child { border-right: none; }
.process-card.is-active { background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 7%, transparent), transparent); }
.process-num { display: block; font-size: 11px; letter-spacing: 2px; color: var(--text-dim); margin-bottom: 14px; transition: color 0.4s ease; }
.process-card.is-active .process-num { color: var(--accent); }
.process-card h4 { font-size: 1.05rem; margin-bottom: 10px; }
.process-card p { font-size: 0.86rem; line-height: 1.6; color: var(--text-dim); }

/* ---------- Education: center-spine timeline ---------- */
.edu-timeline { position: relative; padding: 24px 0; }
.edu-timeline::before {
  content: ''; position: absolute; left: 50%; top: 0; bottom: 0; width: 2px;
  transform: translateX(-50%);
  background: linear-gradient(to bottom, transparent, var(--accent) 10%, var(--accent) 90%, transparent);
  opacity: 0.55;
}
.edu-tl-item { position: relative; width: 50%; padding: 0 64px 56px 0; }
.edu-tl-item:nth-child(even) { margin-left: 50%; padding: 0 0 56px 64px; }
.edu-tl-item:last-child { padding-bottom: 0; }
.edu-tl-node {
  position: absolute; top: 34px; right: -9px;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--bg); border: 3px solid var(--accent);
  z-index: 2;
  animation: nodePulse 2.6s ease-in-out infinite;
}
.edu-tl-item:nth-child(even) .edu-tl-node { right: auto; left: -9px; }
@keyframes nodePulse {
  0%, 100% { box-shadow: 0 0 8px var(--accent); }
  50% { box-shadow: 0 0 24px var(--accent); }
}
.edu-tl-item::after {
  content: ''; position: absolute; top: 42px; right: 9px;
  width: 55px; height: 2px;
  background: linear-gradient(to left, var(--accent), transparent);
  opacity: 0.5;
}
.edu-tl-item:nth-child(even)::after {
  right: auto; left: 9px;
  background: linear-gradient(to right, var(--accent), transparent);
}
.edu-tl-card {
  background: var(--glass);
  border: 1px solid var(--glass-border);
  border-radius: 18px;
  padding: 34px 38px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  transition: all 0.4s ease;
}
.edu-tl-item:hover .edu-tl-card {
  border-color: var(--accent);
  box-shadow: 0 0 50px -16px var(--accent);
  transform: translateY(-6px);
}
.edu-tl-year { display: inline-block; font-size: 0.95rem; letter-spacing: 3px; color: var(--accent); margin-bottom: 12px; }
.edu-tl-card h3 { font-size: clamp(1.3rem, 2.4vw, 1.8rem); font-weight: 600; margin-bottom: 8px; transition: color 0.3s; }
.edu-tl-item:hover .edu-tl-card h3 { color: var(--accent); }
.edu-place { color: var(--text); font-size: 1rem; margin-bottom: 6px; }
.edu-desc { font-size: 0.9rem; }

/* ---------- Experience: compact left-spine timeline ---------- */
.exp-timeline { position: relative; }
.exp-timeline::before {
  content: ''; position: absolute; left: 220px; top: 10px; bottom: 10px; width: 2px;
  background: linear-gradient(to bottom, var(--accent) 0%, var(--accent) 85%, transparent);
  opacity: 0.5;
}
.exp-item {
  position: relative;
  display: grid;
  grid-template-columns: 175px 1fr;
  gap: 90px;
  padding-bottom: 44px;
}
.exp-item:last-child { padding-bottom: 0; }
.exp-when {
  text-align: right;
  color: var(--accent);
  font-size: 0.85rem; letter-spacing: 1px; line-height: 1.7;
  padding-top: 20px;
}
.exp-node {
  position: absolute; left: 220px; top: 26px;
  transform: translateX(-50%);
  width: 15px; height: 15px; border-radius: 50%;
  background: var(--accent);
  animation: nodePulse 2.6s ease-in-out infinite;
  z-index: 2;
}
.exp-body {
  background: var(--glass);
  border: 1px solid var(--glass-border);
  border-radius: 16px;
  padding: 26px 34px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  transition: all 0.4s ease;
}
.exp-item:hover .exp-body {
  border-color: var(--accent);
  box-shadow: 0 0 45px -14px var(--accent);
  transform: translateY(-4px);
}
.exp-title-row { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 6px; }
.exp-title-row h3 { font-size: 1.45rem; transition: color 0.3s; }
.exp-item:hover .exp-title-row h3 { color: var(--accent); }
.exp-mode {
  font-size: 9px; letter-spacing: 2px; color: var(--accent);
  border: 1px solid var(--glass-border); border-radius: 999px; padding: 5px 12px;
}
.exp-role { color: var(--text); font-weight: 500; margin-bottom: 10px; }
.exp-desc { font-size: 0.92rem; }
.exp-cert-link {
  display: inline-block; margin-top: 16px;
  font-size: 11px; letter-spacing: 2px;
  color: var(--accent); text-decoration: none;
  padding-bottom: 3px;
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s ease;
}
.exp-cert-link:hover { border-bottom-color: var(--accent); }

/* ---------- Engineering Lab: experiment log ---------- */
.lab-intro {
  font-size: 1.05rem; color: var(--text-dim);
  margin: -24px 0 22px;
}

/* workbench status ticker */
.lab-bench {
  display: flex; flex-wrap: wrap; gap: 8px 26px;
  font-size: 10px; letter-spacing: 2px; color: var(--text-dim);
  margin-bottom: 24px;
}
.lab-bench b { color: var(--accent); font-weight: 500; }

/* oscilloscope divider: graticule background + flowing trace */
.lab-scope {
  position: relative; height: 46px; margin-bottom: 30px;
  border-block: 1px solid var(--glass-border);
  background:
    repeating-linear-gradient(to right, rgba(255, 255, 255, 0.045) 0 1px, transparent 1px 40px),
    repeating-linear-gradient(to bottom, rgba(255, 255, 255, 0.045) 0 1px, transparent 1px 11px);
}
.lab-scope svg { width: 100%; height: 100%; display: block; }
.scope-wave {
  fill: none; stroke: var(--accent); stroke-width: 1.6;
  filter: drop-shadow(0 0 6px var(--accent));
  stroke-dasharray: 7 5;
  animation: scopeFlow 1.4s linear infinite;
}
@keyframes scopeFlow { to { stroke-dashoffset: -120; } }
.lab-scope-label {
  position: absolute; top: 6px; right: 10px;
  font-size: 9px; letter-spacing: 2px; color: var(--text-dim);
}

/* category filter chips */
.lab-filters { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 30px; }
.lab-filter {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 2px;
  color: var(--text-dim); background: transparent;
  border: 1px solid var(--glass-border); border-radius: 999px;
  padding: 9px 16px; cursor: none;
  transition: all 0.3s ease;
}
.lab-filter b { color: var(--accent); font-weight: 500; margin-left: 8px; }
.lab-filter:hover { border-color: var(--accent); color: var(--text); transform: translateY(-2px); }
.lab-filter.is-on { background: var(--accent); border-color: var(--accent); color: #fff; }
.lab-filter.is-on b { color: #fff; }

.lab-grid {
  display: grid;
  /* min() keeps the track from outgrowing the column on narrow phones */
  grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
  gap: 22px;
}
.lab-card {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column;
  padding: 28px 26px;
  border: 1px solid var(--glass-border);
  border-radius: 10px;
  background: var(--glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  transition: border-color 0.35s ease, box-shadow 0.35s ease, transform 0.35s ease;
}
.lab-card:hover {
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  box-shadow: 0 0 44px -16px var(--accent);
  transform: translateY(-5px);
}
/* HUD corner brackets that flare out on hover */
.lab-card::before, .lab-card::after {
  content: ''; position: absolute; width: 14px; height: 14px;
  opacity: 0.45; pointer-events: none;
  transition: all 0.35s ease;
}
.lab-card::before { top: 8px; left: 8px; border-top: 2px solid var(--accent); border-left: 2px solid var(--accent); }
.lab-card::after { bottom: 8px; right: 8px; border-bottom: 2px solid var(--accent); border-right: 2px solid var(--accent); }
.lab-card:hover::before, .lab-card:hover::after { width: 24px; height: 24px; opacity: 1; }
/* scanline sweeping across the card on hover */
.lab-scan {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 40%, color-mix(in srgb, var(--accent) 14%, transparent) 50%, transparent 60%);
  transform: translateX(-120%);
}
.lab-card:hover .lab-scan { animation: labScan 0.9s ease; }
@keyframes labScan { to { transform: translateX(120%); } }

.lab-card-top {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 18px;
}
.lab-id { font-size: 9px; letter-spacing: 2px; color: var(--text-dim); }
.lab-cat {
  font-size: 9px; letter-spacing: 2px; color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 999px; padding: 6px 12px;
}
.lab-artifact {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 9px; letter-spacing: 2px; color: var(--text-dim);
}
.lab-led {
  width: 6px; height: 6px; border-radius: 50%;
  background: #7dffa8; box-shadow: 0 0 8px #7dffa8;
  animation: pulseDot 1.6s ease-in-out infinite;
}
/* desync the LEDs so the wall of cards blinks organically, not in unison */
.lab-card:nth-child(2n) .lab-led { animation-delay: 0.4s; }
.lab-card:nth-child(3n) .lab-led { animation-delay: 0.9s; }
.lab-card:nth-child(5n) .lab-led { animation-delay: 1.3s; }
.lab-card h3 { font-size: 1.15rem; margin-bottom: 10px; }
.lab-card p { font-size: 0.88rem; line-height: 1.65; flex: 1; }
.lab-card .project-tags { margin: 16px 0 18px; }
.lab-link {
  font-size: 11px; letter-spacing: 2px;
  color: var(--accent); text-decoration: none;
  padding-bottom: 3px; align-self: flex-start;
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s ease;
}
.lab-link:hover { border-bottom-color: var(--accent); }

/* ---------- Certifications: hover-flip cards ---------- */
/* two rows (3 + 2 centered): bigger cards, less dead space above/below */
.certs-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 22px; }
/* card matches the certificate's landscape ratio so the flip reveals it edge-to-edge */
.cert-card { perspective: 1500px; aspect-ratio: 1.43 / 1; grid-column: span 2; }
.cert-card:nth-child(4) { grid-column: 2 / span 2; }
.cert-inner {
  position: relative; width: 100%; height: 100%;
  transform-style: preserve-3d;
  transition: transform 0.9s cubic-bezier(0.35, 0.1, 0.2, 1);
}
.cert-card:hover .cert-inner { transform: rotateY(180deg); }
/* A card with no scan behind it has nothing to flip to — it sits flat and
   ignores hover and tap. The registry ID, seal and corner brackets stay, so
   it still reads as part of the same set. */
.cert-card.cert-flat:hover .cert-inner,
.cert-card.cert-flat.is-flipped .cert-inner { transform: none; }
.cert-front, .cert-back {
  position: absolute; inset: 0;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  border-radius: 20px; overflow: hidden;
  border: 1px solid var(--glass-border);
  background: rgba(13, 10, 26, 0.85);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 22px 18px;
}
.cert-back { transform: rotateY(180deg); border-color: var(--accent); padding: 0; }
.cert-icon { font-size: 1.3rem; color: var(--accent); margin-bottom: 8px; text-shadow: 0 0 24px var(--accent); }
.cert-front h3 {
  font-size: 1rem; margin-bottom: 4px; line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.cert-issuer { color: var(--text); font-size: 0.82rem; }
.cert-date { color: var(--accent); font-size: 9px; letter-spacing: 2px; margin: 8px 0 10px; }
.cert-desc {
  font-size: 0.73rem; line-height: 1.55; max-width: 340px;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
}
.cert-flip-hint { margin-top: 12px; font-size: 8px; letter-spacing: 2px; color: var(--text-dim); opacity: 0.7; }
/* narrow: drop the 3+2 shape and wrap into comfortable columns */
@media (max-width: 1350px) {
  .certs-grid { grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 20px; }
  .cert-card, .cert-card:nth-child(4) { grid-column: auto; }
}
.cert-back img { width: 100%; height: 100%; object-fit: cover; }
/* PDF-sourced certificates: show the full page and let the card's
   background (set inline, matched to the certificate color) fill the rest */
.cert-back-fill img { object-fit: contain; }
.cert-img-ph {
  width: 100%; height: 100%; border-radius: 12px;
  border: 1px dashed var(--glass-border);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
  background: radial-gradient(circle at 50% 40%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 70%);
}
.cert-img-ph .mono { font-size: 10px; letter-spacing: 4px; color: var(--text-dim); }

/* Registry ledger: console-style totals line under the section title */
.cert-ledger {
  display: flex; align-items: center; flex-wrap: wrap; gap: 14px;
  margin: -14px 0 36px;
  font-size: 10px; letter-spacing: 2px; color: var(--text-dim);
}
.cert-led {
  width: 7px; height: 7px; border-radius: 50%;
  background: #7dffa8; box-shadow: 0 0 10px #7dffa8;
  animation: pulseDot 1.6s ease-in-out infinite;
}
.cert-ledger b { color: var(--accent); font-weight: 500; }
.ledger-sep { opacity: 0.4; }
.ledger-status {
  margin-left: auto; color: #7dffa8;
  border: 1px solid color-mix(in srgb, #7dffa8 35%, transparent);
  border-radius: 999px; padding: 6px 14px;
}
@media (max-width: 700px) { .ledger-status { margin-left: 0; } }

/* Scanner beam: sweeps the grid once on entrance, "activating" each card */
.certs-wrap { position: relative; }
.certs-beam {
  position: absolute; top: -18px; bottom: -18px; left: -3%;
  width: 3px; z-index: 2; pointer-events: none; opacity: 0;
  background: linear-gradient(to bottom, transparent, var(--accent) 50%, transparent);
  box-shadow: 0 0 22px var(--accent);
}
/* activation flash as the beam passes over a card */
.cert-card.is-scanned .cert-front {
  border-color: var(--accent);
  box-shadow: 0 0 38px -10px var(--accent);
}

/* HUD corner brackets that flare out on hover (same language as the lab cards) */
.cert-card { position: relative; }
.cert-card::before, .cert-card::after {
  content: ''; position: absolute; width: 14px; height: 14px;
  z-index: 1; opacity: 0.45; pointer-events: none;
  transition: all 0.35s ease;
}
.cert-card::before { top: -5px; left: -5px; border-top: 2px solid var(--accent); border-left: 2px solid var(--accent); }
.cert-card::after { bottom: -5px; right: -5px; border-bottom: 2px solid var(--accent); border-right: 2px solid var(--accent); }
.cert-card:hover::before, .cert-card:hover::after { width: 26px; height: 26px; opacity: 1; }
.cert-card:hover .cert-back { box-shadow: 0 0 44px -12px var(--accent); }

/* registry ID tag (text filled in by JS: CRT-001 …) */
.cert-id {
  position: absolute; top: 14px; left: 16px;
  font-size: 8px; letter-spacing: 2px; color: var(--text-dim); opacity: 0.85;
}

/* verified seal: static check inside a slowly rotating dashed ring */
.cert-seal {
  position: absolute; top: 10px; right: 12px;
  width: 28px; height: 28px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; color: #7dffa8;
}
.cert-seal::before {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  border: 1px dashed color-mix(in srgb, var(--accent) 70%, transparent);
  animation: spin 10s linear infinite;
}

/* idle heartbeat on the diamond so the wall never sits perfectly still */
.cert-icon { animation: certPulse 3.2s ease-in-out infinite; }
.cert-card:nth-child(2n) .cert-icon { animation-delay: 0.7s; }
.cert-card:nth-child(3n) .cert-icon { animation-delay: 1.4s; }
@keyframes certPulse {
  0%, 100% { transform: scale(1); text-shadow: 0 0 24px var(--accent); }
  50% { transform: scale(1.18); text-shadow: 0 0 40px var(--accent); }
}

/* zoom hint pinned to the revealed certificate (injected by JS) */
.cert-zoom-hint {
  position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%);
  font-size: 8px; letter-spacing: 2px; white-space: nowrap; color: #fff;
  background: rgba(5, 1, 15, 0.7); border: 1px solid var(--glass-border);
  border-radius: 999px; padding: 5px 12px;
  opacity: 0; transition: opacity 0.3s ease 0.4s;
}
.cert-card:hover .cert-zoom-hint, .cert-card.is-flipped .cert-zoom-hint { opacity: 1; }

/* touch devices: tap flips the card (JS toggles the class) */
.cert-card.is-flipped .cert-inner { transform: rotateY(180deg); }

/* ---------- Certificate lightbox ---------- */
.cert-lightbox {
  position: fixed; inset: 0; z-index: 80;
  display: flex; align-items: center; justify-content: center;
  padding: 5vmin; visibility: hidden;
}
.cert-lightbox.open { visibility: visible; }
.cert-lightbox-backdrop {
  position: absolute; inset: 0;
  background: rgba(3, 0, 12, 0.85);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.cert-lightbox-frame { position: relative; max-width: min(1000px, 92vw); }
.cert-lightbox-frame img {
  display: block; width: 100%; max-height: 76vh; object-fit: contain;
  border-radius: 14px; border: 1px solid color-mix(in srgb, var(--accent) 60%, transparent);
  box-shadow: 0 0 90px -20px var(--accent);
  background: rgba(13, 10, 26, 0.9);
}
.cert-lightbox-cap {
  margin-top: 14px; text-align: center;
  font-size: 10px; letter-spacing: 3px; color: var(--text-dim);
}
.cert-lightbox-close {
  position: absolute; top: -16px; right: -16px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 2px;
  color: var(--text); background: rgba(13, 10, 26, 0.95);
  border: 1px solid var(--accent); border-radius: 999px;
  padding: 10px 16px; cursor: none;
  transition: background 0.3s ease, color 0.3s ease;
}
.cert-lightbox-close:hover { background: var(--accent); color: #fff; }
.clb-corner { position: absolute; width: 26px; height: 26px; opacity: 0.9; }
.clb-tl { top: -9px; left: -9px; border-top: 2px solid var(--accent); border-left: 2px solid var(--accent); }
.clb-tr { top: -9px; right: -9px; border-top: 2px solid var(--accent); border-right: 2px solid var(--accent); }
.clb-bl { bottom: -9px; left: -9px; border-bottom: 2px solid var(--accent); border-left: 2px solid var(--accent); }
.clb-br { bottom: -9px; right: -9px; border-bottom: 2px solid var(--accent); border-right: 2px solid var(--accent); }

@media (prefers-reduced-motion: reduce) {
  .cert-led, .cert-icon, .cert-seal::before { animation: none; }
  .certs-beam { display: none; }
}

/* ---------- Short films: cinematic panels ---------- */
.films-intro {
  font-size: 1.05rem; color: var(--text-dim);
  max-width: 780px;
  margin: -24px 0 44px;
}
.film-card {
  display: grid;
  grid-template-columns: 340px 1fr 1.05fr;
  margin-bottom: 48px;
  border: 1px solid var(--glass-border);
  border-radius: 24px; overflow: hidden;
  background: var(--glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  transition: border-color 0.4s ease, box-shadow 0.4s ease;
}
.film-card:hover { border-color: var(--accent); box-shadow: 0 0 60px -18px var(--accent); }
/* poster shows in full at column width; card height follows the poster */
.film-poster { position: relative; display: flex; align-items: center; overflow: hidden; border-right: 1px solid var(--glass-border); }
.film-poster img { width: 100%; height: auto; display: block; }
.poster-ph {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
  background:
    repeating-linear-gradient(0deg, transparent 0 46px, rgba(255, 255, 255, 0.035) 46px 48px),
    radial-gradient(circle at 50% 30%, color-mix(in srgb, var(--accent) 20%, transparent), transparent 65%),
    linear-gradient(160deg, rgba(255, 255, 255, 0.04), rgba(0, 0, 0, 0.4));
}
.poster-glyph { font-size: 3.6rem; }
.poster-ph .mono { font-size: 10px; letter-spacing: 4px; color: var(--text-dim); }
.film-info { padding: 48px; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; }
.film-meta { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 20px; }
.film-badge {
  font-size: 10px; letter-spacing: 2px; color: var(--accent);
  border: 1px solid var(--glass-border); padding: 7px 14px; border-radius: 999px;
}
.film-info h3 { font-size: clamp(1.7rem, 3vw, 2.4rem); margin-bottom: 16px; }
.film-desc { margin-bottom: 28px; }
.film-btn { font-size: 12px; padding: 14px 28px; }
.film-trailer { padding: 32px; display: flex; align-items: center; }
.film-trailer iframe, .trailer-ph {
  width: 100%; aspect-ratio: 16 / 9;
  border-radius: 14px;
  border: 1px solid var(--glass-border);
}
.trailer-ph {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
  background: radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--accent) 12%, transparent), rgba(0, 0, 0, 0.35) 75%);
  transition: border-color 0.3s ease;
}
.trailer-ph:hover { border-color: var(--accent); }
.play-icon {
  width: 64px; height: 64px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--accent); color: var(--accent); font-size: 1.2rem;
  padding-left: 4px;
  box-shadow: 0 0 24px -6px var(--accent);
  animation: orbPulse 3s ease-in-out infinite;
}
.trailer-ph .mono { font-size: 10px; letter-spacing: 4px; color: var(--text-dim); }

/* ---------- Skills: SKILL BAY — a ship-systems console. Category "racks"
   on the left select which system the display panel shows; chips warp in
   with a scanline sweep. Every chip is identical on purpose: a toolkit,
   not a leaderboard. ---------- */

/* registry ledger above the console */
.skillbay-ledger {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  font-size: 11px; letter-spacing: 3px; color: var(--text-dim);
  margin-bottom: 26px;
}
.skillbay-ledger b { color: var(--text); font-weight: 500; }
.skillbay-led {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 10px var(--accent);
  animation: skillbayLed 2.2s ease-in-out infinite;
}
@keyframes skillbayLed { 50% { opacity: 0.35; box-shadow: 0 0 3px var(--accent); } }
.skillbay-ledger-note { margin-left: auto; font-size: 10px; opacity: 0.75; }

/* console frame: dark glass so the 3D scenery behind never washes out
   the readouts */
.skillbay {
  display: grid;
  grid-template-columns: 290px 1fr;
  border: 1px solid var(--glass-border);
  background: rgba(5, 1, 15, 0.78);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
  margin-bottom: 64px;
}

/* --- left: system racks (tabs) --- */
.skillbay-tabs {
  display: flex; flex-direction: column;
  border-right: 1px solid var(--glass-border);
  scrollbar-width: none;
}
.skillbay-tabs::-webkit-scrollbar { display: none; }
.skillbay-tab {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center; gap: 12px;
  padding: 22px 20px;
  text-align: left;
  background: transparent; border: none;
  border-bottom: 1px solid var(--glass-border);
  color: var(--text-dim);
  font-family: var(--font-main);
  cursor: none;
  overflow: hidden;
  transition: color 0.3s ease, background 0.3s ease, padding-left 0.3s ease;
}
.skillbay-tab:last-child { border-bottom: none; }
.skillbay-tab::before {
  /* accent spine that grows in when the rack is live */
  content: '';
  position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--accent);
  transform: scaleY(0);
  transition: transform 0.35s cubic-bezier(0.68, -0.55, 0.27, 1.55);
}
.skillbay-tab:hover { color: var(--text); background: var(--glass); padding-left: 26px; }
.skillbay-tab.is-live {
  color: #fff; background: linear-gradient(90deg, rgba(255,255,255,0.05), transparent 75%);
}
.skillbay-tab.is-live::before { transform: scaleY(1); }
.sbt-idx { font-family: var(--font-mono); font-size: 10px; letter-spacing: 2px; color: var(--accent); }
.sbt-name { font-size: 0.95rem; font-weight: 600; letter-spacing: 0.4px; }
.sbt-count {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 1px;
  color: var(--text-dim);
  border: 1px solid var(--glass-border); border-radius: 100px;
  padding: 3px 8px;
  transition: color 0.3s ease, border-color 0.3s ease;
}
.skillbay-tab.is-live .sbt-count { color: var(--accent); border-color: var(--accent); }
.sbt-progress {
  position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  pointer-events: none;
}
.sbt-progress i {
  position: absolute; inset: 0;
  background: linear-gradient(90deg, var(--accent), transparent);
  transform: scaleX(0); transform-origin: left;
}

/* --- right: display panel --- */
.skillbay-panel {
  position: relative;
  padding: 30px 36px 58px;
  min-height: 340px;
  overflow: hidden;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.025) 1px, transparent 1px);
  background-size: 44px 44px;
}
.sb-corner {
  position: absolute; width: 16px; height: 16px;
  border: 1px solid var(--accent); opacity: 0.7; z-index: 2;
}
.sb-tl { top: 10px; left: 10px; border-right: none; border-bottom: none; }
.sb-tr { top: 10px; right: 10px; border-left: none; border-bottom: none; }
.sb-bl { bottom: 10px; left: 10px; border-right: none; border-top: none; }
.sb-br { bottom: 10px; right: 10px; border-left: none; border-top: none; }

.skillbay-head {
  display: flex; align-items: baseline; gap: 16px;
  font-size: 12px; letter-spacing: 2px;
  margin-bottom: 30px;
  min-height: 1.4em;
}
.sb-cat-line { color: var(--text); }
.sb-cat-line b { color: var(--accent); font-weight: 500; }
.sb-cat-count { margin-left: auto; font-size: 10px; color: var(--text-dim); white-space: nowrap; }

/* the scatter field: nodes are positioned absolutely at randomized spots
   (main.js re-rolls them every render), so neither order nor placement can
   be read as a ranking. Falls back to .is-flow rows on narrow panels. */
.skillbay-chips {
  position: relative; z-index: 1;
  height: 350px;
}
.skillbay-chips.is-flow {
  height: auto; min-height: 170px;
  display: flex; flex-wrap: wrap; align-content: flex-start;
  gap: 16px 22px;
}
.skillbay-chips.is-flow .skill-node { position: static; }

.skill-node {
  position: absolute;
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-mono);
  font-size: 1.02rem; font-weight: 500; letter-spacing: 0.3px;
  color: var(--text);
  white-space: nowrap;
  z-index: 2;
}
.node-dot {
  width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0;
  background: var(--accent);
  box-shadow: 0 0 12px var(--accent);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.node-label {
  position: relative;
  padding: 2px 10px;
  transition: color 0.25s ease, text-shadow 0.25s ease;
}
/* targeting brackets close around the hovered star */
.node-label::before,
.node-label::after {
  position: absolute; top: 50%;
  font-size: 13px; color: var(--accent); opacity: 0;
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.node-label::before { content: '['; left: -2px; transform: translateY(-50%) translateX(-6px); }
.node-label::after  { content: ']'; right: -2px; transform: translateY(-50%) translateX(6px); }
.skill-node:hover .node-label { color: #fff; text-shadow: 0 0 16px var(--accent); }
.skill-node:hover .node-dot { transform: scale(1.6); box-shadow: 0 0 18px var(--accent); }
.skill-node:hover .node-label::before,
.skill-node:hover .node-label::after { opacity: 1; transform: translateY(-50%) translateX(0); }

/* constellation threads between neighbouring nodes (endpoints tracked
   per-frame in main.js so they ride along with the drift + magnet pulls) */
.skillbay-lines {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%;
  pointer-events: none;
  overflow: visible;
}
.skillbay-lines line {
  stroke: var(--accent); stroke-width: 1; opacity: 0.16;
  transition: opacity 0.25s ease;
}

.sb-rescatter {
  margin-left: auto;
  background: none;
  border: 1px solid var(--glass-border);
  color: var(--text-dim);
  font-size: 9px; letter-spacing: 2px;
  padding: 5px 10px;
  cursor: none;
  transition: color 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}
.sb-rescatter:hover {
  color: #fff; border-color: var(--accent);
  box-shadow: 0 0 14px -4px var(--accent);
}

/* scanline that sweeps the panel on every system switch */
.skillbay-scan {
  position: absolute; left: 0; right: 0; top: -3px; height: 3px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  box-shadow: 0 0 18px var(--accent);
  opacity: 0; pointer-events: none; z-index: 3;
}

.skillbay-foot {
  position: absolute; left: 36px; right: 36px; bottom: 16px;
  display: flex; align-items: center; gap: 8px;
  font-size: 9px; letter-spacing: 2px; color: var(--text-dim);
  opacity: 0.8;
}
.skillbay-foot .caret { font-size: 10px; }

/* Marquee strip */
.marquee {
  overflow: hidden; white-space: nowrap;
  border-top: 1px solid var(--glass-border);
  border-bottom: 1px solid var(--glass-border);
  padding: 22px 0;
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.marquee-track {
  display: inline-block;
  animation: marquee 22s linear infinite;
}
.marquee:hover .marquee-track { animation-play-state: paused; }
.marquee-track span {
  font-family: var(--font-mono); font-size: 1.1rem; letter-spacing: 4px;
  color: var(--text-dim); margin: 0 28px;
}
.marquee-track span:nth-child(even) { color: var(--accent); font-size: 0.8rem; }
@keyframes marquee { to { transform: translateX(-50%); } }

/* ---------- Projects: "the deck" — a manifest rail + one fixed-height stage.
     Every project after the first is free vertical space: the rail scrolls,
     the stage never grows. ---------- */
.deck {
  --deck-h: clamp(470px, 62vh, 600px);
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 20px;
  align-items: stretch;
}

/* --- left: the manifest --- */
.deck-rail {
  height: var(--deck-h);
  display: flex; flex-direction: column;
  padding: 16px 12px;
  border: 1px solid var(--glass-border);
  border-radius: 20px;
  background: var(--glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  overflow: hidden;
}
.deck-rail-head {
  flex-shrink: 0;
  display: flex; justify-content: space-between; align-items: center;
  padding: 0 8px 12px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--glass-border);
  font-size: 9px; letter-spacing: 3px; color: var(--text-dim);
}
.deck-count { color: var(--accent); }

.deck-tabs {
  position: relative;
  flex: 1; min-height: 0;
  display: flex; flex-direction: column; gap: 4px;
  overflow-y: auto; overflow-x: hidden;
  padding-right: 4px;
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--accent) 50%, transparent) transparent;
}
.deck-tabs::-webkit-scrollbar { width: 4px; }
.deck-tabs::-webkit-scrollbar-track { background: transparent; }
.deck-tabs::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--accent) 50%, transparent);
  border-radius: 999px;
}

/* the highlight is one element that slides between rows, not a class swap —
   it reads as a selector travelling down the list */
.deck-marker {
  position: absolute; left: 0; right: 4px;
  top: 0; height: 0;
  border-radius: 13px;
  border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
  background: color-mix(in srgb, var(--accent) 13%, transparent);
  box-shadow: 0 0 30px -12px var(--accent), inset 0 0 22px -14px var(--accent);
  pointer-events: none;
  transition: top 0.45s cubic-bezier(0.22, 1, 0.36, 1),
              height 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
.deck-marker::before {
  content: '';
  position: absolute; left: -1px; top: 22%; bottom: 22%;
  width: 2px; border-radius: 2px;
  background: var(--accent);
  box-shadow: 0 0 12px var(--accent);
}

.deck-tab {
  position: relative; z-index: 1; flex-shrink: 0;
  display: flex; align-items: center; gap: 11px;
  width: 100%;
  padding: 9px 11px;
  border: 1px solid transparent; border-radius: 13px;
  background: none; color: inherit;
  font-family: inherit; text-align: left;
  cursor: none;
  transition: transform 0.35s ease;
}
.deck-tab:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
.deck-tab:hover { transform: translateX(3px); }
/* Wordmark tile: the project's own UI background with its own brand colour
   on top. Dimmed until the row is live, so the rail reads as one list rather
   than five competing logos. The mark auto-shrinks to fit via a font-size
   that scales with the tile, and clamps to one line. */
.deck-tab-tile {
  --brand-bg: #12101c;
  --brand-fg: #ffffff;
  flex-shrink: 0;
  width: 54px; height: 34px;
  display: grid; place-items: center;
  padding: 0 5px;
  border-radius: 7px; overflow: hidden;
  border: 1px solid var(--glass-border);
  background: var(--brand-bg);
  opacity: 0.5; filter: saturate(0.55);
  transition: opacity 0.4s ease, filter 0.4s ease,
              border-color 0.4s ease, transform 0.4s ease;
}
.deck-tab-tile b {
  display: block; max-width: 100%;
  font-size: 9.5px; font-weight: 700; letter-spacing: -0.2px;
  line-height: 1;
  color: var(--brand-fg);
  white-space: nowrap; overflow: hidden; text-overflow: clip;
}
.deck-tab-tile.is-mono b {
  font-family: var(--font-mono);
  font-size: 8px; font-weight: 500; letter-spacing: 0.4px;
}
.deck-tab:hover .deck-tab-tile,
.deck-tab.is-active .deck-tab-tile {
  opacity: 1; filter: none;
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
}
.deck-tab.is-active .deck-tab-tile { transform: scale(1.04); }
.deck-tab-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.deck-tab-name,
.deck-tab-stack { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.deck-tab-name {
  font-size: 0.92rem; font-weight: 500;
  color: var(--text-dim);
  transition: color 0.35s ease;
}
.deck-tab:hover .deck-tab-name,
.deck-tab.is-active .deck-tab-name { color: #fff; }
.deck-tab-stack {
  font-size: 8.5px; letter-spacing: 1.6px;
  color: var(--text-dim); opacity: 0.7;
  transition: color 0.35s ease, opacity 0.35s ease;
}
.deck-tab.is-active .deck-tab-stack { color: var(--accent); opacity: 1; }

.deck-hint {
  flex-shrink: 0;
  margin-top: 10px; padding-top: 11px;
  border-top: 1px solid var(--glass-border);
  font-size: 8px; letter-spacing: 2.5px; color: var(--text-dim);
  text-align: center; opacity: 0.7;
}

/* --- right: the stage --- */
.deck-stage {
  position: relative;
  height: var(--deck-h);
  display: grid; grid-template-rows: auto 1fr;
  border: 1px solid var(--glass-border);
  border-radius: 20px;
  overflow: hidden;
  background: var(--glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  transition: border-color 0.4s ease, box-shadow 0.4s ease;
}
.deck-stage:hover {
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  box-shadow: 0 0 70px -22px var(--accent);
}

.deck-bar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 11px 16px;
  border-bottom: 1px solid var(--glass-border);
  background: rgba(0, 0, 0, 0.25);
  font-size: 10px; letter-spacing: 3px; color: var(--text-dim);
}
.deck-index { color: var(--accent); }
.deck-nav { display: flex; gap: 7px; }
.deck-arrow {
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border: 1px solid var(--glass-border); border-radius: 8px;
  background: transparent; color: var(--text-dim);
  font-family: inherit; font-size: 12px; line-height: 1;
  cursor: none;
  transition: all 0.3s ease;
}
.deck-arrow:hover {
  color: #fff;
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  box-shadow: 0 0 18px -6px var(--accent);
}
.deck-arrow:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }

.deck-frames { position: relative; min-height: 0; }
.deck-panel {
  position: absolute; inset: 0;
  display: grid; grid-template-columns: 1.35fr 1fr;
  opacity: 0; visibility: hidden;
}
.deck-panel.is-active { opacity: 1; visibility: visible; }

.deck-shot {
  position: relative; overflow: hidden;
  display: grid; place-items: center;
  padding: 26px; min-width: 0;
  background:
    radial-gradient(circle at 30% 30%, color-mix(in srgb, var(--accent) 16%, transparent), transparent 65%),
    rgba(0, 0, 0, 0.25);
}
.deck-shot .browser-mock { width: 100%; max-height: 100%; }
.deck-shot .browser-body { min-height: 0; }

/* the info column reuses .project-info's typography; the double class keeps
   these overrides ahead of it no matter which block is declared first */
.project-info.deck-info {
  padding: 30px 34px;
  border-left: 1px solid var(--glass-border);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--accent) 40%, transparent) transparent;
}
.deck-info::-webkit-scrollbar { width: 4px; }
.deck-info::-webkit-scrollbar-track { background: transparent; }
.deck-info::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--accent) 40%, transparent);
  border-radius: 999px;
}
.project-info.deck-info h3 { font-size: clamp(1.35rem, 2vw, 1.95rem); margin-bottom: 14px; }
.project-info.deck-info > p { font-size: 0.95rem; margin-bottom: 22px; }
.deck-info .project-num { margin-bottom: 14px; }
.deck-info .project-tags { gap: 8px; margin-bottom: 22px; }
.deck-info .project-tags span { font-size: 9px; padding: 5px 12px; }
.deck-info .project-links { gap: 22px; }

/* Browser-window mockup: keeps the screenshot from clashing with the site's
   glowing/glass look — it reads as "a website", not a raw cropped image.
   No rotateX/rotateY here on purpose: any perspective rotation foreshortens
   one edge and the window stops reading as a window. It stays a true
   rectangle and moves by drift + glare instead (driven from main.js). */
.browser-mock {
  position: relative;
  width: 100%; height: auto;
  display: flex; flex-direction: column;
  border-radius: 14px; overflow: hidden;
  background: rgba(10, 7, 20, 0.85);
  border: 1px solid var(--glass-border);
  box-shadow: 0 30px 60px -25px rgba(0, 0, 0, 0.6), 0 0 50px -20px var(--accent);
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 0.5s ease, border-color 0.4s ease;
  will-change: transform;
}
/* a soft light that tracks the cursor across the glass — the motion people
   read as "3D" without a single degree of rotation */
.browser-mock::after {
  content: '';
  position: absolute; inset: 0; z-index: 2;
  border-radius: inherit; pointer-events: none;
  background: radial-gradient(circle 240px at var(--gx, 50%) var(--gy, -40%),
    rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0.04) 45%, transparent 72%);
  opacity: 0; transition: opacity 0.4s ease;
}
.deck-stage:hover .browser-mock {
  border-color: color-mix(in srgb, var(--accent) 50%, var(--glass-border));
  box-shadow: 0 36px 70px -26px rgba(0, 0, 0, 0.7), 0 0 64px -20px var(--accent);
}
.deck-stage:hover .deck-panel.is-active .browser-mock::after { opacity: 1; }
.browser-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 11px 14px;
  background: rgba(0, 0, 0, 0.35);
  border-bottom: 1px solid var(--glass-border);
  flex-shrink: 0;
}
.browser-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.browser-dot.dot-red { background: #ff5f57; }
.browser-dot.dot-yellow { background: #febc2e; }
.browser-dot.dot-green { background: #28c840; }
.browser-url {
  margin: 0 auto; max-width: 72%;
  font-size: 10px; letter-spacing: 0.5px; color: var(--text-dim);
  background: rgba(255, 255, 255, 0.05);
  border-radius: 999px; padding: 5px 16px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* the mock sizes itself to the screenshot — full image, nothing cropped */
.browser-body { position: relative; overflow: hidden; }
.browser-body img { width: 100%; height: auto; display: block; }

.project-info {
  display: flex; flex-direction: column; justify-content: center;
  padding: 52px 56px;
}
.project-num { font-size: 11px; letter-spacing: 4px; color: var(--accent); margin-bottom: 18px; }
.project-info h3 { font-size: clamp(1.7rem, 3.4vw, 2.5rem); margin-bottom: 18px; letter-spacing: -0.5px; }
.project-info > p { font-size: 1rem; margin-bottom: 28px; }
.project-tags { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 28px; }
.project-tags span {
  font-size: 10px; letter-spacing: 1px; color: var(--accent);
  border: 1px solid var(--glass-border); padding: 6px 14px; border-radius: 999px;
}
.project-links { display: flex; gap: 28px; }
.project-links a {
  color: var(--text); text-decoration: none;
  font-size: 12px; letter-spacing: 2px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--glass-border);
  transition: all 0.3s;
}
.project-links a:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* ---------- Interests: expanding vertical slabs ---------- */
.interests-strip {
  display: flex; gap: 16px;
  height: 340px;
}
.interests-strip-2 { margin-top: 16px; }
.interest-panel {
  flex: 1;
  position: relative;
  border: 1px solid var(--glass-border);
  border-radius: 20px;
  background: var(--glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  padding: 24px 20px;
  transition: flex 0.55s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.4s, box-shadow 0.4s;
}
.interest-panel:hover {
  flex: 2.4;
  border-color: var(--accent);
  box-shadow: 0 0 50px -16px var(--accent);
}
/* full-bleed artwork; dimmed until hover */
.interest-art {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0.8; filter: saturate(0.9);
  transition: opacity 0.55s ease, filter 0.55s ease, transform 0.55s ease;
}
.interest-panel:hover .interest-art { opacity: 1; filter: saturate(1.05); transform: scale(1.04); }
/* darkening gradient so the caption stays readable over the art */
.interest-panel::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(5, 3, 12, 0.88) 0%, rgba(5, 3, 12, 0.35) 34%, transparent 62%);
  pointer-events: none;
}
.interest-num {
  position: absolute; top: 20px; left: 24px; z-index: 2;
  font-size: 11px; letter-spacing: 3px; color: rgba(255, 255, 255, 0.75);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.8);
}
.interest-body {
  position: relative; z-index: 2;
  text-align: center;
  max-width: 280px;
}
.interest-body h3 { font-size: 1.2rem; margin: 0 0 8px; color: #fff; text-shadow: 0 0 18px var(--accent); }
.interest-body p {
  font-size: 0.85rem; line-height: 1.5;
  max-height: 0; opacity: 0; overflow: hidden; transform: translateY(12px);
  transition: max-height 0.5s ease, opacity 0.4s ease 0.12s, transform 0.4s ease 0.12s;
}
.interest-panel:hover .interest-body p { max-height: 120px; opacity: 1; transform: translateY(0); }

/* ---------- Contact: comms console ---------- */
/* comms console: two-column mission-control layout */
.contact-lead { max-width: 560px; }
.contact-console {
  display: grid; grid-template-columns: 1.08fr 0.92fr; gap: 44px;
  align-items: stretch; margin-top: 10px;
}
.contact-left { min-width: 0; }

/* live status chips */
.contact-status {
  display: flex; flex-wrap: wrap; gap: 12px;
  margin-top: 28px;
}

/* email CTA + copy */
.contact-email-row {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 14px;
}
.copy-btn { font-size: 12px; padding: 16px 26px; cursor: none; }
.copy-btn.copied { border-color: #7dffa8; color: #7dffa8; box-shadow: 0 0 22px -8px #7dffa8; }

/* comm channel cards: stacked rail under the CTA */
.comm-grid {
  display: grid; grid-template-columns: 1fr; gap: 14px;
  max-width: 560px;
}
.comm-card {
  display: flex; align-items: center; gap: 16px; text-align: left;
  min-width: 0; /* let the handle line ellipsize instead of widening the grid */
  padding: 20px 22px; border-radius: 16px;
  border: 1px solid var(--glass-border);
  background: var(--glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  text-decoration: none; color: var(--text);
  transition: border-color 0.35s ease, box-shadow 0.35s ease, transform 0.35s ease;
}
.comm-card:hover {
  border-color: var(--accent);
  box-shadow: 0 0 40px -14px var(--accent);
  transform: translateY(-4px);
}
.comm-icon {
  flex-shrink: 0; width: 42px; height: 42px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--glass-border);
  color: var(--accent);
  transition: all 0.35s ease;
}
.comm-icon svg { width: 18px; height: 18px; fill: currentColor; }
.comm-card:hover .comm-icon {
  background: var(--accent); color: #fff;
  border-color: var(--accent);
  box-shadow: 0 0 18px var(--accent);
}
.comm-info { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.comm-info b { font-size: 0.95rem; letter-spacing: 1px; }
.comm-info .mono {
  font-size: 10px; letter-spacing: 1px; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.comm-arrow {
  margin-left: auto; color: var(--accent); font-size: 1.1rem;
  opacity: 0.4;
  transition: opacity 0.3s ease, transform 0.3s ease;
}
.comm-card:hover .comm-arrow { opacity: 1; transform: translate(3px, -3px); }

/* ---------- Uplink terminal ---------- */
.contact-terminal {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column;
  border: 1px solid var(--glass-border); border-radius: 20px;
  background: rgba(13, 10, 26, 0.78);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 0 70px -34px var(--accent);
  transition: border-color 0.35s ease, box-shadow 0.35s ease;
}
.contact-terminal:hover {
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  box-shadow: 0 0 70px -22px var(--accent);
}
/* faint CRT scanlines over the whole panel */
.contact-terminal::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(0deg, transparent 0 3px, rgba(255, 255, 255, 0.016) 3px 4px);
}
.term-bar {
  display: flex; align-items: center; gap: 7px;
  padding: 14px 18px; border-bottom: 1px solid var(--glass-border);
  font-size: 9px; letter-spacing: 2px; color: var(--text-dim);
}
.term-dot { width: 10px; height: 10px; border-radius: 50%; }
.td-r { background: #ff5f57; } .td-y { background: #febc2e; } .td-g { background: #28c840; }
.term-title { margin-left: 8px; }
/* live signal meter: bars pulse at different phases */
.term-signal { margin-left: auto; display: flex; align-items: flex-end; gap: 3px; height: 14px; }
.term-signal i {
  width: 3px; height: 100%; border-radius: 1px;
  background: var(--accent); transform-origin: bottom;
  animation: sigBar 1.15s ease-in-out infinite;
}
.term-signal i:nth-child(2) { animation-delay: 0.18s; }
.term-signal i:nth-child(3) { animation-delay: 0.36s; }
.term-signal i:nth-child(4) { animation-delay: 0.54s; }
.term-signal i:nth-child(5) { animation-delay: 0.72s; }
@keyframes sigBar { 0%, 100% { transform: scaleY(0.3); } 50% { transform: scaleY(1); } }
.term-body {
  flex: 1; min-height: 250px; padding: 22px 20px;
  font-size: 11.5px; line-height: 2.15; letter-spacing: 1px; color: var(--text);
  text-align: left;
}
.term-line { display: block; white-space: pre-wrap; word-break: break-word; }
.term-line b { color: var(--accent); font-weight: 500; margin-right: 9px; }
.term-line.t-dim { color: var(--text-dim); }
.term-caret {
  display: inline-block; width: 7px; height: 13px;
  background: var(--accent); box-shadow: 0 0 10px var(--accent);
  margin-left: 6px; vertical-align: -2px;
  animation: blink 1s steps(1) infinite;
}
.term-foot {
  display: flex; align-items: center; gap: 18px;
  padding: 14px 20px; border-top: 1px dashed var(--glass-border);
}
.radar.radar-mini { width: 72px; height: 72px; flex-shrink: 0; }
.radar-mini .radar-ring.rr-2 { inset: 12px; }
.radar-mini .radar-ring.rr-3 { inset: 24px; }

/* ---------- Signature outro: giant stroked name ---------- */
.contact-sign { margin-top: 76px; text-align: center; }
.sign-eyebrow { display: block; font-size: 9px; letter-spacing: 5px; color: var(--text-dim); margin-bottom: 16px; }
.sign-name {
  font-size: clamp(2.6rem, 8.5vw, 7.5rem);
  font-weight: 700; line-height: 1; letter-spacing: 4px;
  color: transparent;
  -webkit-text-stroke: 1.5px color-mix(in srgb, var(--accent) 60%, transparent);
  user-select: none; cursor: none;
}
.sign-name .sn { display: inline-block; transition: color 0.25s ease, text-shadow 0.25s ease; }
.sign-name .sn:hover { color: var(--accent); text-shadow: 0 0 44px var(--accent); }
.sign-role { display: block; margin-top: 18px; font-size: 10px; letter-spacing: 4px; color: var(--text-dim); }

/* scanning radar (lives in the terminal footer) */
.radar { position: relative; width: 132px; height: 132px; }
.radar::before, .radar::after {
  content: ''; position: absolute;
  background: color-mix(in srgb, var(--accent) 18%, transparent);
}
.radar::before { left: 50%; top: 0; bottom: 0; width: 1px; }
.radar::after { top: 50%; left: 0; right: 0; height: 1px; }
.radar-ring {
  position: absolute; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
}
.rr-1 { inset: 0; }
.rr-2 { inset: 22px; }
.rr-3 { inset: 44px; }
.radar-sweep {
  position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(from 0deg,
    color-mix(in srgb, var(--accent) 50%, transparent), transparent 80deg);
  animation: radarSpin 3.2s linear infinite;
}
@keyframes radarSpin { to { transform: rotate(360deg); } }
.radar-pulse {
  position: absolute; inset: 0; border-radius: 50%;
  border: 1px solid var(--accent);
  animation: radarPulse 2.8s ease-out infinite;
}
@keyframes radarPulse {
  0% { transform: scale(0.15); opacity: 0.9; }
  100% { transform: scale(1.03); opacity: 0; }
}
.radar-blip {
  position: absolute; width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 10px var(--accent);
  animation: blipBlink 3.2s ease-in-out infinite;
}
.rb-1 { left: 28%; top: 34%; }
.rb-2 { left: 68%; top: 22%; animation-delay: 1.1s; }
.rb-3 { left: 58%; top: 66%; animation-delay: 2.2s; }
@keyframes blipBlink { 0%, 14% { opacity: 1; } 32%, 100% { opacity: 0.15; } }
.radar-label { font-size: 9px; letter-spacing: 3px; color: var(--text-dim); }

#contact footer { position: absolute; bottom: 24px; left: 0; right: 0; text-align: center; }
#contact footer span { font-size: 10px; letter-spacing: 2px; color: var(--text-dim); opacity: 0.6; }

@media (max-width: 900px) {
  .contact-console { grid-template-columns: 1fr; gap: 36px; }
  .comm-grid { max-width: 100%; }
  .contact-sign { margin-top: 56px; }
  .sign-name { letter-spacing: 2px; }
}

/* ---------- Hero photo: desktop sits it beside the text, mobile stacks above ---------- */
@media (min-width: 901px) {
  .hero-inner {
    display: flex;
    flex-direction: row-reverse;
    align-items: center;
    justify-content: space-between;
    gap: 56px;
  }
  .hero-text { flex: 1; min-width: 0; }
  /* the current portrait is a tighter crop than the old one (0.88 aspect vs
     0.75), so it needs more width to read at the same size on the page.
     The 300px floor is load-bearing: any wider and the text column narrows
     enough to break "HASSAN" across two lines around 960px. */
  .hero-photo { width: clamp(300px, 31vw, 530px); flex-shrink: 0; margin: 0 3vw 0 0; }
}

/* ---------- Responsive ---------- */
@media (max-width: 1350px) {
  .film-card { grid-template-columns: 300px 1fr; }
  .film-trailer { grid-column: 1 / -1; padding-top: 0; }
}
/* ---------- Laptop widths: the rail gives 50px back to the stage and the
     write-up tightens, so the info column doesn't start scrolling ---------- */
@media (max-width: 1400px) {
  .deck { grid-template-columns: 268px 1fr; gap: 16px; }
  .project-info.deck-info { padding: 24px 26px; }
  .project-info.deck-info h3 { font-size: 1.3rem; margin-bottom: 12px; }
  .project-info.deck-info > p { font-size: 0.88rem; margin-bottom: 18px; }
  .deck-info .project-tags { margin-bottom: 18px; }
  .deck-shot { padding: 20px; }
}

/* ---------- The deck folds: the manifest lies down into a horizontal strip
     above the stage, and the stage stacks screenshot over write-up ---------- */
@media (max-width: 1100px) {
  .deck {
    --deck-h: clamp(520px, 68vh, 660px);
    grid-template-columns: 1fr;
    gap: 14px;
  }
  .deck-rail { height: auto; padding: 12px; }
  .deck-hint { display: none; }
  .deck-tabs {
    flex-direction: row; gap: 8px;
    overflow-x: auto; overflow-y: hidden;
    padding: 0 0 6px;
  }
  .deck-tabs::-webkit-scrollbar { height: 4px; width: auto; }
  /* a sliding marker can't track a row that scrolls sideways — the active
     tab wears the highlight itself here */
  .deck-marker { display: none; }
  .deck-tab {
    flex: 0 0 auto; width: 200px;
    border-color: var(--glass-border);
  }
  .deck-tab:hover { transform: none; }
  .deck-tab.is-active {
    border-color: color-mix(in srgb, var(--accent) 55%, transparent);
    background: color-mix(in srgb, var(--accent) 13%, transparent);
  }
  .deck-panel { grid-template-columns: 1fr; grid-template-rows: minmax(0, 0.9fr) minmax(0, 1fr); }
  .project-info.deck-info {
    border-left: none;
    border-top: 1px solid var(--glass-border);
    padding: 24px 26px;
  }
  .deck-shot { padding: 20px; }
}

@media (max-width: 1000px) {
  .interests-strip { flex-direction: column; height: auto; }
  .interests-strip-2 { margin-top: 16px; }
  .interest-panel { min-height: 210px; padding: 22px 20px; }
  /* wide short panels: aim the crop at the artwork's subject */
  .interest-art { object-position: 50% 32%; }
  .interest-body { text-align: center; max-width: none; }
  .interest-body p { max-height: 120px; opacity: 1; transform: none; }
}
@media (max-width: 900px) {
  .section[data-num]::before { display: none; }
  .about-grid { grid-template-columns: 1fr; }
  .process-track { display: none; }
  .process-grid { grid-template-columns: 1fr; border-top: none; }
  .process-fill { display: none; }
  .process-card { border-right: none; border-top: 1px solid var(--glass-border); border-left: 2px solid transparent; }
  .process-card.is-active { border-left-color: var(--accent); }
  #dots-nav { right: 14px; }
  #social-rail { left: 8px; gap: 12px; }
  .social-dot { width: 34px; height: 34px; }
  .social-dot svg { width: 14px; height: 14px; }
  .social-dot::after { display: none; }
  #topbar { padding: 20px 24px; }
  #header-nav { display: none; }
  .section { padding: 100px 6vw; }
  /* skill bay stacks: racks become a horizontal strip above the panel */
  .skillbay { grid-template-columns: 1fr; }
  .skillbay-tabs {
    flex-direction: row; overflow-x: auto;
    border-right: none; border-bottom: 1px solid var(--glass-border);
  }
  .skillbay-tab {
    flex: 1 0 auto;
    grid-template-columns: auto 1fr;
    gap: 8px; padding: 14px 16px;
    border-bottom: none; border-right: 1px solid var(--glass-border);
  }
  .skillbay-tab:hover { padding-left: 16px; }
  .skillbay-tab::before { width: 100%; height: 2px; bottom: auto; transform: scaleX(0); }
  .skillbay-tab.is-live::before { transform: scaleX(1); }
  .sbt-count { display: none; }
  .sbt-name { font-size: 0.8rem; white-space: nowrap; }
  .skillbay-panel { padding: 24px 20px 52px; min-height: 0; }
  .skillbay-foot { left: 20px; right: 20px; }
  .skillbay-ledger-note { margin-left: 0; flex-basis: 100%; }
  /* timeline collapses to a left spine */
  .edu-timeline::before { left: 9px; transform: none; }
  .edu-tl-item, .edu-tl-item:nth-child(even) { width: 100%; margin-left: 0; padding: 0 0 44px 48px; }
  .edu-tl-node, .edu-tl-item:nth-child(even) .edu-tl-node { right: auto; left: 0; }
  .edu-tl-item::after, .edu-tl-item:nth-child(even)::after {
    right: auto; left: 18px; width: 30px;
    background: linear-gradient(to right, var(--accent), transparent);
  }
  /* experience timeline collapses to a left spine */
  .exp-timeline::before { left: 9px; }
  .exp-item { grid-template-columns: 1fr; gap: 10px; padding: 0 0 40px 48px; }
  .exp-when { text-align: left; padding-top: 0; }
  .exp-node { left: 9px; top: 4px; }
  .film-card { grid-template-columns: 1fr; }
  .film-poster { border-right: none; border-bottom: 1px solid var(--glass-border); }
  .film-info { padding: 32px 28px; }
  .film-trailer { padding: 24px 28px 32px; }
  .cert-front { padding: 22px 20px; }
  .cert-icon { font-size: 1.5rem; margin-bottom: 6px; }
  .cert-front h3 { font-size: 1.15rem; }
  .cert-desc { font-size: 0.78rem; }
  .cert-date { margin: 6px 0 8px; }
  .cert-flip-hint { margin-top: 10px; }
}
@media (max-width: 640px) {
  .float-chip { display: none; }
  .hero-stats { gap: 12px; }
  .hero-stats b { font-size: 1.2rem; }
}
@media (max-width: 520px) {
  .socials { flex-direction: column; gap: 16px; }
}

/* ============================================================
   RESPONSIVE — tablet & phone
   Two fixed rails float over the page (social on the left, section
   dots on the right), so every breakpoint below either reserves real
   room for them or retires them. The rest is fixed-size furniture —
   consoles, timelines, posters — being let out of its desktop shape.
   ============================================================ */

/* the hero photo's orbit rings are wider than the photo and used to push a
   sliver of horizontal scroll; clip it without making a scroll container */
html, body { overflow-x: clip; }

/* ---------- Laptop & tablet: rails stay, content moves out from under them.
     5vw stops clearing the 66px-wide social rail below ~1520px, so the gutters
     get a floor. max() means nothing ever gets *tighter* than the base 5vw. --- */
@media (max-width: 1520px) {
  .section { padding-left: max(5vw, 88px); padding-right: max(5vw, 58px); }
  #contact footer { left: max(5vw, 88px); right: max(5vw, 58px); }
}

/* ---------- Interests: once the strip stacks, the caption sits mid-slab
     instead of at its foot, so a bottom-up scrim no longer covers it ---------- */
@media (max-width: 1000px) {
  .interest-panel::after {
    background: linear-gradient(to top,
      rgba(5, 3, 12, 0.9) 0%, rgba(5, 3, 12, 0.66) 48%, rgba(5, 3, 12, 0.52) 100%);
  }
  .interest-art { opacity: 0.7; }
  .interest-panel:hover .interest-art { opacity: 0.85; }
}

/* ---------- Skill bay: the console footer can't stay pinned once the
     panel starts wrapping, or it slides under the last modules ---------- */
@media (max-width: 900px) {
  .skillbay-panel { padding: 24px 20px; }
  .skillbay-foot {
    position: static; margin-top: 20px;
    flex-wrap: wrap; gap: 10px;
  }
  .skillbay-foot > span:first-child,
  .skillbay-foot .caret { display: none; }
  .sb-rescatter { margin-left: 0; }
  /* mobile browser chrome eats a slice of 100vh — svh always fits */
  .section { min-height: 100svh; }
}

/* ---------- Phones ---------- */
@media (max-width: 760px) {
  /* the social rail costs 11% of a phone's width; both of its links live in
     the contact console anyway, so it stands down and the dots slim to a
     thin ladder (their hover labels never fire on touch) */
  #social-rail { display: none; }
  #dots-nav { right: 7px; gap: 14px; }
  .dot { width: 8px; height: 8px; }
  .dot::before { display: none; }

  .section { padding: 92px 20px; padding-right: 36px; }
  .section-title { margin-bottom: 34px; }
  .section-inner, .section-inner.wide { max-width: 100%; }

  /* top bar: logo · zone · CV all on one line */
  #topbar { padding: 16px 18px; gap: 10px; }
  .logo { font-size: 15px; }
  .topbar-right { gap: 10px; }
  .zone-label { font-size: 8px; letter-spacing: 1.5px; }
  .cv-chip { padding: 7px 12px; font-size: 9px; gap: 5px; letter-spacing: 1.5px; }
  .cv-chip svg { width: 11px; height: 11px; }

  /* hero */
  .hero-photo { width: min(268px, 70vw); margin-bottom: 28px; }
  .eyebrow { font-size: 11px; letter-spacing: 3px; margin-bottom: 18px; }
  .hero-tagline { font-size: 1rem; margin: 22px 0 20px; }
  .hero-meta { gap: 9px; margin-bottom: 28px; }
  .meta-chip { padding: 9px 14px; font-size: 9px; letter-spacing: 1.5px; }
  .hero-cta { gap: 12px; }
  .hero-cta .btn { padding: 14px 24px; font-size: 12px; }
  /* the hero grows past one screen on a phone, so the pinned hint would land
     on top of the stat line — let it fall into the flow instead */
  .scroll-hint {
    position: static; transform: none;
    margin: 40px auto 0; font-size: 9px;
  }
  .scroll-line { height: 36px; }
  /* keep the pre-flight readout clear of the dot ladder */
  .boot-wrap { width: min(430px, 76vw); }

  /* about */
  .about-now { padding: 22px 20px; }
  .about-now-lines { font-size: 10px; }
  .stat-value { font-size: 2.1rem; }
  .stat-label { font-size: 10px; letter-spacing: 2px; }
  .about-process { margin-top: 44px; }
  .process-card { padding: 22px 20px; }

  /* skills */
  .skill-node { font-size: 0.92rem; }
  .marquee-track span { font-size: 0.95rem; margin: 0 18px; }
  .skillbay { margin-bottom: 44px; }

  /* projects: a phone has no room for a scrollbar inside a card, so the stage
     drops its fixed height and sizes to the one project on it. The section
     still costs the same whether there are two projects or twenty — only ever
     one panel is in the flow. */
  .deck-tab { width: 172px; padding: 8px 9px; gap: 9px; }
  .deck-tab-tile { width: 46px; height: 29px; }
  .deck-tab-tile b { font-size: 8.5px; }
  .deck-tab-tile.is-mono b { font-size: 7px; }
  .deck-tab-name { font-size: 0.84rem; }
  .deck-bar { padding: 9px 12px; font-size: 9px; letter-spacing: 2px; }
  .deck-stage { height: auto; }
  .deck-frames { position: static; }
  .deck-panel {
    position: relative; inset: auto;
    display: none;
    grid-template-columns: 1fr; grid-template-rows: auto auto;
  }
  .deck-panel.is-active { display: grid; }
  .project-info.deck-info { padding: 22px 20px; overflow: visible; }
  .deck-shot { padding: 14px; }

  /* lab */
  .lab-card { padding: 24px 20px; }
  .lab-scope { margin-bottom: 24px; }
  .lab-bench { gap: 8px 16px; font-size: 9px; }

  /* films: poster stays whole — it's the point of the section */
  .film-info { padding: 28px 22px; }
  .film-trailer { padding: 20px 22px 26px; }
  .film-card { margin-bottom: 32px; }

  /* interests */
  .interest-panel { min-height: 180px; padding: 20px 18px; }

  /* contact: the CTA row stacks, so give each button the full width */
  .contact-console { gap: 30px; }
  .contact-email-row { gap: 10px; }
  .contact-email-row .btn { width: 100%; justify-content: center; text-align: center; }
  .btn-big { font-size: 14px; padding: 18px 20px; margin: 24px 0 0; }
  .cv-inline { padding: 16px 20px; }
  .comm-card { padding: 16px 18px; gap: 12px; }
  .comm-icon { width: 36px; height: 36px; }
  .term-body { min-height: 200px; padding: 18px 16px; font-size: 10.5px; line-height: 2; }
  .radar-mini { width: 96px; height: 96px; }
  .contact-sign { margin-top: 48px; }
  .sign-name { font-size: clamp(1.5rem, 8.6vw, 2.6rem); letter-spacing: 2px; }
  .sign-role { font-size: 9px; letter-spacing: 2px; }
  /* unpin the footer so it can't land under the copilot button */
  #contact footer {
    position: static; left: auto; right: auto;
    margin-top: 48px; padding-bottom: 86px;
  }
}

/* ---------- Small phones ---------- */
@media (max-width: 520px) {
  /* the zone readout is the first thing to go when the bar gets tight */
  .zone-label { display: none; }
  .section-title.big { font-size: clamp(2rem, 9.5vw, 2.8rem); }
  .lead { font-size: 1.1rem; }
  .hero-stats { margin-top: 32px; }
  /* certificate cards: at one-per-row the landscape shape is too short for the
     blurb, so the card gets taller and the clamps get an extra line each */
  .cert-card { aspect-ratio: 1.06 / 1; }
  .cert-front { padding: 20px 18px; }
  .cert-front h3 { -webkit-line-clamp: 3; }
  .cert-desc { -webkit-line-clamp: 5; }
  .film-badge { font-size: 8px; }
  .project-tags span { font-size: 9px; }
}

/* ============================================================
   LAUNCH SEQUENCE — countdown, ignition, HUD & hero theatrics
   ============================================================ */

/* ---------- Countdown overlay ---------- */
#launch-overlay {
  position: fixed; inset: 0; z-index: 95;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
#launch-overlay.gone { display: none; }
.boot-wrap {
  position: relative; z-index: 2;
  width: min(430px, 86vw);
  opacity: 0;
}
.boot-title {
  font-size: 10px; letter-spacing: 6px; color: var(--accent);
  margin-bottom: 22px;
}
.boot-line {
  display: flex; align-items: baseline; gap: 10px;
  font-size: 11px; letter-spacing: 2px; color: var(--text-dim);
  margin-bottom: 12px; opacity: 0;
}
.boot-line .lead {
  flex: 1;
  border-bottom: 1px dotted rgba(255, 255, 255, 0.18);
  transform: translateY(-3px);
}
.boot-line b { color: var(--accent); font-weight: 500; }
.boot-go {
  font-size: 13px; letter-spacing: 3px; color: #fff;
  text-shadow: 0 0 18px var(--accent);
  margin-top: 18px;
}
.boot-bar-row { display: flex; align-items: center; gap: 14px; margin-top: 20px; }
.boot-bar {
  flex: 1; height: 3px; border-radius: 999px;
  background: var(--glass);
  border: 1px solid var(--glass-border);
  overflow: hidden;
}
.boot-bar-fill {
  display: block; width: 0%; height: 100%;
  background: linear-gradient(90deg, var(--accent), #fff);
  box-shadow: 0 0 14px var(--accent);
}
.boot-pct { font-size: 11px; letter-spacing: 1px; color: var(--text-dim); min-width: 4ch; text-align: right; }
.boot-pct b { color: var(--accent); font-weight: 500; }
.shockwave {
  position: absolute; left: 50%; top: 50%;
  width: 150px; height: 150px; margin: -75px 0 0 -75px;
  border: 2px solid var(--accent); border-radius: 50%;
  opacity: 0; transform: scale(0);
}
.shock-2 { width: 220px; height: 220px; margin: -110px 0 0 -110px; border-width: 1px; }
#ignite-flash {
  position: fixed; inset: 0; z-index: 96; pointer-events: none; opacity: 0;
  background: radial-gradient(circle at 50% 55%,
    #fff 0%, rgba(255, 255, 255, 0.75) 40%, rgba(139, 92, 246, 0.4) 100%);
}

/* While GSAP owns the hero intro, CSS transitions/loops must not fight it */
#hero.launching * { transition: none !important; }
#hero.launching .float-chip { animation: none; }

/* ---------- Hero name letters ---------- */
.hero-name .ltr { display: inline-block; will-change: transform; }
/* cursor-wave smoothing only after the intro finishes (never during GSAP slam) */
.hero-name.wave-ready .ltr { transition: transform 0.3s ease, text-shadow 0.3s ease; }
/* gradient applied per-letter with staggered shine = wave sweeping the word */
.ltr-grad {
  background: linear-gradient(120deg, var(--accent), #fff 60%, var(--accent));
  background-size: 200% auto;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: shine 4s linear infinite;
}

/* ---------- Occasional signal glitch ---------- */
.hero-name.glitch { animation: glitchSkew 0.24s steps(2) 1; }
.hero-name.glitch .ltr { text-shadow: 3px 0 #22d3ee, -3px 0 #f43f5e; }
@keyframes glitchSkew {
  0% { transform: skewX(-2.5deg) translateX(-4px); }
  50% { transform: skewX(2deg) translateX(3px); }
  100% { transform: none; }
}
.hero-photo-frame.glitch img { animation: photoGlitch 0.24s steps(3) 1; }
@keyframes photoGlitch {
  0% { clip-path: inset(4% 0 58% 0); transform: translateX(-7px); }
  33% { clip-path: inset(46% 0 18% 0); transform: translateX(6px); }
  66% { clip-path: inset(72% 0 2% 0); transform: translateX(-4px); }
  100% { clip-path: none; transform: none; }
}

/* ---------- Hologram scanline sweeping the portrait ---------- */
.holo-scan {
  position: absolute; left: 2%; right: 2%; top: -12%; height: 44px;
  z-index: 3; pointer-events: none;
  background: linear-gradient(to bottom, transparent,
    color-mix(in srgb, var(--accent) 60%, transparent) 50%, transparent);
  mix-blend-mode: screen; opacity: 0;
  animation: holoScan 5s ease-in-out 2s infinite;
}
@keyframes holoScan {
  0%, 54% { top: -12%; opacity: 0; }
  60% { opacity: 0.75; }
  92% { top: 104%; opacity: 0.45; }
  100% { top: 104%; opacity: 0; }
}

/* ---------- Cockpit HUD ---------- */
.hud { position: absolute; inset: 0; pointer-events: none; z-index: 1; }
.hud-corner { position: absolute; width: 30px; height: 30px; opacity: 0.55; }
.hud-tl { top: 92px; left: 26px; border-top: 2px solid var(--accent); border-left: 2px solid var(--accent); transform-origin: top left; }
.hud-tr { top: 92px; right: 26px; border-top: 2px solid var(--accent); border-right: 2px solid var(--accent); transform-origin: top right; }
.hud-bl { bottom: 26px; left: 26px; border-bottom: 2px solid var(--accent); border-left: 2px solid var(--accent); transform-origin: bottom left; }
.hud-br { bottom: 26px; right: 26px; border-bottom: 2px solid var(--accent); border-right: 2px solid var(--accent); transform-origin: bottom right; }
.hud-readout { position: absolute; font-size: 9px; letter-spacing: 2px; color: var(--text-dim); }
.hud-readout b { color: var(--accent); font-weight: 500; }
.hud-fuel { top: 98px; right: 70px; }
.hud-clock { bottom: 32px; left: 70px; }
.hud-coords { top: 98px; left: 70px; } /* top-left — bottom-right is the AI beacon's corner */
/* HUD readouts glitch along with the name + portrait */
.hud-readout.glitch {
  color: var(--text);
  text-shadow: 2px 0 #22d3ee, -2px 0 #f43f5e;
  animation: hudJitter 0.24s steps(3) 1;
}
@keyframes hudJitter {
  0% { transform: translateX(-2px); }
  50% { transform: translateX(2px); }
  100% { transform: none; }
}
/* fuel gauge pulses while topping back up */
.hud-fuel.refueling { color: var(--accent); animation: refuelPulse 0.8s ease-in-out infinite; }
@keyframes refuelPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
@media (max-width: 900px) { .hud { display: none; } }

@media (prefers-reduced-motion: reduce) {
  .holo-scan { display: none; }
  .hero-name.glitch, .hero-photo-frame.glitch img { animation: none; }
  .hud-readout.glitch, .hud-fuel.refueling { animation: none; }
  .radar-sweep, .radar-pulse, .radar-blip { animation: none; }
  .term-signal i, .term-caret { animation: none; }
}

/* ============================================================
   AI COPILOT — UPLINK-02
   A floating comms beacon that unfolds into a CRT chat console.
   Inherits the live zone --accent, so it recolors as you fly.
   ============================================================ */
.copilot { position: fixed; right: 28px; bottom: 28px; z-index: 80; }

/* --- launcher: pulsing beacon with an orbiting satellite --- */
.copilot-fab {
  position: relative; width: 72px; height: 72px;
  border-radius: 50%; border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
  background: rgba(13, 10, 26, 0.82);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  display: grid; place-items: center;
  box-shadow: 0 0 38px -12px var(--accent);
  transition: border-color 0.3s, box-shadow 0.3s, opacity 0.35s, transform 0.35s;
}
.copilot-fab:hover { border-color: var(--accent); box-shadow: 0 0 52px -8px var(--accent); }
.fab-core {
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 22px var(--accent);
  transition: background 0.3s, box-shadow 0.3s;
}
.fab-ping {
  position: absolute; inset: 14px; border-radius: 50%;
  border: 1px solid var(--accent);
  animation: fabPing 2.6s ease-out infinite;
  pointer-events: none;
}
.fab-ping.p2 { animation-delay: 1.3s; }
@keyframes fabPing {
  0% { transform: scale(0.45); opacity: 0.9; }
  80%, 100% { transform: scale(1.5); opacity: 0; }
}
.fab-orbit {
  position: absolute; inset: 6px; border-radius: 50%;
  animation: fabOrbit 5s linear infinite; pointer-events: none;
}
.fab-orbit i {
  position: absolute; top: -2px; left: 50%;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--text); opacity: 0.85;
}
@keyframes fabOrbit { to { transform: rotate(360deg); } }
.fab-tag {
  position: absolute; right: calc(100% + 12px); top: 50%;
  transform: translateY(-50%);
  padding: 6px 12px; border-radius: 8px; white-space: nowrap;
  border: 1px solid var(--glass-border); background: rgba(13, 10, 26, 0.85);
  font-size: 9px; letter-spacing: 3px; color: var(--text-dim);
  transition: color 0.25s, border-color 0.25s;
  pointer-events: none;
}
.copilot-fab:hover .fab-tag { color: var(--text); border-color: var(--accent); }
/* beacon docks away while the console is deployed */
.copilot.open .copilot-fab { opacity: 0; transform: scale(0.5); pointer-events: none; }

/* --- console shell: glass + CRT --- */
.copilot-panel {
  position: absolute; right: 0; bottom: 74px;
  width: min(450px, calc(100vw - 40px)); height: min(680px, calc(100vh - 130px));
  display: none; flex-direction: column; overflow: visible;
  border: 1px solid var(--glass-border); border-radius: 18px;
  background: rgba(9, 6, 20, 0.92);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 0 80px -30px var(--accent);
  transform-origin: bottom right;
}
.copilot.open .copilot-panel { display: flex; animation: crtOn 0.45s cubic-bezier(0.2, 0.9, 0.3, 1.2); }
/* CRT power-on: a horizontal beam that snaps open */
@keyframes crtOn {
  0% { transform: scale(0.7, 0.012); opacity: 0; }
  40% { transform: scale(1.02, 0.02); opacity: 1; }
  70% { transform: scale(0.99, 1.04); }
  100% { transform: scale(1, 1); }
}
/* scanlines over everything inside */
.copilot-panel::after {
  content: ''; position: absolute; inset: 0; border-radius: 18px; pointer-events: none;
  background: repeating-linear-gradient(0deg, transparent 0 3px, rgba(255, 255, 255, 0.018) 3px 4px);
}

/* --- header --- */
.cw-bar {
  display: flex; align-items: center; gap: 7px;
  padding: 13px 16px; border-bottom: 1px solid var(--glass-border);
  font-size: 9px; letter-spacing: 2px; color: var(--text-dim);
}
.cw-title { margin-left: 8px; }
.cw-status { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.cw-status b { font-weight: 500; color: var(--text-dim); letter-spacing: 2px; }
.cw-led {
  width: 7px; height: 7px; border-radius: 50%;
  background: #28c840; box-shadow: 0 0 8px #28c840;
  animation: cwLed 2.4s ease-in-out infinite;
}
@keyframes cwLed { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
.copilot.thinking .cw-led { background: #febc2e; box-shadow: 0 0 8px #febc2e; animation-duration: 0.6s; }
/* mac traffic lights — real controls, glyphs appear on bar hover */
.cw-dot {
  position: relative; flex: 0 0 auto; padding: 0; border: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.cw-dot::after {
  content: ''; font-size: 9px; line-height: 1; font-weight: 700;
  color: rgba(0, 0, 0, 0.55); opacity: 0; transition: opacity 0.15s;
}
.td-r.cw-dot::after { content: '×'; }
.td-y.cw-dot::after { content: '−'; }
.td-g.cw-dot::after { content: '+'; }
.cw-bar:hover .cw-dot::after { opacity: 1; }

/* green — enlarge a notch (click again to restore) */
.copilot-panel.big {
  width: min(580px, calc(100vw - 40px));
  height: min(860px, calc(100vh - 130px));
}
/* yellow — collapse to just the title bar (after .big so it wins when both are set) */
.copilot-panel.min .cw-scope, .copilot-panel.min .cw-log, .copilot-panel.min .cw-chips,
.copilot-panel.min .cw-input, .copilot-panel.min .cw-foot { display: none; }
.copilot-panel.min { height: auto; }

/* "this is Hassan" tag — shown only while voice is live */
.cw-voicetag {
  margin-left: 10px; white-space: nowrap;
  font-size: 7.5px; letter-spacing: 1.5px; color: var(--accent); opacity: 0.85;
}
@media (max-width: 420px) { .cw-voicetag { display: none; } }

/* speaker toggle — only rendered while /api/speak reports voice quota */
.cw-voice {
  margin-left: 10px; padding: 4px 7px;
  background: none; border: 1px solid transparent; border-radius: 6px;
  color: var(--accent); line-height: 0;
  transition: color 0.25s, border-color 0.25s;
}
.cw-voice:hover { border-color: var(--glass-border); }
.cw-voice .cwv-slash { opacity: 0; transition: opacity 0.2s; }
.cw-voice.muted { color: var(--text-dim); }
.cw-voice.muted .cwv-wave { opacity: 0.25; }
.cw-voice.muted .cwv-slash { opacity: 1; }

/* --- heartbeat trace: flat at idle, alive while decoding --- */
.cw-scope { height: 24px; padding: 0 16px; border-bottom: 1px dashed var(--glass-border); opacity: 0.5; transition: opacity 0.3s; }
.cw-scope svg { width: 100%; height: 100%; }
.cw-wave {
  fill: none; stroke: var(--accent); stroke-width: 1.5;
  stroke-dasharray: 60 240; stroke-dashoffset: 300;
  animation: cwWave 2.2s linear infinite paused;
}
.copilot.thinking .cw-scope { opacity: 1; }
.copilot.thinking .cw-wave { animation-play-state: running; }
@keyframes cwWave { to { stroke-dashoffset: 0; } }

/* --- transmission log --- */
.cw-log {
  flex: 1; overflow-y: auto; padding: 18px 16px 10px;
  font-size: 11.5px; line-height: 1.9; letter-spacing: 0.6px;
  scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--accent) 45%, transparent) transparent;
}
.cw-log::-webkit-scrollbar { width: 4px; }
.cw-log::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--accent) 45%, transparent); border-radius: 2px; }
.cw-msg { margin-bottom: 16px; animation: cwIn 0.3s ease both; }
@keyframes cwIn { from { opacity: 0; transform: translateY(8px); } }
.cw-meta { display: block; font-size: 8.5px; letter-spacing: 2.5px; color: var(--text-dim); margin-bottom: 4px; }
.cw-meta b { color: var(--accent); font-weight: 500; }
/* per-message speaker — reads that reply aloud in Hassan's voice */
.cw-say {
  display: none; align-items: center; justify-content: center;
  margin-left: 8px; padding: 2px 4px; vertical-align: -2px;
  background: none; border: 1px solid transparent; border-radius: 5px;
  color: var(--accent); line-height: 0; cursor: pointer;
  transition: color 0.2s, border-color 0.2s, opacity 0.2s;
}
.copilot.voiced .cw-say { display: inline-flex; }
.cw-say:hover { border-color: var(--glass-border); }
.cw-say.on { animation: cwLed 0.8s ease-in-out infinite; }
/* fetching audio — icon dims, a tiny ring spins over it (click again cancels) */
.cw-say { position: relative; }
.cw-say.loading svg { opacity: 0.2; }
.cw-say.loading::after {
  content: ''; position: absolute; inset: 0; margin: auto;
  width: 9px; height: 9px; border-radius: 50%;
  border: 1px solid var(--accent); border-top-color: transparent;
  animation: cwSpin 0.7s linear infinite;
}
@keyframes cwSpin { to { transform: rotate(360deg); } }
.cw-text { white-space: pre-wrap; word-break: break-word; color: var(--text); }
.cw-text a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; word-break: break-all; }
/* visitor transmissions sit right, tinted with the zone color */
.cw-msg.you { text-align: right; }
.cw-msg.you .cw-text {
  display: inline-block; text-align: left;
  padding: 8px 12px; border-radius: 10px 10px 2px 10px;
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.cw-msg.err .cw-text { color: #f43f5e; }
.cw-msg.boot .cw-text { color: var(--text-dim); font-size: 10px; letter-spacing: 1.5px; }
.cw-caret {
  display: inline-block; width: 6px; height: 12px; margin-left: 4px; vertical-align: -2px;
  background: var(--accent); box-shadow: 0 0 8px var(--accent);
  animation: blink 1s steps(1) infinite;
}

/* --- quick-question chips --- */
.cw-chips { display: flex; flex-wrap: wrap; gap: 7px; padding: 4px 16px 12px; }
.cw-chips.gone { display: none; }
.cw-chip {
  padding: 6px 11px; border-radius: 999px;
  border: 1px solid var(--glass-border); background: none;
  font-size: 8.5px; letter-spacing: 2px; color: var(--text-dim);
  transition: color 0.25s, border-color 0.25s, background 0.25s;
}
.cw-chip:hover { color: var(--bg); background: var(--accent); border-color: var(--accent); }

/* --- command line --- */
.cw-input {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; border-top: 1px dashed var(--glass-border);
}
.cw-prompt { color: var(--accent); font-size: 13px; text-shadow: 0 0 10px var(--accent); }
.cw-input input {
  flex: 1; min-width: 0; background: none; border: none; outline: none;
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: 1px;
  color: var(--text); caret-color: var(--accent);
}
.cw-input input::placeholder { color: var(--text-dim); opacity: 0.55; letter-spacing: 2px; }
.cw-send {
  padding: 7px 12px; border-radius: 8px;
  border: 1px solid var(--glass-border); background: none;
  font-family: var(--font-mono); font-size: 9px; letter-spacing: 2px;
  color: var(--text-dim);
  transition: color 0.25s, border-color 0.25s, background 0.25s;
}
.cw-send:hover, .cw-send:focus-visible { color: var(--bg); background: var(--accent); border-color: var(--accent); }

/* --- status strip --- */
.cw-foot {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 16px 11px; border-top: 1px solid var(--glass-border);
  font-size: 8px; letter-spacing: 2px; color: var(--text-dim);
}
.cw-foot-right { margin-left: auto; }

@media (max-width: 520px) {
  .copilot { right: 16px; bottom: 16px; }
  .copilot-panel {
    position: fixed; right: 12px; left: 12px; bottom: 86px;
    width: auto; height: min(560px, calc(100dvh - 110px));
  }
  .copilot-panel.big { width: auto; height: calc(100dvh - 110px); }
  .fab-tag { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .fab-ping, .fab-orbit { animation: none; }
  .fab-ping { display: none; }
  .copilot.open .copilot-panel { animation: none; }
  .cw-wave, .cw-led { animation: none; }
  .cw-msg { animation: none; }
  .cw-say.loading::after { animation-duration: 1.6s; }
}

/* ============================================================
   OPTICAL NAV — gesture scrolling
   Bottom-left counterpart to the copilot beacon: same glass + CRT
   language, mirrored. Recolors with the live zone --accent.
   ============================================================ */
.gesture { position: fixed; left: 28px; bottom: 28px; z-index: 80; }

/* --- launcher --- */
.gesture-fab {
  position: relative; width: 58px; height: 58px;
  border-radius: 50%; border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
  background: rgba(13, 10, 26, 0.82);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  display: grid; place-items: center; overflow: hidden;
  color: var(--text-dim);
  box-shadow: 0 0 34px -14px var(--accent);
  transition: border-color 0.3s, box-shadow 0.3s, color 0.3s, transform 0.35s;
}
.gesture-fab:hover { border-color: var(--accent); color: var(--text); box-shadow: 0 0 48px -8px var(--accent); }
.gn-hand { position: relative; z-index: 1; transition: transform 0.35s cubic-bezier(0.2, 0.9, 0.3, 1.3); }
.gesture-fab:hover .gn-hand { transform: translateY(-2px) rotate(-8deg); }
/* a scanner line crawling up the palm — the whole idea in one motion */
.gn-sweep {
  position: absolute; left: 0; right: 0; height: 34%;
  background: linear-gradient(180deg, transparent, color-mix(in srgb, var(--accent) 45%, transparent), transparent);
  animation: gnSweep 3.2s ease-in-out infinite;
  pointer-events: none;
}
@keyframes gnSweep {
  0% { top: 100%; opacity: 0; }
  15%, 85% { opacity: 1; }
  100% { top: -34%; opacity: 0; }
}
.gn-tag {
  position: absolute; left: calc(100% + 12px); top: 50%;
  transform: translateY(-50%) translateX(-6px);
  padding: 6px 12px; border-radius: 8px; white-space: nowrap;
  border: 1px solid var(--glass-border); background: rgba(13, 10, 26, 0.85);
  font-size: 9px; letter-spacing: 3px; color: var(--text-dim);
  opacity: 0; pointer-events: none;
  transition: opacity 0.25s, transform 0.25s, color 0.25s, border-color 0.25s;
}
.gesture-fab:hover .gn-tag {
  opacity: 1; transform: translateY(-50%) translateX(0);
  color: var(--text); border-color: var(--accent);
}
.gesture.open .gesture-fab { transform: scale(0.86); }
.gesture.open .gn-tag { display: none; }
/* live: the beacon breathes with the accent so it reads as "watching" */
.gesture.live .gesture-fab { border-color: var(--accent); color: var(--text); animation: gnAlive 2.2s ease-in-out infinite; }
@keyframes gnAlive {
  0%, 100% { box-shadow: 0 0 34px -14px var(--accent); }
  50% { box-shadow: 0 0 56px -6px var(--accent); }
}

/* --- console --- */
.gesture-panel {
  position: absolute; left: 0; bottom: 74px;
  width: 268px; display: none; flex-direction: column;
  border: 1px solid var(--glass-border); border-radius: 16px;
  background: rgba(9, 6, 20, 0.93);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 0 70px -28px var(--accent);
  transform-origin: bottom left;
}
.gesture.open .gesture-panel { display: flex; animation: crtOn 0.45s cubic-bezier(0.2, 0.9, 0.3, 1.2); }

.gn-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 11px 14px; border-bottom: 1px solid var(--glass-border);
  font-size: 9px; letter-spacing: 2px; color: var(--text-dim);
}
.gn-led {
  width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto;
  background: var(--text-dim); box-shadow: none;
  transition: background 0.3s, box-shadow 0.3s;
}
.gesture.live .gn-led { background: #ff4d4d; box-shadow: 0 0 9px #ff4d4d; animation: cwLed 1.6s ease-in-out infinite; }
.gesture.booting .gn-led { background: #febc2e; box-shadow: 0 0 9px #febc2e; animation: cwLed 0.6s ease-in-out infinite; }
.gn-title { flex: 1; }
.gn-close {
  border: none; background: none; padding: 2px 4px; cursor: pointer;
  font-family: var(--font-mono); font-size: 11px; line-height: 1;
  color: var(--text-dim); transition: color 0.2s, transform 0.2s;
}
.gn-close:hover { color: #ff5f57; transform: scale(1.2); }

/* --- viewfinder --- */
.gn-stage {
  position: relative; overflow: hidden;
  aspect-ratio: 4 / 3; background: #07040f;
  border-bottom: 1px solid var(--glass-border);
}
#gesture-video, #gesture-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%;
}
#gesture-video { object-fit: cover; transform: scaleX(-1); opacity: 0; transition: opacity 0.5s; }
.gesture.live #gesture-video { opacity: 0.82; }
#gesture-canvas { pointer-events: none; }

/* targeting grid + a scan beam, only while the feed is hot */
.gn-grid, .gn-beam { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity 0.5s; }
.gesture.live .gn-grid, .gesture.live .gn-beam { opacity: 1; }
.gn-grid {
  background:
    linear-gradient(color-mix(in srgb, var(--accent) 16%, transparent) 1px, transparent 1px) 0 0 / 100% 25%,
    linear-gradient(90deg, color-mix(in srgb, var(--accent) 16%, transparent) 1px, transparent 1px) 0 0 / 25% 100%;
}
.gn-beam {
  inset: auto 0 0 0; height: 22%;
  background: linear-gradient(180deg, transparent, color-mix(in srgb, var(--accent) 28%, transparent));
  animation: gnBeam 4s ease-in-out infinite alternate;
}
@keyframes gnBeam { 0% { bottom: 0; } 100% { bottom: 78%; } }

/* direction arrows — the matching one lights up while you scroll */
.gn-arrow {
  position: absolute; left: 50%; transform: translateX(-50%);
  font-family: var(--font-mono); font-size: 22px; line-height: 1;
  color: var(--accent); opacity: 0; text-shadow: 0 0 18px var(--accent);
  transition: opacity 0.2s; pointer-events: none;
}
.gn-arrow.up { top: 8px; }
.gn-arrow.down { bottom: 8px; }
.gesture[data-g='up'] .gn-arrow.up { opacity: 1; animation: gnPulseUp 0.7s ease-in-out infinite; }
.gesture[data-g='down'] .gn-arrow.down { opacity: 1; animation: gnPulseDown 0.7s ease-in-out infinite; }
@keyframes gnPulseUp { 0%, 100% { transform: translate(-50%, 0); } 50% { transform: translate(-50%, -5px); } }
@keyframes gnPulseDown { 0%, 100% { transform: translate(-50%, 0); } 50% { transform: translate(-50%, 5px); } }

.gn-hint {
  position: absolute; inset: auto 12px 12px; z-index: 2;
  padding: 7px 9px; border-radius: 7px;
  border: 1px solid var(--glass-border); background: rgba(9, 6, 20, 0.88);
  font-size: 8px; line-height: 1.5; letter-spacing: 1.4px; color: var(--text-dim);
}
.gn-hint[data-kind='err'] { color: #ff8080; border-color: color-mix(in srgb, #ff5f57 45%, transparent); }

/* --- readout --- */
.gn-readout {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px 13px;
  font-size: 9px; letter-spacing: 2px;
}
.gn-state { color: var(--text-dim); transition: color 0.2s; }
.gn-state[data-g='up'], .gn-state[data-g='down'] { color: var(--accent); }
.gn-state[data-g='stop'] { color: #febc2e; }
.gn-state[data-g='edge'] { color: #ff8080; }
.gn-rate { margin-left: auto; color: var(--text-dim); font-size: 8px; }
.gn-meter {
  position: absolute; left: 14px; right: 14px; bottom: 6px; height: 2px;
  border-radius: 2px; background: var(--glass); overflow: hidden;
}
.gn-meter i {
  display: block; height: 100%; transform-origin: left; transform: scaleX(0);
  background: linear-gradient(90deg, var(--accent), #fff);
}

/* --- legend --- */
.gn-legend {
  list-style: none; display: grid; gap: 4px;
  padding: 10px 14px; border-top: 1px solid var(--glass-border);
}
.gn-legend li {
  display: flex; align-items: center; gap: 9px;
  padding: 5px 8px; border-radius: 7px;
  border: 1px solid transparent;
  font-size: 8px; letter-spacing: 1.6px; color: var(--text-dim);
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.gn-legend li b { width: 12px; text-align: center; font-weight: 400; opacity: 0.7; }
.gn-legend li span { flex: 1; }
.gn-legend li em { font-style: normal; opacity: 0.55; }
.gn-legend li.on {
  color: var(--text); background: var(--glass);
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
}
.gn-legend li.on b { color: var(--accent); opacity: 1; }

.gn-foot {
  padding: 9px 14px 11px; border-top: 1px solid var(--glass-border);
  font-size: 7.5px; line-height: 1.6; letter-spacing: 1.6px; color: var(--text-dim);
}

/* Gesture scrolling needs a free hand and a steady camera — neither of
   which a phone held in one hand can offer. */
@media (max-width: 720px) { .gesture { display: none; } }

/* Short windows: shrink the viewfinder rather than drop the legend —
   the legend is the only place the gestures are ever explained. */
@media (max-height: 640px) {
  .gn-stage { aspect-ratio: auto; height: 124px; }
  .gn-foot { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .gn-sweep, .gn-beam, .gn-arrow { animation: none !important; }
  .gn-sweep { display: none; }
  .gesture.live .gesture-fab { animation: none; }
  .gesture.open .gesture-panel { animation: none; }
}
