Smithery Logo
MCPsSkillsDocsPricing
Login
NewFlame, an assistant that learns and improves. Available onTelegramSlack
    dylantarre

    motion-scale

    dylantarre/motion-scale
    Design
    11
    1 installs

    About

    SKILL.md

    Install

    • Telegram
      Telegram
    • Slack
      Slack
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    • Download skill
    ├─
    ├─
    └─
    Smithery Logo

    Give agents more agency

    Resources

    DocumentationPrivacy PolicySystem Status

    Company

    PricingAboutBlog

    Connect

    © 2026 Smithery. All rights reserved.

    About

    Generates animation duration, easing curves, and delay tokens with prefers-reduced-motion support. Use when creating transition timing, animation speed, or motion systems...

    SKILL.md

    Motion Scale Generator

    Overview

    Generate consistent animation and transition tokens for duration, easing, and delay. Creates a motion system that feels cohesive and respects user preferences for reduced motion.

    When to Use

    • Setting up animation tokens for a new project
    • Standardizing transition timing across components
    • Replacing hardcoded animation values
    • Implementing reduced motion support
    • Building micro-interaction patterns

    Quick Reference: Duration Scale

    Token Value Use Case
    instant 0ms Immediate, no animation
    fastest 50ms Micro-feedback (ripples, highlights)
    fast 100ms Hover, focus, small changes
    normal 200ms Most transitions, toggles
    slow 300ms Modals, drawers, reveals
    slower 400ms Page transitions, complex sequences
    slowest 500ms Elaborate animations, onboarding

    Quick Reference: Easing Curves

    Token Curve Use Case
    linear linear Progress bars, looping
    ease-in cubic-bezier(0.4, 0, 1, 1) Exit animations
    ease-out cubic-bezier(0, 0, 0.2, 1) Enter animations (most common)
    ease-in-out cubic-bezier(0.4, 0, 0.2, 1) Move, resize, continuous
    ease-bounce cubic-bezier(0.34, 1.56, 0.64, 1) Playful, attention
    ease-elastic cubic-bezier(0.68, -0.55, 0.27, 1.55) Springy, overshoot

    The Process

    1. Choose duration scale: How many steps? (5-7 typical)
    2. Define base duration: 200ms is standard baseline
    3. Select ratio: How durations scale (1.5x or 2x)
    4. Pick easing curves: Standard set + any special curves
    5. Create semantic aliases: Map to component behaviors
    6. Add reduced motion: Respect user preferences
    7. Choose format: CSS, Tailwind, or JSON

    Output Formats

    CSS Custom Properties:

    :root {
      /* ===== Durations ===== */
      --duration-0: 0ms;
      --duration-50: 50ms;
      --duration-100: 100ms;
      --duration-150: 150ms;
      --duration-200: 200ms;
      --duration-300: 300ms;
      --duration-400: 400ms;
      --duration-500: 500ms;
      --duration-700: 700ms;
      --duration-1000: 1000ms;
    
      /* Named aliases */
      --duration-instant: var(--duration-0);
      --duration-fastest: var(--duration-50);
      --duration-fast: var(--duration-100);
      --duration-normal: var(--duration-200);
      --duration-slow: var(--duration-300);
      --duration-slower: var(--duration-500);
      --duration-slowest: var(--duration-700);
    
      /* ===== Easings ===== */
      --ease-linear: linear;
      --ease-in: cubic-bezier(0.4, 0, 1, 1);
      --ease-out: cubic-bezier(0, 0, 0.2, 1);
      --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
    
      /* Expressive easings */
      --ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
      --ease-elastic: cubic-bezier(0.68, -0.55, 0.27, 1.55);
      --ease-snap: cubic-bezier(0.2, 0, 0, 1);
    
      /* Deceleration/Acceleration (Material Design style) */
      --ease-decelerate: cubic-bezier(0, 0, 0.2, 1);
      --ease-accelerate: cubic-bezier(0.4, 0, 1, 1);
      --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
    
      /* ===== Delays ===== */
      --delay-none: 0ms;
      --delay-short: 50ms;
      --delay-medium: 100ms;
      --delay-long: 200ms;
    
      /* Stagger delays for sequential animations */
      --delay-stagger-1: 0ms;
      --delay-stagger-2: 50ms;
      --delay-stagger-3: 100ms;
      --delay-stagger-4: 150ms;
      --delay-stagger-5: 200ms;
    
      /* ===== Semantic Transitions ===== */
      --transition-colors: color, background-color, border-color, fill, stroke;
      --transition-opacity: opacity;
      --transition-transform: transform;
      --transition-shadow: box-shadow;
      --transition-all: all;
    
      /* Component transitions */
      --transition-hover: var(--duration-fast) var(--ease-out);
      --transition-focus: var(--duration-fast) var(--ease-out);
      --transition-active: var(--duration-fastest) var(--ease-out);
      --transition-enter: var(--duration-normal) var(--ease-out);
      --transition-exit: var(--duration-fast) var(--ease-in);
      --transition-move: var(--duration-normal) var(--ease-in-out);
      --transition-expand: var(--duration-slow) var(--ease-out);
      --transition-collapse: var(--duration-normal) var(--ease-in);
    }
    
    /* ===== Reduced Motion ===== */
    @media (prefers-reduced-motion: reduce) {
      :root {
        --duration-50: 0ms;
        --duration-100: 0ms;
        --duration-150: 0ms;
        --duration-200: 0ms;
        --duration-300: 0ms;
        --duration-400: 0ms;
        --duration-500: 0ms;
        --duration-700: 0ms;
        --duration-1000: 0ms;
      }
    }
    
    /* Alternative: Keep minimal motion */
    @media (prefers-reduced-motion: reduce) {
      :root {
        --duration-fastest: 0ms;
        --duration-fast: 0ms;
        --duration-normal: 50ms;  /* Minimal feedback */
        --duration-slow: 50ms;
        --duration-slower: 100ms;
        --duration-slowest: 100ms;
    
        /* Disable expressive easings */
        --ease-bounce: var(--ease-out);
        --ease-elastic: var(--ease-out);
      }
    }
    

    Tailwind Config:

    module.exports = {
      theme: {
        extend: {
          transitionDuration: {
            '0': '0ms',
            '50': '50ms',
            '100': '100ms',
            '150': '150ms',
            '200': '200ms',
            '300': '300ms',
            '400': '400ms',
            '500': '500ms',
            '700': '700ms',
            '1000': '1000ms',
          },
          transitionTimingFunction: {
            'in': 'cubic-bezier(0.4, 0, 1, 1)',
            'out': 'cubic-bezier(0, 0, 0.2, 1)',
            'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)',
            'bounce': 'cubic-bezier(0.34, 1.56, 0.64, 1)',
            'elastic': 'cubic-bezier(0.68, -0.55, 0.27, 1.55)',
            'snap': 'cubic-bezier(0.2, 0, 0, 1)',
          },
          transitionDelay: {
            '0': '0ms',
            '50': '50ms',
            '100': '100ms',
            '150': '150ms',
            '200': '200ms',
          },
          animation: {
            'fade-in': 'fade-in 200ms ease-out',
            'fade-out': 'fade-out 150ms ease-in',
            'slide-up': 'slide-up 200ms ease-out',
            'slide-down': 'slide-down 200ms ease-out',
            'scale-in': 'scale-in 200ms ease-out',
            'spin-slow': 'spin 2s linear infinite',
          },
          keyframes: {
            'fade-in': {
              '0%': { opacity: '0' },
              '100%': { opacity: '1' },
            },
            'fade-out': {
              '0%': { opacity: '1' },
              '100%': { opacity: '0' },
            },
            'slide-up': {
              '0%': { transform: 'translateY(10px)', opacity: '0' },
              '100%': { transform: 'translateY(0)', opacity: '1' },
            },
            'slide-down': {
              '0%': { transform: 'translateY(-10px)', opacity: '0' },
              '100%': { transform: 'translateY(0)', opacity: '1' },
            },
            'scale-in': {
              '0%': { transform: 'scale(0.95)', opacity: '0' },
              '100%': { transform: 'scale(1)', opacity: '1' },
            },
          },
        },
      },
    };
    

    JSON Tokens:

    {
      "motion": {
        "duration": {
          "0": { "value": "0ms", "type": "duration" },
          "50": { "value": "50ms", "type": "duration" },
          "100": { "value": "100ms", "type": "duration" },
          "200": { "value": "200ms", "type": "duration" },
          "300": { "value": "300ms", "type": "duration" },
          "500": { "value": "500ms", "type": "duration" }
        },
        "easing": {
          "linear": { "value": "linear", "type": "cubicBezier" },
          "ease-in": { "value": "cubic-bezier(0.4, 0, 1, 1)", "type": "cubicBezier" },
          "ease-out": { "value": "cubic-bezier(0, 0, 0.2, 1)", "type": "cubicBezier" },
          "ease-in-out": { "value": "cubic-bezier(0.4, 0, 0.2, 1)", "type": "cubicBezier" },
          "bounce": { "value": "cubic-bezier(0.34, 1.56, 0.64, 1)", "type": "cubicBezier" }
        },
        "delay": {
          "none": { "value": "0ms", "type": "duration" },
          "short": { "value": "50ms", "type": "duration" },
          "medium": { "value": "100ms", "type": "duration" }
        }
      }
    }
    

    Easing Curve Reference

    Standard Curves

    ease-out (enter/appear):
        ●━━━━━━━━━━━━━━━━━━●
        Fast start, gentle stop
        Best for: Elements entering view
    
    ease-in (exit/leave):
        ●━━━━━━━━━━━━━━━━━━●
        Gentle start, fast end
        Best for: Elements leaving view
    
    ease-in-out (move/resize):
        ●━━━━━━━━━━━━━━━━━━●
        Gentle start and end
        Best for: Elements moving position
    
    linear (progress):
        ●━━━━━━━━━━━━━━━━━━●
        Constant speed
        Best for: Progress bars, spinners
    

    Expressive Curves

    bounce (playful):
        ●━━━━━━━━╮
                ╰━━━●
        Overshoots then settles
        Best for: Notifications, confirmations
    
    elastic (springy):
        ●━━━╮   ╭━╮
            ╰━━━╯ ╰●
        Oscillates before settling
        Best for: Attention, drag-and-drop
    
    snap (decisive):
        ●━━━━━━━━━━━━━━━━●
        Very fast deceleration
        Best for: Snapping, selections
    

    Custom Curve Creation

    /*
      cubic-bezier(x1, y1, x2, y2)
    
      x1, y1 = First control point (affects start)
      x2, y2 = Second control point (affects end)
    
      y values > 1 = overshoot
      y values < 0 = anticipation
    */
    
    /* Dramatic entrance */
    --ease-dramatic: cubic-bezier(0.2, 0.8, 0.2, 1);
    
    /* Snappy with slight overshoot */
    --ease-snappy: cubic-bezier(0.2, 1.2, 0.3, 1);
    
    /* Gentle float */
    --ease-float: cubic-bezier(0.4, 0.2, 0.2, 1);
    

    Component Patterns

    Button Hover

    .button {
      transition:
        background-color var(--transition-hover),
        transform var(--transition-active);
    }
    
    .button:hover {
      background-color: var(--color-primary-600);
    }
    
    .button:active {
      transform: scale(0.98);
    }
    

    Modal Enter/Exit

    .modal-backdrop {
      transition: opacity var(--duration-normal) var(--ease-out);
    }
    
    .modal-content {
      transition:
        opacity var(--duration-normal) var(--ease-out),
        transform var(--duration-normal) var(--ease-out);
    }
    
    /* Enter */
    .modal-backdrop.entering { opacity: 0; }
    .modal-backdrop.entered { opacity: 1; }
    .modal-content.entering { opacity: 0; transform: scale(0.95) translateY(10px); }
    .modal-content.entered { opacity: 1; transform: scale(1) translateY(0); }
    
    /* Exit (faster) */
    .modal-backdrop.exiting {
      opacity: 0;
      transition-duration: var(--duration-fast);
    }
    .modal-content.exiting {
      opacity: 0;
      transform: scale(0.95);
      transition-duration: var(--duration-fast);
    }
    

    Dropdown Menu

    .dropdown-menu {
      transform-origin: top;
      transition:
        opacity var(--duration-fast) var(--ease-out),
        transform var(--duration-fast) var(--ease-out);
    }
    
    .dropdown-menu[data-state="closed"] {
      opacity: 0;
      transform: scaleY(0.9);
      pointer-events: none;
    }
    
    .dropdown-menu[data-state="open"] {
      opacity: 1;
      transform: scaleY(1);
    }
    

    Staggered List Animation

    .list-item {
      opacity: 0;
      transform: translateY(10px);
      animation: slide-up var(--duration-normal) var(--ease-out) forwards;
    }
    
    .list-item:nth-child(1) { animation-delay: var(--delay-stagger-1); }
    .list-item:nth-child(2) { animation-delay: var(--delay-stagger-2); }
    .list-item:nth-child(3) { animation-delay: var(--delay-stagger-3); }
    .list-item:nth-child(4) { animation-delay: var(--delay-stagger-4); }
    .list-item:nth-child(5) { animation-delay: var(--delay-stagger-5); }
    
    @keyframes slide-up {
      to {
        opacity: 1;
        transform: translateY(0);
      }
    }
    

    Loading Spinner

    .spinner {
      animation: spin var(--duration-1000) var(--ease-linear) infinite;
    }
    
    @keyframes spin {
      to { transform: rotate(360deg); }
    }
    
    /* Pulsing loader */
    .pulse {
      animation: pulse var(--duration-700) var(--ease-in-out) infinite alternate;
    }
    
    @keyframes pulse {
      0% { opacity: 0.4; transform: scale(0.95); }
      100% { opacity: 1; transform: scale(1); }
    }
    

    Skeleton Loading

    .skeleton {
      background: linear-gradient(
        90deg,
        var(--color-gray-200) 0%,
        var(--color-gray-100) 50%,
        var(--color-gray-200) 100%
      );
      background-size: 200% 100%;
      animation: shimmer 1.5s var(--ease-in-out) infinite;
    }
    
    @keyframes shimmer {
      0% { background-position: 200% 0; }
      100% { background-position: -200% 0; }
    }
    

    Reduced Motion

    Strategy 1: Remove All Motion

    @media (prefers-reduced-motion: reduce) {
      *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
      }
    }
    

    Strategy 2: Reduce, Don't Remove

    @media (prefers-reduced-motion: reduce) {
      :root {
        /* Keep brief transitions for feedback */
        --duration-fast: 0ms;
        --duration-normal: 50ms;
        --duration-slow: 100ms;
    
        /* Simplify easings */
        --ease-bounce: var(--ease-out);
        --ease-elastic: var(--ease-out);
      }
    
      /* Disable parallax, auto-play, infinite loops */
      .parallax { transform: none !important; }
      .auto-animate { animation: none !important; }
    }
    

    Strategy 3: Provide Alternatives

    /* Full motion */
    .card-enter {
      animation: slide-up var(--duration-normal) var(--ease-out);
    }
    
    /* Reduced: fade only, no movement */
    @media (prefers-reduced-motion: reduce) {
      .card-enter {
        animation: fade-in var(--duration-fast) var(--ease-out);
      }
    }
    

    Duration Guidelines

    Duration Feel Use For
    0-50ms Instant Ripples, micro-feedback
    50-100ms Snappy Hover states, focus, toggles
    100-200ms Quick Most UI transitions
    200-300ms Smooth Modals, panels, reveals
    300-500ms Deliberate Page transitions, onboarding
    500ms+ Slow Complex sequences, emphasis

    Rule of thumb:

    • Smaller elements = faster (50-150ms)
    • Larger elements = slower (200-400ms)
    • User-triggered = fast (100-200ms)
    • System-triggered = can be slower (200-400ms)

    Testing Checklist

    • Transitions feel smooth, not jarring
    • Hover/focus feedback is immediate (<150ms)
    • Modals/drawers don't feel sluggish
    • Animations enhance, don't block interaction
    • prefers-reduced-motion is respected
    • No layout shift during animations
    • Animations work at 60fps
    • Consistent timing across similar interactions
    Recommended Servers
    Excalidraw
    Excalidraw
    OpenZeppelin
    OpenZeppelin
    MantleKit Launch Planner
    MantleKit Launch Planner
    Repository
    dylantarre/design-system-skills
    Files