micro-interaction
iart-ai/web-animation-skills · Agent Skill
UI motion guidance for hover and press feedback, toggles, toasts, drawers, modals, list transitions, and shared-element interactions.
Jump to install ↓Overview
| Publisher | |
|---|---|
| Repository | iart-ai/web-animation-skills ↗ |
| Skill folder | micro-interaction |
| Stars | 58 |
| Forks | 9 |
| Bundled files | 4 |
| License | MIT |
| Last updated | June 22, 2026 |
| Links | Skill source ↗ · Repository ↗ |
Mozgi check
What we found in the skill files. Details come with a subscription.
Installation
A skill is a folder with a SKILL.md file. Pick your agent and run the commands in a terminal (macOS, Linux or Git Bash on Windows) from your project root.
Copy the prompt into Claude, Codex or another assistant: it will review the skill and install it for you.
Install the “micro-interaction” skill from mozgi.io (https://mozgi.io/skills/iart-ai-micro-interaction/) for me. 1. Download the archive: https://mozgi.io/skills/iart-ai-micro-interaction/download If it fails, take the skill folder from the source: https://github.com/iart-ai/web-animation-skills/tree/main/skills/micro-interaction 2. Read SKILL.md and the other files. Check the skill is safe: no hidden commands, no sending data elsewhere, no scripts doing something other than described. If anything looks suspicious, stop and tell me. 3. Put the “micro-interaction” folder into your agent's skills folder: .claude/skills/ for Claude Code, .agents/skills/ for Codex, .cursor/skills/ for Cursor, .gemini/skills/ for Gemini CLI. Inside the project if we are in one, otherwise in the home folder (~/.claude/skills/ etc.). 4. Make sure <skills folder>/micro-interaction/SKILL.md exists. 5. Briefly tell me what this skill does and offer to try it on my task. If you cannot do a step yourself, tell me what to click or type.
git clone --depth 1 --branch main https://github.com/iart-ai/web-animation-skills.git /tmp/web-animation-skills mkdir -p .claude/skills cp -r /tmp/web-animation-skills/skills/micro-interaction .claude/skills/micro-interaction
Restart Claude Code — the skill appears in the list; call it manually with /micro-interaction. For all projects use ~/.claude/skills.
git clone --depth 1 --branch main https://github.com/iart-ai/web-animation-skills.git /tmp/web-animation-skills mkdir -p .agents/skills cp -r /tmp/web-animation-skills/skills/micro-interaction .agents/skills/micro-interaction
Codex looks for skills in .agents/skills from the current folder up to the repo root; call one with /skills or $micro-interaction. For all projects use ~/.agents/skills.
git clone --depth 1 --branch main https://github.com/iart-ai/web-animation-skills.git /tmp/web-animation-skills mkdir -p .cursor/skills cp -r /tmp/web-animation-skills/skills/micro-interaction .cursor/skills/micro-interaction
Cursor picks the skill up on start; call it with “/” in Agent chat. Cursor also reads .claude/skills and .agents/skills. For all projects use ~/.cursor/skills.
git clone --depth 1 --branch main https://github.com/iart-ai/web-animation-skills.git /tmp/web-animation-skills mkdir -p .gemini/skills cp -r /tmp/web-animation-skills/skills/micro-interaction .gemini/skills/micro-interaction
Gemini CLI offers to activate the skill when a task matches — you approve it. For all projects use ~/.gemini/skills.
Read SKILL.md and any companion files before deciding whether to install. Click a file to preview it.
SKILL.md contents
Original author text · read-onlyMicro-interactions (UI Motion)
Small, functional motion that makes an interface feel responsive and alive: hover/press/focus feedback, toggles, toasts, drawers, and list/layout animation. The goal is feedback and continuity, not decoration.
When to use
- Hover/press/focus feedback; toggles, checkboxes, like/heart buttons
- Toasts/snackbars, drawers, modals, tooltips, accordions (enter/exit)
- List add/remove/reorder; shared-element ("magic move") layout transitions
- Loading → success → error state transitions
Principles (apply to all of it)
- Duration: UI micro-interactions live in 100–250ms. Anything over ~400ms feels laggy for a click response.
- Animate
transformandopacityonly — they are GPU-composited (no layout/paint). Avoid animatingwidth/height/top/left; usescaleor layout animation instead. - Give instant press feedback:
scale: 0.96on tap with a fast spring. - Asymmetric timing: enter slightly slower (ease-out), exit faster (ease-in). Things should arrive gracefully and leave promptly.
- Respect
prefers-reduced-motion: gate non-essential motion; keep opacity changes, drop large movement. - Easing defaults: ease-out for entrances
cubic-bezier(0.16, 1, 0.3, 1); a tasteful overshoot iscubic-bezier(0.34, 1.56, 0.64, 1); standard movecubic-bezier(0.4, 0, 0.2, 1).
Framer Motion (motion/react) essentials
As of v11+, the package is imported as motion/react (the framer-motion name still works).
Gestures and springs
import { motion } from "motion/react";
<motion.button
whileHover={{ scale: 1.03 }}
whileTap={{ scale: 0.96 }}
whileFocus={{ boxShadow: "0 0 0 3px rgba(59,130,246,.5)" }}
transition={{ type: "spring", stiffness: 400, damping: 30 }}
/>
Spring intuition: higher stiffness = faster; higher damping = less bounce. stiffness: 400, damping: 30 is a snappy UI default. For visible bounce, lower damping (e.g. damping: 12).
Enter / exit with AnimatePresence
Exit animations require AnimatePresence wrapping conditionally-rendered children, each with a stable key.
import { AnimatePresence, motion } from "motion/react";
<AnimatePresence>
{open && (
<motion.div
key="panel"
initial={{ opacity: 0, y: 8 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 8 }}
transition={{ duration: 0.2, ease: [0.16, 1, 0.3, 1] }}
/>
)}
</AnimatePresence>
For toasts/lists, use mode="popLayout" so removed items don't hold space while exiting.
Layout animation (the superpower)
layout automatically animates any layout change (position/size) using transforms — perfect for reordering, expanding cards, and grid<->list.
<motion.li layout transition={{ type: "spring", stiffness: 500, damping: 40 }} />
Shared-element transition across components: give two elements the same layoutId and Framer Motion animates between them as one mounts and the other unmounts.
{!open && <motion.div layoutId="card" onClick={() => setOpen(true)} />}
<AnimatePresence>
{open && <motion.div layoutId="card" />} {/* "magic moves" from the source */}
</AnimatePresence>
Gotcha: a plain layout element distorts border-radius and text during scale. Add layout to direct children that should counter-scale, and prefer borderRadius/boxShadow as motion values, or use layout="position" to animate position only.
Pure CSS path (no JS, including discrete properties)
Modern CSS can animate enter/exit and even display toggles without a library.
.toast {
transition: opacity 0.2s ease, transform 0.2s ease;
/* allow animating to/from display:none and from initial render */
transition-behavior: allow-discrete;
}
.toast[hidden] { display: none; }
/* animate FROM these values on first render / when entering */
@starting-style {
.toast { opacity: 0; transform: translateY(8px); }
}
@starting-style defines the "before-open" values so an element animates in on first appearance; transition-behavior: allow-discrete lets display (and overlay for popovers/dialogs) participate so exit animations run before the element is removed. Baseline in Chrome/Edge/Safari; provide a no-animation fallback for older browsers.
Always include a reduced-motion guard:
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
State, not just decoration
Loading → success → error should be one continuous motion (e.g. a button morphs spinner → checkmark), not a jump cut. Keep the element mounted and animate between states so the eye tracks the same object.
Deliver & verify (standalone HTML)
> Packaged helper (scripts/): scripts/seek-shot.sh anim.html 0 1.5 3 freezes the ?t=N harness and screenshots each moment; scripts/contact-sheet.sh sheet.png frame-*.png tiles them for one-glance review. See scripts/README.md.
For a self-contained interaction demo (toggle, like button, toast, drawer) the deliverable is one HTML file that opens directly in a browser. Pure-CSS interactions ship as-is; for a Framer Motion demo, load React + motion from CDN (esm.sh) into one inline module — no build step. One file is the right tier; don't reach for a bundler.
Output contract:
- One
.htmlfile: your markup plus either CSS transitions/@starting-styleor an inline<script type="module">importingmotionfrom CDN. - A way to land on the resolved end state for a screenshot — interactions are state-driven, not time-driven, so freeze the state rather than a clock.
Seek harness — pin a deterministic state. A micro-interaction's "frames" are its states (idle / hover / pressed / open). ?state=open applies the target state on load so a screenshot captures it settled:
<script>
const s = new URLSearchParams(location.search).get("state");
if (s) document.documentElement.dataset.state = s; // CSS keys off [data-state="open"]
// Framer Motion: set the controlled prop from `s` (e.g. const [open]=useState(s==="open"))
// For a CSS @keyframes loop instead, freeze it: el.style.animationDelay=(-N)+"s"; el.style.animationPlayState="paused";
window.__ready = true;
</script>
Verify loop — render → set state → screenshot → check: open each meaningful state (?state=idle, ?state=hover, ?state=open), screenshot, and check fidelity (press feedback reads instant, exit runs before unmount) plus artifacts (layout distorting border-radius/text, toast holding space after exit, FOUC, jank). Any headless tool works:
npx playwright screenshot --wait-for-timeout=400 "file://$PWD/demo.html?state=open" open.png
Before you finish:
1. Opens standalone — no console errors, CDN React/motion (if used) resolves.
2. The ?state= (or controlled-prop) freeze lands a deterministic, settled state.
3. Screenshotted across states — idle / active / open — matches the brief, no artifacts.
4. prefers-reduced-motion honored — large movement dropped, opacity/feedback kept.
5. Easing is intentional — enter ease-out, exit ease-in, durations in the 100–250ms band.
Quick reference
| Need | Approach |
|------|----------|
| Press feedback | whileTap={{ scale: 0.96 }} spring 400/30 |
| Enter/exit | AnimatePresence + initial/animate/exit |
| Reorder / resize | layout prop (spring) |
| Magic move | shared layoutId |
| Toast stack | AnimatePresence mode="popLayout" |
| No-JS enter | @starting-style + transition |
| Animate to display:none | transition-behavior: allow-discrete |
| Accessibility | prefers-reduced-motion guard always |
Reference files
references/framer-motion-recipes.md— variants + stagger,AnimatePresencemodes,layout/layoutIdmagic move,Reorderdrag-to-sort, drag constraints, gesture composition, anduseReducedMotion.references/css-recipes.md—@starting-style,transition-behavior: allow-discrete, popover/dialog exit animation, keyframe spinners/toggles,@propertyfor animatable custom properties, andprefers-reduced-motionpatterns.
Frequently asked questions
What does the micro-interaction skill do?
UI motion guidance for hover and press feedback, toggles, toasts, drawers, modals, list transitions, and shared-element interactions.
How do I install micro-interaction?
Open the “Installation” block on this page and pick your agent — Claude Code, Codex, Cursor or Gemini CLI — for ready-made commands that copy the skill folder to the right place. Or copy the prompt from the “Via assistant” tab and let the assistant review and install the skill.
Which AI models work with micro-interaction?
Skills are plain Markdown instructions (the Agent Skills format), so micro-interaction works with any agent that reads SKILL.md: Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and more. The model loads the instructions only when a task matches the skill's description.
Is micro-interaction free?
The skill is published openly by iart-ai under the MIT license. The skill itself costs nothing — you only pay your AI provider for the tokens you use.
Is it safe to install skills?
A skill is a set of instructions your agent will follow, so read SKILL.md and its companion files before installing. Scripts in the skill folder only run if your agent runs them — keep an eye on what it does and do not grant unnecessary permissions.
How is a skill different from an MCP server or a plugin?
An MCP server or plugin gives the model new tools — code that runs and returns a result. A skill gives it knowledge and process: how to approach a task, which steps to follow and what good output looks like. It needs no server or API key.