Estratégia antes do post.
A atuação conecta planejamento, repertório e execução.
Movimento que explica o que mudou.
As ações frequentes respondem imediatamente. Entradas pontuais explicam a composição; modais e gavetas preservam a relação entre contexto e detalhe.
| Uso | Token | Intenção |
|---|---|---|
| Pressão | --xq-motion-press | 100 ms para confirmar o acionamento. |
| Estados de controle | --xq-motion-control | 160 ms para mudanças de cor e limite. |
| Dialog e toast | --xq-motion-panel | 240 ms para orientar a entrada e a saída. |
| Entrada editorial | --xq-revelar | 600 ms para estabelecer a composição do ensaio. |
| Sequência | --xq-motion-stagger | 32 ms entre etapas. |
| Pulso da superfície | --xq-motion-editorial | 400 ms em uma execução, sem repetição contínua. |
| Entrada e saída | --xq-ease-out | Começa responsivo, chega suave. |
| Janela gráfica | --xq-ease-inout | Continuidade no recorte. |
| Gaveta | --xq-ease-drawer | O detalhe vem da borda da tela. |
Opacidade e deslocamento curto. Reservar para a primeira leitura de uma mensagem editorial.
A atuação conecta planejamento, repertório e execução.
opacity + transform · ease-out
O recorte revela a superfície da esquerda para a direita. O enquadramento participa da assinatura da marca.
E de volta aos dados.
clip-path + opacity · ease-in-out
Intervalos de 32 ms distinguem as etapas sem bloquear a leitura nem a interação.
3 entradas · intervalo de 32 ms
Um pulso sutil confirma o encontro com a superfície. Ativo no hover apenas com ponteiro preciso; disponível por botão para toque e teclado.
O caminho para o sucesso.
opacity · 400 ms · sem loop
Repetir deve funcionar no primeiro clique e nos seguintes. O reset neutraliza animações anteriores, confirma o estado inicial e retoma após dois quadros. Cada nova solicitação cancela os quadros pendentes da anterior.
alvo.classList.add('is-resetting');
alvo.classList.remove('is-visivel');
void alvo.offsetWidth;
requestAnimationFrame(() => {
requestAnimationFrame(() => {
alvo.classList.remove('is-resetting');
alvo.classList.add('is-visivel');
});
});
.is-resetting,
.is-resetting *,
.is-resetting::before,
.is-resetting::after,
.is-resetting *::before,
.is-resetting *::after,
.is-resetting::backdrop {
transition: none !important;
animation: none !important;
}
Cliques rápidos cancelam os frames pendentes. O alvo final permanece visível. Sem JavaScript, a mensagem nasce legível.
Com prefers-reduced-motion: reduce, deslocamentos e recortes são removidos; os estados mudam imediatamente. O pulso gráfico deixa de acontecer.
Com forced-colors: active, foco e seleção continuam distinguíveis por contorno. O pulso decorativo é removido.
Os exemplos de movimento têm botão explícito. O conteúdo não depende de hover. Modais e gavetas preservam foco, Escape e retorno ao acionador.
<article id="entrada" class="xq-motion-entrada" data-xq-motion>…</article>
<button type="button" data-xq-repeat="entrada">Repetir entrada</button>
Motion explica uma mudança que já tem significado. Pressão confirma o gesto; uma entrada editorial apresenta a composição; uma janela revela o plano. Nenhuma animação pode bloquear o conteúdo, disputar o foco ou reiniciar por acidente.
Repetir depende de uma sequência verificável: neutralizar transições, remover o estado ativo, consolidar a geometria e só então reativar. A linha do tempo abaixo separa o reset sem movimento da apresentação de 600 ms.
Adicionar .is-resetting antes de mudar o estado. A regra cobre descendentes, pseudo elementos e backdrop para impedir transições herdadas durante o reset.
Remover .is-visivel enquanto o reset neutraliza efeitos. O conteúdo só deve ficar oculto nesse trecho controlado; o HTML inicial permanece legível.
Ler a dimensão do alvo força o reflow necessário. A mesma instância retém o controle do ciclo; não clonar conteúdo para fabricar uma entrada.
Os dois requestAnimationFrame separam o estado inicial do estado final. O segundo retira .is-resetting e reaplica .is-visivel.
O ease-out reduz a velocidade na chegada. Usar a duração e a distância do papel da animação, sem mola ou overshoot adicionados por hábito.
prefers-reduced-motion mantém o conteúdo no estado final. Um novo replay cancela o quadro anterior e não acumula ciclos ou anúncios.
Valor ou alias no tema claro, propriedade consumidora e limite de uso. Cores são apresentadas em RGB equivalente; a fonte continua no CSS de tokens. O inspetor mostra a resolução no tema escolhido.
| Token / expressão | Aplicação CSS | Regra |
|---|---|---|
--xq-revelar
600ms
|
.xq-motion-entrada.is-ready
transition-duration
|
600 ms para entrada editorial. Não aplicar esse tempo a cada resposta frequente de controle. |
--xq-motion-press
100ms
|
.xq-btn
transition-duration
|
100 ms no transform de pressão. Resposta curta, sem atrasar o acionamento. |
--xq-motion-control
160ms
|
.xq-btn
transition-duration
|
160 ms nas mudanças de cor e borda. Não animar layout do controle. |
--xq-motion-panel
240ms
|
.xq-gaveta
transition-duration
|
240 ms para a relação espacial entre a borda da tela e o detalhe. |
--xq-motion-stagger
32ms
|
.xq-motion-grupo.is-visivel .xq-motion-passo:nth-child(2 of .xq-motion-passo)
transition-delay
|
32 ms por posição; cinco passos usam múltiplos de 0 a 4. Não crescer indefinidamente. |
--xq-motion-editorial
400ms
|
.xq-pisca-no-hover.is-visivel::after
animation-duration
|
400 ms em uma execução. O pulso não roda continuamente no fundo. |
--xq-motion-travel-lg
24px
|
.xq-motion-entrada.is-ready
transform
|
24 px no eixo vertical da entrada; a chegada retorna a translateY(0). |
--xq-motion-travel-md
12px
|
.xq-motion-grupo.is-ready .xq-motion-passo
transform
|
12 px negativos no eixo horizontal; sequência mantém ordem e espaço final. |
--xq-ease-out
cubic-bezier(0.23, 1, 0.32, 1)
|
.xq-motion-entrada.is-ready
transition-timing-function
|
Curva de chegada compartilhada; preservar a resposta imediata no início. |
--xq-ease-inout
cubic-bezier(0.77, 0, 0.175, 1)
|
.xq-motion-janela.is-ready
transition-timing-function
|
Curva do clip-path. Recorte termina em inset(0), sem deixar texto parcialmente cortado. |
--xq-ease-drawer
cubic-bezier(0.32, 0.72, 0, 1)
|
.xq-gaveta
transition-timing-function
|
A gaveta entra pelo mesmo eixo em que sai; o foco continua controlado pelo dialog. |
--xq-display-leading
0.96
|
.xq-motion-alvo h3
line-height
|
0,96 no título do alvo. Reservar altura final para evitar saltos na revelação. |
Compare a mesma intenção em duas composições. Os exemplos são amostras de leitura; os controles operáveis ficam no playground.
Uma entrada curta, acionada por intenção, com conteúdo disponível no HTML inicial.
Texto escondido até a sequência terminar.
Aguarde 3 segundosLoop infinito · bounce · delays aleatórios
O laboratório muda a mensagem de cada estado dentro do mesmo plano. “Repetir animação” ensaia a revelação da bancada, operada por XequeGuia; os exemplos acima ensaiam XequeCore. Ambos usam .is-resetting, reflow e dois quadros, cancelando a repetição anterior. Nenhum ensaio inicia um loop.
Entrada pronta para um novo ensaio.
600 ms
Pronto. Altere um controle para inspecionar o contrato.
Ensaio local e determinístico. A ação percorre carregamento → sucesso; movimento reduzido entrega o estado final imediatamente. Repetir preserva os controles.
--xq-revelar--xq-motion-press--xq-motion-control--xq-motion-panel--xq-motion-stagger--xq-motion-editorial--xq-motion-travel-lg--xq-motion-travel-md--xq-ease-out--xq-ease-inout--xq-ease-drawer--xq-display-leadingNos componentes com data-xq-motion montados pelo módulo, XequeCore.replay executa o reset compartilhado. A função devolve um cancelador e conserva .is-visivel como estado final. A bancada desta prancha pertence ao XequeGuia e usa .is-visible; não misturar as duas classes.
const alvo = document.querySelector("[data-xq-motion]");
const cancelar = XequeCore.replay(alvo);
// Se precisar interromper antes da conclusão:
// cancelar();
// alvo.classList.add("is-visivel");
// Antes de remover o componente:
// XequeCore.destroy(alvo);
A classe is-ready é aprimoramento do módulo. Sem ela, a entrada e a janela já exibem o conteúdo; o JavaScript prepara apenas os alvos que consegue operar.
<article class="xq-motion-alvo xq-motion-entrada" data-xq-motion>
<h3>Estratégia antes do post.</h3>
<p>A atuação conecta planejamento e execução.</p>
</article>
A fundação zera as distâncias e os tempos dos papéis de movimento; o CSS de entrada também garante opacidade final e neutraliza o recorte. Uma integração própria precisa preservar essas três condições. O trecho mostra o contrato já aplicado aos exemplos, sem atrasar interação ou foco.
@media (prefers-reduced-motion: reduce) {
.xq-motion-entrada.is-ready {
opacity: 1;
transform: none;
transition: none;
}
.xq-motion-janela.is-ready {
opacity: 1;
clip-path: inset(0);
transition: none;
}
}