skills/motion-design-web/SKILL.md
Motion design and micro-animations for web interfaces — Framer Motion layout animations, CSS scroll-driven animations, View Transitions API, GSAP ScrollTrigger, spring physics tuning, loading choreography, and Disney's 12 principles applied to UI. Makes interfaces feel alive without feeling busy. Activate on 'web animation', 'Framer Motion', 'micro-interaction', 'scroll animation', 'page transition', 'View Transitions API', 'spring animation web', 'motion design', 'loading animation', 'skeleton screen', 'hover effect', 'GSAP ScrollTrigger'.
npx skillsauth add curiositech/windags-skills motion-design-webInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Motion is the invisible layer between good design and great design. When done right, users don't notice the animations — they notice the app feels responsive, alive, intentional. When done wrong, they notice that something is bouncing and they wish it would stop.
Project Requirements → Library Choice
├── Simple transitions (hover, fade, slide)?
│ └── Use CSS transitions/animations
│ - Low bundle size impact
│ - Hardware accelerated
│ - Good enough for 80% of needs
├── Layout animations, gesture handling, or complex sequences?
│ ├── React project?
│ │ └── Use Framer Motion
│ │ - Layout animations automatic
│ │ - AnimatePresence for mount/unmount
│ │ - Spring physics built-in
│ └── Vanilla JS or non-React?
│ └── Use GSAP
│ - Maximum control and performance
│ - ScrollTrigger for scroll effects
│ - Complex timeline orchestration
├── Scroll-driven effects only?
│ ├── Browser support modern (Chrome 115+)?
│ │ └── Use CSS scroll-driven animations
│ │ - Zero JavaScript overhead
│ │ - Runs off main thread
│ └── Need older browser support?
│ └── Use GSAP ScrollTrigger
└── Cross-page transitions?
├── Shared elements between pages?
│ └── Use View Transitions API
│ - Browser handles morphing automatically
│ - Fallback to regular page load
└── Simple page-level effects?
└── CSS animations with navigation events
Animation Purpose → Duration Range
├── Instant feedback (hover acknowledgment)?
│ └── 100-150ms with ease-out
├── State change confirmation (toggle, selection)?
│ └── 200-250ms with ease-in-out
├── Content reveal (dropdown, accordion)?
│ └── 300-400ms with spring physics
├── Major context change (modal, page)?
│ └── 400-600ms with anticipation + follow-through
└── Background activity (loading, progress)?
└── 1.5-2s cycle or tied to actual progress
Interaction Type → Spring Config
├── Snappy UI controls (buttons, switches)?
│ └── stiffness: 400, damping: 28
├── Smooth panels (modals, cards)?
│ └── stiffness: 200, damping: 24
├── Playful elements (success animations)?
│ └── stiffness: 300, damping: 15 (more bounce)
├── Heavy elements (full-page sheets)?
│ └── stiffness: 120, damping: 20, mass: 1.5
└── Gesture-driven (drag, swipe)?
└── stiffness: 300, damping: 20, velocity inheritance
Detection: Animation drops below 60fps, DevTools Performance tab shows purple "Layout" blocks during animation Symptoms: Choppy motion, especially on slower devices; scrolling feels laggy during transitions Root Cause: Animating properties that trigger layout recalculation (width, height, margin, padding, top, left) Fix: Only animate transform, opacity, filter, clip-path; use transform: scale() instead of width/height changes
Detection: Elements bounce for >1 second after interaction; users wait for UI to settle before next action Symptoms: Damping too low (<15) or stiffness too high (>500) with low damping; feels like everything is made of jello Root Cause: Misunderstanding that lower damping = more bounce = longer settle time Fix: Keep damping ≥20 for interactive elements; test on actual devices, not fast desktop; use duration-based transitions for predictable timing
Detection: Multiple elements animating simultaneously with no clear visual hierarchy; user doesn't know where to look Symptoms: Everything moves at once on page load; competing animations fight for attention Root Cause: Ignoring Disney's "staging" principle; treating each animation in isolation Fix: Stagger children by 40-80ms; animate hero/primary element first; max 1-2 simultaneous animation groups
Detection: No @media (prefers-reduced-motion) styles; animations run at full intensity for all users Symptoms: User reports motion sensitivity issues; fails accessibility audits Root Cause: Treating reduced motion as optional nice-to-have instead of legal/safety requirement Fix: Always provide crossfade or instant alternatives; test with prefers-reduced-motion: reduce enabled
Detection: Animation library adds >50KB to bundle; first-page animations cause layout shift or delay Symptoms: Slow initial page load; animations start late after JavaScript parses Root Cause: Loading heavy animation library for simple transitions; not code-splitting animation features Fix: Use CSS for simple effects; lazy-load Framer Motion/GSAP; inline critical animation CSS; measure Core Web Vitals impact
Scenario: Product card needs hover effect that feels premium but performs well on mobile.
Novice approach:
.card:hover {
width: 102%;
height: 102%;
margin-top: -4px;
border-width: 2px;
}
Expert analysis: This will trigger layout recalculation on every frame. Width/height changes force reflow. Border-width change affects box model.
Expert solution with decision points:
.card {
transition: transform 200ms ease-out, box-shadow 200ms ease-out;
will-change: transform; /* Hint for layer promotion */
}
.card:hover {
transform: translateY(-4px) scale(1.01); /* Lift + subtle scale */
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.08); /* Depth increase */
}
@media (prefers-reduced-motion: reduce) {
.card {
transition: box-shadow 200ms ease-out; /* Keep depth change, remove movement */
}
.card:hover {
transform: none; /* No movement for motion-sensitive users */
}
}
Performance validation: DevTools Performance tab shows no Layout blocks during hover, maintains 60fps on mid-range mobile device.
Do NOT use this skill for:
threejs-expert for 3D graphics and particle systemsios-app-beauty for SwiftUI or Android animation systemsDelegate to other skills:
react-performance-optimizer for bundle analysis and render optimizationscroll-experience-designer for scroll-jacking and custom scroll behaviorsdesign-system-architect for consistent animation tokens and guidelinesdata-ai
license: Apache-2.0 NOT for unrelated tasks outside this domain.
development
Use when designing caching strategies (cache-aside, write-through, write-behind), implementing distributed locks, building rate limiters, leaderboards, real-time streams (XADD/consumer groups), pub/sub, or tuning eviction policies. Triggers: thundering-herd on cache miss, dogpile on key expiry, Redlock vs SET-NX-PX choice, sliding-window rate limiter, hot-key on a single cluster slot, big-key blowup, MULTI/EXEC across slots, KEYS in production. NOT for Redis Cluster operations/admin (different domain), embedded KV (SQLite, leveldb), in-process LRU caches, or Memcached.
tools
Drawing the `'use client'` boundary correctly in React Server Components apps (Next.js App Router, RSC frameworks) — leaf-pushing, slot composition, serialization rules, and environment poisoning prevention. Grounded in react.dev and Next.js 16 docs.
development
Use when designing rate limiting for an API, choosing between token bucket / sliding window / leaky bucket / fixed window, implementing it in Redis, deciding edge (Cloudflare/Upstash) vs origin enforcement, sizing per-user vs per-IP vs per-endpoint quotas, returning the right 429 response with Retry-After, or fixing the boundary-burst bug in fixed-window limiters. Triggers: 429 too many requests, INCR + EXPIRE, ZADD + ZREMRANGEBYSCORE + ZCARD, X-RateLimit-Remaining header, Cloudflare WAF rate limiting rules, Upstash @upstash/ratelimit, leaky bucket shaping vs policing, distributed rate limiter consistency. NOT for DDoS mitigation specifically (different scale), CAPTCHA / bot management, full WAF design, or per-user quota billing.