hamedmp/matrix-os/animate
Claude Code and agent skill by hamedmp/matrix-os
- community
Checking that the SKILL.md file is still in the repository.
Design and build web animations that feel right, grounded in the complete "Animations on the Web" course (animations.dev). Use proactively whenever building or improving motion — deciding whether to animate, choosing easing/duration/springs, implementing entrances, exits, hovers, gestures, drawers, popovers, morphs, layout and shared-element transitions, SVG animation, or fixing motion that feels janky, sluggish, or off. Triggers on — animate, animation, motion, easing, ease-out, ease-in-out, c…
Install
npx vskill@latest install hamedmp/matrix-os/animateSKILL.md
Building Animations
The complete builder's guide to motion that feels right, distilled from Emil Kowalski's Animations on the Web course (animations.dev). Use it to make decisions first, then implement.
Core Philosophy
An animation feels right when it satisfies three things at once:
- It feels natural. It mirrors the physics of the real world. Nothing around us moves at a constant speed or appears out of nowhere — so
lineareasing feels lifeless andscale(0)entrances feel wrong. - It has a purpose. You can answer "why does this animate?" in one sentence, and neither you nor the user is surprised or annoyed by it.
- It's made with taste. Taste is trained, not innate — the ability to tell good motion from bad and justify why. In a world where everyone's software works, taste is the differentiator.
Two consequences run through everything below:
- Unseen details compound. Most motion details users never consciously notice — that's the point. The aggregate of invisible correctness is what makes an interface feel expensive.
- If everything animates, nothing stands out. Motion is a spice, not the meal. Pace it through the experience; the more you add, the less each one is worth.
Load These When Implementing
This file is the decision layer. When you move to code, load the companion reference for the exact recipe:
- [css-techniques.md](css-techniques.md) — transitions vs keyframes, transforms,
clip-path,@starting-style, stagger, hover patterns, 3D. - [framer-motion.md](framer-motion.md) —
motion/react:initial/animate/exit, spring configs,AnimatePresencemodes,layout/layoutId, motion values & hooks, animating height, and the component recipes (drawer, crossfade, morph, shared-element, trash). - [svg-animation.md](svg-animation.md) —
viewBox, line-drawing (stroke-dashoffset),transform-box/origin, path morphing, shakes, ambient "life."
Err on the side of loading a reference rather than approximating a value.
The Animation Decision Framework
Answer these in order before writing animation code.
1. Should this animate at all?
Match motion to how often the user sees it:
| Frequency | Decision | |
|---|---|---|
| 100+/day (keyboard shortcuts, command-palette toggle, arrow-key list nav) | No animation. Ever. | |
| Tens/day (hover effects, list navigation) | Remove or drastically reduce | |
| Occasional (modals, drawers, toasts) | Standard animation | |
| Rare / first-time (onboarding, feedback, celebrations) | Can add delight |
Never animate keyboard-initiated actions — they repeat hundreds of times a day; animation makes them feel slow and disconnected. Raycast has no open/close animation — that's correct for something opened hundreds of times a day. A high-frequency selection highlight should be instant (track the cursor exactly), not a smooth fade that trails one step behind.
2. What's the purpose?
Every animation needs one of: explanation (marketing/onboarding), feedback/responsiveness (a button that reacts to a press), spatial consistency (an element enters and exits the same way), state indication, preventing a jarring change (a toast that eases in instead of popping), or — rarely — delight (reserved for interactions seen seldom, so it stays a pleasant surprise). "It looks cool" on a frequently-seen element is not a purpose.
3. Then pick the ingredients
Easing → duration → physicality → (spring?) → interruptibility → performance → accessibility. The rest of this file is those ingredients.
Easing
Easing is the single most important part of an animation — it can make a bad animation look great or a great one feel wrong.
| Situation | Curve | |
|---|---|---|
| Entering or exiting the screen | `ease-out` (fast start, gentle settle — feels responsive) | |
| Moving / morphing while already on screen | `ease-in-out` (car accelerating then braking) | |
| Hover / color / background / opacity | `ease` (asymmetric, elegant for small changes; CSS default) | |
| Constant motion (marquee, spinner, timer, hold-to-delete) | `linear` | |
| Default | `ease-out` |
Never use `ease-in` on UI. It starts slow — delaying the exact moment the user is watching — then accelerates into the stop, the opposite of how things settle.
Built-in named curves are almost never strong enough. Their acceleration is too weak, so animations feel flat. Every course example uses a custom curve. Prefer asymmetric curves (steep start, slow settle) — they feel alive and mimic a spring without one. When an animation feels flat, the curve is probably too weak, not the duration.
Curves worth reaching for:
Pair entering and exiting elements to the same direction and curve family so the interaction reads as one coherent space.
Duration
Keep UI animations under ~300ms unless justified. A 180ms dropdown feels more responsive than a 400ms one. Faster spinners make loads feel faster.
| Element | Duration | |
|---|---|---|
| Button press | ~150ms | |
| Tooltips, small popovers | 125–200ms | |
| Dropdowns, selects | 150–250ms | |
| Modals, drawers | 200–500ms | |
| Small floating drawer | ~270ms | |
| Wide menu resize | ~250ms | |
| Big element crossing the screen | up to ~1s |
Duration and easing are inseparable. A steep curve can afford a longer duration (Vaul's 500ms doesn't feel slow because the curve front-loads the movement); a weak curve must be shorter. Choose the easing first, then tune duration to it. Duration scales with element size and travel distance (a bigger element is heavier). Exits are shorter and simpler than entries — the user already decided; get out of the way. Too fast is as bad as too slow. Marketing pages can run longer; product must feel fast.
For transitions whose size varies (an auto-height drawer), make duration proportional to how much changed so small changes don't over-animate — see the adaptive-duration recipe in framer-motion.md.
Physicality
- Never animate from `scale(0)`. Start entrances from
scale(0.9–0.95)+opacity: 0. Nothing appears from nothing; a near-full start reads as "it was always almost there." Bigger floating elements start closer to 1 (a nav menu usesscale(0.98)). - Button press:
transform: scale(0.97)on:active,transition: transform ~150ms. Press feedback is felt, not seen —scale(0.9)visibly collapses. Buttons feel best with both hover and press feedback; hover with nothing on click feels dead. - Hover scale: 1–2% is plenty (
scale(1.02)).hover:scale-105inflates like a balloon. Hover duration 100–150ms. - Origin-aware popovers. Scale from the trigger, not the center (the CSS default
transform-origin: centeris wrong for almost every triggered element). Use the library's variable:
``css .popover { transform-origin: var(--radix-popover-content-transform-origin); } /* Radix */ .popover { transform-origin: var(--transform-origin); } /* Base UI */ .menu { transform-origin: top center; } /* trigger above */ ` **Modals are exempt** — they appear centered, keep transform-origin: center`.
- Never put a hover lift on the hover target itself. Animating
translateYon the hovered element moves it out from under the cursor → hover ends → it drops → flicker loop. Move the lift to an inner child; the parent stays under the cursor.
Springs
Springs simulate physics (mass, stiffness/tension, damping) with no fixed duration, so they feel organic and alive. Reach for them for: drag with momentum, "alive" elements (Dynamic Island), interruptible gestures, and cursor-following. Simple color/opacity changes don't need a spring. Real springs are impossible in pure CSS (only approximable with linear()).
- Default bounce to 0. No overshoot keeps UI natural and elegant. Add bounce only intentionally — a slight bounce at the end of a drag (a drag applies force); a press-to-close gets none. Bounce is personality: more = playful, zero = serious.
- Bounce scales inversely with element size — smaller elements need more bounce to read the same amount.
- Springs are interruptible — redirected mid-motion, they carry velocity, so gestures the user reverses stay smooth. This is why the Sonner toast bug (new toast jumping) was a keyframe/interruptibility problem.
- "Weird" spring motion is usually fixed by increasing `damping`.
Interruptibility
Anything triggered rapidly (toasts, toggles, drawers, accordions, drags) must animate from its current state, not restart. CSS transitions and springs are interruptible; @keyframes restart from zero and make new items jump. Prefer transitions/springs for dynamic UI, and @keyframes only for autonomous, looping, or one-shot motion. Use @starting-style to animate an enter without JS — see css-techniques.md.
Performance
The golden rule: only animate `transform` and `opacity`. They run on the GPU (Composite step only). width/height/margin/padding/top/left trigger Layout + Paint + Composite and drop frames. Prefer transform: translate (percentages — relative to the element's own size) over margin/top, and scale over animating dimensions. Target 60fps (≤16.7ms/frame).
- Framer Motion `x`/`y`/`scale` shorthands are not hardware-accelerated — they run on the main thread via rAF. When motion must stay smooth under load, animate the full
transformstring. - Don't drive child transforms through a CSS variable on a shared parent — inherited vars recalc styles for all descendants (the Vaul lag past ~20 items). Set
transformdirectly on the element. - CSS/WAAPI beat JS under load — they run off the main thread. Use CSS for predetermined motion, JS for dynamic/interruptible.
- `will-change: transform` fixes 1px GPU/CPU shift and promotes heavy/filtered elements to their own layer — but add it (and
contain: layout style paint,translateZ(0)) only once you see dropped frames; too many layers cost memory. - Keep animated `blur()` ≤ ~20px — blur gets laggy fast, especially in Safari.
For the full frame-budget model (the Layout/Paint/Composite pipeline, main-thread vs GPU, React re-renders, and a diagnosis checklist for dropped frames), use the animation-performance skill.
Stagger, hierarchy & orchestration
Stagger group entrances 30–80ms apart — longer feels slow, and stagger is decorative so it must never block interaction. Vary the delay and distance by visual importance: the most important element appears first with the most screen time; the least important can just fade in without sliding. Uniform stagger (identical delay/distance/easing per item) kills hierarchy and feels artificial.
One entrance per container. Don't slide a panel in and trickle its children in — slide it in with content already there. Sometimes the best animation is no animation.
Cohesion & spatial consistency
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 96 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/matrix/animate/SKILL.md
Popularity
- Repository stars
- 85
- Repository forks
- 25
- 7-day trend score
- 0
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/hamedmp/matrix-os/animate)