/* =========================================================
   ANIMAÇÕES — MARCELINHO
   1) Scroll reveal (via IntersectionObserver em scroll-reveal.js).
   2) Micro-flutuação do mascote (fallback estático) — sutil.
   3) Sprite sheet do mascote "acenando" via steps() — PRONTO,
      porém COMENTADO até o asset do sprite chegar.
   Tudo respeita prefers-reduced-motion.
   ========================================================= */

/* ---------- SCROLL REVEAL ---------- */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity var(--duration-slow) var(--ease-out),
              transform var(--duration-slow) var(--ease-out);
}
.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Delays escalonados (efeito cascata discreto no hero) */
.reveal--delay-1 { transition-delay: 0.06s; }
.reveal--delay-2 { transition-delay: 0.14s; }
.reveal--delay-3 { transition-delay: 0.22s; }
.reveal--delay-4 { transition-delay: 0.30s; }
.reveal--delay-5 { transition-delay: 0.38s; }

/* =========================================================
   INTRO: MASCOTE "VIVO" (micro-animações transform-only)
   ---------------------------------------------------------
   Respiração muito sutil (escala + sobe/desce) + leve sway do
   corpo/cabeça, em fases diferentes p/ não ficar robótico. Só
   transform (sem reflow/CLS). A piscada (introBlink) age no
   overlay .intro__eyes e nasce DESLIGADA (JS INTRO_BLINK=false).
   ========================================================= */
/* AJUSTE 3 — respiração levemente mais profunda (personagem vivo, não rígido);
   transform-only sobre o conjunto: NENHUM traço do rosto é alterado. */
@keyframes introBreathe {
  0%, 100% { transform: translateX(-50%) translateY(0) scale(1); }
  50%      { transform: translateX(-50%) translateY(-1.05%) scale(1.018); }
}
/* AJUSTE 3 — micro-movimento de cabeça (leve tilt do conjunto), levemente mais
   perceptível porém discreto; fase própria (9s) desalinhada da respiração (6s)
   p/ não ficar robótico. */
@keyframes introSway {
  0%, 100% { rotate: -0.75deg; }
  50%      { rotate: 0.75deg; }
}
/* AJUSTE 3 — piscada natural: pálpebra varre de cima p/ baixo (transform-origin
   top center no .intro__eyes) e reabre, com fechamento rápido + micro-hold,
   menos "espremido" que a versão simétrica. Nasce DESLIGADA (JS INTRO_BLINK). */
@keyframes introBlink {
  0%   { transform: scaleY(1); }
  45%  { transform: scaleY(0.06); }
  60%  { transform: scaleY(0.06); }
  100% { transform: scaleY(1); }
}
/* Fade suave do site ao concluir a intro (sem trocar de página). */
@keyframes introReveal {
  from { opacity: 0; }
  to   { opacity: 1; }
}
body.intro-done { animation: introReveal 460ms var(--ease-out) both; }

/* Indicador de scroll da abertura: sugestão sutil de "role" — SÓ transform
   (GPU), deslocamento vertical de ~7px, lento. A opacity (fade ao rolar) fica
   com scroll-cue.js (.is-hidden) p/ não brigar com o bob. */
@keyframes scrollCueBob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(7px); }
}

/* =========================================================
   HERO ESCURO: ENTRADA (roda no LOAD, independente de JS/scroll)
   ---------------------------------------------------------
   Badge desce (fade-in-down); headline/subtítulo/CTAs/trust sobem
   (fade-in-up) escalonados. Puro CSS: se o JS do shader falhar, o
   conteúdo aparece igual (LCP protegido). Reduced-motion desliga
   tudo (conteúdo visível de imediato). Só transform/opacity → sem CLS.
   ========================================================= */
@keyframes heroInDown {
  from { opacity: 0; transform: translateY(-14px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes heroInUp {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* Título (provável LCP): anima SÓ transform, mantendo opacity:1 — assim o
   navegador conta o elemento como pintado desde o 1º frame (não adia o LCP). */
@keyframes heroInUpTitle {
  from { transform: translateY(22px); }
  to   { transform: translateY(0); }
}
.hero__eyebrow  { animation: heroInDown 0.55s var(--ease-out) both; }
.hero__title    { animation: heroInUpTitle 0.7s 0.06s var(--ease-out) both; }
.hero__subtitle { animation: heroInUp 0.7s 0.16s var(--ease-out) both; }
.hero__actions  { animation: heroInUp 0.7s 0.26s var(--ease-out) both; }
.hero__trust    { animation: heroInUp 0.7s 0.36s var(--ease-out) both; }

/* =========================================================
   SHOWROOM: micro-flutuação permanente + troca de info
   ---------------------------------------------------------
   "Objeto premium suspenso / vivo" (fiel à bola do SLAMDUNK e ao giro do
   S24 3D central): sobe/desce discreto (translateY) + leve GIRO contínuo
   tipo turntable (rotateY) + leve balanço (rotateZ), só transform (sem
   reflow, GPU). Aplicada na SUBCAMADA .showroom-phone__float (elemento
   INTERNO), separada da transição de posição/seleção do card e das custom
   props do coverflow (--tx/--ty/--ry/--sc no .showroom-phone/__body), p/ as
   duas não brigarem. Vale p/ TODOS os cards (central + laterais); nos
   laterais lê discreto de graça porque o coverflow já os recua (escala
   menor + blur + opacidade). rotateY em ±5° nunca cruza 90° → jamais revela
   a face traseira vazia do mockup. Como é keyframe CSS, o browser pausa
   sozinho quando a aba (ou a .view via display:none) fica oculta — nada
   conta tempo escondido. Reduced-motion desliga tudo (abaixo).
   ========================================================= */
@keyframes showroomFloat {
  0%, 100% { transform: translateY(0)     rotateY(-5deg) rotateZ(-0.6deg); }
  50%      { transform: translateY(-12px) rotateY(5deg)  rotateZ(0.6deg); }
}
/* Troca de aparelho: a info some/reaparece com leve subida (fade+slide). */
@keyframes showroomInfoSwap {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---------- REDUÇÃO DE MOVIMENTO ----------
   Quem pede menos movimento vê o mascote PARADO (frame estático),
   os reveals já visíveis e nada de flutuação/aceno. */
@media (prefers-reduced-motion: reduce) {
  /* Showroom: sem flutuação, sem "voo" de seleção e sem fade de troca — a
     seleção passa a ser um corte instantâneo (acessível), mantendo a
     hierarquia visual (blur/escala/opacidade continuam, só não animam). */
  .showroom-phone__float { animation: none; }
  .showroom-phone,
  .showroom-phone__body { transition: none; }
  .showroom__ambient { transition: none; }
  .showroom__info.is-swapped { animation: none; }
  .reveal {
    opacity: 1;
    transform: none;
  }
  /* Intro estática: mascote parado (sem respiração/sway/reveal). O JS
     também não engata a jornada nem importa o three em reduced-motion. */
  .intro__mascote { animation: none; transform: translateX(-50%); }
  body.intro-done { animation: none; }
  /* Indicador de scroll: sem bob (em reduced-motion a jornada nem engata, mas
     garante que nenhum deslocamento contínuo escape). */
  .scroll-cue { animation: none; }
  /* Hero escuro: sem entrada animada (conteúdo já visível). O shader
     WebGL2 também não roda em reduced-motion (tratado em hero-shader.js:
     fica só o fundo estático de marca). */
  .hero__eyebrow,
  .hero__title,
  .hero__subtitle,
  .hero__actions,
  .hero__trust {
    animation: none;
  }
}
