Motion Craft
Add or change UI animation the disciplined way. Decide first whether it should animate at all (frequency gate), name its purpose, pick the cheapest tool, then the right properties, easing, duration.
Distilled from Emil Kowalski's skills (animate, animation-vocabulary, animation-performance; MIT). For recipes (toasts, drawers, hold-to-confirm, Expo), install upstream:
npx skills@latest add emilkowalski/skills.
Core Rule
The best animation is often none. Before writing motion code, answer two questions: how often will people see this? and what is it for? If it's seen 100+ times a day, or you can't name a purpose, don't animate it. Writing zero lines of motion code is a valid result.
Values: agent_docs/motion.md.
Steps
- Frequency gate. 100+/day or keyboard-initiated → none. Tens/day → barely there. Occasional → standard. Rare → delight allowed.
- Name the purpose. Feedback · spatial consistency · state indication · preventing a jarring change · explanation · delight (rare only). Write it in a code comment if it's not obvious.
- Check the direction.
DESIGN_MAP.md → Character. A dashboard stays crisp; a playful product can be a little bouncier. Use the map's motion curve if one is set. - Cheapest tool. CSS transition →
@starting-style→ CSS animation → WAAPI → Motion/Framer (springs, layout, exit, gestures). Use the project's existing animation library if there is one; ask before adding one. - Build it right.
transformandopacityonly. Notransition: all.- Enter with ease-out
cubic-bezier(0.23, 1, 0.32, 1). Move on screen with ease-in-out. Never use ease-in on UI. - Durations: press 100–160ms · tooltip 125–200ms · dropdown 150–250ms · modal/drawer 200–300ms. UI stays under 300ms unless there's a stated reason.
- Start from
scale(0.95–0.97)plusopacity: 0, neverscale(0). Popovers usetransform-originat the trigger; modals stay centered. - Use transitions (which retarget) for anything that can fire twice a second. Keyframes are for predetermined sequences only.
- Stagger groups at 30–60ms, ~6 items max.
- Ship the guards with it.
@media (prefers-reduced-motion: reduce): keep opacity and color, drop movement.@media (hover: hover) and (pointer: fine)around hover motion.
- Look at it. If you can, record or step through it frame by frame. If you can't, say the timing is unverified.
Output
For each animation you add: the element, frequency tier, purpose, properties, duration and curve, and how reduced motion is handled. One line each.
Never
- Animate keyboard shortcuts, the command palette, typing, or list navigation.
- Add
animate-pulse/animate-pingto things that aren't live. - Animate
width,height,top,left,marginorpadding(heighton an accordion is the one tolerated exception).
.claude/hooks/motion-gate.sh warns when an edited file adds motion without a reduced-motion guard or animates layout properties.
Brand Method
Make or critique a brand identity (logo, type, palette) as 1–4 sets built together from one brief.
Slop Audit
Audit a screen for AI-slop signs (reflex gradients, glows, emoji icons, hype copy, heavy headings, pulsing elements, off-scale spacing, template look), decide how much slop there is (heavy, light,.