<!--
Fontes destiladas e adaptadas (arquivo MODIFICADO — condensado, traduzido para PT-BR, adaptado ao contexto do plugin):
- skill "hallmark" (Licença MIT, © 2026 Hallmark contributors) — motion, microinteractions.
- skill "web-animation-design" (baseada no curso "Animations on the Web" de Emil Kowalski) — princípios de animação.
Licença do hallmark em ../../../licenses/hallmark-LICENSE-MIT.txt
-->

# Movimento e microinterações

Página de serviço leve (HTML único, CSS inline, sem build, JS mínimo). O movimento aqui
tem uma função: confirmar toque, guiar o olho, dar sensação de "coisa bem-feita". Nunca
decorar. O padrão da IA é animar demais — cards que pulsam, fade em cada rolagem, ícones
saltitando. Faça o contrário: **um momento orquestrado vale mais que dez pequenos.**

Regra-mestra: se você não consegue dizer o que uma animação comunica, ela é enfeite. Corte.

## 1. Easing (curvas)

Anime apenas com curvas customizadas. As curvas padrão do navegador (`ease`,
`ease-in-out`, `linear`) parecem "sem acabamento" — elas denunciam trabalho genérico.

Defina três tokens e nunca improvise:

```css
:root {
  --ease-out:    cubic-bezier(0.16, 1, 0.3, 1);    /* elemento ENTRANDO — desacelera ao chegar */
  --ease-in:     cubic-bezier(0.7, 0, 0.84, 0);    /* elemento SAINDO — acelera ao partir */
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);   /* algo já visível que se MOVE/alterna */
}
```

Como escolher:
- **ease-out** — 90% dos casos. Tudo que o usuário aciona e que entra na tela: hover,
  botão, tooltip, seção aparecendo, menu abrindo. O início rápido dá sensação de resposta
  instantânea; o elemento "pula" ao destino e assenta.
- **ease-in** — só na saída de algo (menu fechando, elemento sumindo). A saída acelera.
- **ease-in-out** — algo que já está na tela e se desloca/alterna (raro nesta página).

Evite:
- **`ease-in`** em UI: começa lento, atrasa o feedback visual, parece travado.
- **`linear`**: robótico. Reserve para barras de progresso e loaders contínuos.
- **overshoot/bounce** (`cubic-bezier(0.34, 1.56, 0.64, 1)` e parentes): datado, "template
  de 2018". Não use em botão, card ou seção.

## 2. Duração (números concretos)

Três faixas. Não invente valores fora delas.

```css
:root {
  --dur-micro: 120ms;   /* toque/press, troca de cor, tick de estado */
  --dur-curta: 200ms;   /* hover, tooltip, fade de propriedade única */
  --dur-longa: 400ms;   /* entrada de seção, transição com várias propriedades */
}
```

Referência por tipo:
- **Press / toque**: 80–120ms (o cérebro lê como imediato).
- **Hover / foco / tooltip**: 150–200ms.
- **Entrada de seção no scroll**: 400ms.
- **Saída**: 60–75% da entrada. Uma entrada de 200ms sai em ~150ms. Nunca o contrário.

Rápido demais: abaixo de ~80ms parece "piscar", sem transição perceptível.
Lento demais: acima de 400ms em UI parece arrastado. Regra: UI abaixo de 300ms;
só entrada de seção chega a 400ms. Elemento maior anima um pouco mais lento que menor.

Muitas coisas **não devem animar** (0ms): foco de teclado, navegação por teclado,
aparição de erro. Instantâneo é resposta certa com frequência surpreendente.

## 3. Hover e press (feel de botão)

O feel de um botão bem-feito: sobe de leve no hover, afunda no press, foco sempre visível.

```css
.btn {
  transition: background-color var(--dur-curta) var(--ease-out),
              transform 120ms var(--ease-out);
}
.btn:active { transform: translateY(1px); }           /* afunda ao tocar */
.btn:focus-visible { outline: 2px solid; outline-offset: 3px; }  /* nunca anime o anel */

/* hover só onde há hover de verdade (evita disparo no toque) */
@media (hover: hover) and (pointer: fine) {
  .btn:hover { transform: translateY(-1px); }
}
```

Princípios:
- **Um sinal por hover.** Escolha subir OU sombra OU cor — não os cinco juntos.
- `translateY(-1px)` no hover, `translateY(0)`/`+1px` no press. Ou `scale(0.97)` no `:active`.
- Nunca parta de `scale(0)` (surge do nada). Parta de `scale(0.95)` + `opacity: 0`.
- O anel de foco (`:focus-visible`) aparece instantâneo, nunca com fade — senão o usuário
  de teclado fica sem indicador no início.
- Foco por teclado precisa do mesmo destaque do hover. Nada é hover-only.

**Botão flutuante de WhatsApp** (CTA fixo desta página):
- Alvo de toque ≥ 44×44px.
- Feedback de press idêntico ao acima: `transform: scale(0.96)` no `:active`, ~120ms.
- Pode ter **uma** entrada suave ao carregar (surge de baixo, `--ease-out`, 400ms) para
  não parecer colado. Depois disso, fica parado — nada de pulso infinito puxando o olho.
- Se quiser um chamativo, use no máximo UM pulso de borda que roda **uma vez** ao entrar
  na tela. Loops infinitos cansam e gritam "template".

## 4. Entrada / scroll (com moderação)

Uma única entrada orquestrada. Cada seção surge uma vez ao entrar na viewport — e pronto.

```css
.reveal {
  opacity: 0;
  transform: translateY(8px);
  animation: reveal var(--dur-longa) var(--ease-out) forwards;
  animation-delay: calc(var(--i, 0) * 60ms);   /* escalonar por índice, no HTML: style="--i:0" */
}
@keyframes reveal { to { opacity: 1; transform: none; } }
```

O que evita jank (travamento):
- **Anime só `transform` e `opacity`.** São compostos na GPU, não recalculam layout.
- **Nunca** anime `width`, `height`, `top`, `left`, `margin`, `padding` — disparam reflow
  a cada frame e engasgam.
- `will-change: transform` só se um elemento específico tremer 1px no início/fim — e só
  nele, enquanto anima. Nunca preventivamente numa classe inteira.
- Detecte a viewport com `IntersectionObserver`, **nunca** com listener de evento `scroll`.
- **Dispare uma vez só.** Não re-anime a seção a cada rolagem — a página nunca "assenta".
- Limite o escalonamento total a ~500ms. Além disso a página parece lenta para se acomodar.
- Sem scroll-triggered em telas abaixo de ~40rem (mobile): entregue o conteúdo direto.

## 5. Acessibilidade (obrigatório)

`prefers-reduced-motion` não é opcional. Colapse todo movimento espacial em fade curto:

```css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .reveal { opacity: 1; transform: none; animation: none; }
}
```

- Toda animação espacial vira crossfade de opacidade ≤ 150ms, ou some.
- Nada de estado só por cor (erro, ativo): acompanhe com ícone, texto ou borda.
- Sem piscada acima de 3 Hz.
- Alvos de toque ≥ 44×44px. Toda affordance de hover tem equivalente de foco.

## 6. Restrições deste contexto — o que NÃO fazer

A página abre instantâneo e é mobile-first. Só CSS e transições leves. Sem biblioteca de
animação, sem JS pesado, sem framework.

Proibido:
- **Carrossel / slider automático** — viola WCAG 2.2.2 e adiciona peso e JS. Nunca.
- **`transition: all`** — anima até o que deveria ser instantâneo. Liste as propriedades.
- **`hover:scale-105` universal** em todo card — o gesto reflexo da IA. Sem propósito.
- **Parallax** e **fundos com gradiente animado** — distraem, custam caro, comunicam nada.
- **Cursor customizado / dot que segue o mouse** — sempre slop; dispara enjoo vestibular.
- **Fade-up em todo parágrafo** ao rolar — ler não é experiência cinematográfica.
- **Loops infinitos** (fora loaders funcionais) — puxam o olho e nunca soltam.
- **Toast de sucesso** ("Pronto!") quando o efeito já é visível — sucesso silencioso é bom gosto.
- **Bounce/overshoot** em elemento de UI.
- **Spinner que pisca** ao terminar em 80ms — atrase 150ms ou mantenha visível 300ms mínimo.

Teste final antes de entregar: percorra cada animação e pergunte *"se isto fosse instantâneo,
alguém notaria?"*. Se a resposta for "não", remova. Buscar a versão parada é sinal de bom
gosto; buscar mais movimento é o padrão da IA.
