Skip to content
cccskills
FreePublished on GitHub

interaction-design

Design and implement interface responses such as button feedback, loading indicators, page transitions, and swipe gestures. Use motion to communicate actions and state changes, with guidance on timing, performance, and support for people who prefer reduced animation.

OriginalShow the original 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.

See how to install

Good for

  • Adding hover and click feedback to buttons
  • Showing loading placeholders and progress indicators
  • Creating transitions for pages and interface components
  • Implementing swipe gestures and drag-and-drop interactions
  • Adapting animations to reduced-motion preferences

Files included (4)

  • SKILL.md7.4 KB
  • references/animation-libraries.md10.7 KB
  • references/microinteraction-patterns.md13.2 KB
  • references/scroll-animations.md9.1 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

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

DurationUse Case
100-150msMicro-feedback (hovers, clicks)
200-300msSmall transitions (toggles, dropdowns)
300-500msMedium 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

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Build and review interfaces against WCAG 2.2 accessibility guidelines. Covers keyboard navigation, screen readers that read interface content aloud, accessible forms, mobile support, and display preferences, helping identify and fix barriers to using a website or app.

  • Audit an interface for accessibility issues
  • Add keyboard navigation and focus management
  • Improve screen reader support for forms
wshobson/agents41.2KUpdated Oct 20, 2026

ai-debt-detector

FreeSummary

Review AI-generated code for problems hidden behind successful runs. Check failure handling, resource cleanup, unusual inputs, nonexistent dependencies, and departures from project conventions to identify missing safeguards before merging or accepting the work as complete.

  • Audit code after an AI generation session
  • Review an AI-generated pull request before merging
  • Investigate brittle code that appears to work
wshobson/agents41.2KUpdated Oct 20, 2026

Build Apache Airflow workflows for data pipelines and scheduled jobs. The skill guides task dependencies, retries, waiting for conditions, testing, and deployment, with patterns for tasks that can be safely rerun.

  • Building scheduled data pipelines
  • Designing task order and dependencies
  • Implementing custom tasks and condition checks
wshobson/agents41.2KUpdated Oct 20, 2026

Plan and carry out an AngularJS to Angular migration, from choosing a rewrite strategy to converting components, services, and routes. Includes a hybrid approach that runs both frameworks together while individual features are migrated.

  • Planning an AngularJS to Angular migration
  • Moving a large app one feature at a time
  • Converting directives into Angular components
wshobson/agents41.2KUpdated Oct 20, 2026

Identify software protections that hinder inspection, such as debugger detection and obfuscation that makes code harder to understand. Support authorized binary analysis and CTF security challenges with protection findings, bypass strategies, reports, and analysis scripts.

  • Identify protections in an authorized malware sample
  • Plan analysis of a packed executable
  • Implement debugger detection for a CTF challenge
wshobson/agents41.2KUpdated Oct 20, 2026

Design and review REST and GraphQL APIs with consistent naming, data structures, error responses, pagination for large result sets, and versioning strategies. Helps teams define shared standards and plan changes that existing clients can adopt gradually.

  • Designing a new REST or GraphQL API
  • Reviewing API specifications before implementation
  • Establishing shared API design standards
wshobson/agents41.2KUpdated Oct 20, 2026

See all skills by wshobson

Report a problem with this skill