/* animations.css — keyframes e stati di reveal (solo con .js) */

@keyframes status-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .35; }
}

@keyframes cue-grow {
  0% { transform: scaleY(0); }
  55% { transform: scaleY(1); }
  100% { transform: scaleY(1); opacity: 0; }
}

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

/* stati iniziali dei reveal: attivi solo quando JS + gsap sono operativi
   (la classe .gsap la aggiunge js/animations.js dopo il check dei vendor),
   così senza JS, senza gsap o in reduced-motion tutto resta visibile */
.js.gsap [data-animate="lines"] .li { transform: translateY(110%); }
.js.gsap [data-animate="fade"] { opacity: 0; transform: translateY(24px); }

.js.gsap .hero-title__word { transform: translateY(110%); }
.js.gsap .hero-top,
.js.gsap .hero-name,
.js.gsap .hero-bottom { opacity: 0; }
.js.gsap .hero-statement { opacity: 0; transform: translateY(12px); }
.js.gsap [data-hero-meta] { opacity: 0; transform: translateY(12px); }

/* loop infiniti (status-pulse, cue-grow): girano solo mentre il loro chapter
   è in scena. .in-view è gestita da scroll.js sui chapter attivo ± 1; senza
   JS la classe non esiste e l'animazione resta sempre attiva. */
.js .chapter:not(.in-view) .status-dot,
.js .chapter:not(.in-view) .scroll-cue__line,
.js .chapter:not(.in-view) .contact-term__caret {
  animation-play-state: paused;
}

/* reduced motion: tutto visibile, niente animazioni */
@media (prefers-reduced-motion: reduce) {
  .js.gsap [data-animate="lines"] .li,
  .js.gsap [data-animate="fade"],
  .js.gsap .hero-title__word,
  .js.gsap .hero-top,
  .js.gsap .hero-name,
  .js.gsap .hero-bottom,
  .js.gsap .hero-statement,
  .js.gsap [data-hero-meta] {
    transform: none !important;
    opacity: 1 !important;
  }
  .status-dot, .scroll-cue__line, .contact-term__caret { animation: none; }
  .marquee__track { animation: none; }
  .rail__packet, .stack-packet { display: none !important; }
}
