/* ─────────────────────────────────────────────────────
   effects.css — keyframes, ambient glow, scanlines, transitions
───────────────────────────────────────────────────── */

/* ── First-paint stagger ── cascade reveals the hero in rhythm ── */
@keyframes heroReveal {
  0%   { opacity: 0; transform: translateY(10px); filter: blur(6px); }
  60%  { filter: blur(0); }
  100% { opacity: 1; transform: translateY(0); filter: blur(0); }
}
.hero > .hero-id,
.hero > .hero-h,
.hero > .terminal,
.hero > .chips,
.hero > .hero-hint {
  animation: heroReveal 700ms var(--ease) both;
}
.hero > .hero-id    { animation-delay:  40ms; }
.hero > .hero-h     { animation-delay: 120ms; }
.hero > .terminal   { animation-delay: 260ms; }
.hero > .chips      { animation-delay: 420ms; }
.hero > .hero-hint  { animation-delay: 540ms; }

@media (prefers-reduced-motion: reduce) {
  .hero > .hero-id,
  .hero > .hero-h,
  .hero > .terminal,
  .hero > .chips,
  .hero > .hero-hint { animation: none; }
}

/* ── Vignette — pure radial dark, no corner tints, frames the starfield ── */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 49;
  background: radial-gradient(ellipse at 50% 40%, transparent 55%, rgba(0, 0, 0, 0.5) 100%);
}

/* ── Pulse (accent dot) ── */
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}
.sb-dot,
.brand-dot,
.t-pill-dot,
.palette-dot {
  animation: pulse 2.4s var(--ease) infinite;
}

/* ── Blink (terminal caret) ── */
@keyframes blink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}
.t-prompt .caret {
  animation: blink 1.1s steps(1) infinite;
}

/* ── Sidebar line entrance (boot + dmesg) ── */
@keyframes sbIn {
  0%   { opacity: 0; transform: translateX(-4px); filter: blur(2px); letter-spacing: 0.12em; }
  50%  { opacity: 1; filter: blur(0); letter-spacing: 0.02em; }
  100% { opacity: 1; transform: translateX(0); letter-spacing: 0; }
}
.sb-line { animation: sbIn 360ms var(--ease) both; }

/* ── Terminal line entrance (output) ── */
@keyframes tLineIn {
  0%   { opacity: 0; transform: translateY(3px); filter: blur(1px); }
  100% { opacity: 1; transform: translateY(0); filter: blur(0); }
}
.t-line,
.t-out {
  animation: tLineIn 260ms var(--ease) both;
}

/* ── Palette open ── */
@keyframes overlayIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
.palette-overlay.on { animation: overlayIn 0.2s ease; }

@keyframes paletteIn {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.palette-overlay.on .palette {
  animation: paletteIn 0.28s var(--ease);
}


/* ── Scroll-fade for essays row appearing on scroll ── */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.observe-in {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
.observe-in.visible {
  opacity: 1;
  transform: translateY(0);
}
