/* ==========================================================================
   CORE — motion
   Os três ganchos globais de entrada. Componente NÃO escreve observer nem
   keyframe próprio para "aparecer": usa data-rv, data-split ou .ttl.
   Regra: nada entra seco. Toda entrada carrega blur indo a zero.
   ========================================================================== */

/* ---- data-rv: o reveal padrão ----
   Fade + blur + subida. data-d="1|2|3" escalona o delay entre irmãos. */
[data-rv]{
  opacity:0;filter:blur(14px);transform:translateY(22px);
  transition:opacity 1s var(--ease),filter 1.1s var(--ease),transform 1s var(--ease);
}
[data-rv].in{opacity:1;filter:blur(0);transform:none}
[data-rv][data-d="1"]{transition-delay:.08s}
[data-rv][data-d="2"]{transition-delay:.16s}
[data-rv][data-d="3"]{transition-delay:.24s}

/* ---- data-split: revelação palavra a palavra ----
   O JS quebra o texto em .w preservando as tags internas (<em>, <a>). */
.w{
  display:inline-block;opacity:0;filter:blur(12px);transform:translateY(.5em);
  transition:opacity .9s var(--ease),filter .9s var(--ease),transform .9s var(--ease);
}
.w.in{opacity:1;filter:blur(0);transform:none}

/* ---- .ttl: título de seção ----
   Animação própria (não transition) para poder disparar por classe sem
   depender do estado anterior. */
.ttl{opacity:0;filter:blur(14px);transform:translateY(10px)}
.ttl.see{animation:ttlReveal .9s var(--ease) forwards}
@keyframes ttlReveal{
  0%{opacity:0;filter:blur(14px);transform:translateY(10px)}
  100%{opacity:1;filter:blur(0);transform:translateY(0)}
}

/* ---- Acessibilidade ----
   Quem pediu menos movimento vê a página inteira, parada. */
@media(prefers-reduced-motion:reduce){
  [data-rv],.w,.ttl{
    opacity:1!important;filter:none!important;
    transform:none!important;transition:none!important;
  }
  .ttl.see{animation:none}
}
