/* ==========================================================================
   ANIMATIONS.CSS
   Stati di supporto alle animazioni GSAP gestite in js/animations.js.
   Questo file NON contiene le animazioni stesse (i tween vivono in
   GSAP/ScrollTrigger), ma gli stati iniziali "prima che l'animazione
   parta" e le poche micro-animazioni puramente decorative che non
   richiedono orchestrazione via JS.

   CONTRATTO con js/animations.js (da rispettare quando verrà scritto):
   1. Il markup parte con <html class="no-js">.
   2. main.js sostituisce subito "no-js" con "js" (primo script eseguito,
      prima del paint quando possibile) — senza JS il sito resta
      interamente visibile e leggibile, nessun contenuto nascosto.
   3. animations.js, SOLO dopo aver inizializzato correttamente GSAP,
      aggiunge la classe "gsap-ready" a <html>. Se GSAP non si carica o
      lancia un errore, animations.js deve intercettarlo e NON aggiungere
      questa classe, cosicché gli elementi [data-animate] restino nel
      loro stato finale visibile (vedi regola sotto) invece di rimanere
      invisibili per sempre.
   4. Gli stati "nascosti" qui sotto si applicano SOLO quando sono vere
      entrambe le condizioni: html.js E html.gsap-ready. In ogni altro
      caso (no-js, GSAP non pronto, reduced motion) il contenuto è
      visibile di default: nessun opacity:0 permanente.
   ========================================================================== */

/* --------------------------------------------------------------------
   STATI INIZIALI PER SCROLL REVEAL
   Applicati via attributo data-animate="..." sul markup. Il valore
   indica la direzione/tipo di ingresso che js/animations.js userà come
   "from" del tween GSAP.
   -------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {

  html.js.gsap-ready [data-animate] {
    will-change: transform, opacity;
  }

  html.js.gsap-ready [data-animate="fade-up"] {
    opacity: 0;
    transform: translateY(32px);
  }

  html.js.gsap-ready [data-animate="fade-in"] {
    opacity: 0;
  }

  html.js.gsap-ready [data-animate="scale-in"] {
    opacity: 0;
    transform: scale(0.96);
  }

  html.js.gsap-ready [data-animate="fade-left"] {
    opacity: 0;
    transform: translateX(-32px);
  }

  html.js.gsap-ready [data-animate="fade-right"] {
    opacity: 0;
    transform: translateX(32px);
  }

  /* Contenitori a stagger: i figli diretti con [data-animate-child]
     partono nascosti, animations.js li anima in sequenza con un
     leggero delay incrementale (gsap.to con stagger). */
  html.js.gsap-ready [data-animate-stagger] [data-animate-child] {
    opacity: 0;
    transform: translateY(24px);
  }

  /* Una volta completata l'animazione, JS aggiunge questa classe
     all'elemento: rimuove will-change per liberare risorse GPU. */
  [data-animate].is-animated {
    will-change: auto;
  }
}

/* --------------------------------------------------------------------
   HERO — ingresso del contenuto
   Stessa logica del reveal generico, isolata perché la hero anima al
   caricamento della pagina (non allo scroll) e ha un ordine di
   ingresso specifico gestito via timeline GSAP dedicata.
   -------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  html.js.gsap-ready .hero__eyebrow,
  html.js.gsap-ready .hero__title,
  html.js.gsap-ready .hero__text,
  html.js.gsap-ready .hero__actions,
  html.js.gsap-ready .hero__scroll {
    opacity: 0;
    transform: translateY(24px);
  }

  html.js.gsap-ready .hero__media {
    transform: scale(1.08);
  }
}

/* --------------------------------------------------------------------
   MICRO-ANIMAZIONI DECORATIVE — non orchestrate da GSAP, autonome via
   CSS perché continue/looping e senza necessità di ScrollTrigger.
   Rispettano comunque prefers-reduced-motion (già gestito anche in modo
   globale in reset.css, qui ridondanza intenzionale sui loop infiniti).
   -------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {

  .hero__scroll-line::after {
    animation: scroll-indicator 2.2s var(--ease-in-out) infinite;
  }

  @keyframes scroll-indicator {
    0% { transform: translateY(-100%); }
    100% { transform: translateY(200%); }
  }

  .btn--loading .btn__spinner {
    animation: spin 0.7s linear infinite;
  }

  @keyframes spin {
    to { transform: rotate(360deg); }
  }
}

/* Spinner: markup e dimensioni indipendenti dal movimento, così resta
   visibile anche con reduced motion (semplicemente non ruota) */
.btn--loading {
  pointer-events: none;
  opacity: 0.75;
}

.btn__spinner {
  width: 16px;
  height: 16px;
  border: 2px solid rgba(255, 255, 255, 0.4);
  border-top-color: currentColor;
  border-radius: var(--radius-full);
}

/* --------------------------------------------------------------------
   TRANSIZIONI DI STATO GENERICHE
   Piccole utility per componenti che cambiano stato senza bisogno di
   un tween GSAP dedicato (hover/press già gestiti nei singoli
   componenti in components.css). Qui solo la classe di supporto per
   il fade-in dei contenuti caricati dinamicamente (es. stato form).
   -------------------------------------------------------------------- */
.fade-transition {
  transition: opacity var(--transition-base) var(--ease-standard);
}

.fade-transition.is-hidden {
  opacity: 0;
  pointer-events: none;
  position: absolute;
}
