Communitygithub.com

motion

Cria animações para interfaces de produto na web. Decide se algo deve se mover, por quê, qual ferramenta usar (CSS transition, WAAPI, Motion, spring), propriedades, curva, duração, interrupção, saída e caminho de movimento reduzido, e escreve o código. Também cobre escalonação e coreografia, gestos (arrastar, deslizar, folhas), tokens de movimento e desempenho de animação.

O que é motion?

Este skill especializado em motion para interfaces de produto web orienta o desenvolvedor através de uma sequência de decisões que vão desde determinar se um elemento deve se mover até escrever o código final. Ele promove o uso da ferramenta mais barata e eficaz: prioriza CSS transitions para estados alternados, `@starting-style` para entradas de `display: none`, `@keyframes` para sequências únicas, WAAPI para animações controladas por JavaScript (como cancelamento e reversão) e a biblioteca Motion para mola (spring), saída de componentes React e layout compartilhado. O skill enfatiza que zero linhas de animação é um resultado válido e desejável para elementos de alta frequência, evitando atrasos desnecessários. Ele também define coreografia (papéis de lead, support, decoration e static), interrupções seguras (transições ou molas, nunca keyframes para alternâncias rápidas), saídas direcionais e tratamento de `prefers-reduced-motion` integrado desde o início. Referências a arquivos externos (tokens, receitas, gestos, desempenho) são carregadas apenas quando necessário, garantindo foco e eficiência.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/nkurunziza-saddy/hmm-interfaces/tree/HEAD/motion

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que motion faz?

Este skill constrói motion. Ele estende a seção de motion de product-ui/references/values.md, que contém os números definidos (curvas de easing, escala de pressionamento, bounce, escalonação, tabela de duração, durações de toast e layout, distâncias de viagem, razão saída-entrada). Esses números não são repetidos aqui; este skill adiciona a ordem das decisões, os tokens, as receitas e os modos de falha.

Antes de qualquer decisão, aplique product-ui §1 (o diário de gosto e precedência) e §5 (qual skill é dona do quê).

A ordem de decisão

Percorra de cima para baixo. Cada passo pode encerrar o trabalho. Zero linhas de animação é um resultado válido, e você diz isso.

1. Deve se mover? O portão de frequência

Pergunte quantas vezes por dia um único usuário vê isso. Os níveis estão em values.md. Na prática:

  • Iniciado pelo teclado, ou visto 100+ vezes por dia: sem movimento. Por quê: movimento repetido se transforma em atraso.
  • Visto dezenas de vezes por dia (hover, troca de aba, seleção de linha): nenhum, ou uma mudança instantânea de cor.
  • Dados que o usuário está lendo ou agindo (um número em uma tabela, um gráfico em um dashboard ao vivo) nunca se movem por estilo. Por quê: movimento desvia o olhar da coisa que está sendo lida.
  • Se o portão disser não, não escreva animação. Diga qual nível atingiu e ofereça a alternativa estática (uma mudança de estado instantânea).

2. Nomeie o propósito

Escolha uma palavra: espacial (de onde veio ou para onde foi), estado (isto mudou), feedback (ouvi você), continuidade (evita um pulo), explicação (apenas momentos raros). Se não conseguir nomear: pare. Por quê: "fica bonito" em um elemento frequente é a principal fonte de UI que parece lenta.

3. Escolha a ferramenta: a mais barata que funciona

NecessidadeFerramenta
Um estado alternado por classe, atributo, hover ou pressCSS transition
Entrada de display: none, popover ou dialog@starting-style + transition-behavior: allow-discrete
Uma sequência única, escalonação, ou motion que deve rodar enquanto a página está ocupadaCSS @keyframes
JS decide quando; você precisa de cancelamento, reversão, finished, ou FLIPWAAPI el.animate()
Molas (springs), handoff de velocidade, saída de um nó React que está desmontando, layout compartilhadoMotion (motion/react)

Se a coisa é um componente inteiro (menu, toast, drawer), use uma biblioteca que lida com foco e pergunte pick-library. Nunca instale Motion para um fade. Por quê: CSS roda fora da thread principal e não custa bundle.

4. Propriedades

  • Anime transform e opacity; filter apenas para um blur de troca ≤ 2px. Nomeie cada propriedade; nunca transition: all.
  • Mudanças de altura e layout: veja references/recipes.md (linhas de grid, FLIP). Nunca anime width, top, left ou margin para mover algo. Por quê: cada um força layout em cada frame.
  • Nunca anime box-shadow. Em vez disso, faça fade da opacity de um pseudo-elemento.
  • Percentuais de translate são relativos ao tamanho do próprio elemento, então translateY(100%) serve para drawers e toasts de qualquer altura.

5. Curva e duração, combinadas ao uso

Nunca escolha o número mais próximo do seu palpite. Diga o uso ("fechamento de menu", "troca de ícone"), então pegue essa linha de references/tokens.md. Se nenhuma linha corresponder ao uso, adicione um novo token nomeado para o uso; não adapte um existente. Por quê: um token é uma declaração sobre para que serve o movimento, então um número próximo com o uso errado é o token errado.

  • Entrando ou saindo: --ease-out. Movendo na tela: --ease-in-out. Drawers: --ease-drawer. Cor: ease. Spinners: linear. Nunca ease-in.
  • Qualquer coisa arrastável ou interrompível durante o movimento usa uma mola (spring), não uma curva. Por quê: uma curva não pode aceitar a velocidade que a mão do usuário tinha.
  • Sensação lenta: reduza a duração primeiro, depois a distância, e só então toque na curva.

6. Interrupção

  • Qualquer coisa que o usuário possa acionar duas vezes em um segundo é uma transição ou uma mola, nunca @keyframes. Por quê: uma transição redireciona do valor atual; keyframes reiniciam e pulam.
  • WAAPI: cancele a animação antiga após ler o valor atual e inicie a nova a partir dele (references/recipes.md).
  • Uma alternância pressionada 10 vezes deve terminar no estado correto sem pulo. Teste isso.

7. Saída

  • A saída padrão é um fade, mais curto que a entrada (o arquivo de tokens tem cada par).
  • Qualquer coisa com direção (drawer, folha, toast deslizado) sai pelo caminho que veio.
  • O elemento que está saindo para de ocupar espaço imediatamente, então os irmãos fecham a lacuna enquanto ele desvanece.
  • Saídas são simultâneas e nunca escalonadas. Por quê: o usuário já decidiu sair.

8. Movimento reduzido, enviado com a animação

Opacidade e cor permanecem. Slides, escala, blur e bounce desaparecem; slides viram fades, bounce vira 0. Nunca use motion como único indicador. Padrão em references/recipes.md.

Coreografia

Atribua um papel a cada elemento em movimento antes de temporizá-lo:

PapelTratamento
Lead (a única coisa a notar)Move-se primeiro, viaja mais
Suporte (Support)Segue, viaja menos
Decoração (Decoration)Desvanece no lugar, ou nada
Estático (Static) (containers, chrome)Nunca se move
  • Uma entrada por container. Se o painel desliza para dentro, seu conteúdo já está lá. Por quê: duas entradas em camadas fazem o usuário esperar duas vezes.
  • Ordene por importância, não por ordem DOM. O atraso permanece nos passos de values.md (40ms entre itens, 100ms entre título, texto e ações). Varie distância e duração por papel, em vez do atraso.
  • Limite a escalonação de uma lista ao índice 6 (um atraso final de 240ms); itens além disso compartilham esse atraso. A entrada funciona enquanto isso ocorre.
  • Nunca escalone um menu, paleta de comandos, conteúdo de aba ou qualquer abertura repetida.
  • Fique parado: qualquer coisa que o usuário está prestes a clicar, qualquer coisa já na tela quando a página carrega novamente, e uma atualização que chega dentro de 150ms da anterior (pule para o estado final).
  • Direção segue significado: próximo entra pela direita, voltar pela esquerda; coisas que o usuário acionou crescem para fora a partir do gatilho.

Carregar quando necessário

  • references/tokens.md: carregue para qualquer valor exato de duração, distância, escala, blur, easing ou spring, e para tokenizar uma base de código existente.
  • references/recipes.md: carregue ao construir um menu, popover, dialog, drawer, toast, entrada de lista, troca de ícone, mudança de altura, indicador de aba ou mudança de número.
  • references/gestures.md: carregue para arrastar, deslizar, arremessar, folhas, ou qualquer coisa que siga um ponteiro.
  • references/performance.md: carregue quando o motion cair frames, antes de recorrer a will-change, e quando as atualizações chegarem rápido.

Pares

QuebradoCorrigidoPor quê
.menu { transition: all 300ms ease-in }transition: opacity 200ms, transform 200ms var(--ease-out)Propriedades nomeadas; ease-in é lerdo; menus ≤ 200ms
scale(0) para scale(1)scale(0.95) e opacity: 0 para 1Nada aparece do nada
Popover escala do seu centrotransform-origin: var(--transform-origin)Deve crescer a partir de seu gatilho
.open { animation: slide-in 300ms }transition: transform no estado alternadoKeyframes dão pulo quando interrompidos
Cada linha animation-delay: i * 120msmin(i, 6) * 40msA última linha chega em menos de 300ms
Drawer desvanece após deslizar para dentroDesliza de volta pelo caminho que veioDireção é a explicação
Soltura de arraste em um ease-out fixoUma mola (spring) alimentada com a velocidade de solturaO momentum da mão continua
setY(y) em pointermoveel.style.transform = ...Sem re-renderização por frame

Antes de finalizar

Pesquise o diff, depois verifique.

Pesquise porCorrija
transition: all, will-change em *, ease-inPropriedades nomeadas, remova, --ease-out
scale(0), transform-origin: center em um popover0.95, a origem do gatilho (diálogos permanecem centralizados)
@keyframes em uma classe que alternaUma transição
Uma duração acima da sua linha em tokens.md, ou um número não em tokens.mdO token do uso
Motion em handlers keydown ou uma paletaRemova
width, height, top, left, box-shadow em uma transiçãotransform, opacity, ou a receita
Sem caminho prefers-reduced-motionAdicione

Verifique no aplicativo em execução: reproduza a 4× (painel Animations do DevTools, ou multiplique as durações), spamme qualquer alternância, teste com movimento reduzido ativado e limite a CPU em 4×. Diga quais destes você não conseguiu executar.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

nkurunziza-saddy/break

Stress-tests a piece of UI with worst-case data and every reachable state, then reports what broke with a numbered fix for each. Use it when the user types /break, or asks to "break this", "stress-test", "try the worst case", "what happens with long names", "check the empty and error states" or "find the edge cases" on a component or screen.

nkurunziza-saddy/layout

Structure and space in product UI on the web. It sets the spacing scale, grouping, alignment, density (compact or comfortable), hit areas, app shells (sidebar, toolbar, content, inspector), max widths, container-query responsiveness, dropdown and popover sizing, room for long and translated text, layout stability (no shift on load) and sticky elements that must not cover focus.

nkurunziza-saddy/pick-library

Picks the right library for a frontend task from a curated, status-checked list, instead of hand-rolling it or installing an abandoned package. Use it when the user asks "what should I use for…", "is there a library for…", or names a package, and when you are about to build a toast, command menu, drawer, date picker, table, virtual list, drag and drop, chart, OTP input, animated number, theme switch, form validation…

nkurunziza-saddy/surfaces

What product UI is made of on the web. It sets elevation levels with exact shadow recipes for light and dark mode, when to use a shadow and when a border, the transparent border for forced-colours mode, a small radius scale with concentric nesting, image outlines, every interactive state as a surface change (hover, pressed, selected, disabled, focus-visible), icons (one set, currentColor, outline and fill, stroke tha…

Habilidades Relacionadas