Design and implement microinteractions, motion design

Interaction design

by wshobson · MIT license · ★ 39,857 on GitHub · updated Sep 21

Interaction design cover

Design and implement microinteractions, motion design, transitions, and user feedback patterns. Use when adding polish to UI interactions, implementing loading states, or creating delightful user experiences.

---
name: interaction-design
description: Design and implement microinteractions, motion design, transitions, and user feedback patterns. Use when adding polish to UI interactions, implementing loading states, or creating delightful user experiences.
---

# Interaction Design

Create engaging, intuitive interactions through motion, feedback, and thoughtful state transitions that enhance usability and delight users.

## When to Use This Skill

- Adding microinteractions to enhance user feedback
- Implementing smooth page and component transitions
- Designing loading states and skeleton screens
- Creating gesture-based interactions
- Building notification and toast systems
- Implementing drag-and-drop interfaces
- Adding scroll-triggered animations

Overview

Create engaging, intuitive interactions through motion, feedback, and thoughtful state transitions that enhance usability and delight users.

Manual install (npx, ZIP)
Claude Codenpx skills add wshobson/agents --skill interaction-design -g -a claude-code
Claude Code (manual)mkdir -p ~/.claude/skills && curl -sL https://codeload.github.com/wshobson/agents/tar.gz/4236bb91f839 \ | tar -xz -C ~/.claude/skills --strip-components=4 agents-4236bb91f839/plugins/ui-design/skills/interaction-design
Windows (PowerShell)New-Item -ItemType Directory -Force "$HOME\.claude\skills" | Out-Null; Invoke-WebRequest "https://m.agentalley.io/zip/42c38c749aa7b994b4e9/interaction-design.zip" -OutFile "$env:TEMP\interaction-design.zip"; Expand-Archive "$env:TEMP\interaction-design.zip" -DestinationPath "$HOME\.claude\skills" -Force
Claude.ai / desktopDownload the ZIP and upload it under Settings → Capabilities → Skills.
Codex, Cursor, other agentsPoint them at SKILL.md. The other files are plain text.

Connects with Agent Alley MCP · agentalley.io/mcp

Files included

  • SKILL.md7.4 KB
  • references/3 files · 33.0 KB
Read the files here
wshobson/4236bb94 files
SKILL.md
Show the full text321 lines

Interaction Design

Create engaging, intuitive interactions through motion, feedback, and thoughtful state transitions that enhance usability and delight users.

When to Use This Skill

  • Adding microinteractions to enhance user feedback
  • Implementing smooth page and component transitions
  • Designing loading states and skeleton screens
  • Creating gesture-based interactions
  • Building notification and toast systems
  • Implementing drag-and-drop interfaces
  • Adding scroll-triggered animations
  • Designing hover and focus states

Core Principles

1. Purposeful Motion

Motion should communicate, not decorate:

  • Feedback: Confirm user actions occurred
  • Orientation: Show where elements come from/go to
  • Focus: Direct attention to important changes
  • Continuity: Maintain context during transitions
2. Timing Guidelines
Duration Use Case
100-150ms Micro-feedback (hovers, clicks)
200-300ms Small transitions (toggles, dropdowns)
300-500ms Medium transitions (modals, page changes)
500ms+ Complex choreographed animations
3. Easing Functions
/* Common easings */
--ease-out: cubic-bezier(0.16, 1, 0.3, 1); /* Decelerate - entering */
--ease-in: cubic-bezier(0.55, 0, 1, 0.45); /* Accelerate - exiting */
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); /* Both - moving between */
--spring: cubic-bezier(0.34, 1.56, 0.64, 1); /* Overshoot - playful */

Quick Start: Button Microinteraction

import { motion } from "framer-motion";

export function InteractiveButton({ children, onClick }) {
  return (
    <motion.button
      onClick={onClick}
      whileHover={{ scale: 1.02 }}
      whileTap={{ scale: 0.98 }}
      transition={{ type: "spring", stiffness: 400, damping: 17 }}
      className="px-4 py-2 bg-blue-600 text-white rounded-lg"
    >
      {children}
    </motion.button>
  );
}

Interaction Patterns

1. Loading States

Skeleton Screens: Preserve layout while loading

function CardSkeleton() {
  return (
    <div className="animate-pulse">
      <div className="h-48 bg-gray-200 rounded-lg" />
      <div className="mt-4 h-4 bg-gray-200 rounded w-3/4" />
      <div className="mt-2 h-4 bg-gray-200 rounded w-1/2" />
    </div>
  );
}

Progress Indicators: Show determinate progress

function ProgressBar({ progress }: { progress: number }) {
  return (
    <div className="h-2 bg-gray-200 rounded-full overflow-hidden">
      <motion.div
        className="h-full bg-blue-600"
        initial={{ width: 0 }}
        animate={{ width: `${progress}%` }}
        transition={{ ease: "easeOut" }}
      />
    </div>
  );
}
2. State Transitions

Toggle with smooth transition:

function Toggle({ checked, onChange }) {
  return (
    <button
      role="switch"
      aria-checked={checked}
      onClick={() => onChange(!checked)}
      className={`
        relative w-12 h-6 rounded-full transition-colors duration-200
        ${checked ? "bg-blue-600" : "bg-gray-300"}
      `}
    >
      <motion.span
        className="absolute top-1 left-1 w-4 h-4 bg-white rounded-full shadow"
        animate={{ x: checked ? 24 : 0 }}
        transition={{ type: "spring", stiffness: 500, damping: 30 }}
      />
    </button>
  );
}
3. Page Transitions

Framer Motion layout animations:

import { AnimatePresence, motion } from "framer-motion";

function PageTransition({ children, key }) {
  return (
    <AnimatePresence mode="wait">
      <motion.div
        key={key}
        initial={{ opacity: 0, y: 20 }}
        animate={{ opacity: 1, y: 0 }}
        exit={{ opacity: 0, y: -20 }}
        transition={{ duration: 0.3 }}
      >
        {children}
      </motion.div>
    </AnimatePresence>
  );
}
4. Feedback Patterns

Ripple effect on click:

function RippleButton({ children, onClick }) {
  const [ripples, setRipples] = useState([]);

  const handleClick = (e) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const ripple = {
      x: e.clientX - rect.left,
      y: e.clientY - rect.top,
      id: Date.now(),
    };
    setRipples((prev) => [...prev, ripple]);
    setTimeout(() => {
      setRipples((prev) => prev.filter((r) => r.id !== ripple.id));
    }, 600);
    onClick?.(e);
  };

  return (
    <button onClick={handleClick} className="relative overflow-hidden">
      {children}
      {ripples.map((ripple) => (
        <span
          key={ripple.id}
          className="absolute bg-white/30 rounded-full animate-ripple"
          style={{ left: ripple.x, top: ripple.y }}
        />
      ))}
    </button>
  );
}
5. Gesture Interactions

Swipe to dismiss:

function SwipeCard({ children, onDismiss }) {
  return (
    <motion.div
      drag="x"
      dragConstraints={{ left: 0, right: 0 }}
      onDragEnd={(_, info) => {
        if (Math.abs(info.offset.x) > 100) {
          onDismiss();
        }
      }}
      className="cursor-grab active:cursor-grabbing"
    >
      {children}
    </motion.div>
  );
}

CSS Animation Patterns

Keyframe Animations
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.animate-fadeIn {
  animation: fadeIn 0.3s ease-out;
}
.animate-pulse {
  animation: pulse 2s ease-in-out infinite;
}
.animate-spin {
  animation: spin 1s linear infinite;
}
CSS Transitions
.card {
  transition:
    transform 0.2s ease-out,
    box-shadow 0.2s ease-out;
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);
}

Accessibility Considerations

/* Respect user motion preferences */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
function AnimatedComponent() {
  const prefersReducedMotion = window.matchMedia(
    "(prefers-reduced-motion: reduce)",
  ).matches;

  return (
    <motion.div
      animate={{ opacity: 1 }}
      transition={{ duration: prefersReducedMotion ? 0 : 0.3 }}
    />
  );
}

Best Practices

  1. Performance First: Use transform and opacity for smooth 60fps
  2. Reduce Motion Support: Always respect prefers-reduced-motion
  3. Consistent Timing: Use a timing scale across the app
  4. Natural Physics: Prefer spring animations over linear
  5. Interruptible: Allow users to cancel long animations
  6. Progressive Enhancement: Work without JS animations
  7. Test on Devices: Performance varies significantly

Common Issues

  • Janky Animations: Avoid animating width, height, top, left
  • Over-animation: Too much motion causes fatigue
  • Blocking Interactions: Never prevent user input during animations
  • Memory Leaks: Clean up animation listeners on unmount
  • Flash of Content: Use will-change sparingly for optimization
1---
2name: interaction-design
3description: Design and implement microinteractions, motion design, transitions, and user feedback patterns. Use when adding polish to UI interactions, implementing loading states, or creating delightful user experiences.
4---
5 
6# Interaction Design
7 
8Create engaging, intuitive interactions through motion, feedback, and thoughtful state transitions that enhance usability and delight users.
9 
10## When to Use This Skill
11 
12- Adding microinteractions to enhance user feedback
13- Implementing smooth page and component transitions
14- Designing loading states and skeleton screens
15- Creating gesture-based interactions
16- Building notification and toast systems
17- Implementing drag-and-drop interfaces
18- Adding scroll-triggered animations
19- Designing hover and focus states
20 
21## Core Principles
22 
23### 1. Purposeful Motion
24 
25Motion should communicate, not decorate:
26 
27- **Feedback**: Confirm user actions occurred
28- **Orientation**: Show where elements come from/go to
29- **Focus**: Direct attention to important changes
30- **Continuity**: Maintain context during transitions
31 
32### 2. Timing Guidelines
33 
34| Duration | Use Case |
35| --------- | ----------------------------------------- |
36| 100-150ms | Micro-feedback (hovers, clicks) |
37| 200-300ms | Small transitions (toggles, dropdowns) |
38| 300-500ms | Medium transitions (modals, page changes) |
39| 500ms+ | Complex choreographed animations |
40 
41### 3. Easing Functions
42 
43```css
44/* Common easings */
45--ease-out: cubic-bezier(0.16, 1, 0.3, 1); /* Decelerate - entering */
46--ease-in: cubic-bezier(0.55, 0, 1, 0.45); /* Accelerate - exiting */
47--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); /* Both - moving between */
48--spring: cubic-bezier(0.34, 1.56, 0.64, 1); /* Overshoot - playful */
49```
50 
51## Quick Start: Button Microinteraction
52 
53```tsx
54import { motion } from "framer-motion";
55 
56export function InteractiveButton({ children, onClick }) {
57 return (
58 <motion.button
59 onClick={onClick}
60 whileHover={{ scale: 1.02 }}
61 whileTap={{ scale: 0.98 }}
62 transition={{ type: "spring", stiffness: 400, damping: 17 }}
63 className="px-4 py-2 bg-blue-600 text-white rounded-lg"
64 >
65 {children}
66 </motion.button>
67 );
68}
69```
70 
71## Interaction Patterns
72 
73### 1. Loading States
74 
75**Skeleton Screens**: Preserve layout while loading
76 
77```tsx
78function CardSkeleton() {
79 return (
80 <div className="animate-pulse">
81 <div className="h-48 bg-gray-200 rounded-lg" />
82 <div className="mt-4 h-4 bg-gray-200 rounded w-3/4" />
83 <div className="mt-2 h-4 bg-gray-200 rounded w-1/2" />
84 </div>
85 );
86}
87```
88 
89**Progress Indicators**: Show determinate progress
90 
91```tsx
92function ProgressBar({ progress }: { progress: number }) {
93 return (
94 <div className="h-2 bg-gray-200 rounded-full overflow-hidden">
95 <motion.div
96 className="h-full bg-blue-600"
97 initial={{ width: 0 }}
98 animate={{ width: `${progress}%` }}
99 transition={{ ease: "easeOut" }}
100 />
101 </div>
102 );
103}
104```
105 
106### 2. State Transitions
107 
108**Toggle with smooth transition**:
109 
110```tsx
111function Toggle({ checked, onChange }) {
112 return (
113 <button
114 role="switch"
115 aria-checked={checked}
116 onClick={() => onChange(!checked)}
117 className={`
118 relative w-12 h-6 rounded-full transition-colors duration-200
119 ${checked ? "bg-blue-600" : "bg-gray-300"}
120 `}
121 >
122 <motion.span
123 className="absolute top-1 left-1 w-4 h-4 bg-white rounded-full shadow"
124 animate={{ x: checked ? 24 : 0 }}
125 transition={{ type: "spring", stiffness: 500, damping: 30 }}
126 />
127 </button>
128 );
129}
130```
131 
132### 3. Page Transitions
133 
134**Framer Motion layout animations**:
135 
136```tsx
137import { AnimatePresence, motion } from "framer-motion";
138 
139function PageTransition({ children, key }) {
140 return (
141 <AnimatePresence mode="wait">
142 <motion.div
143 key={key}
144 initial={{ opacity: 0, y: 20 }}
145 animate={{ opacity: 1, y: 0 }}
146 exit={{ opacity: 0, y: -20 }}
147 transition={{ duration: 0.3 }}
148 >
149 {children}
150 </motion.div>
151 </AnimatePresence>
152 );
153}
154```
155 
156### 4. Feedback Patterns
157 
158**Ripple effect on click**:
159 
160```tsx
161function RippleButton({ children, onClick }) {
162 const [ripples, setRipples] = useState([]);
163 
164 const handleClick = (e) => {
165 const rect = e.currentTarget.getBoundingClientRect();
166 const ripple = {
167 x: e.clientX - rect.left,
168 y: e.clientY - rect.top,
169 id: Date.now(),
170 };
171 setRipples((prev) => [...prev, ripple]);
172 setTimeout(() => {
173 setRipples((prev) => prev.filter((r) => r.id !== ripple.id));
174 }, 600);
175 onClick?.(e);
176 };
177 
178 return (
179 <button onClick={handleClick} className="relative overflow-hidden">
180 {children}
181 {ripples.map((ripple) => (
182 <span
183 key={ripple.id}
184 className="absolute bg-white/30 rounded-full animate-ripple"
185 style={{ left: ripple.x, top: ripple.y }}
186 />
187 ))}
188 </button>
189 );
190}
191```
192 
193### 5. Gesture Interactions
194 
195**Swipe to dismiss**:
196 
197```tsx
198function SwipeCard({ children, onDismiss }) {
199 return (
200 <motion.div
201 drag="x"
202 dragConstraints={{ left: 0, right: 0 }}
203 onDragEnd={(_, info) => {
204 if (Math.abs(info.offset.x) > 100) {
205 onDismiss();
206 }
207 }}
208 className="cursor-grab active:cursor-grabbing"
209 >
210 {children}
211 </motion.div>
212 );
213}
214```
215 
216## CSS Animation Patterns
217 
218### Keyframe Animations
219 
220```css
221@keyframes fadeIn {
222 from {
223 opacity: 0;
224 transform: translateY(10px);
225 }
226 to {
227 opacity: 1;
228 transform: translateY(0);
229 }
230}
231 
232@keyframes pulse {
233 0%,
234 100% {
235 opacity: 1;
236 }
237 50% {
238 opacity: 0.5;
239 }
240}
241 
242@keyframes spin {
243 to {
244 transform: rotate(360deg);
245 }
246}
247 
248.animate-fadeIn {
249 animation: fadeIn 0.3s ease-out;
250}
251.animate-pulse {
252 animation: pulse 2s ease-in-out infinite;
253}
254.animate-spin {
255 animation: spin 1s linear infinite;
256}
257```
258 
259### CSS Transitions
260 
261```css
262.card {
263 transition:
264 transform 0.2s ease-out,
265 box-shadow 0.2s ease-out;
266}
267 
268.card:hover {
269 transform: translateY(-4px);
270 box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);
271}
272```
273 
274## Accessibility Considerations
275 
276```css
277/* Respect user motion preferences */
278@media (prefers-reduced-motion: reduce) {
279 *,
280 *::before,
281 *::after {
282 animation-duration: 0.01ms !important;
283 animation-iteration-count: 1 !important;
284 transition-duration: 0.01ms !important;
285 }
286}
287```
288 
289```tsx
290function AnimatedComponent() {
291 const prefersReducedMotion = window.matchMedia(
292 "(prefers-reduced-motion: reduce)",
293 ).matches;
294 
295 return (
296 <motion.div
297 animate={{ opacity: 1 }}
298 transition={{ duration: prefersReducedMotion ? 0 : 0.3 }}
299 />
300 );
301}
302```
303 
304## Best Practices
305 
3061. **Performance First**: Use `transform` and `opacity` for smooth 60fps
3072. **Reduce Motion Support**: Always respect `prefers-reduced-motion`
3083. **Consistent Timing**: Use a timing scale across the app
3094. **Natural Physics**: Prefer spring animations over linear
3105. **Interruptible**: Allow users to cancel long animations
3116. **Progressive Enhancement**: Work without JS animations
3127. **Test on Devices**: Performance varies significantly
313 
314## Common Issues
315 
316- **Janky Animations**: Avoid animating `width`, `height`, `top`, `left`
317- **Over-animation**: Too much motion causes fatigue
318- **Blocking Interactions**: Never prevent user input during animations
319- **Memory Leaks**: Clean up animation listeners on unmount
320- **Flash of Content**: Use `will-change` sparingly for optimization
321 
View all files on GitHub →

Details

Updated
Sep 21, 2026
License
MIT
Stars on the repo
★ 39,857
Checked
Source
wshobson/agents ↗
Creator
wshobson · 179 listings
View creator

Similar skills

See all →
SkillDesign, redesign, shape, critique, audit, polish, clarifyImpeccablepbakaus/impeccable · by pbakausUse when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a frontend interface. Covers websites, landing pages, dashboards, product UI, app shells, components, forms, settings, onboarding, and empty states. Handles UX review, visual hierarchy, information architecture, cognitive load, accessibility, performance, responsive behavior, theming, anti-patterns, typography, fonts, spacing, layout, alignment, color, motion, micro-interactions, UX copy, error states, edge cases, i18n, and reusable design systems or tokens. Also use for bland designs that need to become bolder or more delightful, loud designs that should become quieter, live browser iteration on UI elements, or ambitious visual effects that should feel technically extraordinary. Not for backend-only or non-UI tasks.★ 70.4k GitHub starsSkillApple's approach to interface design and fluidApple designemilkowalski/skills · by emilkowalskiApple's approach to interface design and fluid, physical motion, translated for the web. Use when building or reviewing gesture-driven UI, spring animations, drag/swipe/sheet interactions, momentum and interruptible transitions, translucent materials and depth, typography (optical sizing, tracking, leading), reduced-motion, or the design foundations (feedback, spatial consistency, restraint) behind Apple-style interfaces.★ 40.8k GitHub starsSkillBuild an animation from scratchBuilding Animationsemilkowalski/skills · by emilkowalskiBuild an animation from scratch, making the decisions in the order that determines whether it feels right — should it animate at all, what purpose, which tool, which properties, which curve and duration, how it interrupts, how it exits. Writes the implementation. Use when asked to animate something, add motion, make a component feel alive, or build a transition. For critiquing existing motion use review-animations; for auditing a whole codebase use improve-animations.★ 40.8k GitHub starsSkillRenders a component you choose in every stateBreakjakubkrehel/skills · by jakubkrehelRenders a component you choose in every state and scenario on a temporary page and stress tests it.★ 7.1k GitHub starsSkillReviews your work across multiple categories like UIChange reviewjakubkrehel/skills · by jakubkrehelReviews your work across multiple categories like UI, typography, layout, color, writing and accessibility and gives you a detailed analysis of the findings.★ 7.1k GitHub starsSkillCraft-first interface design for dashboards, admin panelsThe ProblemDammyjay93/interface-design · by Dammyjay93Craft-first interface design for dashboards, admin panels, SaaS apps, tools, settings pages, data interfaces, and interactive products. Use when designing, building, reviewing, auditing, or refining product UI where visual craft, layout hierarchy, tokens, states, visual direction, or design-system consistency matter. Not for marketing pages, landing pages, campaigns, or brand-only work.★ 5.8k GitHub stars

More from wshobson

SkillMaster C/.NET backend development patterns for buildingwshobson/agents · by wshobsonMaster C#/.NET backend development patterns for building robust APIs, MCP servers, and enterprise applications. Covers async/await, dependency injection, Entity Framework Core, Dapper, configuration, caching, and testing with xUnit. Use when developing .NET backends, reviewing C# code, or designing API architectures.★ 39.9k GitHub starsSkillImplement WCAG 2.2 compliant interfaces with mobileAccessibility compliancewshobson/agents · by wshobsonImplement WCAG 2.2 compliant interfaces with mobile accessibility, inclusive design patterns, and assistive technology support. Use when auditing accessibility, implementing ARIA patterns, building for screen readers, or ensuring inclusive user experiences.★ 39.9k GitHub starsSkillMaster Material Design 3 and Jetpack Compose patternsAndroid Mobile Designwshobson/agents · by wshobsonMaster Material Design 3 and Jetpack Compose patterns for building native Android apps. Use when designing Android interfaces, implementing Compose UI, or following Google's Material Design guidelines.★ 39.9k GitHub starsSkillMigrate from AngularJS to Angular using hybrid modeAngular migrationwshobson/agents · by wshobsonMigrate from AngularJS to Angular using hybrid mode, incremental component rewriting, and dependency injection updates. Use when upgrading AngularJS applications, planning framework migrations, or modernizing legacy Angular code.★ 39.9k GitHub starsSkillUnderstand anti-reversing, obfuscationAnti reversing techniqueswshobson/agents · by wshobsonUnderstand anti-reversing, obfuscation, and protection techniques encountered during software analysis. Use this skill when analyzing malware evasion techniques, when implementing anti-debugging protections for CTF challenges, when reverse engineering packed binaries, or when building security research tools that need to detect virtualized environments.★ 39.9k GitHub starsSkillBuild production Apache Airflow DAGs with best practicesApache Airflow DAG Patternswshobson/agents · by wshobsonBuild production Apache Airflow DAGs with best practices for operators, sensors, testing, and deployment. Use when creating data pipelines, orchestrating workflows, or scheduling batch jobs.★ 39.9k GitHub stars