animate

Adds smooth motion and animations to websites to make them feel alive and responsive.

Installation
Run `npx skills add "https://github.com/aladicf/better-web-ui" --skill "animate"` to install this skill, then follow its SKILL.md instructions for my next request.

Paste this into Claude Code, Cursor, or any agent that can run commands.

SKILL.mdShow the author's original SKILL.md
---
name: animate
description: Improve or implement purposeful motion systems, micro-interactions, gestures, and transition behavior for production-grade UI. Use when the user mentions animation, motion, transitions, micro-interactions, hover states, drawers, toasts, gestures, or making the UI feel more alive.
metadata:
  argument-hint: "[target]"
---

Analyze a feature and add motion that improves clarity, feedback, perceived performance, and polish without making the interface feel slow, noisy, or theatrical.

## MANDATORY PREPARATION

Users start this workflow with `/animate`. Once this skill is active, load $frontend-design — it contains design principles, anti-patterns, and the **Context Gathering Protocol**. Follow that protocol before proceeding — if no design context exists yet, you MUST load $setup first. Additionally gather: performance constraints.

Consult the [motion reference](../frontend-design/reference/motion-design.md) for timing, easing, choreography, and reduced-motion handling.
Consult the [animate reference index](reference/README.md) when you need to browse the deeper motion library by use case instead of guessing filenames.
Consult the [elevation system](../frontend-design/reference/elevation-system.md) when motion should reinforce raised, pressed, inset, dragged, or layered depth.
Consult the [interaction reference](../frontend-design/reference/interaction-design.md) when animation decisions overlap with focus, loading, transitions, or feedback states.
Consult the [component anatomy reference](../frontend-design/reference/component-anatomy.md) when motion affects custom primitives such as buttons, tabs, tooltips, toasts, toggles, drawers, or submit actions.
Consult the [responsive design reference](../frontend-design/reference/responsive-design.md) when motion needs to adapt across small screens, touch contexts, or reduced viewport space.
Consult the [framework official docs reference](../frontend-design/reference/framework-official-docs.md) before making framework-specific animation decisions.
Consult the [React shadcn accelerators reference](../frontend-design/reference/react-shadcn-accelerators.md) when the request overlaps with React toasts, drawers, text motion, or other UI patterns that already have strong accelerators.
Consult the [CSS, Tailwind, and WAAPI motion reference](../frontend-design/reference/css-tailwind-and-waapi-motion.md) to decide when modern CSS, Tailwind, or WAAPI can solve the motion cleanly without reaching for a framework animation library.
Consult the [scroll-driven animations reference](../frontend-design/reference/scroll-driven-animations.md) when motion should progress with scroll position rather than time.
Consult the [view transitions reference](../frontend-design/reference/view-transitions.md) when animating between page states or DOM changes with shared-element continuity.
Consult [attribution and sources](reference/attribution-and-sources.md) for the source lineage behind this skill's Emil-inspired motion guidance.
Consult [entrance animations](reference/entrance-animations.md), [exit animations](reference/exit-animations.md), [gesture interactions](reference/gesture-interactions.md), and [micro-interactions](reference/micro-interactions.md) for consolidated thematic guidance by motion type.
Consult [ease-out defaults](reference/ease-out-default.md), [easing by context](reference/easing-context.md), and [custom easing curves](reference/custom-easing-curves.md) when choosing motion curves.
Consult [UI under 300ms](reference/ui-under-300ms.md), [asymmetric press and release timing](reference/asymmetric-press-release.md), [500ms drawer timing](reference/drawer-500ms-duration.md), [faster perceived performance](reference/faster-improves-performance.md), and [tooltip timing escalation](reference/tooltip-delay-instant-followups.md) when the main question is duration rather than easing.
Consult [on-screen movement easing](reference/ease-in-out-on-screen-movement.md), [sheet and drawer easing](reference/sheet-drawer-easing.md), and [spring motion](reference/spring-motion.md) when the motion pattern needs more specific guidance.
Consult [damped drag boundaries](reference/damp-drag-boundaries.md), [upward drag friction](reference/upward-drag-friction.md), [interruptible animations](reference/interruptible-animations.md), [momentum dismissal](reference/momentum-dismissal.md), [pointer capture](reference/pointer-capture.md), [scroll and drag conflicts](reference/scroll-drag-conflicts.md), and [velocity-aware snap points](reference/velocity-aware-snap-points.md) when implementing gesture-heavy surfaces.
Consult [blur-bridged transitions](reference/blur-bridge-states.md), [clip-path tabs](reference/clip-path-tab-transitions.md), [respect reduced motion](reference/respect-reduced-motion.md), [opacity fallback](reference/opacity-reduced-motion-fallback.md), [reduced motion alternatives](reference/reduced-motion-not-zero.md), [Motion's `useReducedMotion`](reference/use-reduced-motion-hook.md), [hover gap fill](reference/hover-gap-fill.md), [scroll reveal thresholds](reference/scroll-animation-threshold.md), [child orchestration](reference/stagger-children-orchestration.md), and [toast stack depth](reference/toast-stack-depth.md) for polish and accessibility refinement.
Consult [transform and opacity only](reference/transform-opacity-only.md), [avoid CSS variables in drag loops](reference/avoid-css-variables-drag.md), [clip-path reveals](reference/clip-path-layout-free-reveals.md), [hardware-accelerated motion under load](reference/hardware-accelerated-busy-main-thread.md), and [surgical `will-change`](reference/will-change-subpixel-shift.md) for performance-sensitive property choices.
Consult [immediate action feedback](reference/immediate-feedback-actions.md), [interaction frequency](reference/interaction-frequency.md), [no keyboard animation](reference/no-animation-for-keyboard.md), [marketing exceptions](reference/marketing-exception.md), and [animation purpose](reference/animation-purpose.md) for strategy-heavy motion decisions.
Consult [preserve-3d effects](reference/preserve-3d-effects.md), [never scale from zero](reference/never-scale-zero.md), [origin-aware animations](reference/origin-aware-animations.md), and [percentage translateY](reference/percentage-translate-y.md) when the question is really about transform technique and spatial feel.
Consult [button press scale 0.97](reference/button-press-scale-097.md), [scale affecting children](reference/scale-affects-children.md), and [SVG path morph disclosure icons](reference/svg-path-morph-disclosure.md) for finer transform polish details.

If the interface already feels laggy under frequent use, also load `optimize`.
If the interface needs stronger resilience around reduced motion, errors, overflow, edge cases, or mixed input modes, also load `harden`.

---

## Attribution and Inspiration

This skill's motion guidance is informed in part by [Emil Kowalski's animations.dev course](https://animations.dev/), especially the emphasis on easing choice, timing, tasteful restraint, springs, and motion that "feels right" in production UI.

It is also informed by Emil's animation-heavy open-source work on [Sonner](https://github.com/emilkowalski/sonner) and [Vaul](https://github.com/emilkowalski/vaul), which are already relevant elsewhere in this library for React toast and drawer guidance.

This repository rewrites those lessons into original, repository-specific guidance rather than reproducing the course materials directly.

---

## Motion Operating Model

Use this decision order before adding any animation:

1. **Fix structure first** — motion should reinforce hierarchy and state, not rescue a confusing layout.
2. **Animate only with a job to do** — every animation should improve feedback, orientation, relationship, or delight.
3. **Bias toward speed** — product UI should feel responsive first and impressive second.
4. **Keep motion interruptible** — new user intent beats finishing the old animation.
5. **Match the input method** — mouse, touch, and keyboard interactions do not all deserve the same motion treatment.
6. **Plan reduced motion up front** — accessibility is part of the system, not a cleanup pass.
7. **Prefer the lightest implementation that fits** — modern CSS and Tailwind first, WAAPI when imperative timing matters, Motion when the interaction genuinely needs it.

Use motion for one or more of these jobs:

- **Feedback** — acknowledge that an action happened
- **Orientation** — help users understand where something came from or where it went
- **Relationship** — show how surfaces, layers, and controls relate spatially
- **Delight** — add warmth or personality after the fundamentals already work

If the animation cannot justify itself with one of those jobs, cut it.

## Assess Motion Opportunities

Analyze where motion would improve the experience:

1. **Identify static areas**:
   - **Missing feedback**: Actions without visual acknowledgment (button clicks, form submission, etc.)
   - **Jarring transitions**: Instant state changes that feel abrupt (show/hide, page loads, route changes)
   - **Unclear relationships**: Spatial or hierarchical relationships that aren't obvious
   - **Lack of delight**: Functional but joyless interactions
   - **Missed guidance**: Opportunities to direct attention or explain behavior

2. **Understand the context**:
   - What's the personality? (Playful vs serious, energetic vs calm)
  - What's the performance budget? (Compact-layout-first? Complex page?)
   - Who's the audience? (Motion-sensitive users? Power users who want speed?)
   - What matters most? (One hero animation vs many micro-interactions?)
   - Which inputs matter? (mouse, touch, keyboard, stylus)
   - Which interactions are high-frequency and should stay especially snappy?

If any of these are unclear from the codebase, ask the user directly to clarify what you cannot infer.

**CRITICAL**: Respect `prefers-reduced-motion`. Always provide non-animated alternatives for users who need them.

Motion should reinforce hierarchy, not compensate for weak hierarchy. If the layout only becomes understandable once it moves, fix the layout first.

## Plan Animation Strategy

Create a purposeful animation plan:

- **Hero moment**: What's the ONE signature animation? (Page load? Hero section? Key interaction?)
- **Feedback layer**: Which interactions need acknowledgment?
- **Transition layer**: Which state changes need smoothing?
- **Gesture layer**: Which drag, swipe, snap, or dismiss interactions need physical logic?
- **Delight layer**: Where can we surprise and delight?
- **Depth logic**: Which elements should feel raised, pressed, dragged, inset, or layered?
- **Reduced-motion plan**: What simplifies to fade, blur, or instant state change?
- **Performance budget**: Which motions must stay lightweight because they happen often?

**IMPORTANT**: One well-orchestrated experience beats scattered animations everywhere. Focus on high-impact moments.

## Default Motion Rules

Use these as the default guidelines for animation work unless the product context gives a strong reason to deviate.

### 1. Strategy and Purpose

- Every animation must earn its place through **feedback, orientation, relationship, or delight**.
- Product interfaces should usually feel **fast, calm, and precise**. Save slower or more dramatic motion for onboarding, hero moments, storytelling, or marketing surfaces.
- Favor **one signature moment plus disciplined micro-interactions** over adding motion everywhere.
- Do **not** animate keyboard-initiated actions just because pointer interactions animate. Keyboard users usually want predictable state change with minimal delay.
- The more often an interaction happens, the less motion it usually needs. High-frequency controls should feel nearly instant.
- Acknowledge user input immediately. Aim for visible feedback within roughly **80ms** for micro-interactions whenever possible.
- If real work may exceed roughly **400ms**, respond immediately with optimistic UI, skeletons, progress, or clear loading feedback instead of leaving a dead pause.
- Never use motion to disguise slow loading, weak hierarchy, or missing state design.

### 2. Easing Defaults

- Use **ease-out** as the default for entrances, reveals, and most feedback transitions.
- Use **custom cubic-bezier curves** instead of the generic CSS `ease` default.
- Use **ease-in-out** for reversible, on-screen state changes that travel there and back.
- Use **spring motion** when the movement should feel physically connected to gesture input or object behavior.
- For drawers, sheets, and similar surfaces, a good starting point is the sheet-style curve `cubic-bezier(0.32, 0.72, 0, 1)`.
- Prefer exponential-style deceleration such as `ease-out-quart`, `ease-out-quint`, or `ease-out-expo` for refined UI motion.
- Avoid bounce and elastic curves unless the product intentionally embraces a toy-like or playful physical metaphor. They usually feel dated, noisy, or self-conscious.
- Match easing to context:
  - **entering surfaces** → ease-out
  - **exiting surfaces** → shorter duration, often ease-in or a snappier exit curve
  - **state toggles / reversible movement** → ease-in-out
  - **gesture-linked movement** → spring or velocity-aware interpolation

### 3. Timing and Duration

- Keep most recurring UI motion under **300ms**.
- Use **100-150ms** for press states, toggles, color changes, and immediate acknowledgment.
- Use **200-300ms** for standard UI state changes such as hover, menus, tooltips, and small reveals.
- Use **300-500ms** for larger layout transitions such as drawers, modals, accordions, and major surface changes.
- Treat **500ms** as a special-case upper bound for bigger surface motion like sheets or staged entrances, not as the default for ordinary controls.
- Exit animations should be faster than entrances. A good default is roughly **75%** of enter duration.
- Press should be faster than release. Downward feedback should feel immediate; reset can be slightly softer.
- Delay the **first** tooltip or hover-revealed helper when needed, but make subsequent related reveals much faster or instant so the interface does not feel sticky.
- Long stagger chains are a smell. Cap total stagger time so the last item does not arrive embarrassingly late.

### 4. Property Selection and Performance

- Prefer animating **transform** and **opacity**.
- Avoid animating **width, height, top, left, padding, margin, border-width**, or other layout-heavy properties unless there is a strong reason and the surface is small.
- For accordion-like height transitions, prefer **grid-template-rows** or equivalent layout-friendly patterns over raw `height` animation when possible.
- Use **clip-path**, masks, or composited reveals when you need a layout-free reveal effect.
- Use hardware-friendly transforms when the main thread is busy or the component animates frequently.
- Use `will-change` sparingly and only when animation is imminent or proven to need it.
- During drag loops, avoid animation setups that route every frame through expensive CSS-variable or layout recalculation paths if they introduce lag.
- Prefer Intersection Observer for scroll-triggered motion and stop observing once the motion has completed if it only needs to happen once.

### 5. Transform and Scale Techniques

- For button or chip press feedback, `scale(0.97)` is a strong default starting point.
- Never animate entry from `scale(0)`. Start closer to `scale(0.95)` or higher so the element keeps believable mass.
- Use percentage-based translate values when movement should scale with the element or viewport size.
- Make motion **origin-aware**:
  - menus and tooltips should emerge from the trigger edge
  - drawers and sheets should move from their anchored side
  - lifted cards should feel like they rise from their current plane
- Remember that scaling affects children. Text and icons can feel blurry or distorted if the scale range is too aggressive.
- Use 3D transforms only when they improve spatial understanding or delight meaningfully. Do not reach for `preserve-3d` just because it looks flashy in isolation.

### 6. Gesture and Interaction Patterns

- Make interactive animations **interruptible**. Users should not have to wait for motion to finish before expressing new intent.
- For swipe-to-dismiss, sheet snapping, and similar gestures, use **distance plus velocity**, not distance alone.
- Add **friction or damping** near boundaries so drags resist instead of hard-stopping.
- Handle **scroll-vs-drag conflicts** intentionally. Nested surfaces should not feel like they are fighting over input.
- Use robust pointer handling such as pointer capture or equivalent gesture ownership when implementing drag interactions.
- Visually lift dragged items with depth cues such as shadow, slight scale, or elevated layering.
- When a surface can be dragged past its resting point, allow controlled resistance instead of making the gesture feel abruptly blocked.
- Snap points should feel velocity-aware and purposefully chosen, not like arbitrary invisible walls.

### 7. Accessibility and Polish

- Always respect `prefers-reduced-motion`.
- Reduced motion should usually mean **simplified motion**, not zero feedback. Replace large spatial movement with opacity, blur, highlight, or shorter transitions where possible.
- Preserve functional cues such as focus states, progress, loading feedback, and success or error acknowledgment.
- Use blur carefully to bridge between visual states when a straight cut feels harsh.
- Use stagger intentionally for orchestration, not as decoration. Small lists can benefit; huge lists usually cannot.
- Scroll reveals should trigger before the user has fully passed the element, but not so early that the effect feels detached from scroll context.
- Fill hover gaps between triggers and floating surfaces so tooltips, menus, and popovers do not flicker closed during pointer travel.
- Toast stacks can use offset, scale, and opacity to imply depth without becoming chaotic.
- Respect motion sensitivity in compact and touch-capable contexts as much as in wide layouts. Gesture-led movement can be especially uncomfortable if overdone.

## Implement Animations

Add motion systematically across these categories:

### Entrance Animations
- **Page load choreography**: Stagger only where it improves comprehension; keep total orchestration tight
- **Hero section**: Give the primary story moment a distinct entrance if the product tone supports it
- **Content reveals**: Scroll-triggered animations using intersection observer
- **Modal/drawer entry**: Smooth slide + fade, backdrop fade, focus management

### Micro-interactions
- **Button feedback**:
  - Hover: Subtle scale, color shift, or shadow change only if it improves affordance
  - Click / press: Quick scale down then up, pressed-in feel, or depth shift
  - Loading: Spinner or pulse state
- **Form interactions**:
  - Input focus: Border, background, or elevation transition that clarifies focus without being distracting
  - Validation: Prefer clear color, icon, or text-state change before ornamental motion
- **Toggle switches**: Smooth slide + color transition
- **Checkboxes/radio**: Clear state change with tight timing
- **Like/favorite**: Small scale or icon motion only if it fits the product tone

### State Transitions
- **Show/hide**: Fade + slide (not instant), appropriate timing (200-300ms)
- **Expand/collapse**: Layout-friendly open/close transitions with overflow handling, icon rotation if helpful
- **Loading states**: Skeleton screen fades, spinner animations, progress bars
- **Success/error**: Color transitions, icon animations, gentle scale pulse
- **Enable/disable**: Opacity transitions, cursor changes

### Navigation & Flow
- **Page transitions**: Crossfade between routes, shared element transitions when they truly clarify continuity
- **Tab switching**: Slide indicator, content fade, clip-path, or other fast directional cues
- **Carousel/slider**: Smooth transforms, snap points, momentum, and interruptible input
- **Scroll effects**: Parallax layers, sticky headers with state changes, scroll progress indicators

### Feedback & Guidance
- **Hover hints**: Tooltip fade-ins, cursor changes, element highlights
- **Drag & drop**: Lift effect (shadow + scale), drop zone highlights, smooth repositioning — dragging should feel like the item pops forward on the z-axis
- **Copy/paste**: Brief highlight flash on paste, "copied" confirmation
- **Focus flow**: Highlight path through form or workflow

### Depth & Elevation Motion
- Raised elements should feel like they move toward the user
- Pressed elements should feel like they move inward or downward
- Use shadow and movement together to communicate state, not just style
- Match motion emphasis to the same hierarchy logic used for color and typography

### Delight Moments
- **Empty states**: Subtle floating animations on illustrations
- **Completed actions**: Confetti, check mark flourish, success celebrations
- **Easter eggs**: Hidden interactions for discovery
- **Contextual animation**: Weather effects, time-of-day themes, seasonal touches

## Technical Implementation

Use appropriate techniques for each animation:

### Timing & Easing

**Durations by purpose:**
- **100-150ms**: Instant feedback (button press, toggle)
- **200-300ms**: State changes (hover, menu open)
- **300-500ms**: Layout changes (accordion, modal, drawer)
- **500ms max by default**: Large surface transitions that truly need it

**Easing curves (use these, not CSS defaults):**
```css
/* Recommended - natural deceleration */
--ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);    /* Smooth, refined */
--ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);   /* Slightly snappier */
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);     /* Confident, decisive */
--ease-in-out-standard: cubic-bezier(0.65, 0, 0.35, 1); /* Reversible movement */
--ease-sheet-standard: cubic-bezier(0.32, 0.72, 0, 1);   /* Sheets / drawers */

/* AVOID - feel dated and tacky */
/* bounce: cubic-bezier(0.34, 1.56, 0.64, 1); */
/* elastic: cubic-bezier(0.68, -0.6, 0.32, 1.6); */
```

**Exit animations are faster than entrances.** Use ~75% of enter duration.

### CSS Animations
```css
/* Prefer for simple, declarative animations */
- transitions for state changes
- @keyframes for complex sequences
- transform + opacity first (GPU-friendly)
- Tailwind utilities when the project already uses Tailwind
```

### JavaScript Animation
```javascript
/* Use for complex, interactive animations */
- Web Animations API for programmatic control
- Framer Motion / Motion for React
- GSAP for complex sequences
```

Default rule: if a hover, press, reveal, or reduced-motion fallback can be expressed cleanly with modern CSS or Tailwind utilities, prefer that path before escalating to Motion.

### Performance
- **GPU acceleration**: Use `transform` and `opacity`, avoid layout properties
- **will-change**: Add sparingly for known expensive animations
- **Reduce paint**: Minimize repaints, use `contain` where appropriate
- **Monitor FPS**: Ensure 60fps on target devices
- **Interaction-first**: Frequent product interactions should feel responsive even on weaker devices

### Accessibility
```css
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
```

Prefer replacing large movement with short fades, highlights, blur transitions, or instant state changes instead of deleting every form of feedback.

## Useful Default Values

Use these as starting points, then tune for context:

| Value | Good default use |
| --- | --- |
| `scale(0.97)` | Button and chip press feedback |
| `scale(0.95)` | Minimum believable enter scale |
| `200ms` | Standard UI transition |
| `300ms` | Soft cap for common UI motion |
| `500ms` | Large sheet / drawer transition upper bound |
| `cubic-bezier(0.32, 0.72, 0, 1)` | Drawer / bottom-sheet easing |
| `10-16px` | Toast-stack offset starting range |
| `~100px` from viewport edge | Scroll-reveal trigger starting point |

**NEVER**:
- Use bounce or elastic easing curves by default—they draw attention to the animation itself
- Animate layout properties such as width, height, top, or left when transform or opacity would do the job
- Use long durations for routine feedback—it feels laggy fast
- Animate without purpose—every animation needs a reason
- Ignore `prefers-reduced-motion`—this is an accessibility violation
- Animate everything—animation fatigue makes interfaces feel exhausting
- Force users to wait for motion to finish before they can continue
- Use motion to paper over weak structure, unclear hierarchy, or slow data fetching
- Ship gesture logic that ignores momentum, damping, or scroll conflicts

## Verify Quality

Test animations thoroughly:

- **Smooth at 60fps**: No jank on target devices
- **Feels natural**: Easing curves feel organic, not robotic
- **Appropriate timing**: Not too fast (jarring) or too slow (laggy)
- **Immediate acknowledgment**: Inputs get visible response quickly
- **Interruptible where needed**: New intent can override old motion
- **Gesture quality**: Drag, swipe, snap, and dismiss interactions feel physically coherent
- **Reduced motion works**: Animations disabled or simplified appropriately
- **Doesn't block**: Users can interact during/after animations
- **Adds value**: Makes interface clearer or more delightful

Remember: the best UI animation usually feels inevitable, not attention-seeking. Animate with purpose, tune for responsiveness, respect accessibility, and let motion support the product instead of starring in it.

Ships with 51 supporting files:

  • reference/animation-purpose.md
  • reference/asymmetric-press-release.md
  • reference/attribution-and-sources.md
  • reference/avoid-css-variables-drag.md
  • reference/blur-bridge-states.md
  • reference/button-press-scale-097.md
  • reference/clip-path-layout-free-reveals.md
  • reference/clip-path-tab-transitions.md
  • reference/custom-easing-curves.md
  • reference/damp-drag-boundaries.md
  • reference/drawer-500ms-duration.md
  • reference/ease-in-out-on-screen-movement.md
  • reference/ease-out-default.md
  • reference/easing-context.md
  • reference/entrance-animations.md
  • reference/exit-animations.md
  • reference/faster-improves-performance.md
  • reference/gesture-interactions.md
  • reference/hardware-accelerated-busy-main-thread.md
  • reference/hover-gap-fill.md
  • … and 31 more

Mirrored from the author's public source. Install counts from the open skills registry.

The systems behind these skills get built for partners every week.

Partner with us