/* Animações fiéis ao main.css original */

@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes fade-in-up {
  from { transform: translateY(20px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}
@keyframes fade-in-down {
  from { transform: translateY(-10px); opacity: 0; }
  to   { transform: translateY(0);     opacity: 1; }
}
@keyframes pulse {
  50% { opacity: .5; }
}
@keyframes ping {
  75%, 100% { transform: scale(2); opacity: 0; }
}
@keyframes spin {
  to { transform: rotate(360deg); }
}

.animate-fade-in       { animation: fade-in .5s ease-out; }
.animate-fade-in-up    { animation: fade-in-up .8s ease-out forwards; }
.animate-fade-in-down  { animation: fade-in-down .6s ease-out; }
.animate-pulse         { animation: pulse 2s cubic-bezier(.4,0,.6,1) infinite; }
.animate-ping          { animation: ping 1.5s cubic-bezier(0,0,.2,1) infinite; }
.animate-spin          { animation: spin 1s linear infinite; }

.delay-100 { animation-delay: 100ms; }
.delay-200 { animation-delay: 200ms; }
.delay-300 { animation-delay: 300ms; }
.delay-400 { animation-delay: 400ms; }
.delay-500 { animation-delay: 500ms; }
.delay-600 { animation-delay: 600ms; }
.delay-800 { animation-delay: 800ms; }

/* Componente Reveal (IntersectionObserver) — Progressive enhancement.
   Default: visível. Se o JS demora ou falha, conteúdo aparece normalmente
   (evita FOUR — flash of unrevealed reveal). O JS só esconde elementos
   abaixo da dobra antes de animar a entrada deles.
   Transition declarada apenas no estado de destino (is-visible) — assim
   o hide inicial é instantâneo, mas o reveal anima suavemente. */
.reveal {
  opacity: 1;
  transform: none;
}
.reveal.reveal-prepared:not(.is-visible) {
  opacity: 0;
  transform: translateY(40px);
}
.reveal.reveal-prepared.is-visible {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 1s ease-out, transform 1s ease-out;
}
