animation-motion
Create smooth animations and micro-interactions with Framer Motion and CSS. Covers enter/exit animations, gestures, scroll animations, loading states, and performance optimization. Use for polished UIs, interactive elements, and engaging user experiences.
Best use case
animation-motion is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Create smooth animations and micro-interactions with Framer Motion and CSS. Covers enter/exit animations, gestures, scroll animations, loading states, and performance optimization. Use for polished UIs, interactive elements, and engaging user experiences.
Teams using animation-motion should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/animation-motion/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How animation-motion Compares
| Feature / Agent | animation-motion | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Create smooth animations and micro-interactions with Framer Motion and CSS. Covers enter/exit animations, gestures, scroll animations, loading states, and performance optimization. Use for polished UIs, interactive elements, and engaging user experiences.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Animation & Motion Design
Create smooth, purposeful animations that enhance user experience.
## Instructions
1. **Animate with purpose** - Every animation should serve a function
2. **Keep it subtle** - 200-400ms for most UI transitions
3. **Respect reduced motion** - Honor user preferences
4. **Optimize performance** - Use transform and opacity
5. **Use consistent easing** - Create a motion language
## Framer Motion Basics
### Simple Animations
```tsx
import { motion } from 'framer-motion';
// Fade in on mount
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3 }}
>
Content
</motion.div>
// Slide up with spring
<motion.div
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{
type: 'spring',
stiffness: 300,
damping: 30,
}}
>
Content
</motion.div>
```
### Exit Animations
```tsx
import { AnimatePresence, motion } from 'framer-motion';
function Modal({ isOpen, onClose, children }) {
return (
<AnimatePresence>
{isOpen && (
<>
{/* Backdrop */}
<motion.div
className="fixed inset-0 bg-black/50"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
onClick={onClose}
/>
{/* Modal content */}
<motion.div
className="fixed inset-0 flex items-center justify-center"
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.95 }}
transition={{ duration: 0.2 }}
>
{children}
</motion.div>
</>
)}
</AnimatePresence>
);
}
```
### Gesture Animations
```tsx
import { motion } from 'framer-motion';
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
transition={{ type: 'spring', stiffness: 400, damping: 17 }}
>
Click me
</motion.button>
// Drag
<motion.div
drag
dragConstraints={{ left: 0, right: 300, top: 0, bottom: 300 }}
dragElastic={0.1}
whileDrag={{ scale: 1.1 }}
>
Drag me
</motion.div>
```
### List Animations
```tsx
import { motion } from 'framer-motion';
const container = {
hidden: { opacity: 0 },
show: {
opacity: 1,
transition: {
staggerChildren: 0.1,
},
},
};
const item = {
hidden: { opacity: 0, y: 20 },
show: { opacity: 1, y: 0 },
};
function List({ items }) {
return (
<motion.ul
variants={container}
initial="hidden"
animate="show"
>
{items.map((data) => (
<motion.li key={data.id} variants={item}>
{data.title}
</motion.li>
))}
</motion.ul>
);
}
```
### Layout Animations
```tsx
import { motion, LayoutGroup } from 'framer-motion';
function Tabs({ tabs, activeTab, onTabChange }) {
return (
<LayoutGroup>
<div className="flex space-x-2">
{tabs.map((tab) => (
<button
key={tab.id}
onClick={() => onTabChange(tab.id)}
className="relative px-4 py-2"
>
{tab.label}
{activeTab === tab.id && (
<motion.div
layoutId="activeTab"
className="absolute inset-0 bg-blue-100 rounded-lg"
style={{ zIndex: -1 }}
transition={{ type: 'spring', stiffness: 500, damping: 30 }}
/>
)}
</button>
))}
</div>
</LayoutGroup>
);
}
```
### Scroll Animations
```tsx
import { motion, useScroll, useTransform } from 'framer-motion';
function ParallaxHero() {
const { scrollY } = useScroll();
const y = useTransform(scrollY, [0, 500], [0, 150]);
const opacity = useTransform(scrollY, [0, 300], [1, 0]);
return (
<motion.div
style={{ y, opacity }}
className="h-screen flex items-center justify-center"
>
<h1 className="text-6xl font-bold">Welcome</h1>
</motion.div>
);
}
// Scroll-triggered animation
import { useInView } from 'framer-motion';
function FadeInSection({ children }) {
const ref = useRef(null);
const isInView = useInView(ref, { once: true, margin: '-100px' });
return (
<motion.div
ref={ref}
initial={{ opacity: 0, y: 50 }}
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 50 }}
transition={{ duration: 0.5 }}
>
{children}
</motion.div>
);
}
```
## CSS Animations
### Keyframe Animations
```css
/* Tailwind config */
animation: {
'fade-in': 'fadeIn 0.3s ease-out',
'slide-up': 'slideUp 0.3s ease-out',
'spin-slow': 'spin 3s linear infinite',
'pulse-subtle': 'pulse 2s ease-in-out infinite',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
},
slideUp: {
'0%': { transform: 'translateY(10px)', opacity: '0' },
'100%': { transform: 'translateY(0)', opacity: '1' },
},
}
```
### Transition Classes
```tsx
// Hover transitions
<button className="
transition-all duration-200 ease-out
hover:scale-105 hover:shadow-lg
active:scale-95
">
Click me
</button>
// Color transitions
<div className="
transition-colors duration-300
bg-gray-100 hover:bg-gray-200
dark:bg-gray-800 dark:hover:bg-gray-700
">
Content
</div>
```
## Loading States
### Skeleton Loading
```tsx
function SkeletonCard() {
return (
<div className="animate-pulse">
<div className="h-48 bg-gray-200 rounded-lg" />
<div className="mt-4 space-y-3">
<div className="h-4 bg-gray-200 rounded w-3/4" />
<div className="h-4 bg-gray-200 rounded w-1/2" />
</div>
</div>
);
}
```
### Spinner Component
```tsx
function Spinner({ size = 'md' }) {
const sizes = {
sm: 'w-4 h-4',
md: 'w-6 h-6',
lg: 'w-8 h-8',
};
return (
<svg
className={`animate-spin ${sizes[size]} text-blue-600`}
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
/>
</svg>
);
}
```
## Reduced Motion Support
```tsx
import { useReducedMotion } from 'framer-motion';
function AnimatedComponent() {
const shouldReduceMotion = useReducedMotion();
return (
<motion.div
initial={{ opacity: 0, y: shouldReduceMotion ? 0 : 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: shouldReduceMotion ? 0 : 0.3 }}
>
Content
</motion.div>
);
}
// CSS approach
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
```
## Performance Tips
1. **Animate transform and opacity only** - GPU accelerated
2. **Use `will-change` sparingly** - For complex animations
3. **Avoid layout thrashing** - Don't animate width/height
4. **Use `AnimatePresence` mode="wait"** - Prevent animation overlap
5. **Lazy load animations** - For below-fold content
```tsx
// GPU-optimized animation
<motion.div
animate={{ x: 100 }} // Good: transform
// animate={{ left: 100 }} // Bad: layout property
/>
// will-change for complex animations
<div style={{ willChange: 'transform' }}>
Heavy animation here
</div>
```
## Best Practices
1. **200-400ms for transitions** - Feels responsive
2. **Spring for interactive elements** - Natural feel
3. **Ease-out for enter** - Elements arrive and settle
4. **Ease-in for exit** - Elements accelerate away
5. **Stagger lists** - 50-100ms between items
6. **Match motion to meaning** - Slide for navigation, fade for content
## When to Use
- Page transitions and navigation
- Modal and dialog animations
- Loading and progress states
- Micro-interactions and feedback
- Scroll-driven effects
- Interactive data visualizations
## Notes
- Test on lower-end devices
- Always respect prefers-reduced-motion
- Keep animations consistent across the app
- Don't animate everything - be selectiveRelated Skills
animation
Expert guidance for creating premium, performant animations in React using Motion (motion.dev). Covers all animation types, best practices, accessibility, and performance optimization.
animation-interaction-validator
Ensures engaging user experience through validation of animations, transitions, micro-interactions, and feedback states, preventing flat/static interfaces that lack polish and engagement. Works with Tanstack Start (React) + shadcn/ui components.
motion-animation
Motion (Framer Motion) animation library integration for Remotion - smooth, production-grade UI animations
animation-best-practices
CSS and UI animation patterns for responsive, polished interfaces. Use when implementing hover effects, tooltips, button feedback, transitions, or fixing animation issues like flicker and shakiness.
android-motion-specialist
Expert Android developer for the Motion Detector project. Use this skill when working on Camera2 API integration, motion detection algorithms, Android networking (LAN sockets + Supabase Realtime), debugging crashes, or any Android/Kotlin development tasks specific to this sprint timing application.
sales-motion-design
When the user wants to choose between PLG and sales-led, design a sales motion, optimize time-to-first-value, or build a value-before-purchase experience. Also use when the user mentions 'PLG,' 'product-led growth,' 'sales-led,' 'sales motion,' 'free trial,' 'freemium,' 'self-serve,' 'demo-first,' 'time-to-first-value,' 'TTFV,' or 'agent-led sales.' This skill covers sales motion selection, value delivery design, and go-to-market motion architecture.
remotion-visual-debug
Visual debugging for Remotion video projects. Use when working with Remotion compositions to verify animations, layouts, positioning, and timing by rendering frame samples. Essential for self-correcting visual issues that aren't apparent from code alone.
astro-animations
Animation patterns for Astro sites. Scroll animations, micro-interactions, transitions, loading states. Performance-focused, accessibility-aware.
animations-transitions
SwiftUI animations, @Animatable macro, withAnimation, transitions, PhaseAnimator, KeyframeAnimator, and interactive motion design. Use when user asks about animations, transitions, @Animatable, withAnimation, spring animations, keyframes, or motion design.
animation-principles
Applies Disney's 12 animation principles to UI motion design. Use when improving animation quality, designing micro-interactions, creating easing curves, or making transitions feel natural and purposeful.
animation-designer
Expert in web animations, transitions, and motion design using Framer Motion and CSS
animation-creator
CSS animation and transition creator. Generates optimized @keyframes, transitions, and transform sequences with performance best practices and motion accessibility. Use when adding animations, transitions, or micro-interactions.