Use this skill when the user wants to add animations, make transitions smooth, add micro-interactions, or apply final polish. Also use when the user says 'my app feels static,' 'add some life to this,' 'make it feel smoother,' 'the transitions are janky,' or 'make this feel like Linear/Stripe.' Covers transition patterns, micro-interactions, page transitions, loading animations, scroll interactions, and the restraint principle.
Animation is the final 10% that makes a functional app feel premium. Apply motion to reinforce spatial relationships, confirm user actions, and smooth state changes. This skill covers what to animate, how to animate it, and — most importantly — what to leave alone.
This skill is for adding motion and animation polish. For visual design (colors, typography, spacing), use beautify. For page layouts and component selection, use ui-patterns. For user flow and navigation design, use ux-design. For a full design audit, use design-review.
Tell AI:
Add polish animations to my app. Apply these in order of impact:
1. Button press feedback (subtle scale on click)
2. Hover states on cards and interactive elements
3. Smooth transitions on modals, dropdowns, and side panels
4. Loading skeletons replacing spinners for content areas
5. Toast notification entrance/exit animations
Use CSS transitions where possible (not JS). Respect prefers-reduced-motion.
Keep all durations under 300ms. Use ease-out for entrances, ease-in for exits.
Add motion polish (in priority order):
- [ ] Button press feedback (active:scale-[0.98])
- [ ] Hover states on cards and list items
- [ ] Modal/dropdown entrance transitions (fade + scale from 95%)
- [ ] Loading skeletons instead of spinners
- [ ] Toast notification entrance/exit
- [ ] Staggered list entrance on page load
- [ ] Reduced motion support (prefers-reduced-motion)
Do these in order. Each one is independently valuable. Stop whenever it feels like enough.
Lovable / Replit — paste the Quick Start prompt above. These tools apply Tailwind transitions directly.
Claude Code — use the Quick Start prompt, or point to specific components: "Add hover state animation to the card component in src/components/Card.tsx."
What you don't animate matters more than what you do. If a user notices an animation, it's probably too much. Motion should feel like physics — objects have weight, momentum, and settle into place. It should never feel like a performance.
Hard rules:
| Interaction Type | Duration | Why |
|---|---|---|
| Micro-interactions (hover, focus) | 100–150ms | Must feel instant. User expects immediate feedback. |
| Element transitions (expand, collapse) | 150–250ms | Enough to see the change, not enough to wait. |
| Page transitions | 200–300ms | Smooth the jarring content swap. |
| Complex sequences (staggered lists) | 200–400ms total | Individual items faster, total sequence under 400ms. |
Hard ceiling: 500ms. No UI animation should ever exceed this. Anything longer feels broken, not polished.
ease-out — For entrances. Element arrives and decelerates into place. Most common easing in UI.ease-in — For exits. Element accelerates away. Use when something is leaving the screen.ease-in-out — For state changes where the element stays on screen (toggle slide, position shift).linear for UI animations. Linear motion has no acceleration — it feels robotic and mechanical. Reserve it for infinite loops like spinners.transition-all duration-150 ease-out /* micro-interactions */
transition-all duration-200 ease-out /* element transitions */
transition-all duration-300 ease-in-out /* page/state transitions */
For custom easing, define cubic-bezier values in your Tailwind config. A good general-purpose curve: cubic-bezier(0.4, 0, 0.2, 1) (Material Design standard).
Use for content replacing content — tab changes, page loads, image swaps.
/* CSS */
.fade-enter { opacity: 0; }
.fade-enter-active { opacity: 1; transition: opacity 200ms ease-out; }
.fade-exit-active { opacity: 0; transition: opacity 150ms ease-in; }
Tailwind: transition-opacity duration-200 ease-out
Fade is the safest default. When unsure which transition to use, fade.
Use for panels, drawers, mobile menus, and side sheets. The direction must match the trigger — a left sidebar slides in from the left, a bottom sheet slides up from the bottom.
/* Slide from right (for side panels) */
.panel { transform: translateX(100%); transition: transform 250ms ease-out; }
.panel.open { transform: translateX(0); }
Tailwind for a right panel: translate-x-full → translate-x-0 with transition-transform duration-250 ease-out
Use for modals, tooltips, popovers, and dropdown menus. Scale from 95% to 100% — not 0% to 100%. The subtle 5% scale change adds life without being dramatic.
.modal { opacity: 0; transform: scale(0.95); transition: all 200ms ease-out; }
.modal.open { opacity: 1; transform: scale(1); }
Tailwind: scale-95 opacity-0 → scale-100 opacity-100 with transition-all duration-200 ease-out
Always combine scale with fade. Scale alone looks jarring.
Use for accordions, detail disclosures, and expandable sections. Animate max-height or grid-template-rows — not height, which requires knowing the exact pixel value.
/* Modern approach using grid */
.collapsible { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 250ms ease-in-out; }
.collapsible.open { grid-template-rows: 1fr; }
.collapsible > div { overflow: hidden; }
Tailwind: Use grid with grid-rows-[0fr] → grid-rows-[1fr] and transition-all duration-250 ease-in-out. The inner content needs overflow-hidden.
These are the small details that make an app feel alive. Each one takes minutes to implement and compounds into a premium feel.
Add a subtle scale on press. Not on hover — on active press.