@keyframes blink {
  0%, 49%  { opacity: 1; }
  50%, 100% { opacity: 0; }
}

@keyframes revealUp {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: none; }
}

@keyframes glowPulse {
  0%, 100% { opacity: .5; }
  50%       { opacity: .85; }
}

@keyframes floatGrid {
  from { transform: translateY(0); }
  to   { transform: translateY(-40px); }
}

@keyframes rootScan {
  from { transform: translateY(-100%); }
  to   { transform: translateY(100vh); }
}

@keyframes rootGlitch {
  0%, 100% { transform: translate(0, 0);    opacity: 1; }
  20%       { transform: translate(-3px, 1px); }
  40%       { transform: translate(3px, -1px); }
  60%       { transform: translate(-2px, 0); }
  80%       { transform: translate(2px, 1px); }
}

@keyframes rootFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes bannerWipe {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 -2% 0 0); }
}

@keyframes bannerGlow {
  0%, 100% { filter: drop-shadow(0 1px 14px rgba(var(--purple-rgb), 0.40)); }
  50%       { filter: drop-shadow(0 1px 22px rgba(var(--lilac-rgb), 0.62)); }
}

.section-reveal {
  animation: revealUp .7s both;
  animation-timeline: view();
  animation-range: entry 0% entry 45%;
}
