Skip to main content
skill Claude Code CX Codex Cursor

interaction-design — Claude Code skill: UI motion

This skill helps design microinteractions, transitions, and feedback states. Use it when polishing a UI or building loading and gesture patterns.

Install into Claude Code · Plugin marketplace All methods and platforms ↓
/plugin marketplace add wshobson/agents
/plugin install ui-design@claude-code-workflows
Open on GitHub

What interaction-design does

The skill covers microinteractions, motion design, transitions, and feedback patterns for interface work. It includes guidance for loading states, skeleton screens, progress indicators, toast notifications, drag-and-drop, swipe gestures, scroll-triggered animation, and hover or focus states.

The examples use React and Framer Motion for interactive buttons, toggles, page transitions, ripple effects, and swipe-to-dismiss cards. CSS sections cover keyframes, transitions, easing values, and prefers-reduced-motion. Framer Motion is required for the related examples.

Install it when an existing UI needs clearer state changes and more deliberate interaction behavior. It is a poor fit for a static interface with no motion or feedback states.

What it helps with

  • add button feedback for hover and press states
  • show loading with a skeleton screen or progress bar
  • build transitions between pages and components
  • implement swipe-to-dismiss behavior
  • respect the prefers-reduced-motion setting

Example prompts for the agent

  • Add hover and press feedback to this button with Framer Motion.
  • Create a skeleton screen and progress bar for the data-loading state.
  • Implement a page transition and disable motion when `prefers-reduced-motion` is enabled.

How to install interaction-design

1Plugin marketplace

/plugin marketplace add wshobson/agents
/plugin install ui-design@claude-code-workflows

This installs the whole ui-design plugin with all its skills

2Skills CLI (Vercel)

npx skills add wshobson/agents --skill interaction-design -a claude-code

3Manually: put the files in place

~/.claude/skills/interaction-design/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/interaction-design/

From the same set213

The whole set →
typescript-advanced-types Seth Hobson Guides an agent through advanced TypeScript types, from generics to conditional and mapped types. Use it for typed libraries, API clients, or strict configuration objects. Claude Code CX Codex Cursor 92,169installs tailwind-design-system Seth Hobson Helps build design systems with Tailwind CSS v4, from theme tokens to component variants. Use it when a project needs shared UI patterns. Claude Code CX Codex Cursor 70,180installs brand-landingpage Travis D. Elliott This skill interviews you about the product and its visual direction, then builds a landing page through Stitch. Use it when there’s no established design yet. Claude Code CX Codex Cursor 39,476installs python-testing-patterns Seth Hobson This skill guides Python testing with pytest, fixtures and mocks. Use it when building a test suite or tracking down failing checks. Claude Code CX Codex Cursor 36,943installs python-performance-optimization Seth Hobson This skill profiles Python code to locate CPU and memory bottlenecks. Use it when an application responds slowly or consumes too many resources. Claude Code CX Codex Cursor 35,675installs nextjs-app-router-patterns Seth Hobson This skill covers Next.js App Router patterns for rendering, routing, and data fetching. Use it when starting an App Router project or moving from Pages Router. Claude Code CX Codex Cursor 32,529installs api-design-principles Seth Hobson Use this skill to plan or review REST and GraphQL APIs. It helps when writing a specification or setting API conventions for a team. Claude Code CX Codex Cursor 30,348installs code-review-excellence Seth Hobson This skill guides pull request reviews, catches logic and security issues, and helps teams give specific feedback. Use it for review standards or developer mentoring. Claude Code CX Codex Cursor 30,193installs

Similar

Questions about interaction-design

How do I install interaction-design in Claude Code?

Run npx skills add wshobson/agents --skill interaction-design -a claude-code. The skill file is placed at ~/.claude/skills/interaction-design/SKILL.md.

What does interaction-design do?

It guides the design of microinteractions, motion, transitions, and user feedback states for interface work.

What library do the interaction-design examples use?

The React interaction examples use Framer Motion. The CSS examples use keyframes, transitions, and prefers-reduced-motion.

Source text

SKILL.md · MIT
---
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
- 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

```css
/* 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

```tsx
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

```tsx
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

```tsx
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**:

```tsx
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**:

```tsx
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**:

```tsx
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**:

```tsx
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

```css
@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

```css
.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

```css
/* 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;
  }
}
```

```tsx
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

© Seth Hobson · MIT · wshobson/agents

See also

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor