/* =========================================================================
   Tournament Legacy — Motion layer (animazioni di scroll + micro-interazioni)
   Caricato DOPO styles.css. Tutto opt-in via classi aggiunte da animations.js
   (niente FOUC: se il JS non parte, il contenuto resta visibile e statico).
   Palette = PALETTE_A. Anima SOLO transform/opacity. Rispetta reduced-motion.
   ========================================================================= */

/* La classe sul <html> viene messa da animations.js SOLO se:
   - il browser supporta IntersectionObserver
   - l'utente NON ha prefers-reduced-motion: reduce
   Finché non c'è, ogni contenuto è nel suo stato finale (zero rischio di pagine "vuote"). */

/* ---- Stati iniziali reveal (solo quando le animazioni sono attive) ---- */
html.has-motion [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 22px, 0);
  will-change: transform, opacity;
}
html.has-motion [data-reveal="left"]  { transform: translate3d(-26px, 0, 0); }
html.has-motion [data-reveal="right"] { transform: translate3d(26px, 0, 0); }
html.has-motion [data-reveal="scale"] { transform: scale(.94); }

/* Stato rivelato (GSAP scrive inline per i casi orchestrati; questa classe è il
   fallback CSS per i blocchi gestiti via IntersectionObserver puro). */
html.has-motion [data-reveal].is-in {
  opacity: 1;
  transform: none;
  transition:
    opacity .6s cubic-bezier(.22, 1, .36, 1),
    transform .7s cubic-bezier(.22, 1, .36, 1);
}
/* stagger per i figli di una griglia rivelata insieme */
html.has-motion [data-reveal].is-in { transition-delay: var(--reveal-delay, 0ms); }

/* Una volta dentro, libera la GPU */
html.has-motion [data-reveal].is-in { will-change: auto; }

/* =========================================================================
   BARRA DI AVANZAMENTO SCROLL — CSS scroll-driven NATIVO (compositor, 0 JS)
   Fallback: se animation-timeline non è supportato (Firefox senza flag),
   animations.js la pilota con rAF. La barra non causa layout shift: è fixed.
   ========================================================================= */
.scroll-progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 3px;
  z-index: 100;
  transform-origin: 0 50%;
  transform: scaleX(0);
  background: linear-gradient(90deg, var(--primary) 0%, var(--accent) 100%);
  pointer-events: none;
}
/* Quando il browser ha le scroll-driven animations native, usale (più fluide). */
@supports (animation-timeline: scroll()) {
  .scroll-progress {
    animation: sp-grow linear both;
    animation-timeline: scroll(root block);
  }
  @keyframes sp-grow { to { transform: scaleX(1); } }
}

/* =========================================================================
   HERO — leggero "respiro" di profondità (parallax morbido del poster)
   Gestito da JS (GSAP) per restare sotto controllo; qui solo il setup GPU.
   ========================================================================= */
html.has-motion .hero .poster,
html.has-motion .hero .poster-badge { will-change: transform; }

/* Conta-numeri: nessuno stile particolare, ma evitiamo che i numeri "saltino"
   di larghezza mentre contano (cifre tabellari). */
[data-count] { font-variant-numeric: tabular-nums; }

/* =========================================================================
   MICRO-INTERAZIONI
   ========================================================================= */

/* Pulsanti: ripple (onda) al click. Il contenitore deve clippare l'onda. */
.btn { position: relative; overflow: hidden; isolation: isolate; }
.btn > * { position: relative; z-index: 1; }
.btn .ripple {
  position: absolute;
  border-radius: 50%;
  transform: scale(0);
  background: currentColor;
  opacity: .28;
  pointer-events: none;
  z-index: 0;
  animation: ripple .55s ease-out forwards;
}
/* sul primario (coral) l'onda bianca legge meglio */
.btn--primary .ripple { background: #fff; opacity: .34; }
@keyframes ripple { to { transform: scale(2.4); opacity: 0; } }

/* Magnetismo: il JS scrive --mx/--my (px). La transizione di rientro è morbida.
   Solo dispositivi con puntatore fine (no touch). */
@media (hover: hover) and (pointer: fine) {
  [data-magnetic] {
    transition: transform .35s cubic-bezier(.22, 1, .36, 1);
  }
  html.has-motion [data-magnetic] {
    transform: translate3d(var(--mx, 0px), var(--my, 0px), 0);
  }
  /* mentre il puntatore è dentro, il movimento è immediato (lo guida il JS) */
  html.has-motion [data-magnetic].is-magnetizing { transition: none; }
}

/* Card tilt 3D leggerissimo: prospettiva sul contenitore, rotazione sulla card.
   Solo puntatore fine. */
@media (hover: hover) and (pointer: fine) {
  html.has-motion [data-tilt] {
    transform:
      perspective(900px)
      rotateX(var(--rx, 0deg))
      rotateY(var(--ry, 0deg))
      translate3d(0, var(--lift, 0px), 0);
    transform-style: preserve-3d;
    transition: transform .25s cubic-bezier(.22, 1, .36, 1);
  }
  html.has-motion [data-tilt].is-tilting { transition: transform .08s linear; }
  /* un velo di luce che segue il puntatore sul poster */
  html.has-motion [data-tilt] .tilt-glare {
    position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
    opacity: 0; transition: opacity .25s ease; z-index: 2;
    background: radial-gradient(
      260px circle at var(--gx, 50%) var(--gy, 0%),
      rgba(255, 255, 255, .35), rgba(255, 255, 255, 0) 60%);
    mix-blend-mode: soft-light;
  }
  html.has-motion [data-tilt].is-tilting .tilt-glare { opacity: 1; }
}

/* Bottone "copia codice": stato copiato */
.copy-code {
  cursor: pointer; border: 0; font: inherit; color: inherit;
  background: transparent; padding: 0;
  display: inline-flex; align-items: center; gap: 14px;
  align-self: flex-start;        /* non stirare nel .code-demo (flex-column) */
  flex-wrap: wrap;               /* su schermi stretti l'hint va a capo, niente overflow */
}
.copy-code .copy-hint {
  font-family: var(--font-body);
  font-size: .7rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--primary-deep); background: var(--primary-soft);
  border-radius: var(--r-pill); padding: 6px 12px;
  display: inline-flex; align-items: center; gap: 7px;
  transition: transform .18s ease, background .18s ease, color .18s ease;
  white-space: nowrap;
}
.copy-code .copy-hint svg { width: 15px; height: 15px; }
@media (hover: hover) { .copy-code:hover .copy-hint { transform: translateY(-1px); } }
.copy-code.copied .copy-hint { background: var(--success); color: #fff; }
.copy-code.copied .copy-hint .ico-copy { display: none; }
.copy-code .copy-hint .ico-done { display: none; }
.copy-code.copied .copy-hint .ico-done { display: inline-flex; }
/* lampo morbido del token quando copi */
@keyframes code-pop { 0% { transform: none; } 35% { transform: scale(1.04); } 100% { transform: none; } }
html.has-motion .code-token.copied-flash { animation: code-pop .4s ease; }

/* =========================================================================
   STRISCIA STATISTICHE (conta-numeri) — banda crema, numeri Anton coral/blu
   ========================================================================= */
.stats { background: var(--surface); border-block: 1px solid var(--border); }
.stats .wrap { padding-block: clamp(var(--s-5), 6vw, var(--s-6)); }
.stats-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s-3);
  text-align: center;
}
.stat { padding: var(--s-2) var(--s-1); position: relative; }
.stat + .stat::before {
  content: ""; position: absolute; left: 0; top: 14%; height: 72%; width: 1px;
  background: var(--border);
}
.stat .n {
  font-family: var(--font-display); font-weight: 400; line-height: 1;
  font-size: clamp(2.4rem, 5.4vw, 3.4rem); color: var(--primary-deep);
  letter-spacing: -0.01em; display: block;
}
.stat:nth-child(2) .n, .stat:nth-child(4) .n { color: var(--accent-deep); }
.stat .l {
  display: block; margin-top: 8px; color: var(--muted);
  font-size: var(--t-body-sm); font-weight: 600; line-height: 1.3;
}
@media (max-width: 760px) {
  .stats-grid { grid-template-columns: repeat(2, 1fr); gap: var(--s-4) var(--s-3); }
  .stat:nth-child(3)::before { display: none; }
}

/* =========================================================================
   HERO LOTTIE (coriandoli) — contenitore sopra il poster, non cliccabile
   ========================================================================= */
.hero-confetti {
  position: absolute;
  inset: -8% -6% auto -6%;
  height: 118%;
  z-index: 2;            /* sopra il poster, sotto i contenuti testuali (che non sono qui) */
  pointer-events: none;
  opacity: 0;            /* il JS la accende al play */
  transition: opacity .4s ease;
}
.hero-confetti.is-on { opacity: 1; }
.hero-confetti svg { width: 100%; height: 100%; }
/* il badge "Bomber" deve restare leggibile sopra i coriandoli */
.hero-card-stack .poster-badge { z-index: 3; }

/* =========================================================================
   LIVE poster: il pallino "Finale" pulsa già (in styles.css). Aggiungiamo un
   battito appena percettibile allo score quando l'hero entra (una volta).
   ========================================================================= */
@keyframes score-beat { 0% { transform: scale(1); } 40% { transform: scale(1.06); } 100% { transform: scale(1); } }
html.has-motion .poster .score.beat { animation: score-beat .6s cubic-bezier(.22,1,.36,1); }

/* =========================================================================
   ACCESSIBILITÀ — reduced motion: tutto fermo e leggibile.
   (animations.js già NON aggiunge .has-motion in questo caso; questo blocco è
   la cintura di sicurezza per qualunque keyframe residuo, incluso .pill--live.)
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  html.has-motion [data-reveal] { opacity: 1 !important; transform: none !important; }
  .scroll-progress { display: none !important; }
  .hero-confetti { display: none !important; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}
