/* /assets/css/motion.css — camada base de animação (CSS puro, sem dependências)
   Copie para o projeto e ajuste apenas o bloco :root. O resto funciona como está.
   Requer: <html class="js"> injetado pelo motion.js e os atributos data-* no HTML. */

/* ---------------------------------------------------------------
   1. TOKENS — ajuste por projeto
   --------------------------------------------------------------- */
:root {
  /* Curvas. A diferença entre "animação de site" e "animação boa" mora aqui.
     ease-out para entradas (rápido no início, desacelera = natural).
     ease-in para saídas. spring para confirmações e microinterações. */
  --mo-out:    cubic-bezier(0.16, 1, 0.3, 1);
  --mo-in:     cubic-bezier(0.7, 0, 0.84, 0);
  --mo-inout:  cubic-bezier(0.65, 0, 0.35, 1);
  --mo-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* Durações. Acima de 600ms o usuário sente que está esperando. */
  --mo-fast:  180ms;
  --mo-base:  400ms;
  --mo-slow:  650ms;

  /* Deslocamento padrão do reveal. Sutil ganha de dramático. */
  --mo-shift: 24px;

  /* Intervalo entre itens em cascata. Acima de 120ms parece lento. */
  --mo-stagger: 70ms;
}

/* ---------------------------------------------------------------
   2. REVEAL — entrada ao aparecer na viewport
   Nada aqui esconde conteúdo sem JS: tudo depende de .js no <html>.
   --------------------------------------------------------------- */
.js [data-reveal] {
  opacity: 0;
  transition:
    opacity var(--mo-slow) var(--mo-out),
    transform var(--mo-slow) var(--mo-out),
    filter var(--mo-slow) var(--mo-out);
  transition-delay: calc(var(--i, 0) * var(--mo-stagger));
  will-change: opacity, transform;
}

.js [data-reveal="up"]    { transform: translate3d(0, var(--mo-shift), 0); }
.js [data-reveal="down"]  { transform: translate3d(0, calc(var(--mo-shift) * -1), 0); }
.js [data-reveal="left"]  { transform: translate3d(calc(var(--mo-shift) * -1), 0, 0); }
.js [data-reveal="right"] { transform: translate3d(var(--mo-shift), 0, 0); }
.js [data-reveal="scale"] { transform: scale(0.94); }
.js [data-reveal="blur"]  { filter: blur(10px); transform: translate3d(0, 12px, 0); }
.js [data-reveal="fade"]  { transform: none; }

/* Estado final único: o JS só adiciona .is-in e tudo converge para cá. */
.js [data-reveal].is-in {
  opacity: 1;
  transform: none;
  filter: none;
  will-change: auto;
}

/* Máscara de texto: a linha sobe de dentro de um recorte.
   Use no título do hero — é o reveal mais elegante que existe em CSS puro. */
.mo-mask { overflow: hidden; display: block; }
.js .mo-mask > * {
  display: block;
  transform: translate3d(0, 100%, 0);
  transition: transform var(--mo-slow) var(--mo-out);
  transition-delay: calc(var(--i, 0) * var(--mo-stagger));
}
.js .mo-mask.is-in > * { transform: none; }

/* ---------------------------------------------------------------
   3. MICROINTERAÇÕES — hover, focus, active
   --------------------------------------------------------------- */

/* Card que sobe. 4px é suficiente; 12px parece brinquedo. */
.mo-lift {
  transition:
    transform var(--mo-base) var(--mo-out),
    box-shadow var(--mo-base) var(--mo-out);
}
.mo-lift:hover,
.mo-lift:focus-visible {
  transform: translate3d(0, -4px, 0);
  box-shadow: 0 12px 32px -8px rgb(0 0 0 / 0.18);
}

/* Feedback tátil: comprime no clique. Vale para todo botão. */
.mo-press { transition: transform var(--mo-fast) var(--mo-out); }
.mo-press:active { transform: scale(0.97); }

/* Sublinhado que cresce do início. Link que parece caro. */
.mo-underline {
  position: relative;
  text-decoration: none;
}
.mo-underline::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--mo-base) var(--mo-out);
}
.mo-underline:hover::after,
.mo-underline:focus-visible::after { transform: scaleX(1); }

/* Brilho que atravessa o botão. Use em UM botão da página — o principal. */
.mo-shine {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.mo-shine::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 40%, rgb(255 255 255 / 0.28) 50%, transparent 60%);
  transform: translateX(-100%);
  transition: transform var(--mo-slow) var(--mo-inout);
  pointer-events: none;
}
.mo-shine:hover::before { transform: translateX(100%); }

/* Zoom contido na imagem, sem estourar o container. */
.mo-zoom { overflow: hidden; }
.mo-zoom img {
  display: block;
  width: 100%;
  transition: transform var(--mo-slow) var(--mo-out);
}
.mo-zoom:hover img { transform: scale(1.05); }

/* Foco visível. Nunca remova outline sem repor algo. */
.mo-focus:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---------------------------------------------------------------
   4. ESTADOS DE CARREGAMENTO
   --------------------------------------------------------------- */
.mo-spin {
  animation: mo-spin 800ms linear infinite;
  transform-origin: center;
}
@keyframes mo-spin { to { transform: rotate(360deg); } }

/* Skeleton: sempre melhor que spinner quando você sabe o formato do conteúdo. */
.mo-skeleton {
  position: relative;
  overflow: hidden;
  background: rgb(0 0 0 / 0.06);
  border-radius: 4px;
}
.mo-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgb(255 255 255 / 0.55), transparent);
  animation: mo-shimmer 1.4s infinite;
}
@keyframes mo-shimmer {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100%); }
}

/* Pulso para badge de notificação ou status ao vivo. */
.mo-pulse { animation: mo-pulse 2s var(--mo-inout) infinite; }
@keyframes mo-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.6; transform: scale(1.08); }
}

/* ---------------------------------------------------------------
   5. SEQUÊNCIA DE PAGE LOAD
   Aplique data-load nos elementos do hero. O motion.js dispara na carga.
   --------------------------------------------------------------- */
.js [data-load] {
  opacity: 0;
  transform: translate3d(0, 16px, 0);
  transition:
    opacity var(--mo-slow) var(--mo-out),
    transform var(--mo-slow) var(--mo-out);
  transition-delay: calc(var(--i, 0) * 90ms + 120ms);
}
.js.is-loaded [data-load] { opacity: 1; transform: none; }

/* ---------------------------------------------------------------
   6. SCROLL-DRIVEN NATIVO (Chrome/Edge; degrada limpo nos demais)
   Zero JS, roda no compositor. Ideal para barra de progresso e parallax.
   --------------------------------------------------------------- */
@supports (animation-timeline: scroll()) {
  .mo-progress {
    position: fixed;
    top: 0;
    left: 0;
    height: 3px;
    width: 100%;
    transform-origin: left;
    transform: scaleX(0);
    z-index: 100;
    animation: mo-progress linear;
    animation-timeline: scroll(root block);
  }
  @keyframes mo-progress { to { transform: scaleX(1); } }

  .mo-parallax {
    animation: mo-parallax linear;
    animation-timeline: view();
    animation-range: entry 0% exit 100%;
  }
  @keyframes mo-parallax {
    from { transform: translate3d(0, 8%, 0); }
    to   { transform: translate3d(0, -8%, 0); }
  }
}

/* ---------------------------------------------------------------
   7. TRANSIÇÃO ENTRE PÁGINAS (multipágina PHP)
   Ver references/php-stack.md para o cuidado com POST e formulários.
   --------------------------------------------------------------- */
@view-transition { navigation: auto; }

::view-transition-old(root) {
  animation: mo-fade-out 180ms var(--mo-in) both;
}
::view-transition-new(root) {
  animation: mo-fade-in 320ms var(--mo-out) both;
}
@keyframes mo-fade-out { to { opacity: 0; } }
@keyframes mo-fade-in  { from { opacity: 0; transform: translate3d(0, 8px, 0); } }

/* ---------------------------------------------------------------
   8. MOVIMENTO REDUZIDO — obrigatório
   Mantém a mudança de estado (conteúdo aparece), remove o deslocamento.
   --------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .js [data-reveal],
  .js [data-load],
  .js .mo-mask > * {
    opacity: 1;
    transform: none;
    filter: none;
  }
}
