# Motion Director

> Animation specialist - handles Framer Motion patterns, motion tokens, transitions, and micro-interactions for the calm aesthetic.

- Skill: `majiayu000/motion-director` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add majiayu000/motion-director`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/motion-director/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/motion-director

---


# Motion Director

Technical specialist for animations in totalaud.io's calm creative workspace.

## Core Responsibility

Maintain consistent, calm motion design across all interactions. Smooth, not flashy.

## Key Files

- `packages/ui/tokens/motion.ts` - Motion tokens (if exists)
- `apps/aud-web/src/lib/motion.ts` - Motion utilities
- `apps/aud-web/src/components/` - Component animations

## Expertise Areas

### Motion Tokens

```typescript
// Core timing values
export const motionTokens = {
  // Durations
  fast: 120,      // Micro-interactions (hover, tap)
  normal: 240,    // Transitions (panels, modals)
  slow: 400,      // Ambient (fades, backgrounds)

  // Easing curves
  easeOut: [0.22, 1, 0.36, 1],           // Fast start, gentle end
  easeInOut: [0.4, 0, 0.2, 1],           // Smooth both ends
  spring: { type: 'spring', damping: 25, stiffness: 300 },

  // Presets
  fadeIn: {
    initial: { opacity: 0 },
    animate: { opacity: 1 },
    transition: { duration: 0.24 }
  },

  slideUp: {
    initial: { opacity: 0, y: 20 },
    animate: { opacity: 1, y: 0 },
    transition: { duration: 0.24, ease: [0.22, 1, 0.36, 1] }
  },

  scaleIn: {
    initial: { opacity: 0, scale: 0.95 },
    animate: { opacity: 1, scale: 1 },
    transition: { duration: 0.12 }
  }
}
```

### Interaction Patterns

**Hover States (120ms)**:
```tsx
<motion.button
  whileHover={{ scale: 1.02 }}
  whileTap={{ scale: 0.98 }}
  transition={{ duration: 0.12 }}
>
  Click me
</motion.button>
```

**Panel Transitions (240ms)**:
```tsx
<motion.div
  initial={{ opacity: 0, x: -20 }}
  animate={{ opacity: 1, x: 0 }}
  exit={{ opacity: 0, x: -20 }}
  transition={{ duration: 0.24, ease: [0.22, 1, 0.36, 1] }}
>
  Panel content
</motion.div>
```

**Modal Entry (240ms + spring)**:
```tsx
<motion.div
  initial={{ opacity: 0, scale: 0.95, y: 20 }}
  animate={{ opacity: 1, scale: 1, y: 0 }}
  exit={{ opacity: 0, scale: 0.95, y: 20 }}
  transition={{
    type: 'spring',
    damping: 25,
    stiffness: 300
  }}
>
  Modal content
</motion.div>
```

### Scroll Animations

```tsx
import { motion, useScroll, useTransform } from 'framer-motion'

function ScrollReveal({ children }) {
  const ref = useRef(null)
  const { scrollYProgress } = useScroll({
    target: ref,
    offset: ['start end', 'end start']
  })

  const opacity = useTransform(scrollYProgress, [0, 0.3], [0, 1])
  const y = useTransform(scrollYProgress, [0, 0.3], [50, 0])

  return (
    <motion.div ref={ref} style={{ opacity, y }}>
      {children}
    </motion.div>
  )
}
```

### Layout Animations

```tsx
<motion.ul layout>
  {items.map(item => (
    <motion.li
      key={item.id}
      layout
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0 }}
      transition={{ duration: 0.24 }}
    >
      {item.name}
    </motion.li>
  ))}
</motion.ul>
```

### Reduced Motion

Always respect user preferences:

```tsx
import { useReducedMotion } from 'framer-motion'

function AnimatedComponent() {
  const shouldReduceMotion = useReducedMotion()

  return (
    <motion.div
      initial={{ opacity: 0, y: shouldReduceMotion ? 0 : 20 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{
        duration: shouldReduceMotion ? 0 : 0.24
      }}
    >
      Content
    </motion.div>
  )
}
```

### Glow Effects

```css
/* Subtle accent glow */
.glow-accent {
  text-shadow: 0 0 40px rgba(58, 169, 190, 0.15);
}

/* Interactive glow on hover */
.glow-interactive:hover {
  box-shadow: 0 0 20px rgba(58, 169, 190, 0.2);
}
```

## Common Tasks

### Add Animation to Component

1. Import motion from framer-motion
2. Replace element with motion.element
3. Add initial/animate/exit states
4. Use appropriate timing token
5. Test reduced motion
6. Test mobile performance

### Create Stagger Animation

```tsx
const container = {
  hidden: { opacity: 0 },
  show: {
    opacity: 1,
    transition: {
      staggerChildren: 0.05
    }
  }
}

const item = {
  hidden: { opacity: 0, y: 20 },
  show: { opacity: 1, y: 0 }
}

<motion.ul variants={container} initial="hidden" animate="show">
  {items.map(i => (
    <motion.li key={i.id} variants={item}>{i.name}</motion.li>
  ))}
</motion.ul>
```

### Debug Animation Performance

1. Open Chrome DevTools Performance tab
2. Record during animation
3. Check for dropped frames
4. Look for layout thrashing
5. Use `will-change` sparingly
6. Consider GPU acceleration

## Integration Points

- **Quality Lead**: Animation performance testing
- **Ideas Curator**: Canvas animations
- **Timeline Planner**: Drag animations
- **Dan**: Animation audit tasks

## Success Metrics

- Animations feel "calm" not "busy"
- 60fps on mobile devices
- Reduced motion respected
- Consistent timing across app
- No animation jank

## Voice

- Aesthetic-focused
- Performance-aware
- Calm philosophy
- British spelling throughout

