/* ============================================================ */
/* THEME / TOKENS                                               */
/* ============================================================ */
:root {
  --bg: #04070d;
  --bg-2: #070b14;
  --fg: #d6deea;
  --muted: #94a3b8;
  --cyan: #00d4ff;
  --cyan-2: #5b8cff;
  --violet: #a78bfa;
  --emerald: #10ef9a;
  --grid: rgba(0, 212, 255, 0.06);
}

* { box-sizing: border-box; }
html, body { background: var(--bg); color: var(--fg); }
a { color: inherit; text-decoration: none; }
body {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  min-height: 100vh;
  overflow-x: hidden;
  background:
    radial-gradient(1200px 600px at 80% -10%, rgba(0,212,255,0.10), transparent 60%),
    radial-gradient(900px 500px at -10% 30%, rgba(91,140,255,0.08), transparent 60%),
    linear-gradient(180deg, #04070d 0%, #050912 100%);
}

/* Grid background overlay */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  background-image:
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: 48px 48px;
  mask-image: radial-gradient(circle at 50% 30%, #000 0%, transparent 75%);
  -webkit-mask-image: radial-gradient(circle at 50% 30%, #000 0%, transparent 75%);
}

main, header, footer, section { position: relative; z-index: 2; }

/* Selection */
::selection { background: rgba(0,212,255,0.30); color: white; }

/* Scrollbar */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(0,212,255,0.15); border-radius: 8px; }
::-webkit-scrollbar-thumb:hover { background: rgba(0,212,255,0.35); }

/* ============================================================ */
/* UTILITY TOKENS (replace Tailwind CDN)                        */
/* ============================================================ */
.bg-bg { background: var(--bg); }
.bg-bg\/80 { background: rgba(4,7,13,0.8); }
.text-fg { color: var(--fg); }
.text-fg\/85 { color: rgba(214,222,234,0.85); }
.text-fg\/80 { color: rgba(214,222,234,0.80); }
.text-fg\/70 { color: rgba(214,222,234,0.70); }
.text-fg\/60 { color: rgba(214,222,234,0.60); }
.text-fg\/50 { color: rgba(214,222,234,0.50); }
.text-fg\/40 { color: rgba(214,222,234,0.40); }
.text-cyan { color: var(--cyan); }
.text-cyan\/80 { color: rgba(0,212,255,0.80); }
.text-cyan\/60 { color: rgba(0,212,255,0.60); }
.text-violet-400 { color: var(--violet); }
.text-emerald-400 { color: var(--emerald); }
.text-white { color: #ffffff; }
.text-rose-400 { color: #fb7185; }
.text-amber-400 { color: #fbbf24; }

.bg-cyan { background: var(--cyan); }
.bg-cyan\/60 { background: rgba(0,212,255,0.60); }
.bg-cyan\/70 { background: rgba(0,212,255,0.70); }
.bg-cyan\/40 { background: rgba(0,212,255,0.40); }
.bg-cyan\/15 { background: rgba(0,212,255,0.15); }
.bg-emerald-400 { background: var(--emerald); }
.bg-rose-400 { background: #fb7185; }
.bg-amber-400 { background: #fbbf24; }
.bg-black { background: #000; }

/* Borders */
.border { border: 1px solid; }
.border-b { border-bottom: 1px solid; }
.border-y { border-top: 1px solid; border-bottom: 1px solid; }
.border-t { border-top: 1px solid; }
.border-fg\/10 { border-color: rgba(214,222,234,0.10); }
.border-fg\/20 { border-color: rgba(214,222,234,0.20); }
.border-cyan\/30 { border-color: rgba(0,212,255,0.30); }
.border-cyan\/20 { border-color: rgba(0,212,255,0.20); }
.border-cyan\/40 { border-color: rgba(0,212,255,0.40); }
.divide-x > * + * { border-left: 1px solid; }
.divide-cyan\/20 > * + * { border-left-color: rgba(0,212,255,0.20); }

/* Layout */
.grid { display: grid; }
.grid-cols-12 { grid-template-columns: repeat(12, minmax(0,1fr)); }
.grid-cols-3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.grid-cols-2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.grid-cols-1 { grid-template-columns: minmax(0,1fr); }
.grid-cols-6 { grid-template-columns: repeat(6, minmax(0,1fr)); }
.grid-cols-8 { grid-template-columns: repeat(8, minmax(0,1fr)); }
.gap-1 { gap: 0.25rem; }
.gap-1\.5 { gap: 0.375rem; }
.gap-2 { gap: 0.5rem; }
.gap-3 { gap: 0.75rem; }
.gap-4 { gap: 1rem; }
.gap-5 { gap: 1.25rem; }
.gap-6 { gap: 1.5rem; }
.gap-10 { gap: 2.5rem; }
.gap-x-3 { column-gap: 0.75rem; }
.gap-x-5 { column-gap: 1.25rem; }
.gap-y-1 { row-gap: 0.25rem; }
.gap-y-2 { row-gap: 0.5rem; }
.col-span-12 { grid-column: span 12 / span 12; }
.col-span-2 { grid-column: span 2 / span 2; }
.col-span-3 { grid-column: span 3 / span 3; }
.col-span-4 { grid-column: span 4 / span 4; }
.col-span-7 { grid-column: span 7 / span 7; }
.col-span-9 { grid-column: span 9 / span 9; }
.col-span-10 { grid-column: span 10 / span 10; }

.flex { display: flex; }
.inline-flex { display: inline-flex; }
.flex-col { flex-direction: column; }
.flex-wrap { flex-wrap: wrap; }
.flex-1 { flex: 1 1 0%; }
.items-center { align-items: center; }
.items-start { align-items: flex-start; }
.items-end { align-items: flex-end; }
.justify-center { justify-content: center; }
.justify-between { justify-content: space-between; }
.justify-end { justify-content: flex-end; }
.justify-items-center { justify-items: center; }
.text-center { text-align: center; }

/* Sizing */
.w-full { width: 100%; }
.h-full { height: 100%; }
.w-1\.5 { width: 0.375rem; }
.h-1\.5 { height: 0.375rem; }
.w-2 { width: 0.5rem; }
.h-2 { height: 0.5rem; }
.w-3 { width: 0.75rem; }
.h-3 { height: 0.75rem; }
.w-4 { width: 1rem; }
.h-4 { height: 1rem; }
.w-8 { width: 2rem; }
.h-8 { height: 2rem; }
.w-14 { width: 3.5rem; }
.h-14 { height: 3.5rem; }
.w-16 { width: 4rem; }
.h-16 { height: 4rem; }
.w-20 { width: 5rem; }
.h-20 { height: 5rem; }
.h-10 { height: 2.5rem; }
.h-12 { height: 3rem; }
.w-32 { width: 8rem; }
.h-32 { height: 8rem; }
.h-px { height: 1px; }
.h-\[2px\] { height: 2px; }
.aspect-square { aspect-ratio: 1 / 1; }
.aspect-video { aspect-ratio: 16 / 9; }
.min-h-\[60vh\] { min-height: 60vh; }
.min-h-\[120px\] { min-height: 120px; }
.max-w-\[80vw\] { max-width: 80vw; }
.max-w-\[60ch\] { max-width: 60ch; }
.max-w-\[36ch\] { max-width: 36ch; }
.max-w-\[300px\] { max-width: 300px; }
.max-w-\[360px\] { max-width: 360px; }
.max-w-\[480px\] { max-width: 480px; }

/* Spacing */
.p-3 { padding: 0.75rem; }
.p-4 { padding: 1rem; }
.p-5 { padding: 1.25rem; }
.px-3 { padding-left: 0.75rem; padding-right: 0.75rem; }
.px-4 { padding-left: 1rem; padding-right: 1rem; }
.px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
.py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
.py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem; }
.py-5 { padding-top: 1.25rem; padding-bottom: 1.25rem; }
.pt-1 { padding-top: 0.25rem; }
.pt-6 { padding-top: 1.5rem; }
.pt-10 { padding-top: 2.5rem; }
.pt-12 { padding-top: 3rem; }
.pb-4 { padding-bottom: 1rem; }
.pb-10 { padding-bottom: 2.5rem; }
.mt-1 { margin-top: 0.25rem; }
.mt-2 { margin-top: 0.5rem; }
.mt-3 { margin-top: 0.75rem; }
.mt-4 { margin-top: 1rem; }
.mt-5 { margin-top: 1.25rem; }
.mt-6 { margin-top: 1.5rem; }
.mt-8 { margin-top: 2rem; }
.mt-10 { margin-top: 2.5rem; }
.mt-14 { margin-top: 3.5rem; }
.mb-3 { margin-bottom: 0.75rem; }
.mb-4 { margin-bottom: 1rem; }
.mb-6 { margin-bottom: 1.5rem; }
.mb-8 { margin-bottom: 2rem; }
.ml-4 { margin-left: 1rem; }
.ml-auto { margin-left: auto; }
.mx-auto { margin-left: auto; margin-right: auto; }
.mx-4 { margin-left: 1rem; margin-right: 1rem; }
.space-y-1 > * + * { margin-top: 0.25rem; }
.space-y-1\.5 > * + * { margin-top: 0.375rem; }
.space-y-2 > * + * { margin-top: 0.5rem; }
.space-y-2\.5 > * + * { margin-top: 0.625rem; }
.space-y-3 > * + * { margin-top: 0.75rem; }

/* Position */
.fixed { position: fixed; }
.absolute { position: absolute; }
.relative { position: relative; }
.sticky { position: sticky; }
.inset-0 { inset: 0; }
.inset-x-0 { left: 0; right: 0; }
.top-0 { top: 0; }
.bottom-2 { bottom: 0.5rem; }
.bottom-\[-10\%\] { bottom: -10%; }
.left-1\/2 { left: 50%; }
.-translate-x-1\/2 { transform: translateX(-50%); }
.z-30 { z-index: 30; }
.z-10 { z-index: 10; }
.z-0 { z-index: 0; }
.-z-0 { z-index: 0; }
.\[z-100\], .z-\[100\] { z-index: 100; }
.z-\[90\] { z-index: 90; }
.pointer-events-none { pointer-events: none; }
.overflow-hidden { overflow: hidden; }
.object-cover { object-fit: cover; }
.select-none { user-select: none; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Text */
.font-mono { font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace; }
.font-display { font-family: 'Space Grotesk', Inter, system-ui, sans-serif; }
.font-bold { font-weight: 700; }
.uppercase { text-transform: uppercase; }
.tracking-tight { letter-spacing: -0.02em; }
.tracking-wide { letter-spacing: 0.04em; }
.tracking-wider { letter-spacing: 0.06em; }
.tracking-\[0\.15em\] { letter-spacing: 0.15em; }
.tracking-\[0\.2em\] { letter-spacing: 0.2em; }
.tracking-\[0\.25em\] { letter-spacing: 0.25em; }
.tracking-\[0\.3em\] { letter-spacing: 0.3em; }
.tracking-\[0\.4em\] { letter-spacing: 0.4em; }
.tracking-\[0\.5em\] { letter-spacing: 0.5em; }
.leading-tight { line-height: 1.15; }
.leading-relaxed { line-height: 1.625; }
.leading-\[0\.95\] { line-height: 0.95; }
.text-\[9px\] { font-size: 9px; }
.text-\[10px\] { font-size: 10px; }
.text-\[11px\] { font-size: 11px; }
.text-xs { font-size: 11px; }
.text-sm { font-size: 13px; }
.text-base { font-size: 15px; }
.text-lg { font-size: 18px; }
.text-xl { font-size: 20px; }
.text-2xl { font-size: 24px; }
.text-5xl { font-size: 44px; }

/* Hidden/visible */
.hidden { display: none; }
.block { display: block; }
.inline-block { display: inline-block; }
.inline { display: inline; }
.opacity-0 { opacity: 0; }
.opacity-75 { opacity: 0.75; }
.opacity-60 { opacity: 0.60; }

/* Rounded */
.rounded-full { border-radius: 9999px; }
.rounded-sm { border-radius: 2px; }

/* Ring */
.ring-1 { box-shadow: inset 0 0 0 1px; }
.ring-cyan\/40 { color: rgba(0,212,255,0.40); }
.ring-white\/10 { color: rgba(255,255,255,0.10); }

/* Effects */
.backdrop-blur-md { backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.transition-opacity { transition: opacity 0.3s ease; }
.transition-colors { transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease; }
.transition-\[width\] { transition: width 0.15s linear; }
.duration-150 { transition-duration: 150ms; }
.duration-300 { transition-duration: 300ms; }
.duration-700 { transition-duration: 700ms; }
.ease-linear { transition-timing-function: linear; }
.drop-shadow-\[0_0_25px_rgba\(0\,212\,255\,0\.6\)\] { filter: drop-shadow(0 0 25px rgba(0,212,255,0.6)); }

/* Gradients */
.bg-gradient-to-b { background-image: linear-gradient(to bottom, var(--tw-grad-from, transparent), var(--tw-grad-to, transparent)); }
.bg-gradient-to-r { background-image: linear-gradient(to right, var(--tw-grad-from, transparent), var(--tw-grad-via, transparent), var(--tw-grad-to, transparent)); }
.bg-gradient-to-br { background-image: linear-gradient(to bottom right, var(--tw-grad-from, transparent), var(--tw-grad-via, transparent), var(--tw-grad-to, transparent)); }
.from-cyan\/5 { --tw-grad-from: rgba(0,212,255,0.05); }
.from-cyan\/30 { --tw-grad-from: rgba(0,212,255,0.30); }
.from-white { --tw-grad-from: #ffffff; }
.via-cyan { --tw-grad-via: var(--cyan); }
.via-cyan\/40 { --tw-grad-via: rgba(0,212,255,0.40); }
.via-violet-500\/20 { --tw-grad-via: rgba(139,92,246,0.20); }
.to-transparent { --tw-grad-to: transparent; }
.to-cyan\/30 { --tw-grad-to: rgba(0,212,255,0.30); }
.to-violet-300 { --tw-grad-to: #c4b5fd; }
.to-slate-900 { --tw-grad-to: #0f172a; }
.to-slate-800 { --tw-grad-to: #1e293b; }
.from-slate-700 { --tw-grad-from: #334155; }
.from-slate-800 { --tw-grad-from: #1e293b; }
.bg-clip-text { -webkit-background-clip: text; background-clip: text; }
.text-transparent { color: transparent; }

/* Selection helper */
.selection\:bg-cyan-400\/30 *::selection { background: rgba(34,211,238,0.30); }

/* Animations utility names */

.animate-pulse-fast { animation: pulse 1.4s ease-in-out infinite; }
.animate-ping { animation: ping 1.6s cubic-bezier(0,0,.2,1) infinite; }
.animate-blink { animation: blink 1s steps(1) infinite; }

@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
@keyframes ping { 75%,100% { transform: scale(2); opacity: 0; } }
@keyframes blink { 50% { opacity: 0; } }

/* ============================================================ */
/* RESPONSIVE                                                   */
/* ============================================================ */
@media (min-width: 768px) {
  .md\:block { display: block; }
  .md\:flex { display: flex; }
  .md\:hidden { display: none; }
  .md\:inline { display: inline; }
  .md\:inline-flex { display: inline-flex; }
  .md\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
  .md\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
  .md\:grid-cols-6 { grid-template-columns: repeat(6, minmax(0,1fr)); }
  .md\:col-span-2 { grid-column: span 2 / span 2; }
  .md\:col-span-3 { grid-column: span 3 / span 3; }
  .md\:col-span-4 { grid-column: span 4 / span 4; }
  .md\:col-span-7 { grid-column: span 7 / span 7; }
  .md\:col-span-9 { grid-column: span 9 / span 9; }
  .md\:col-span-10 { grid-column: span 10 / span 10; }
  .md\:px-8 { padding-left: 2rem; padding-right: 2rem; }
  .md\:pt-10 { padding-top: 2.5rem; }
  .md\:pt-14 { padding-top: 3.5rem; }
  .md\:pt-16 { padding-top: 4rem; }
  .md\:pt-20 { padding-top: 5rem; }
  .md\:pb-16 { padding-bottom: 4rem; }
  .md\:gap-4 { gap: 1rem; }
  .md\:gap-6 { gap: 1.5rem; }
  .md\:gap-10 { gap: 2.5rem; }
  .md\:mb-6 { margin-bottom: 1.5rem; }
  .md\:mt-6 { margin-top: 1.5rem; }
  .md\:mt-8 { margin-top: 2rem; }
  .md\:mt-12 { margin-top: 3rem; }
  .md\:mt-14 { margin-top: 3.5rem; }
  .md\:p-5 { padding: 1.25rem; }
  .md\:flex-row { flex-direction: row; }
  .md\:items-start { align-items: flex-start; }
  .md\:items-center { align-items: center; }
  .md\:items-end { align-items: flex-end; }
  .md\:justify-between { justify-content: space-between; }
  .md\:min-h-\[600px\] { min-height: 600px; }
  .md\:text-2xl { font-size: 24px; }
  .md\:text-xs { font-size: 11px; }
  .md\:text-base { font-size: 15px; }
  .md\:text-\[68px\] { font-size: 68px; }
  .md\:text-\[72px\] { font-size: 72px; }
  .md\:text-\[88px\] { font-size: 88px; }
  .md\:text-\[150px\] { font-size: 150px; }
  .md\:text-\[64px\] { font-size: 64px; }
}
@media (min-width: 1024px) {
  .lg\:text-\[80px\] { font-size: 80px; }
  .lg\:text-\[96px\] { font-size: 96px; }
}

/* ============================================================ */
/* COMPONENT STYLES                                              */
/* ============================================================ */
.panel {
  position: relative;
  border: 1px solid rgba(0,212,255,0.15);
  background: rgba(7,11,20,0.55);
  border-radius: 2px;
  backdrop-filter: blur(2px);
}
.panel::before, .panel::after { /* corner accents */
  content: "";
  position: absolute;
  width: 10px; height: 10px;
  border-color: rgba(0,212,255,0.55);
  border-style: solid; border-width: 0;
}
.panel::before { top: -1px; left: -1px; border-top-width: 1px; border-left-width: 1px; }
.panel::after  { bottom: -1px; right: -1px; border-bottom-width: 1px; border-right-width: 1px; }

.panel-title {
  font-size: 9px;
  letter-spacing: 0.3em;
  color: var(--cyan);
  opacity: 0.85;
}

.meter {
  height: 3px;
  width: 100%;
  background: rgba(0,212,255,0.10);
  border-radius: 2px;
  overflow: hidden;
}
.meter-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--cyan-2), var(--cyan));
}

/* DATA_STREAM bars */
#m-bars i { display: block; width: 100%; background: rgba(0,212,255,0.65); border-radius: 1px; }
#m-bars { grid-template-columns: repeat(14, 1fr); display: grid; }

/* Menu items */
.menu-item {
  display: grid;
  grid-template-columns: 28px 1fr 20px 22px;
  align-items: center;
  padding: 10px 12px;
  gap: 8px;
  border-top: 1px solid rgba(0,212,255,0.10);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: rgba(214,222,234,0.85);
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease;
}
.menu-item:first-child { border-top: 0; }
.menu-item .num { color: var(--cyan); font-weight: 600; }
.menu-item .arrow { color: rgba(214,222,234,0.50); }
.menu-item .ico { color: var(--cyan); justify-self: end; }
.menu-item:hover { background: rgba(0,212,255,0.06); color: #fff; }
.menu-item:hover .arrow { color: var(--cyan); }

/* HUD overlay indicators — corner labels, vertical scroll hint,
   cursor / parallax badges. Cosmetic, non-interactive. The corner
   readouts (VIEWPORT_WxH / ZOOM_NN%) sit in their own dark pills
   with a cyan border so they read as proper HUD chips rather than
   floating grey text above the float cards. */
.hud-corner {
  position: absolute;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.25em;
  pointer-events: none;
  z-index: 3;
}
.hud-corner-tr {
  top: 18px;
  right: 18px;
  align-items: flex-end;
}
.hud-corner > span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 10px;
  border-radius: 2px;
  background: rgba(4, 7, 13, 0.55);
  border: 1px solid rgba(0, 212, 255, 0.18);
  color: rgba(0, 212, 255, 0.85);
  text-shadow: 0 0 6px rgba(0, 212, 255, 0.25);
}
.hud-dot {
  display: inline-block;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 0 6px var(--cyan);
}

.hud-scroll {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%) rotate(90deg);
  transform-origin: right center;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.4em;
  color: rgba(0, 212, 255, 0.45);
  pointer-events: none;
  z-index: 3;
  white-space: nowrap;
}

.hud-cursor {
  margin-top: 18px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.3em;
  text-align: center;
  justify-content: center;
  pointer-events: none;
}
/* Each readout sits inside its own soft dark pill so the icosahedron
   rays converging at the bottom of the hero can't wash out the text. */
.hud-cursor > span {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 2px;
  background: rgba(4, 7, 13, 0.55);
  border: 1px solid rgba(0, 212, 255, 0.18);
  color: rgba(0, 212, 255, 0.95);
  text-shadow: 0 0 8px rgba(0, 212, 255, 0.35);
}
.hud-cursor b { color: #fff; font-weight: 600; }
/* When the pills sit at the TOP of the hero overlay (above the eyebrow
   line) the row should align left like the rest of the headline copy,
   not centre-align like the original bottom placement. */
.hud-cursor.hud-cursor-top {
  margin-top: 0;
  justify-content: flex-start;
  text-align: left;
}

/* Subtle mouse-parallax wrapper for the hero center. Translated by
   main.js based on pointer position. */
.hero-stage,
#hero-overlay {
  will-change: transform;
}

/* Hero video — plays in the first viewport-height of the page as a
   background layer for the hero section. Freezes on its last frame and
   stays as the hero background. Below this area (when the user scrolls)
   the regular page sections continue normally with their grid backdrop. */
.hero-fullscreen {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  z-index: 0;            /* below #site (z-index:2) and body::before grid */
  background: var(--bg);
  display: none;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.hero-fullscreen.active { display: flex; }
.hero-fullscreen video,
.hero-fullscreen img {
  width: 100%;
  height: 100%;
  /* slight base scale gives the parallax translate room to move
     without revealing the edges of the container */
  transform: scale(1.04);
  transition: transform 0.6s cubic-bezier(.22,.61,.36,1);
  will-change: transform;
  /* `cover` fills the hero area completely — no dark bars on the
     sides. The icosahedron sits in the centre of the source frame
     so only empty dark space at the edges may be cropped. */
  object-fit: cover;
  object-position: center center;
  display: block;
  background: var(--bg);
}

/* Hero video stage — now a transparent positioning anchor for the
   hero text overlay. The actual icosahedron video is the fullscreen
   background; the stage's own video/poster are hidden. */
.hero-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: transparent;
  border: none;
  border-radius: 0;
  overflow: visible;
  box-shadow: none;
}
@media (max-width: 767px) {
  .hero-stage { aspect-ratio: 9 / 16; }
}
.hero-video,
.hero-freeze {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* The hero-stage's own video and freeze poster are no longer shown;
   the fullscreen background video provides the visual. */
.hero-stage > .hero-video,
.hero-stage > .hero-freeze {
  display: none;
}
.hero-freeze { opacity: 0; transition: opacity 0.3s ease; pointer-events: none; }

/* Vignette + scanline veil is no longer needed — the fullscreen video
   is the background and the overlay text has its own text-shadow. */
.hero-stage::after { content: none; }
.hero-stage.frozen::after { content: none; }

/* Hero overlay (text that appears after video freezes).
   Anchored to the TOP-LEFT of the stage, sitting next to the
   SYS_STATUS panel in the left telemetry sidebar. The headline is
   intentionally large so it dominates the upper-left quadrant
   without colliding with the central icosahedron. The numbered menu
   lives BELOW the stage (next to the .hud-cursor readout), not
   inside this overlay. */
.hero-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
  /* Pull the headline up against the top of the stage and just
     inside the left edge so it sits next to SYS_STATUS rather than
     centred vertically. */
  padding: clamp(24px, 3.5%, 56px) 0 0 clamp(16px, 3%, 48px);
  opacity: 0;
  pointer-events: none;
  z-index: 2;
}
.hero-overlay.show { opacity: 1; transition: opacity 0.4s ease; }
.hero-overlay-inner {
  text-align: left;
  /* The headline is much larger now; widen the wrap so each phrase
     fits on its own line, but still clear the central icosahedron. */
  max-width: 760px;
  text-shadow: 0 2px 24px rgba(4,7,13,0.65);
}
/* Fluid hero headline: scales smoothly with viewport width so each
   phrase (I BUILD PRODUCTS / THAT ACTUALLY / WORK.) lands on its own
   line on every viewport from ~768px up to ultra-wide. */
.hero-title span {
  font-size: clamp(40px, 5.4vw, 88px);
  line-height: 0.95;
}
@media (max-width: 767px) {
  /* On phones the stage is portrait (9:16). Centre the overlay so the
     text doesn’t crowd one edge of the screen. */
  .hero-overlay { justify-content: center; padding: 0 24px; }
  .hero-overlay-inner { text-align: center; max-width: 100%; padding: 0; }

  /* Hero tagline (Веб-приложения · SaaS-платформы · …) sits directly
     below the icosahedron in portrait mode and was blending with the
     dark-blue gradient of the video. Boost contrast: brighter colour,
     slightly heavier weight, and a strong text-shadow so each phrase
     pops clearly off the background on phones. */
  #hero-overlay .hero-tagline {
    color: #ffffff;
    font-weight: 500;
    text-shadow:
      0 1px 2px rgba(4, 7, 13, 0.95),
      0 2px 12px rgba(4, 7, 13, 0.85),
      0 0 24px rgba(4, 7, 13, 0.6);
  }
}

/* Hero menu is hidden until video freezes. It inherits the standard
   .panel translucent dark treatment so it visually matches the other
   HUD panels (SYS_STATUS, NODE_CLUSTER, DATA_STREAM, TERMINAL_LOG). */
.hero-menu {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.5s ease, transform 0.5s ease;
  pointer-events: none;
}
.hero-menu.show { opacity: 1; transform: translateY(0); pointer-events: auto; }

/* Float cards — the three HUD windows on the right side of the hero.
   They sit in a 3D space with a pronounced rotation for depth and
   gently drift on a multi-second cycle to feel "alive" like the
   reference design. The base transform is always applied so the 3D
   tilt is visible even when prefers-reduced-motion disables the
   floating animation. */
.float-stack {
  perspective: 900px;
  perspective-origin: 70% 40%;
  transform-style: preserve-3d;
  /* Drop the right card column slightly so the first card (LUMEN)
     doesn't crowd the top HUD readouts. On mobile the cards stack
     below the hero, so no extra top margin is needed. */
  margin-top: 56px;
}
@media (max-width: 767px) {
  .float-stack { margin-top: 0; }
}
.float-card {
  position: relative;
  border: 1px solid rgba(0,212,255,0.22);
  background: linear-gradient(180deg, rgba(10,16,28,0.88), rgba(7,11,20,0.92));
  border-radius: 3px;
  overflow: hidden;
  transform-style: preserve-3d;
  transform-origin: 50% 50%;
  /* CSS variables let the float animation respect the per-card 3D angle */
  --tilt-rx: 0deg;
  --tilt-ry: -14deg;
  --tilt-rz: 0deg;
  --float-x: 0px;
  /* Apply the tilt unconditionally so the cards still look 3D when the
     float animation is disabled (e.g. prefers-reduced-motion). */
  transform:
    translate3d(var(--float-x), 0, 0)
    rotateX(var(--tilt-rx))
    rotateY(var(--tilt-ry))
    rotateZ(var(--tilt-rz));
  animation: float-tilt 7s ease-in-out infinite;
  box-shadow:
    0 14px 40px -16px rgba(0,212,255,0.30),
    0 28px 60px -24px rgba(0,0,0,0.70),
    inset 0 1px 0 rgba(255,255,255,0.04);
  transition: box-shadow 0.4s ease, border-color 0.4s ease;
}
.float-card::before {
  /* subtle gloss line at the top edge */
  content: '';
  position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(0,212,255,0.55), transparent);
  pointer-events: none;
}
.float-card::after {
  /* cyan halo glow that softly leaks outside the card */
  content: '';
  position: absolute; inset: -1px;
  border-radius: inherit;
  pointer-events: none;
  box-shadow: 0 0 28px rgba(0,212,255,0.12) inset;
}
.float-card:hover {
  border-color: rgba(0,212,255,0.45);
  box-shadow:
    0 18px 52px -16px rgba(0,212,255,0.45),
    0 32px 80px -24px rgba(0,0,0,0.80),
    inset 0 1px 0 rgba(255,255,255,0.06);
}
/* Tilt direction: NEGATIVE rotateY rotates the card so its RIGHT edge
   comes forward and LEFT edge recedes — the cards are on the right
   side of the page so they should face slightly INWARD toward the
   icosahedron at the centre. Cards also have small per-card
   rotateX/rotateZ skew so they don't look perfectly aligned. The
   angles are deliberately bold (~15°) so the depth reads clearly. */
.float-card.delay-0 { --tilt-ry: -15deg; --tilt-rx: 4deg; --tilt-rz: 2deg;   --float-x: 0px; animation-delay: 0s;   }
.float-card.delay-1 { --tilt-ry: -17deg; --tilt-rx: 3deg; --tilt-rz: 3deg;   --float-x: 0px; animation-delay: 1.4s; }
.float-card.delay-2 { --tilt-ry: -16deg; --tilt-rx: 5deg; --tilt-rz: 2.5deg; --float-x: 0px; animation-delay: 2.8s; }
@keyframes float-tilt {
  0%, 100% {
    transform:
      translate3d(var(--float-x), 0, 0)
      rotateX(var(--tilt-rx))
      rotateY(var(--tilt-ry))
      rotateZ(var(--tilt-rz));
  }
  50% {
    transform:
      translate3d(var(--float-x), -7px, 0)
      rotateX(calc(var(--tilt-rx) + 0.6deg))
      rotateY(calc(var(--tilt-ry) + 0.5deg))
      rotateZ(var(--tilt-rz));
  }
}

/* Window chrome */
.win-chrome {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  border-bottom: 1px solid rgba(0,212,255,0.12);
  font-size: 10px;
  letter-spacing: 0.18em;
  color: rgba(214,222,234,0.65);
  background: rgba(0,0,0,0.4);
}
.win-chrome .dot { width: 8px; height: 8px; border-radius: 9999px; display: inline-block; }
.win-chrome .title { margin-left: 6px; }

/* Project cards */
.project-card {
  border: 1px solid rgba(0,212,255,0.16);
  background: linear-gradient(180deg, rgba(10,16,28,0.75), rgba(7,11,20,0.85));
  border-radius: 3px;
  overflow: hidden;
  transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}
.project-card:hover {
  transform: translateY(-4px);
  border-color: rgba(0,212,255,0.4);
  box-shadow: 0 12px 40px rgba(0,212,255,0.10);
}
.project-preview {
  padding: 14px;
  background: linear-gradient(180deg, rgba(0,212,255,0.04), transparent);
  min-height: 160px;
}
.project-meta {
  padding: 14px;
  border-top: 1px solid rgba(0,212,255,0.12);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.arrow-link {
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--cyan);
  border: 1px solid rgba(0,212,255,0.30);
  border-radius: 2px;
  transition: background 0.2s ease, transform 0.2s ease;
}
.arrow-link:hover { background: rgba(0,212,255,0.10); transform: translateX(2px); }

/* Project card polish — stronger lift + cyan glow + animated border */
.project-card {
  position: relative;
}
.project-card::after {
  content: '';
  position: absolute; inset: 0;
  pointer-events: none;
  border-radius: inherit;
  box-shadow: 0 0 0 1px rgba(0,212,255,0) inset;
  transition: box-shadow 0.35s ease;
}
.project-card:hover {
  transform: translateY(-6px);
  border-color: rgba(0,212,255,0.55);
  box-shadow:
    0 18px 60px -16px rgba(0,212,255,0.25),
    0 28px 80px -24px rgba(0,0,0,0.7);
}
.project-card:hover::after {
  box-shadow: 0 0 0 1px rgba(0,212,255,0.30) inset, 0 0 24px rgba(0,212,255,0.10) inset;
}

/* Form field focus polish — cyan border + soft cyan glow.
   Browser <input>/<textarea> have a default white background that the
   bg-transparent utility class doesn't override (no Tailwind here), so
   we anchor the resting background to the dark theme on .field-input
   directly. Caret + autofill colours are also normalized for the dark
   theme. */
.field-input {
  background: rgba(8,13,22,0.65);
  color: var(--fg);
  caret-color: var(--cyan);
  border-radius: 0;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}
.field-input::placeholder {
  color: rgba(229,231,235,0.32);
  letter-spacing: 0.05em;
}
.field-input:hover {
  border-color: rgba(0,212,255,0.35);
  background: rgba(0,212,255,0.04);
}
.field-input:focus {
  border-color: rgba(0,212,255,0.75);
  box-shadow: 0 0 0 3px rgba(0,212,255,0.12), 0 0 28px rgba(0,212,255,0.10);
  background: rgba(0,212,255,0.05);
}

/* SEND_MESSAGE button — soft cyan glow on hover + slight lift */
.btn-send {
  position: relative;
  transition: background 0.2s ease, transform 0.18s ease, box-shadow 0.25s ease, color 0.2s ease;
  box-shadow: 0 8px 30px -10px rgba(0,212,255,0.40);
}
.btn-send:hover {
  background: #e6fbff;
  transform: translateY(-1px);
  box-shadow: 0 14px 40px -10px rgba(0,212,255,0.65);
}
.btn-send:active { transform: translateY(0); }

/* Stats banner — gentle inner glow underlines the value during reveal */
.stats-band .num {
  transition: text-shadow 0.4s ease;
}
.stats-band.in-view .num {
  text-shadow: 0 0 24px rgba(139,92,246,0.35);
}

/* Section reveal: fade up when entering viewport. */
[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(.22,.61,.36,1);
  will-change: opacity, transform;
}
[data-reveal].is-visible {
  opacity: 1;
  transform: none;
}
/* Stagger children of the projects grid for a wave effect */
#projects.is-visible .project-card {
  animation: revealUp 0.6s cubic-bezier(.22,.61,.36,1) both;
}
#projects.is-visible .project-card:nth-child(1) { animation-delay: 0.05s; }
#projects.is-visible .project-card:nth-child(2) { animation-delay: 0.15s; }
#projects.is-visible .project-card:nth-child(3) { animation-delay: 0.25s; }
#projects.is-visible .project-card:nth-child(4) { animation-delay: 0.35s; }
#projects.is-visible .project-card:nth-child(5) { animation-delay: 0.45s; }
#projects.is-visible .project-card:nth-child(6) { animation-delay: 0.55s; }
@keyframes revealUp {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: none; }
}

/* Respect user preference: no big motion */
@media (prefers-reduced-motion: reduce) {
  [data-reveal],
  #projects.is-visible .project-card,
  .float-card {
    animation: none !important;
    transition: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ============================================================ */
/* ABOUT SECTION                                                 */
/* ============================================================ */

/* Professional globe panel
   Real Earth orthographic globe rendered into <canvas#about-globe>
   by main.js (d3-geo + world-atlas land-110m). The static SVG inside
   .about-globe-fallback is what shows before the canvas is ready (or
   when CDN is blocked) so the panel is never empty. */
.about-globe-panel {
  background:
    radial-gradient(circle at 50% 50%, rgba(0,212,255,0.05), transparent 70%),
    rgba(7,11,20,0.55);
  overflow: hidden;
}
.about-globe-stage {
  position: relative;
  width: 100%;
  height: 100%;
  display: block;
}
.about-globe-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  opacity: 0;
  transition: opacity 0.6s ease;
  filter: drop-shadow(0 0 14px rgba(0,212,255,0.20));
}
.about-globe-canvas.is-ready { opacity: 1; }
.about-globe-fallback {
  position: absolute;
  inset: 8%;
  width: 84%;
  height: 84%;
  opacity: 0.55;
  filter: drop-shadow(0 0 14px rgba(0,212,255,0.20));
  pointer-events: none;
}
.about-globe-canvas.is-ready + .about-globe-fallback { opacity: 0; }

.globe-tick {
  position: absolute;
  width: 10px;
  height: 10px;
  border-color: rgba(0,212,255,0.6);
  border-style: solid;
  border-width: 0;
  pointer-events: none;
}
.globe-tick-tl { top: 0;    left: 0;    border-top-width: 1px; border-left-width:  1px; }
.globe-tick-tr { top: 0;    right: 0;   border-top-width: 1px; border-right-width: 1px; }
.globe-tick-bl { bottom: 0; left: 0;    border-bottom-width: 1px; border-left-width:  1px; }
.globe-tick-br { bottom: 0; right: 0;   border-bottom-width: 1px; border-right-width: 1px; }

/* Animated avatar ring wrapper */
.about-avatar-wrap {
  position: relative;
  width: 136px;
  height: 136px;
}
.about-avatar-ring {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.about-avatar-inner {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 112px;
  height: 112px;
  border-radius: 9999px;
  background: linear-gradient(135deg, rgba(0,212,255,0.20), rgba(139,92,246,0.15), rgba(0,212,255,0.20));
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 40px rgba(0,212,255,0.15), inset 0 0 30px rgba(0,212,255,0.08);
}
.about-avatar-inner::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
  pointer-events: none;
}

/* "What I deliver" 2x2 grid */
.about-deliver-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
@media (max-width: 767px) {
  .about-deliver-grid { grid-template-columns: 1fr; }
}
.about-deliver-item {
  transition: border-color 0.25s ease, box-shadow 0.25s ease, transform 0.25s ease;
}
.about-deliver-item:hover {
  border-color: rgba(0,212,255,0.40);
  box-shadow: 0 8px 30px rgba(0,212,255,0.08);
  transform: translateY(-2px);
}
.about-deliver-icon {
  opacity: 0.85;
}

/* Work process — horizontal step flow */
.about-process {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}
@media (max-width: 767px) {
  .about-process { grid-template-columns: repeat(2, 1fr); }
}
.about-process-step {
  position: relative;
  padding-top: 4px;
}
.about-process-num {
  font-size: 20px;
  line-height: 1;
}
.about-process-line {
  height: 2px;
  width: 100%;
  margin-top: 8px;
  background: linear-gradient(90deg, var(--cyan), rgba(0,212,255,0.1));
  border-radius: 1px;
}

/* Badges */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 8px;
  border: 1px solid rgba(0,212,255,0.30);
  color: var(--cyan);
  font-size: 9px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  border-radius: 1px;
  background: rgba(0,212,255,0.04);
}

/* Stack list */
.stack-item {
  display: flex;
  align-items: center;
  gap: 12px;
  letter-spacing: 0.15em;
  color: rgba(214,222,234,0.85);
}
.stack-item .ico {
  width: 22px;
  text-align: center;
  color: var(--cyan);
  font-size: 12px;
}

/* Tech icons — uniform sizing + subtle hover so the single-colour
   brand SVGs (Simple Icons) read consistently in the dark theme.
   Hover lifts the icon and adds a soft cyan glow. */
.tech-icon {
  width: 56px;
  height: 56px;
  opacity: 0.88;
  filter: drop-shadow(0 4px 10px rgba(0,0,0,0.35));
  transition: opacity 0.25s ease, transform 0.25s ease, filter 0.25s ease;
  cursor: default;
}
.tech-icon:hover {
  opacity: 1;
  transform: translateY(-3px) scale(1.04);
  filter:
    drop-shadow(0 8px 18px rgba(0,0,0,0.45))
    drop-shadow(0 0 12px rgba(0,212,255,0.35));
}

/* Stats */
.stat {
  padding: 22px 16px;
  text-align: center;
}
.stat .num {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 700;
  font-size: 44px;
  line-height: 1;
}
.stat .lbl {
  margin-top: 8px;
  font-size: 10px;
  letter-spacing: 0.3em;
  color: rgba(214,222,234,0.55);
}

/* Social buttons */
.social-btn {
  width: 36px; height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
  /* Explicit dark bg overrides the browser default button background
     (which was rendering as a light-grey rounded square on top of the
     dark page). HUD-style: transparent panel + cyan border + cyan icon
     stroke on hover. */
  background: rgba(8,13,22,0.45);
  border: 1px solid rgba(0,212,255,0.30);
  color: rgba(0,212,255,0.78);
  border-radius: 2px;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
.social-btn:hover { background: rgba(0,212,255,0.10); color: var(--cyan); transform: translateY(-1px); box-shadow: 0 0 0 1px rgba(0,212,255,0.35), 0 6px 14px -6px rgba(0,212,255,0.45); }

/* Ticker */
.ticker-track {
  display: flex;
  white-space: nowrap;
  width: max-content;
  animation: ticker 35s linear infinite;
}
.ticker-list { display: flex; gap: 28px; padding-right: 28px; align-items: center; flex-shrink: 0; }
.ticker-list b { color: rgba(0,212,255,0.45); font-weight: 400; }
@keyframes ticker {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* Reveal animation for hero overlay lines */
.reveal-line { opacity: 0; transform: translateY(16px); }
.reveal-line.in { opacity: 1; transform: translateY(0); transition: opacity 0.7s cubic-bezier(.22,.61,.36,1), transform 0.7s cubic-bezier(.22,.61,.36,1); }

/* Site reveal */
#site.show { opacity: 1; }

/* (unused legacy overlay rule kept for compatibility) */
.legacy-vignette::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse at center, transparent 40%, rgba(4,7,13,0.75) 100%);
}

/* ============================================================ */
/* PROFESSIONAL POLISH PASS                                     */
/* ============================================================ */

/* ---------- Global accessibility focus ring ---------- */
/* Make keyboard focus visible across all interactive controls
   without disturbing the dark/cyan visual language. */
:focus-visible {
  outline: 2px solid rgba(0,212,255,0.85);
  outline-offset: 2px;
  border-radius: 2px;
}
a:focus-visible,
button:focus-visible,
.menu-item:focus-visible,
.social-btn:focus-visible,
.arrow-link:focus-visible {
  outline-offset: 3px;
}

/* Honour user motion preferences globally. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
html { scroll-behavior: smooth; }

/* ---------- Film-grain noise overlay ---------- */
/* Adds a fine, low-opacity SVG-noise layer above the radial gradients
   and grid so panels read as physical surfaces rather than flat fills.
   pointer-events:none + low z-index keeps it purely decorative. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  opacity: 0.06;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.55 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size: 160px 160px;
}

/* ---------- Header — scroll-spy active state + link underline ---------- */
header a.is-active {
  color: var(--cyan);
}
header a {
  position: relative;
}
header a:not(.is-active)::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -4px;
  height: 1px;
  background: var(--cyan);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s ease;
}
header a:hover::after { transform: scaleX(1); }

/* ---------- Project cards — refined polish ---------- */
/* Scan-line sweep on hover (decorative, GPU-only). The base hover
   lift / glow / border already live above; this layer adds a slow
   horizontal highlight band so cards feel "interactive" without
   being noisy. */
.project-card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    115deg,
    transparent 0%,
    transparent 40%,
    rgba(0,212,255,0.08) 50%,
    transparent 60%,
    transparent 100%
  );
  background-size: 250% 100%;
  background-position: 200% 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.4s ease;
  z-index: 1;
}
.project-card:hover::before {
  opacity: 1;
  animation: cardSweep 1.4s cubic-bezier(.4,0,.2,1) 0.05s 1;
}
@keyframes cardSweep {
  from { background-position: 200% 0; }
  to   { background-position: -50%  0; }
}
.project-card > * { position: relative; z-index: 2; }

/* Window-chrome title goes cyan on card hover so the file-name reads
   as a clickable handle. */
.project-card:hover .win-chrome .title { color: var(--cyan); }
.win-chrome .title { transition: color 0.2s ease; }

/* Arrow link — fill on hover + slide-in. */
.arrow-link {
  position: relative;
  overflow: hidden;
  color: var(--cyan);
  border: 1px solid rgba(0,212,255,0.30);
}
.arrow-link::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--cyan);
  transform: translateX(-101%);
  transition: transform 0.3s cubic-bezier(.4,0,.2,1);
}
.arrow-link > * { position: relative; z-index: 1; }
.arrow-link:hover {
  background: transparent;
  color: var(--bg);
  transform: translateX(0);
  border-color: var(--cyan);
  box-shadow: 0 0 18px rgba(0,212,255,0.35);
}
.arrow-link:hover::before { transform: translateX(0); }

/* Project-card badges go slightly brighter on card hover. */
.project-card:hover .badge {
  border-color: rgba(0,212,255,0.55);
  background: rgba(0,212,255,0.08);
}
.badge { transition: border-color 0.25s ease, background 0.25s ease; }

/* ---------- Seaear thumbnails — fill the dead boxes ---------- */
/* The seaear.ru card had two empty dark squares next to the car
   silhouette. Subtle wheel / interior abstractions keep the e-com
   feel without needing real screenshots. */
.seaear-thumb {
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(0,212,255,0.10);
}
.seaear-thumb::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, rgba(0,212,255,0.05), transparent 60%);
  pointer-events: none;
}

/* ---------- Stack list items — subtle hover state ---------- */
.stack-item {
  padding: 4px 6px;
  margin: -4px -6px;
  border-left: 1px solid transparent;
  transition: color 0.2s ease, border-color 0.2s ease,
              background 0.2s ease, transform 0.2s ease;
  cursor: default;
}
.stack-item:hover {
  color: var(--fg);
  border-left-color: var(--cyan);
  background: linear-gradient(90deg, rgba(0,212,255,0.06), transparent);
  transform: translateX(2px);
}
.stack-item:hover .ico { text-shadow: 0 0 12px rgba(0,212,255,0.65); }
.stack-item .ico { transition: text-shadow 0.2s ease; }

/* ---------- About avatar — subtle orbital dot ---------- */
.about-avatar-orbit {
  position: absolute;
  inset: 0;
  pointer-events: none;
  animation: orbitDot 6s linear infinite;
}
.about-avatar-orbit::before {
  content: "";
  position: absolute;
  top: -2px;
  left: 50%;
  width: 6px;
  height: 6px;
  margin-left: -3px;
  border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 0 12px rgba(0,212,255,0.9), 0 0 24px rgba(0,212,255,0.45);
}
@keyframes orbitDot {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ---------- "What I deliver" tiles — glowing icon on hover ---------- */
.about-deliver-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid rgba(0,212,255,0.20);
  border-radius: 2px;
  background: rgba(0,212,255,0.04);
  transition: border-color 0.25s ease, background 0.25s ease,
              box-shadow 0.25s ease, transform 0.25s ease;
}
.about-deliver-item:hover .about-deliver-icon {
  border-color: rgba(0,212,255,0.55);
  background: rgba(0,212,255,0.08);
  box-shadow: 0 0 18px rgba(0,212,255,0.20);
  transform: scale(1.05);
}

/* ---------- WORK_PROCESS — animated progress line ---------- */
.about-process-step { padding-bottom: 8px; }
.about-process-step::before {
  content: "";
  position: absolute;
  top: 4px;
  left: 0;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 0 12px rgba(0,212,255,0.6);
  transform: translate(-1px, 18px);
}
.about-process-line {
  position: relative;
  overflow: hidden;
  background: rgba(0,212,255,0.15);
  margin-top: 12px;
}
.about-process-line::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, var(--cyan), transparent);
  transform: translateX(-100%);
  animation: processFlow 3.2s cubic-bezier(.4,0,.2,1) infinite;
}
.about-process-step:nth-child(2) .about-process-line::after { animation-delay: 0.4s; }
.about-process-step:nth-child(3) .about-process-line::after { animation-delay: 0.8s; }
.about-process-step:nth-child(4) .about-process-line::after { animation-delay: 1.2s; }
@keyframes processFlow {
  0%   { transform: translateX(-100%); }
  60%  { transform: translateX(100%); }
  100% { transform: translateX(100%); }
}

/* ---------- Stats banner — corner ticks ---------- */
.stats-band {
  position: relative;
}
.stats-band::before,
.stats-band::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  pointer-events: none;
  border-color: var(--cyan);
  border-style: solid;
  border-width: 0;
}
.stats-band::before {
  top: -1px; left: -1px;
  border-top-width: 1px;
  border-left-width: 1px;
}
.stats-band::after {
  bottom: -1px; right: -1px;
  border-bottom-width: 1px;
  border-right-width: 1px;
}
.stat .num {
  background: linear-gradient(180deg, #c4b5fd 0%, var(--violet) 60%, #8b5cf6 100%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 4px 16px rgba(167,139,250,0.25));
}

/* ---------- Contact section — social-btn refinement ---------- */
.social-btn {
  position: relative;
}
.social-btn::after {
  content: "";
  position: absolute;
  inset: -1px;
  border: 1px solid var(--cyan);
  border-radius: 2px;
  opacity: 0;
  transform: scale(1.15);
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.social-btn:hover::after {
  opacity: 1;
  transform: scale(1);
}

/* SEND_MESSAGE button — keep cyan brand but tighten the press/hover. */
.btn-send {
  transition: box-shadow 0.2s ease, transform 0.05s ease, filter 0.2s ease;
  border-radius: 2px;
}
.btn-send:hover {
  box-shadow:
    0 0 0 1px rgba(0,212,255,0.55),
    0 0 28px rgba(0,212,255,0.45),
    0 12px 28px -8px rgba(0,212,255,0.45);
  filter: brightness(1.08);
}
.btn-send:active { transform: translateY(1px); }

/* ---------- Hero menu items — subtle right-arrow slide + scroll-spy ---------- */
.menu-item .arrow { transition: transform 0.25s ease, color 0.25s ease; }
.menu-item:hover .arrow { transform: translateX(4px); color: var(--cyan); }

/* Active state set by initScrollSpy() — current section's menu row
   gets a soft cyan tint + persistent arrow shift so the menu reads
   like a navigation. */
.menu-item.is-active {
  background: linear-gradient(90deg, rgba(0,212,255,0.10), rgba(0,212,255,0.02));
  color: #fff;
  box-shadow: inset 2px 0 0 0 var(--cyan);
}
.menu-item.is-active .arrow {
  color: var(--cyan);
  transform: translateX(4px);
}
.menu-item.is-active .num,
.menu-item.is-active .ico { text-shadow: 0 0 10px rgba(0,212,255,0.65); }

/* ---------- Footer — link hover ---------- */
footer a {
  position: relative;
  transition: color 0.2s ease;
}
footer a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -3px;
  height: 1px;
  background: var(--cyan);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.25s ease;
}
footer a:hover { color: var(--cyan); }
footer a:hover::after {
  transform: scaleX(1);
  transform-origin: left;
}

/* ============================================================ */
/* THIRD POLISH WAVE                                            */
/* ============================================================ */

/* ---------- Project cards: status badge in window chrome ---------- */
/* Tiny HUD chip on the right of each project file-name. Variants
   communicate deployment state at a glance. */
.project-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 7px;
  border: 1px solid rgba(0,212,255,0.30);
  border-radius: 1px;
  font-size: 8.5px;
  letter-spacing: 0.25em;
  background: rgba(0,212,255,0.06);
  color: var(--cyan);
  text-transform: uppercase;
  line-height: 1;
  transition: border-color 0.25s ease, background 0.25s ease, color 0.25s ease;
}
.project-status .sd {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 8px currentColor;
  display: inline-block;
  position: relative;
}
.project-status .sd::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.35;
  animation: statusPing 2.1s cubic-bezier(0, 0, 0.2, 1) infinite;
  pointer-events: none;
}
@keyframes statusPing {
  0%   { transform: scale(0.6); opacity: 0.55; }
  100% { transform: scale(1.6); opacity: 0;    }
}

.project-status.status-live {
  color: #34d399;
  border-color: rgba(52,211,153,0.45);
  background: rgba(52,211,153,0.08);
}
.project-status.status-deployed {
  color: #00d4ff;
  border-color: rgba(0,212,255,0.45);
  background: rgba(0,212,255,0.08);
}
.project-status.status-ready {
  color: #c4b5fd;
  border-color: rgba(167,139,250,0.45);
  background: rgba(167,139,250,0.10);
}
.project-status.status-wip {
  color: #fbbf24;
  border-color: rgba(251,191,36,0.45);
  background: rgba(251,191,36,0.08);
}
.project-status.status-wip .sd::after {
  /* WIP gets a slower, calmer pulse so it doesn't read as 'live' */
  animation-duration: 3.2s;
}

/* ---------- Project cards: micro-metrics row ---------- */
/* Sits between .project-preview and .project-meta. Reads as a thin
   strip of telemetry (UPTIME / USERS / P95 / etc.) and turns cyan on
   card hover so the card feels like a live HUD panel. */
.project-stats {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-top: 1px solid rgba(0,212,255,0.08);
  background: rgba(0,212,255,0.02);
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  line-height: 1.1;
  color: rgba(214,222,234,0.45);
  transition: background 0.25s ease, border-color 0.25s ease, color 0.25s ease;
}
.project-stats .k {
  color: rgba(214,222,234,0.45);
}
.project-stats .v {
  color: var(--cyan);
  font-weight: 600;
}
.project-stats .sep {
  color: rgba(0,212,255,0.30);
  margin: 0 2px;
}
.project-card:hover .project-stats {
  background: rgba(0,212,255,0.05);
  border-top-color: rgba(0,212,255,0.25);
  color: rgba(214,222,234,0.75);
}
.project-card:hover .project-stats .v {
  text-shadow: 0 0 10px rgba(0,212,255,0.45);
}

/* ---------- Tech-icon tooltips ---------- */
/* Wrap each tech-icon SVG in .tech-icon-wrap[data-name="..."] so we
   can render the name on hover or keyboard focus. Pure CSS tooltip. */
.tech-icon-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
  cursor: default;
  outline: none;
}
.tech-icon-wrap::before,
.tech-icon-wrap::after {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
  will-change: opacity, transform;
}
/* Caret */
.tech-icon-wrap::before {
  content: "";
  bottom: calc(100% - 2px);
  left: 50%;
  width: 8px;
  height: 8px;
  background: rgba(8,13,22,0.95);
  border-left: 1px solid rgba(0,212,255,0.45);
  border-top: 1px solid rgba(0,212,255,0.45);
  transform: translate(-50%, 4px) rotate(45deg);
  z-index: 5;
}
/* Label */
.tech-icon-wrap::after {
  content: attr(data-name);
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translate(-50%, 4px);
  padding: 5px 10px;
  font-size: 9px;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--cyan);
  background: rgba(8,13,22,0.95);
  border: 1px solid rgba(0,212,255,0.45);
  white-space: nowrap;
  border-radius: 1px;
  box-shadow: 0 8px 24px -8px rgba(0,212,255,0.30), 0 0 0 1px rgba(0,212,255,0.05);
  z-index: 4;
}
.tech-icon-wrap:hover::before,
.tech-icon-wrap:focus-visible::before {
  opacity: 1;
  transform: translate(-50%, 0) rotate(45deg);
}
.tech-icon-wrap:hover::after,
.tech-icon-wrap:focus-visible::after {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* ---------- Hero scroll-hint ---------- */
/* Small "SCROLL ↓" affordance directly below the tech ticker.
   Pulses + bounces; turns brighter on hover. Acts as a link to
   #about. Hidden when the user has already scrolled past the hero. */
.hero-scroll-hint {
  position: relative;
  left: 50%;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 22px auto 4px;
  padding: 6px 12px;
  width: max-content;
  color: rgba(0,212,255,0.85);
  font-size: 9px;
  letter-spacing: 0.35em;
  text-transform: uppercase;
  border: 1px solid rgba(0,212,255,0.18);
  border-radius: 2px;
  background: rgba(4,7,13,0.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  transform: translateX(-50%);
  transition: color 0.25s ease, border-color 0.25s ease,
              background 0.25s ease, transform 0.25s ease, opacity 0.25s ease;
}
.hero-scroll-hint:hover {
  color: var(--cyan);
  border-color: rgba(0,212,255,0.35);
  background: rgba(0,212,255,0.04);
  transform: translateX(-50%) translateY(-1px);
}
.hero-scroll-hint .hsh-line {
  position: relative;
  width: 36px;
  height: 1px;
  background: rgba(0,212,255,0.20);
  overflow: hidden;
}
.hero-scroll-hint .hsh-line-bar {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, var(--cyan), transparent);
  transform: translateX(-100%);
  animation: scrollHintLine 2.6s cubic-bezier(.4,0,.2,1) infinite;
}
.hero-scroll-hint .hsh-arrow {
  display: inline-block;
  animation: scrollHintBounce 2.2s cubic-bezier(.4,0,.2,1) infinite;
}
@keyframes scrollHintLine {
  0%   { transform: translateX(-100%); }
  55%  { transform: translateX(100%);  }
  100% { transform: translateX(100%);  }
}
@keyframes scrollHintBounce {
  0%, 100% { transform: translateY(0); opacity: 0.7; }
  50%      { transform: translateY(3px); opacity: 1; }
}
/* Auto-hide when the user has scrolled past the hero (set in JS). */
body.scrolled .hero-scroll-hint {
  opacity: 0;
  pointer-events: none;
  transform: translateX(-50%) translateY(8px);
}

/* ---------- Footer: back-to-top button ---------- */
.back-to-top {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 10px;
  border: 1px solid rgba(0,212,255,0.25);
  border-radius: 1px;
  color: rgba(214,222,234,0.85);
  background: rgba(0,212,255,0.02);
  transition: color 0.2s ease, background 0.2s ease,
              border-color 0.2s ease, transform 0.2s ease,
              box-shadow 0.2s ease;
}
.back-to-top::after { display: none !important; } /* don't show link underline */
.back-to-top i {
  font-style: normal;
  display: inline-block;
  transition: transform 0.25s ease;
}
.back-to-top:hover {
  color: var(--cyan);
  background: rgba(0,212,255,0.08);
  border-color: rgba(0,212,255,0.55);
  transform: translateY(-1px);
  box-shadow: 0 0 16px rgba(0,212,255,0.20);
}
.back-to-top:hover i { transform: translateY(-2px); }

/* ---------- TERMINAL_LOG (hero left rail): row hover shimmer ---------- */
/* Subtle cyan sweep behind each terminal-log line on hover so the
   panel reads as an actual scrolling log. */
#site aside .panel:last-child ul li {
  position: relative;
  padding-left: 2px;
  transition: color 0.25s ease, transform 0.25s ease;
  overflow: hidden;
}
#site aside .panel:last-child ul li::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(0,212,255,0.18), transparent 60%);
  transform: translateX(-100%);
  transition: transform 0.45s cubic-bezier(.4,0,.2,1);
  pointer-events: none;
  z-index: 0;
}
#site aside .panel:last-child ul li > * {
  position: relative;
  z-index: 1;
}
#site aside .panel:last-child ul li:hover {
  color: var(--cyan);
  transform: translateX(2px);
}
#site aside .panel:last-child ul li:hover::before {
  transform: translateX(0);
}

/* ---------- Section headers: animated divider underline ---------- */
/* Each section starts with a label ("01_ABOUT") next to a thin
   horizontal line. Animate that line so it draws in from the left
   when the section enters the viewport. */
[data-reveal] .h-px.flex-1 {
  position: relative;
  overflow: hidden;
  background: rgba(214,222,234,0.10);
}
[data-reveal] .h-px.flex-1::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--cyan) 0%, transparent 70%);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 1.2s cubic-bezier(.22,.61,.36,1) 0.15s;
}
[data-reveal].is-visible .h-px.flex-1::after {
  transform: scaleX(1);
}

/* ---------- Reduced motion: kill all the new looping animations ---------- */
@media (prefers-reduced-motion: reduce) {
  .project-status .sd::after,
  .hero-scroll-hint .hsh-line-bar,
  .hero-scroll-hint .hsh-arrow {
    animation: none !important;
  }
  [data-reveal] .h-px.flex-1::after {
    transform: scaleX(1) !important;
    transition: none !important;
  }
}

/* ============================================================ */
/* FOURTH POLISH WAVE                                           */
/* ============================================================ */

/* ---------- Project 4 (HR-BOT): Telegram-style chat mockup ---------- */
.hrbot-preview .hr-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: linear-gradient(160deg, rgba(0,212,255,0.18), rgba(0,212,255,0.02));
  border: 1px solid rgba(0,212,255,0.30);
  flex: none;
}
.hrbot-preview .hr-avatar svg { width: 12px; height: 12px; }
.hrbot-preview .hr-chat {
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin-top: 4px;
}
.hrbot-preview .hr-msg {
  max-width: 88%;
  padding: 5px 8px;
  border-radius: 8px;
  font-size: 9.5px;
  letter-spacing: 0.02em;
  line-height: 1.35;
}
.hrbot-preview .hr-msg-bot {
  align-self: flex-start;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  color: rgba(214,222,234,0.88);
  border-bottom-left-radius: 2px;
}
.hrbot-preview .hr-msg-user {
  align-self: flex-end;
  background: rgba(0,212,255,0.16);
  border: 1px solid rgba(0,212,255,0.40);
  color: #e6f8ff;
  border-bottom-right-radius: 2px;
}
.hrbot-preview .hr-typing {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 4px 8px;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 8px;
  border-bottom-left-radius: 2px;
}
.hrbot-preview .hr-typing span {
  width: 4px; height: 4px;
  border-radius: 50%;
  background: rgba(0,212,255,0.85);
  animation: hrTyping 1.2s ease-in-out infinite;
}
.hrbot-preview .hr-typing span:nth-child(2) { animation-delay: 0.15s; }
.hrbot-preview .hr-typing span:nth-child(3) { animation-delay: 0.30s; }
@keyframes hrTyping {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
  30%           { transform: translateY(-3px); opacity: 1; }
}

/* ---------- Project 5 (SEAEAR): e-commerce product grid ---------- */
.seaear-preview .se-cart {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 6px;
  border: 1px solid rgba(0,212,255,0.30);
  border-radius: 1px;
  color: var(--cyan);
  font-size: 8.5px;
  letter-spacing: 0.25em;
}
.seaear-preview .se-cart i {
  font-style: normal;
  background: var(--cyan);
  color: var(--bg);
  font-weight: 700;
  padding: 0 4px;
  border-radius: 1px;
  font-size: 8.5px;
}
.seaear-preview .se-tile {
  background: linear-gradient(180deg, rgba(11,18,32,0.85), rgba(7,11,20,0.85));
  border: 1px solid rgba(214,222,234,0.10);
  border-radius: 2px;
  padding: 4px 5px 4px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  transition: border-color 0.25s ease, transform 0.25s ease, background 0.25s ease;
}
.seaear-preview .se-tile:hover {
  border-color: rgba(0,212,255,0.45);
  transform: translateY(-1px);
  background: linear-gradient(180deg, rgba(11,18,32,0.95), rgba(0,212,255,0.05));
}
.seaear-preview .se-thumb {
  aspect-ratio: 3 / 2;
  width: 100%;
  background: linear-gradient(180deg, rgba(15,23,42,0.85), rgba(2,6,16,0.85));
  border-radius: 1px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.seaear-preview .se-info {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: 8px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.seaear-preview .se-info span { color: rgba(214,222,234,0.55); }
.seaear-preview .se-info b { color: var(--cyan); font-weight: 600; letter-spacing: 0.10em; }
.seaear-preview .se-stars {
  font-size: 9px;
  letter-spacing: 0.08em;
  color: #fbbf24;
  line-height: 1;
}

/* ---------- Project 6 (FINANCE TRACKER): mini-dashboard mockup ---------- */
.finance-preview .fin-kpi {
  padding: 6px 8px;
  background: rgba(0,212,255,0.03);
  border: 1px solid rgba(0,212,255,0.14);
  border-radius: 2px;
}
.finance-preview .fin-kpi-k {
  font-size: 8.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(214,222,234,0.50);
}
.finance-preview .fin-kpi-v {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 13px;
  color: #fff;
  margin-top: 2px;
  letter-spacing: 0.02em;
}
.finance-preview .fin-feed {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.finance-preview .fin-tx {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1px 0;
  font-size: 8.5px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  border-bottom: 1px dashed rgba(214,222,234,0.07);
}
.finance-preview .fin-tx:last-child { border-bottom: none; }
.finance-preview .fin-tx-k { color: rgba(214,222,234,0.55); }
.finance-preview .fin-tx-v.fin-in  { color: #34d399; font-weight: 600; }
.finance-preview .fin-tx-v.fin-out { color: rgba(214,222,234,0.55); }
.finance-preview .fin-sparkline polyline,
.finance-preview .fin-sparkline path {
  transition: filter 0.3s ease;
}
.project-card:hover .finance-preview .fin-sparkline polyline {
  filter: drop-shadow(0 0 6px rgba(0,212,255,0.6));
}

/* ---------- UTC clock in header ---------- */
.utc-clock {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.18em;
  padding: 4px 8px;
  border-left: 1px solid rgba(214,222,234,0.10);
  border-right: 1px solid rgba(214,222,234,0.10);
  font-variant-numeric: tabular-nums;
}
.utc-clock #utc-clock {
  display: inline-block;
  min-width: 6.5ch;
  text-align: center;
}

/* ---------- About: proficiency bars ---------- */
.prof-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}
@media (min-width: 768px) {
  .prof-grid { grid-template-columns: 1fr 1fr; column-gap: 24px; }
}
.prof-row {
  display: grid;
  grid-template-columns: 130px 1fr 36px;
  align-items: center;
  gap: 10px;
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.prof-k { color: rgba(214,222,234,0.70); }
.prof-bar {
  position: relative;
  height: 4px;
  background: rgba(214,222,234,0.08);
  border-radius: 1px;
  overflow: hidden;
}
.prof-bar::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(
      90deg,
      transparent 0 8px,
      rgba(214,222,234,0.04) 8px 9px
    );
  pointer-events: none;
}
.prof-fill {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 0;
  background: linear-gradient(90deg, var(--cyan), #5b8cff);
  box-shadow: 0 0 10px rgba(0,212,255,0.45);
  transition: width 1.2s cubic-bezier(.22,.61,.36,1);
}
.prof-grid.is-filled .prof-fill { width: var(--w, 0%); }
.prof-row { --w: 0%; }
.prof-row[style*="--w:92%"] .prof-fill { /* unused: width comes from --w */ }
.prof-v {
  text-align: right;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  color: var(--cyan);
  font-variant-numeric: tabular-nums;
}
/* Pick up --w from inline style on .prof-row so the fill knows its target */
.prof-grid.is-filled .prof-row .prof-fill { width: var(--w); }

/* ---------- Toast ---------- */
.toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%) translateY(14px);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: rgba(4,7,13,0.92);
  border: 1px solid rgba(0,212,255,0.55);
  border-radius: 2px;
  color: var(--cyan);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  font-family: 'JetBrains Mono', monospace;
  box-shadow:
    0 12px 32px -8px rgba(0,212,255,0.30),
    0 0 0 1px rgba(0,212,255,0.05);
  opacity: 0;
  pointer-events: none;
  z-index: 9999;
  transition: opacity 0.25s ease, transform 0.25s cubic-bezier(.22,.61,.36,1);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.toast.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}
.toast.is-error {
  border-color: rgba(248,113,113,0.55);
  color: #f87171;
  box-shadow: 0 12px 32px -8px rgba(248,113,113,0.30);
}
.toast .toast-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: rgba(0,212,255,0.20);
  border: 1px solid rgba(0,212,255,0.55);
}
.toast.is-error .toast-icon {
  background: rgba(248,113,113,0.18);
  border-color: rgba(248,113,113,0.55);
}

/* Visual feedback when a button is currently being copied */
.social-btn.is-copied {
  border-color: var(--cyan) !important;
  background: rgba(0,212,255,0.10);
  color: var(--cyan);
}

/* ---------- Contact: SEND_MESSAGE success state ---------- */
.btn-send.is-sent {
  background: #34d399 !important;
  color: var(--bg) !important;
  box-shadow: 0 0 24px rgba(52,211,153,0.45);
}
.btn-send.is-sent .btn-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: rgba(4,7,13,0.20);
  font-size: 10px;
  font-weight: 800;
}
.btn-send:disabled { cursor: default; }

/* ---------- Reduced motion: kill new looping bits ---------- */
@media (prefers-reduced-motion: reduce) {
  .hrbot-preview .hr-typing span { animation: none !important; }
  .prof-fill { transition: none !important; }
  .toast { transition: opacity 0.1s linear !important; }
}

/* ============================================================ */
/* FIFTH POLISH WAVE                                            */
/* ============================================================ */

/* ---------- Skip link (a11y) ---------- */
.skip-link {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 99999;
  padding: 8px 14px;
  background: var(--bg);
  color: var(--cyan);
  border: 1px solid var(--cyan);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  border-radius: 2px;
  transform: translateY(-150%);
  transition: transform 0.18s cubic-bezier(.22,.61,.36,1);
  text-decoration: none;
}
.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
  outline: none;
  box-shadow: 0 0 0 2px rgba(0,212,255,0.45);
}

/* ---------- Project filter chips ---------- */
.proj-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 16px;
}
.proj-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  font-size: 9px;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  font-family: 'JetBrains Mono', monospace;
  color: rgba(214,222,234,0.65);
  border: 1px solid rgba(214,222,234,0.12);
  background: rgba(8,13,22,0.45);
  border-radius: 1px;
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease,
              background 0.2s ease, box-shadow 0.2s ease,
              transform 0.2s ease;
}
.proj-chip i {
  font-style: normal;
  font-size: 8px;
  color: rgba(214,222,234,0.45);
  padding: 0 5px;
  border: 1px solid rgba(214,222,234,0.10);
  border-radius: 1px;
  background: rgba(214,222,234,0.04);
  letter-spacing: 0.1em;
}
.proj-chip:hover {
  color: var(--cyan);
  border-color: rgba(0,212,255,0.40);
  background: rgba(0,212,255,0.04);
}
.proj-chip.is-active {
  color: var(--cyan);
  border-color: var(--cyan);
  background: rgba(0,212,255,0.08);
  box-shadow: 0 0 12px rgba(0,212,255,0.20);
}
.proj-chip.is-active i {
  color: var(--cyan);
  border-color: rgba(0,212,255,0.40);
  background: rgba(0,212,255,0.10);
}

/* Card filter transitions: collapse non-matches smoothly. Grid keeps
   layout because hidden cards leave the document flow only when the
   transition is complete; until then they fade and shrink. */
.project-card {
  transition: opacity 0.35s cubic-bezier(.22,.61,.36,1),
              transform 0.35s cubic-bezier(.22,.61,.36,1);
}
.project-card.is-hidden {
  opacity: 0;
  transform: scale(0.96);
  pointer-events: none;
  display: none;
}

/* ---------- Globe HUD callout ---------- */
.globe-callout {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 3;
  opacity: 0.85;
}
.globe-callout-label {
  position: absolute;
  top: 18%;
  right: 6%;
  padding: 4px 7px;
  background: rgba(4,7,13,0.85);
  border: 1px solid rgba(0,212,255,0.45);
  border-radius: 1px;
  font-size: 7.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--cyan);
  line-height: 1.3;
  white-space: nowrap;
  z-index: 4;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  box-shadow: 0 0 14px rgba(0,212,255,0.20);
  pointer-events: none;
}
.globe-callout-label > div:last-child {
  font-size: 7px;
  letter-spacing: 0.18em;
  margin-top: 1px;
}
/* Slow scan-pulse ring around the globe disk. */
.globe-scan {
  position: absolute;
  inset: 8%;
  border-radius: 50%;
  border: 1px solid rgba(0,212,255,0.18);
  pointer-events: none;
  z-index: 2;
  animation: globeScan 4.2s cubic-bezier(.22,.61,.36,1) infinite;
}
@keyframes globeScan {
  0%   { transform: scale(0.92); opacity: 0.55; }
  100% { transform: scale(1.10); opacity: 0;    }
}

/* ---------- Contact: inline validation ---------- */
.field-input.has-error {
  border-color: rgba(248,113,113,0.65) !important;
  box-shadow: 0 0 0 1px rgba(248,113,113,0.20) inset, 0 0 14px rgba(248,113,113,0.15);
}
.field-err {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  padding: 3px 7px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #f87171;
  background: rgba(248,113,113,0.06);
  border: 1px solid rgba(248,113,113,0.30);
  border-radius: 1px;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: opacity 0.2s ease, max-height 0.25s ease,
              padding 0.2s ease, margin 0.2s ease;
  padding-top: 0;
  padding-bottom: 0;
}
.field-err.is-shown {
  max-height: 26px;
  opacity: 1;
  padding-top: 3px;
  padding-bottom: 3px;
}
.field-err > span:first-child {
  color: rgba(248,113,113,0.65);
  font-weight: 700;
}
/* Send button disabled state should look intentional, not greyed out. */
.btn-send:disabled {
  background: rgba(0,212,255,0.20) !important;
  color: rgba(4,7,13,0.55) !important;
  box-shadow: none !important;
  cursor: not-allowed;
}

/* ---------- Footer system status bar ---------- */
.footer-sysbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 24px;
  padding: 8px 0 10px;
  border-bottom: 1px solid rgba(214,222,234,0.06);
  font-family: 'JetBrains Mono', monospace;
  font-size: 9.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(214,222,234,0.55);
}
.footer-sysbar .fs-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.footer-sysbar .fs-item b {
  color: var(--cyan);
  font-weight: 600;
  letter-spacing: 0.15em;
  font-variant-numeric: tabular-nums;
}
.footer-sysbar .fs-dot {
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #34d399;
  box-shadow: 0 0 8px rgba(52,211,153,0.7);
  animation: fsDot 1.8s cubic-bezier(0,0,0.2,1) infinite;
}
@keyframes fsDot {
  0%, 100% { opacity: 0.65; transform: scale(1); }
  50%      { opacity: 1;    transform: scale(1.15); }
}
.footer-sysbar .fs-uptime { margin-left: auto; }
@media (max-width: 640px) {
  .footer-sysbar .fs-uptime { margin-left: 0; }
}

/* ---------- Mobile: project mockups under 380px ---------- */
@media (max-width: 380px) {
  /* Tighter project preview padding on tiny phones */
  .project-preview { padding: 10px; }
  /* HR-BOT bubbles stay readable */
  .hrbot-preview .hr-msg { max-width: 95%; font-size: 9px; }
  /* SEAEAR grid drops to a single column on very narrow screens */
  .seaear-preview .se-grid { grid-template-columns: 1fr 1fr; }
  .seaear-preview .se-info span,
  .seaear-preview .se-info b { font-size: 7.5px; }
  /* Finance dashboard collapses donut + feed columns */
  .finance-preview .grid.grid-cols-5 { grid-template-columns: 1fr; gap: 8px; }
  .finance-preview .col-span-2,
  .finance-preview .col-span-3 { grid-column: span 1; }
  /* Proficiency rows shrink first column on small screens */
  .prof-row { grid-template-columns: 100px 1fr 32px; gap: 6px; font-size: 9px; }
}

/* ---------- Reduced motion guards for wave 5 ---------- */
@media (prefers-reduced-motion: reduce) {
  .project-card { transition: none !important; }
  .globe-scan { animation: none !important; }
  .footer-sysbar .fs-dot { animation: none !important; }
}

/* =====================================================================
   Wave 6: HUD-frame tech tiles, equal-height projects, scroll progress,
   AVAILABILITY_THIS_WEEK panel, send-button disabled polish, arrow VIEW
   ================================================================== */

/* ---------- Wave 6.1: HUD frames around big tech icons ----------
   Each .tech-icon-wrap (already a tooltip host) becomes an 88x88 HUD
   tile with a panel background, cyan border, and four corner ticks
   (small absolutely-positioned .tech-tick spans). The brand-colored
   SVG sits centred inside so the icons read as a unified set instead
   of as a row of disparate brand stickers. */
.tech-icon-wrap {
  width: 92px;
  height: 92px;
  padding: 14px;
  background: linear-gradient(180deg, rgba(10,16,28,0.55), rgba(7,11,20,0.78));
  border: 1px solid rgba(0,212,255,0.28);
  border-radius: 3px;
  transition: border-color 0.25s ease, background 0.25s ease,
              transform 0.25s ease, box-shadow 0.25s ease;
}
.tech-icon-wrap::after {
  /* The tooltip label sits above the wrap; keep z-index above frame */
  z-index: 8;
}
.tech-icon-wrap:hover,
.tech-icon-wrap:focus-visible {
  border-color: rgba(0,212,255,0.55);
  background: linear-gradient(180deg, rgba(0,212,255,0.06), rgba(10,16,28,0.85));
  transform: translateY(-3px);
  box-shadow: 0 16px 40px -16px rgba(0,212,255,0.35),
              0 0 0 1px rgba(0,212,255,0.10) inset;
}
.tech-icon-wrap:hover .tech-tick,
.tech-icon-wrap:focus-visible .tech-tick {
  border-color: var(--cyan);
  box-shadow: 0 0 8px rgba(0,212,255,0.5);
}
.tech-icon-wrap .tech-icon {
  width: 100%;
  height: 100%;
  /* Reset the v3 hover lift since the wrap now lifts; keep the
     subtle drop-shadow on the SVG itself. */
  filter: drop-shadow(0 2px 8px rgba(0,0,0,0.35));
  transition: transform 0.25s ease, filter 0.25s ease;
}
.tech-icon-wrap:hover .tech-icon,
.tech-icon-wrap:focus-visible .tech-icon {
  transform: scale(1.05);
  filter: drop-shadow(0 4px 14px rgba(0,0,0,0.45))
          drop-shadow(0 0 10px rgba(0,212,255,0.30));
}
.tech-tick {
  position: absolute;
  width: 10px;
  height: 10px;
  border-color: rgba(0,212,255,0.5);
  border-style: solid;
  border-width: 0;
  pointer-events: none;
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
  z-index: 6;
}
.tech-tick-tl { top: -1px;    left: -1px;    border-top-width: 1px; border-left-width:  1px; }
.tech-tick-tr { top: -1px;    right: -1px;   border-top-width: 1px; border-right-width: 1px; }
.tech-tick-bl { bottom: -1px; left: -1px;    border-bottom-width: 1px; border-left-width:  1px; }
.tech-tick-br { bottom: -1px; right: -1px;   border-bottom-width: 1px; border-right-width: 1px; }

/* ---------- Wave 6.2: Project card height equalization ----------
   The grid was leaving uneven gaps because each card sized to its
   content and the meta strip floated wherever it landed. Default grid
   already stretches sibling cards in a row to match the tallest; we
   only need to make each card a flex column so the meta strip pins to
   the bottom of the card. Don't force equal heights across *rows* —
   that would stretch the smaller row and leave dead space. */
.project-card { display: flex; flex-direction: column; }
.project-preview { flex: 1 1 auto; min-height: 200px; }
.project-meta { margin-top: auto; }

/* ---------- Wave 6.3: Scroll-progress bar (top of viewport) ----------
   Pure-CSS-ish: width set from main.js on scroll. Fixed bar above
   everything, 2px tall, cyan glow. Hidden when reduced motion. */
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  z-index: 9999;
  background: rgba(0,212,255,0.08);
  pointer-events: none;
}
.scroll-progress > i {
  display: block;
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg,
    rgba(0,212,255,0) 0%,
    rgba(0,212,255,0.45) 35%,
    rgba(0,212,255,0.95) 75%,
    #b6f3ff 100%);
  box-shadow: 0 0 12px rgba(0,212,255,0.55), 0 0 24px rgba(0,212,255,0.25);
  transition: width 0.12s linear;
  will-change: width;
}

/* ---------- Wave 6.4: SEND_MESSAGE button — disabled state polish ----
   The validation logic flips `disabled` on first paint so the button
   isn't a confidently-bright "ready" CTA before the form is filled in.
   Use a readable HUD-style "awaiting input" treatment instead of the
   washed-out browser default. */
.btn-send:disabled {
  background: rgba(0,212,255,0.10);
  color: rgba(0,212,255,0.85);
  border: 1px solid rgba(0,212,255,0.35);
  box-shadow: none;
  cursor: not-allowed;
  letter-spacing: 0.35em;
}
.btn-send:disabled:hover {
  background: rgba(0,212,255,0.10);
  transform: none;
  box-shadow: none;
}

/* ---------- Wave 6.5: Arrow-link gets a "VIEW" label on hover ----
   Hover state slides a small label in from the left of the arrow tile
   while the existing cyan fill sweeps under it. Click target unchanged. */
.arrow-link {
  position: relative;
  width: auto;
  min-width: 32px;
  height: 32px;
  padding: 0 10px;
  gap: 8px;
  overflow: hidden;
  font-size: 9px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
}
.arrow-link .al-label {
  display: inline-block;
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  opacity: 0;
  transform: translateX(-6px);
  transition: max-width 0.28s ease, opacity 0.18s ease, transform 0.28s ease;
}
.arrow-link:hover .al-label,
.arrow-link:focus-visible .al-label {
  max-width: 64px;
  opacity: 1;
  transform: translateX(0);
}

/* ---------- Wave 6.6: AVAILABILITY_THIS_WEEK panel ----------
   A small 7-cell strip representing the current week's capacity.
   Each cell carries an intensity class (.a-free | .a-some | .a-full).
   Today gets a cyan outline ring so the week reads at a glance. */
.avail-panel { padding: 10px 10px 12px; }
.avail-week {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
  margin-top: 8px;
}
.avail-day {
  position: relative;
  aspect-ratio: 1 / 1.05;
  border: 1px solid rgba(0,212,255,0.15);
  background: rgba(8,13,22,0.55);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding: 4px 0 0;
  font-size: 8px;
  letter-spacing: 0.2em;
  color: rgba(214,222,234,0.55);
}
.avail-day .ad-bar {
  position: absolute;
  left: 1px; right: 1px; bottom: 1px;
  height: 30%;
  background: rgba(0,212,255,0.30);
  transition: height 0.4s ease, background 0.25s ease;
}
.avail-day.a-some .ad-bar { height: 55%; background: rgba(245,194,66,0.55); }
.avail-day.a-full .ad-bar { height: 85%; background: rgba(239,68,68,0.55); }
.avail-day.a-today {
  border-color: rgba(0,212,255,0.75);
  box-shadow: 0 0 0 1px rgba(0,212,255,0.25) inset,
              0 0 14px rgba(0,212,255,0.20);
  color: var(--cyan);
}
.avail-legend {
  display: flex;
  gap: 10px;
  margin-top: 8px;
  font-size: 8px;
  letter-spacing: 0.18em;
  color: rgba(214,222,234,0.45);
}
.avail-legend .ll {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.avail-legend .ll i {
  width: 8px; height: 4px;
  background: rgba(0,212,255,0.4);
  display: inline-block;
}
.avail-legend .ll.l-some i { background: rgba(245,194,66,0.6); }
.avail-legend .ll.l-full i { background: rgba(239,68,68,0.6); }

@media (max-width: 768px) {
  .tech-icon-wrap { width: 78px; height: 78px; padding: 11px; }
}
@media (max-width: 420px) {
  .tech-icon-wrap { width: 68px; height: 68px; padding: 9px; }
  .project-preview { min-height: 160px; }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-progress > i { transition: none !important; }
  .tech-icon-wrap, .tech-icon-wrap .tech-icon { transition: none !important; }
  .arrow-link .al-label { transition: none !important; }
}

/* =================================================================
   WAVE 7 — Pro polish v7
   - Sticky header densification on scroll
   - Bio keyword highlights
   - ACTIVITY_LAST_7D mini commit-graph panel
   - About sidebar / deliver-grid / work-process stagger reveals
   - Print stylesheet for the RESUME_(PDF) link
   ================================================================= */

/* ---- 7.1 Sticky header: subtle densification once user scrolls past hero ---- */
#site-header {
  transition: background-color 0.25s ease, border-color 0.25s ease,
              box-shadow 0.25s ease, backdrop-filter 0.25s ease;
}
#site-header.is-scrolled {
  background-color: rgba(4,7,13,0.92);
  border-bottom-color: rgba(0,212,255,0.22);
  box-shadow: 0 6px 18px -10px rgba(0,212,255,0.18),
              0 0 0 1px rgba(0,212,255,0.03);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
}
/* Soft cyan rule that draws in under the header when scrolled */
#site-header::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: linear-gradient(90deg,
    rgba(0,212,255,0) 0%,
    rgba(0,212,255,0.55) 35%,
    rgba(0,212,255,0.85) 50%,
    rgba(0,212,255,0.55) 65%,
    rgba(0,212,255,0) 100%);
  opacity: 0;
  transform: scaleX(0.6);
  transform-origin: center;
  transition: opacity 0.3s ease, transform 0.4s cubic-bezier(.22,.61,.36,1);
  pointer-events: none;
}
#site-header.is-scrolled::after {
  opacity: 1;
  transform: scaleX(1);
}

/* ---- 7.2 About bio: keyword highlights ---- */
/* Inline <em class="kw"> wraps key terms in the bio; gives a HUD
   "scan" feel without screaming. Uses font-style: normal so it
   stays a single typographic system. */
.kw {
  font-style: normal;
  color: rgba(0,212,255,0.95);
  background: linear-gradient(180deg, transparent 60%, rgba(0,212,255,0.10) 60%);
  padding: 0 1px;
  border-bottom: 1px dotted rgba(0,212,255,0.40);
  transition: color 0.2s ease, background 0.2s ease, border-color 0.2s ease;
}
.kw:hover {
  color: #b6f3ff;
  background: linear-gradient(180deg, transparent 55%, rgba(0,212,255,0.22) 55%);
  border-bottom-color: rgba(182,243,255,0.85);
}

/* ---- 7.3 ACTIVITY_LAST_7D mini commit-graph panel ---- */
.act-panel { padding: 10px 10px 10px; }
.act-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 3px;
  margin-top: 8px;
  align-items: end;
  height: 42px;
}
.act-bar {
  display: block;
  width: 100%;
  height: var(--h, 30%);
  background: linear-gradient(180deg,
    rgba(0,212,255,0.65) 0%,
    rgba(0,212,255,0.25) 100%);
  border-bottom: 1px solid rgba(0,212,255,0.55);
  transition: height 0.4s cubic-bezier(.22,.61,.36,1), background 0.25s ease;
  will-change: height;
}
.act-bar-today {
  background: linear-gradient(180deg,
    rgba(0,212,255,1) 0%,
    rgba(0,212,255,0.45) 100%);
  border-bottom-color: rgba(182,243,255,0.95);
  box-shadow: 0 0 8px rgba(0,212,255,0.35);
}
.act-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 8px;
  font-size: 8px;
  letter-spacing: 0.22em;
  color: rgba(214,222,234,0.45);
}
.act-footer .text-cyan { font-weight: 600; }

/* ---- 7.4 Reveal staggers for about-deliver-grid + work-process ---- */
/* Pieces inside #about reveal with a small wave when the section
   becomes visible. We piggyback on the existing [data-reveal]
   .is-visible class from main.js — no extra JS needed. */
#about .about-deliver-item,
#about .about-process-step,
#about .prof-row {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.5s cubic-bezier(.22,.61,.36,1),
              transform 0.55s cubic-bezier(.22,.61,.36,1);
}
#about.is-visible .about-deliver-item,
#about.is-visible .about-process-step,
#about.is-visible .prof-row {
  opacity: 1;
  transform: none;
}
#about.is-visible .about-deliver-item:nth-child(1) { transition-delay: 0.08s; }
#about.is-visible .about-deliver-item:nth-child(2) { transition-delay: 0.16s; }
#about.is-visible .about-deliver-item:nth-child(3) { transition-delay: 0.24s; }
#about.is-visible .about-deliver-item:nth-child(4) { transition-delay: 0.32s; }
#about.is-visible .prof-row:nth-child(1) { transition-delay: 0.05s; }
#about.is-visible .prof-row:nth-child(2) { transition-delay: 0.10s; }
#about.is-visible .prof-row:nth-child(3) { transition-delay: 0.15s; }
#about.is-visible .prof-row:nth-child(4) { transition-delay: 0.20s; }
#about.is-visible .prof-row:nth-child(5) { transition-delay: 0.25s; }
#about.is-visible .prof-row:nth-child(6) { transition-delay: 0.30s; }
#about.is-visible .about-process-step:nth-child(1) { transition-delay: 0.10s; }
#about.is-visible .about-process-step:nth-child(2) { transition-delay: 0.18s; }
#about.is-visible .about-process-step:nth-child(3) { transition-delay: 0.26s; }
#about.is-visible .about-process-step:nth-child(4) { transition-delay: 0.34s; }

/* Stack lists: cascade each item in */
#stack .stack-item {
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity 0.4s ease, transform 0.4s cubic-bezier(.22,.61,.36,1);
}
#stack.is-visible .stack-item {
  opacity: 1;
  transform: none;
}
#stack.is-visible .stack-item:nth-child(1) { transition-delay: 0.05s; }
#stack.is-visible .stack-item:nth-child(2) { transition-delay: 0.10s; }
#stack.is-visible .stack-item:nth-child(3) { transition-delay: 0.15s; }
#stack.is-visible .stack-item:nth-child(4) { transition-delay: 0.20s; }
#stack.is-visible .stack-item:nth-child(5) { transition-delay: 0.25s; }
#stack.is-visible .stack-item:nth-child(6) { transition-delay: 0.30s; }

/* Accessibility: respect reduced motion */
@media (prefers-reduced-motion: reduce) {
  #about .about-deliver-item,
  #about .about-process-step,
  #about .prof-row,
  #stack .stack-item {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .act-bar { transition: none !important; }
  #site-header,
  #site-header::after { transition: none !important; }
}

/* ---- 7.5 Print stylesheet — RESUME_(PDF) link should print cleanly ---- */
@media print {
  /* Reset dark theme to white background, dark text */
  body, html { background: #fff !important; color: #111 !important; }
  /* Hide all decorative chrome */
  .scroll-progress,
  .skip-link,
  .hero-fullscreen,
  #preloader,
  #hero-stage,
  #site-header,
  #grain-overlay,
  .footer-sysbar,
  .toast,
  .globe-callout,
  .globe-callout-label,
  .globe-scan,
  .globe-tick,
  .footer,
  .terminal-rail,
  .left-rail-top,
  .left-rail-bottom,
  .tech-ticker,
  .scroll-hint,
  .about-globe-wrap,
  .work-process,
  .stats-band,
  .arrow-link,
  .filter-chips,
  .form-status,
  .btn-send,
  #contact form,
  .contact-side,
  .social-btn,
  .back-to-top { display: none !important; }
  /* Show core resume content only */
  main, #site, section { opacity: 1 !important; background: transparent !important;
                         color: #111 !important; padding: 8px 0 !important; }
  .panel, .project-card { background: #fff !important; border: 1px solid #ccc !important;
                          color: #111 !important; box-shadow: none !important; }
  .text-fg\/85, .text-fg\/70, .text-fg\/50 { color: #333 !important; }
  .text-cyan, .kw { color: #0066aa !important; background: none !important;
                    border-bottom: none !important; }
  a { color: #0066aa !important; text-decoration: underline; }
  .badge { border: 1px solid #999 !important; color: #333 !important;
           background: #f5f5f5 !important; padding: 1px 4px; }
}



/* ============================================================
   8. WAVE 8: nav-drawer, NOW panel, OG cover, scroll URL sync
   ============================================================ */

/* ---- 8.1 Mobile hamburger button (md-hidden header) ---- */
.nav-toggle {
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: 1px solid rgba(0, 212, 255, 0.25);
  background: rgba(0, 212, 255, 0.05);
  border-radius: 2px;
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease;
  position: relative;
  /* Only show on mobile — md+ uses the regular header links. The
     parent .md\:hidden Tailwind class also hides it, but we add an
     explicit display rule here in case cascade order shifts. */
  display: inline-flex;
}
@media (min-width: 768px) {
  .nav-toggle { display: none; }
}
.nav-toggle:hover { border-color: rgba(0, 212, 255, 0.55); background: rgba(0, 212, 255, 0.10); }
.nav-toggle:focus-visible {
  outline: 2px solid rgba(0, 212, 255, 0.7);
  outline-offset: 2px;
}
.nav-toggle-bars {
  display: inline-flex;
  flex-direction: column;
  gap: 3px;
  width: 14px;
}
.nav-toggle-bars i {
  display: block;
  height: 1.5px;
  background: #00d4ff;
  transform-origin: center;
  transition: transform 0.25s ease, opacity 0.2s ease;
}
.nav-toggle-bars i:nth-child(1) { width: 14px; }
.nav-toggle-bars i:nth-child(2) { width: 10px; align-self: flex-end; }
.nav-toggle-bars i:nth-child(3) { width: 14px; }
body.is-nav-open .nav-toggle-bars i:nth-child(1) {
  transform: translateY(4.5px) rotate(45deg);
  width: 14px;
}
body.is-nav-open .nav-toggle-bars i:nth-child(2) { opacity: 0; }
body.is-nav-open .nav-toggle-bars i:nth-child(3) {
  transform: translateY(-4.5px) rotate(-45deg);
  width: 14px;
}

/* ---- 8.2 Nav drawer (mobile slide-in) ---- */
.nav-drawer {
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
  display: block;
}
.nav-drawer[hidden] { display: none; }
@media (min-width: 768px) {
  .nav-drawer { display: none !important; }
}
.nav-drawer-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(2, 5, 11, 0);
  backdrop-filter: blur(0px);
  transition: background 0.3s ease, backdrop-filter 0.3s ease;
}
.nav-drawer-panel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(86vw, 320px);
  background: linear-gradient(180deg, rgba(4, 8, 14, 0.98) 0%, rgba(8, 12, 22, 0.98) 100%);
  border-left: 1px solid rgba(0, 212, 255, 0.18);
  box-shadow: -20px 0 40px rgba(0, 0, 0, 0.5);
  transform: translateX(100%);
  transition: transform 0.32s cubic-bezier(0.22, 0.61, 0.36, 1);
  display: flex;
  flex-direction: column;
  padding: 18px 18px 22px;
  pointer-events: auto;
}
.nav-drawer.is-open .nav-drawer-backdrop {
  background: rgba(2, 5, 11, 0.55);
  backdrop-filter: blur(4px);
  pointer-events: auto;
}
.nav-drawer.is-open .nav-drawer-panel {
  transform: translateX(0);
}
.nav-drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid rgba(0, 212, 255, 0.15);
  padding-bottom: 12px;
  margin-bottom: 16px;
}
.nav-drawer-title {
  font-family: "JetBrains Mono", monospace;
  font-size: 10px;
  letter-spacing: 0.25em;
  color: rgba(0, 212, 255, 0.7);
}
.nav-drawer-close {
  border: 1px solid rgba(0, 212, 255, 0.25);
  background: rgba(0, 212, 255, 0.06);
  color: #00d4ff;
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.nav-drawer-close:hover { background: rgba(0, 212, 255, 0.15); border-color: rgba(0, 212, 255, 0.55); }
.nav-drawer-links {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.nav-drawer-link {
  display: grid;
  grid-template-columns: 32px 1fr 20px;
  align-items: center;
  gap: 10px;
  padding: 12px 12px;
  border: 1px solid rgba(255, 255, 255, 0.04);
  background: rgba(255, 255, 255, 0.015);
  color: rgba(255, 255, 255, 0.85);
  font-family: "JetBrains Mono", monospace;
  font-size: 12px;
  letter-spacing: 0.18em;
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease, padding-left 0.2s ease;
  text-decoration: none;
}
.nav-drawer-link .nd-num {
  color: rgba(0, 212, 255, 0.55);
  font-size: 10px;
  letter-spacing: 0.2em;
}
.nav-drawer-link .nd-label { color: rgba(255, 255, 255, 0.85); }
.nav-drawer-link .nd-arrow {
  color: rgba(0, 212, 255, 0.5);
  font-size: 14px;
  transition: transform 0.2s ease, color 0.2s ease;
}
.nav-drawer-link:hover,
.nav-drawer-link:focus-visible {
  border-color: rgba(0, 212, 255, 0.45);
  background: rgba(0, 212, 255, 0.06);
  color: #00d4ff;
  padding-left: 16px;
  outline: none;
}
.nav-drawer-link:hover .nd-arrow,
.nav-drawer-link:focus-visible .nd-arrow {
  color: #00d4ff;
  transform: translateX(3px);
}
.nav-drawer-meta {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.nav-drawer-ext {
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.2em;
  color: rgba(255, 255, 255, 0.55);
  padding: 6px 4px;
  text-decoration: none;
  transition: color 0.2s ease;
}
.nav-drawer-ext:hover { color: #00d4ff; }
.nav-drawer-foot {
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-family: "JetBrains Mono", monospace;
  font-size: 9.5px;
  letter-spacing: 0.2em;
}
body.is-nav-open { overflow: hidden; }
@media (prefers-reduced-motion: reduce) {
  .nav-drawer-panel { transition: none; }
  .nav-toggle-bars i { transition: none; }
}

/* ---- 8.3 NOW_FOCUS panel ---- */
.now-panel {
  padding: 12px 12px 10px;
  position: relative;
}
.now-panel .now-tag {
  font-family: "JetBrains Mono", monospace;
  font-size: 8.5px;
  letter-spacing: 0.3em;
  color: rgba(0, 212, 255, 0.65);
  border: 1px solid rgba(0, 212, 255, 0.25);
  padding: 1px 5px;
}
.now-list {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  list-style: none;
  padding: 0;
}
.now-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-family: "JetBrains Mono", monospace;
  font-size: 9.5px;
  letter-spacing: 0.08em;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.75);
}
.now-item b {
  color: rgba(0, 212, 255, 0.85);
  font-weight: 600;
  letter-spacing: 0.18em;
  font-size: 9px;
  margin-right: 1px;
}
.now-bullet {
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-top: 4px;
  background: #00d4ff;
  box-shadow: 0 0 6px rgba(0, 212, 255, 0.7);
  flex-shrink: 0;
  animation: nowPulse 2.4s ease-in-out infinite;
}
.now-item:nth-child(2) .now-bullet { animation-delay: 0.6s; }
.now-item:nth-child(3) .now-bullet { animation-delay: 1.2s; }
@keyframes nowPulse {
  0%, 100% { opacity: 0.45; transform: scale(1); }
  50%      { opacity: 1;    transform: scale(1.3); }
}
@media (prefers-reduced-motion: reduce) {
  .now-bullet { animation: none; opacity: 0.85; }
}

/* ============================================================
   Language switcher
   Tab-style group of 2-letter buttons. Lives in the desktop
   header (next to GITHUB/TG/EMAIL links) and in the mobile
   nav drawer. The active language gets the cyan HUD treatment
   (filled background + white text). main.js / i18n.js handle
   the .is-active toggling.
   ============================================================ */
.lang-switcher {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border: 1px solid rgba(0, 212, 255, 0.25);
  padding: 2px;
  background: rgba(0, 212, 255, 0.04);
  margin-left: 10px;
}
.lang-opt {
  font: inherit;
  background: transparent;
  border: 0;
  color: rgba(230, 237, 243, 0.65);
  font-size: 9.5px;
  letter-spacing: 0.18em;
  padding: 3px 7px;
  cursor: pointer;
  font-weight: 600;
  line-height: 1;
  transition: background 0.18s ease, color 0.18s ease;
}
.lang-opt:hover,
.lang-opt:focus-visible {
  color: #00d4ff;
  outline: none;
  background: rgba(0, 212, 255, 0.08);
}
.lang-opt.is-active {
  background: #00d4ff;
  color: #04070d;
}
.nav-drawer .lang-switcher {
  margin-left: 0;
  margin-top: 14px;
  align-self: flex-start;
}
@media (max-width: 768px) {
  .lang-switcher { gap: 2px; padding: 2px; }
  .lang-opt { padding: 3px 6px; font-size: 9px; }
}

/* =====================================================================
   Intro scroll-lock. main.js adds .is-intro to <html> and <body> until
   the hero animation has revealed the HUD. While that class is on, the
   document is pinned at the top and overflow is hidden — so reloading
   the page mid-scroll cannot skip past the intro, and neither touch
   nor mousewheel can scrub past it while it plays. */
html.is-intro,
body.is-intro {
  overflow: hidden !important;
  overscroll-behavior: contain;
  touch-action: none;
}

/* =====================================================================
   Wave 10 — Full mobile pass.

   Goals:
   1. No horizontal overflow at any phone width (offender was the
      footer .back-to-top link refusing to wrap).
   2. Hide desktop-only HUD chrome (VIEWPORT_/ZOOM_ chips, vertical
      SCROLL_INDICATOR, MOVE_CURSOR / PARALLAX_ACTIVE pills) on
      touch viewports — they reference inputs touch devices don't have.
   3. Flatten the right-side .float-card 3D tilt on phones so the
      LUMEN / NOVA / AI-CONSULTANT cards no longer overshoot the
      viewport on the right.
   4. Tighten the header so DEV_PORTFOLIO / centered "T." / hamburger
      all fit on one line at 360px without clipping.
   5. WCAG-friendly tap targets (≥ 40px) on language opts and footer
      external links.
   6. Make the SEND_MESSAGE disabled state look intentional, not broken.
   ================================================================== */
@media (max-width: 767px) {
  /* 1 — guard against any subtle overflow from 3D tilts / marquees. */
  html, body { overflow-x: clip; }
  body { max-width: 100vw; }

  /* 2 — drop pointer-only HUD bling + the desktop header lang switcher
     (the mobile drawer has its own copy). The .hidden class alone is
     not enough because .lang-switcher { display: inline-flex; } is
     defined later and wins the cascade without !important. */
  .hud-corner-tr,
  .hud-scroll,
  .hud-cursor.hud-cursor-top,
  #site-header .lang-switcher.hidden {
    display: none !important;
  }

  /* 3 — flatten the floating project cards so their right edge stops
     poking past the viewport. We keep the soft float (vertical) but
     remove the rotateY tilt and any horizontal drift. */
  .float-card,
  .float-card.delay-0,
  .float-card.delay-1,
  .float-card.delay-2 {
    --tilt-rx: 0deg;
    --tilt-ry: 0deg;
    --tilt-rz: 0deg;
    --float-x: 0px;
    transform: none;
    animation: none;
  }
  .float-stack { gap: 10px; }

  /* 4 — header layout. The center column still hosts the "T." mark; we
     tighten gaps and let the left column ellipsize instead of pushing
     the centre out of place. */
  #site-header .grid {
    column-gap: 8px;
    padding-left: 12px;
    padding-right: 12px;
  }
  #site-header .grid > div:first-child {
    min-width: 0;
  }
  #site-header .grid > div:first-child > span:first-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: inline-block;
    max-width: 100%;
  }

  /* 5 — touch tap targets. */
  .nav-drawer-lang.lang-switcher .lang-opt {
    min-height: 40px;
    padding: 10px 14px;
    font-size: 11px;
  }
  .footer-links a,
  .footer-links .back-to-top {
    min-height: 32px;
    display: inline-flex;
    align-items: center;
  }
  .social-btn {
    width: 40px;
    height: 40px;
  }

  /* 6 — SEND_MESSAGE disabled state: intentional HUD look, not "broken". */
  .btn-send:disabled {
    background: rgba(0,212,255,0.14) !important;
    color: rgba(0,212,255,0.85) !important;
    box-shadow: inset 0 0 0 1px rgba(0,212,255,0.40) !important;
    cursor: not-allowed;
  }

  /* Hero subtitle (Web Apps · SaaS Platforms · …) — reduce letter-spacing
     so it stays on one line at 375px and reads cleanly at 360px. */
  #hero-overlay .reveal-line.text-fg\/70,
  #hero-overlay .hero-subtitle {
    letter-spacing: 0.08em;
  }

  /* Hero menu under the icosahedron: full-width on phones. */
  #hero-menu.hero-menu {
    max-width: 100%;
  }

  /* Project preview windows already have their own collapse rules below
     380px; nothing else needed here. */
}

/* Footer bottom row — wrap copyright + links nicely at all phone sizes.
   This rule is breakpoint-independent so it also helps tablets. */
.footer-bottom .footer-links {
  flex-wrap: wrap;
  row-gap: 8px;
}
.footer-bottom .back-to-top {
  white-space: nowrap;
}
@media (max-width: 640px) {
  .footer-bottom { gap: 12px; }
  .footer-bottom .footer-copy { font-size: 9.5px; }
  .footer-bottom .footer-copy .footer-sep {
    /* The "//" separator is decorative; on tiny phones it visually
       collides with the wrapped "BUILT IN…" line. Hide it instead of
       letting it float on its own row. */
    display: none;
  }
  .footer-bottom .footer-links a,
  .footer-bottom .footer-links .back-to-top {
    font-size: 9.5px;
  }
}

/* ============================================================
   Project preview · screenshot variant (NOVA case study)
   ----------------------------------------------------------
   Wraps the live hero shot in a tight win-chrome-style frame so
   the card reads as a real product window rather than a flat
   image. Image fills the slot at object-fit: cover; a small
   tag-strip overlays the bottom for "menu" context.
   ============================================================ */
.project-preview--shot {
  padding: 0;
  background: transparent;
  min-height: 200px;
  display: flex;
  align-items: stretch;
}
.project-shot {
  position: relative;
  width: 100%;
  min-height: 200px;
  overflow: hidden;
  background: linear-gradient(180deg, rgba(0,212,255,0.05), rgba(0,0,0,0));
}
.project-shot img {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 200px;
  object-fit: cover;
  object-position: top center;
  transition: transform 0.5s cubic-bezier(0.2,0.6,0.2,1), filter 0.4s ease;
  filter: saturate(0.95) brightness(0.92);
}
.project-card:hover .project-shot img,
.project-card:focus-visible .project-shot img {
  transform: scale(1.03);
  filter: saturate(1.05) brightness(1);
}
.project-shot::after {
  /* Subtle bottom gradient so the tag is readable over any shot. */
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 40%;
  background: linear-gradient(180deg, rgba(0,0,0,0), rgba(4,7,13,0.75));
  pointer-events: none;
}
.project-shot-tag {
  position: absolute;
  left: 10px;
  bottom: 8px;
  z-index: 1;
  color: rgba(214,222,234,0.75);
  font-size: 9px;
  letter-spacing: 0.2em;
}

/* Clickable card affordance — keep the rest of the card visually
   identical, just lift the cursor and ring on focus so the whole
   tile reads as a button. */
.project-card--case { cursor: pointer; }
.project-card--case:focus-visible {
  outline: none;
  border-color: rgba(0,212,255,0.55);
  box-shadow: 0 0 0 1px rgba(0,212,255,0.45), 0 12px 40px rgba(0,212,255,0.18);
}

/* ============================================================
   Case-study modal (NOVA)
   ----------------------------------------------------------
   Full-viewport overlay with cyan HUD trim. Panel scrolls
   vertically; backdrop dims everything else. Closes via the ✕,
   the backdrop, or Escape (main.js).
   ============================================================ */
.case-modal {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: stretch;
  justify-content: center;
  /* `hidden` HTML attribute drives display; the open class drives
     fade in. */
}
.case-modal[hidden] { display: none; }
.case-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(4,7,13,0.78);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity 0.25s ease;
}
.case-modal.is-open .case-modal-backdrop { opacity: 1; }

.case-modal-panel {
  position: relative;
  margin: auto;
  width: min(1200px, calc(100vw - 24px));
  max-height: calc(100vh - 24px);
  background: linear-gradient(180deg, rgba(11,16,25,0.96), rgba(4,7,13,0.96));
  border: 1px solid rgba(0,212,255,0.22);
  box-shadow: 0 30px 80px rgba(0,212,255,0.10), 0 0 0 1px rgba(0,0,0,0.4);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transform: translateY(12px) scale(0.985);
  opacity: 0;
  transition: opacity 0.28s ease, transform 0.28s cubic-bezier(0.2,0.6,0.2,1);
}
.case-modal.is-open .case-modal-panel {
  transform: translateY(0) scale(1);
  opacity: 1;
}

.case-modal-head {
  position: relative;
  padding: 14px 56px 14px 18px;
  border-bottom: 1px solid rgba(0,212,255,0.12);
  background: rgba(0,212,255,0.03);
}
.case-modal-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 10px;
  letter-spacing: 0.25em;
  color: rgba(214,222,234,0.6);
}
.case-modal-tag { color: var(--cyan); }
.case-modal-dot { color: rgba(0,212,255,0.5); }
.case-modal-link {
  color: rgba(214,222,234,0.85);
  text-decoration: none;
  transition: color 0.2s ease;
}
.case-modal-link:hover { color: var(--cyan); }
.case-modal-title {
  margin: 6px 0 0;
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: clamp(18px, 2.2vw, 24px);
  line-height: 1.15;
  letter-spacing: 0.02em;
  color: #fff;
}
/* Close pinned to the panel corner on every viewport so it sits flush
   with the panel border instead of floating in the header padding. */
.case-modal-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: rgba(214,222,234,0.7);
  background: rgba(0,212,255,0.06);
  border: 1px solid rgba(0,212,255,0.25);
  border-radius: 0;
  cursor: pointer;
  transition: color 0.2s ease, background 0.2s ease, border-color 0.2s ease;
  z-index: 1;
}
.case-modal-close:hover,
.case-modal-close:focus-visible {
  color: var(--cyan);
  border-color: rgba(0,212,255,0.55);
  background: rgba(0,212,255,0.1);
  outline: none;
}

/* Body lays out the case-shot above the actions row in a flex column,
   no scrolling — the image scales to fit whichever viewport dimension
   hits first. Phones scale by width; laptops scale by height. */
.case-modal-body {
  padding: 16px 18px 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
.case-shot {
  position: relative;
  margin: 0;
  border: 1px solid rgba(0,212,255,0.18);
  background: #04070d;
  overflow: hidden;
}
/* Sections tearsheet: centered, capped on both axes so it never
   overflows the viewport. max-height accounts for the header, the
   foot, and the body padding so the image always fits cleanly. */
.case-shot--grid {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px;
}
.case-shot--grid img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: calc(100vh - 220px);
  margin: 0 auto;
}

.case-modal-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-top: 4px;
  flex-wrap: wrap;
  flex-shrink: 0;
}
.case-modal-stack {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
}
.case-modal-actions {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.case-modal-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  font-size: 11px;
  letter-spacing: 0.22em;
  color: var(--cyan);
  background: rgba(0,212,255,0.06);
  border: 1px solid rgba(0,212,255,0.35);
  text-decoration: none;
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.case-modal-cta:hover,
.case-modal-cta:focus-visible {
  background: rgba(0,212,255,0.12);
  border-color: rgba(0,212,255,0.6);
  color: #fff;
  outline: none;
}
/* Secondary CTA (source repo link) — subtler than the primary live-site
   button so the eye still lands on the live site first. */
.case-modal-cta--ghost {
  color: rgba(214,222,234,0.75);
  background: transparent;
  border-color: rgba(214,222,234,0.22);
}
.case-modal-cta--ghost:hover,
.case-modal-cta--ghost:focus-visible {
  color: var(--cyan);
  border-color: rgba(0,212,255,0.45);
  background: rgba(0,212,255,0.06);
}

/* Lock body scroll when a case modal is open. */
body.case-open { overflow: hidden; }

/* Mobile tightening for the case modal. The image already scales by
   width here, so we hand more vertical room back to the picture. */
@media (max-width: 640px) {
  .case-modal-panel { width: calc(100vw - 12px); max-height: calc(100vh - 12px); }
  .case-modal-head { padding: 12px 50px 12px 14px; }
  .case-modal-body { padding: 12px; gap: 12px; }
  .case-modal-title { font-size: 16px; }
  .case-modal-close { top: 8px; right: 8px; }
  .case-shot--grid img { max-height: calc(100vh - 200px); }
  .case-modal-actions { width: 100%; justify-content: flex-end; }
}

@media (prefers-reduced-motion: reduce) {
  .case-modal-backdrop,
  .case-modal-panel,
  .project-shot img {
    transition: none !important;
  }
}
