/* ============================================================
   VitrinAI — animations.css
   Keyframes + reveal au scroll
   ============================================================ */

@keyframes pulse-ring {
  0%   { box-shadow: 0 0 0 0 rgba(61,139,94,0.5); }
  70%  { box-shadow: 0 0 0 10px rgba(61,139,94,0); }
  100% { box-shadow: 0 0 0 0 rgba(61,139,94,0); }
}

@keyframes fade-up {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes pop {
  0%   { transform: scale(0.6); opacity: 0; }
  60%  { transform: scale(1.1); }
  100% { transform: scale(1); opacity: 1; }
}

@keyframes float-arrow {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(6px); }
}

/* Reveal au scroll via IntersectionObserver (.reveal -> .is-visible)
   IMPORTANT : l'état masqué n'est appliqué QUE si le JS est actif (html.js).
   Sans JS — ou si l'animation échoue — le contenu reste visible par défaut. */
.reveal { opacity: 1; transform: none; }
html.js .reveal { opacity: 0; transform: translateY(20px); transition: opacity 600ms ease, transform 600ms ease; will-change: opacity, transform; }
html.js .reveal.is-visible { opacity: 1; transform: translateY(0); }

/* Cascade : délai par index (set en JS via --i) */
html.js .reveal[style*="--i"] { transition-delay: calc(var(--i) * 100ms); }

/* Flèche "voir comment ça marche" */
.bounce-arrow { display: inline-block; animation: float-arrow 1.8s ease-in-out infinite; }

@media (prefers-reduced-motion: reduce) {
  html.js .reveal { opacity: 1; transform: none; transition: none; }
  .pulse-dot, .bounce-arrow { animation: none; }
}
