Skip to main content

design-motion-principles

Context-aware motion design skill with build and audit modes, applying three distinct philosophies from Emil Kowalski, Jakub Krehel, and Jhey Tompkins

Ir para a instalação

Informações da origem

Repositório
reason-machines/design-skills
Última atividade na origem
28 de maio de 2026 às 20:18
Idioma detectado do SKILL.md
inglês
Estrelas
4
Forks
0

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
design-motion-principles
description
Context-aware motion design skill with build and audit modes, applying three distinct philosophies from Emil Kowalski, Jakub Krehel, and Jhey Tompkins
triggers
["audit the motion design in this project","add animation to this component","review these animations for quality","build an animated modal with motion design","check for AI-generated animation patterns","create an interactive component with purposeful motion","analyze motion gaps in the codebase","add enter and exit animations"]
# Design Motion Principles > Skill by [ara.so](https://ara.so) — Design Skills collection. A motion and interaction design skill with **two modes**: **build** interactive components with purposeful motion, or **audit** existing animations. Applies context-aware guidance from three distinct motion-design philosophies distilled from Emil Kowalski, Jakub Krehel, and Jhey Tompkins. ## Installation ```bash npx skills add kylezantos/design-motion-principles ``` Compatible with Claude Code, Cursor, Windsurf, and other AI coding assistants. ## Core Concept The skill applies three motion-design lenses, weighted by project context: | Lens | Philosophy | Key Question | Best For | |------|-----------|--------------|----------| | **Emil Kowalski** | Restraint & speed | "Should this animate at all?" | Productivity tools, high-frequency interactions | | **Jakub Krehel** | Production polish | "Is this subtle enough?" | Shipped consumer apps, professional refinement | | **Jhey Tompkins** | Creative experimentation | "What could this become?" | Kids apps, portfolios, playful contexts | The skill doesn't apply one philosophy everywhere — it weights them based on your project type, creating productive tension between approaches. ## Two Operating Modes ### 1. Create Mode Build interactive components with motion baked in. The skill: 1. Runs discovery (project context + lens weighting) 2. Generates components (React, Framer Motion, CSS, or HTML) 3. Applies appropriate recipes, accessibility, and performance defaults **Trigger phrases:** - "Add animation to this modal" - "Build an animated toast component" - "Create a polished dropdown with motion" ### 2. Audit Mode Review existing motion design. The skill: 1. Does reconnaissance on your project 2. Runs motion-gap analysis (finds UI that should animate but doesn't) 3. Checks against anti-AI-slop checklist 4. Proposes lens weighting 5. Delivers branded HTML report OR terminal markdown report **Trigger phrases:** - "Audit the motion design" - "Review animations in this component" - "Check for motion quality issues" **Audit flags:** ```bash --terminal # Output inline markdown instead of HTML report ``` Default: HTML report writes to `motion-audits/` and opens in browser. ## Mode Detection The skill auto-detects mode from your request: ``` User: "Add enter/exit animation to this modal" → CREATE mode User: "Audit the animations in this codebase" → AUDIT mode User: "Review this component's motion" → Ambiguous — skill will ask ``` ## Context-Aware Weighting Before any work, the skill maps project type to lens weights: **Productivity tool / Dashboard:** ``` Primary: Emil Kowalski (fast, minimal) Secondary: Jakub Krehel (polish) Selective: Jhey Tompkins (only for delight moments) ``` **Kids educational app:** ``` Primary: Jakub Krehel (production quality) Secondary: Jhey Tompkins (playful) Selective: Emil Kowalski (high-frequency interactions only) ``` **Marketing site:** ``` Primary: Jhey Tompkins (creative) Secondary: Jakub Krehel (polish) Selective: Emil Kowalski (utility interactions) ``` ## Motion Cookbook Reference The skill uses a single source-of-truth motion recipe library: ### Enter/Exit Patterns **Fade + Scale (subtle):** ```css @keyframes enter-subtle { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } } .modal { animation: enter-subtle 200ms cubic-bezier(0.16, 1, 0.3, 1); } ``` **Slide + Fade:** ```jsx import { motion } from 'framer-motion'; <motion.div initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -8 }} transition={{ duration: 0.2, ease: [0.16, 1, 0.3, 1] }} > {content} </motion.div> ``` **Height animation (accordion):** ```jsx <motion.div initial={{ height: 0, opacity: 0 }} animate={{ height: 'auto', opacity: 1 }} exit={{ height: 0, opacity: 0 }} transition={{ duration: 0.3, ease: [0.16, 1, 0.3, 1] }} > {content} </motion.div> ``` ### Easing Functions **Emil (fast utility):** ```javascript const ease = [0.16, 1, 0.3, 1]; // CSS: cubic-bezier(0.16, 1, 0.3, 1) const duration = 150; // ms ``` **Jakub (subtle polish):** ```javascript const ease = [0.25, 0.1, 0.25, 1]; // CSS: ease-in-out const duration = 250; ``` **Jhey (playful bounce):** ```javascript const spring = { type: 'spring', damping: 20, stiffness: 300 }; ``` ### Framer Motion Patterns **Conditional render with AnimatePresence:** ```jsx import { AnimatePresence, motion } from 'framer-motion'; <AnimatePresence mode="wait"> {isOpen && ( <motion.div key="modal" initial={{ opacity: 0, scale: 0.96 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, scale: 0.96 }} transition={{ duration: 0.2, ease: [0.16, 1, 0.3, 1] }} > {content} </motion.div> )} </AnimatePresence> ``` **List stagger (use sparingly):** ```jsx const container = { hidden: { opacity: 0 }, show: { opacity: 1, transition: { staggerChildren: 0.05 } } }; const item = { hidden: { opacity: 0, y: 8 }, show: { opacity: 1, y: 0 } }; <motion.ul variants={container} initial="hidden" animate="show"> {items.map(i => ( <motion.li key={i} variants={item}> {i} </motion.li> ))} </motion.ul> ``` ### CSS Custom Properties for Runtime Animation ```css @property --progress { syntax: '<percentage>'; inherits: false; initial-value: 0%; } .progress-bar { background: linear-gradient( 90deg, blue var(--progress), gray var(--progress) ); transition: --progress 300ms ease-out; } ``` ```javascript element.style.setProperty('--progress', '75%'); ``` ### Scroll-Driven Animation ```css @supports (animation-timeline: scroll()) { .parallax { animation: parallax linear; animation-timeline: scroll(); animation-range: 0 500px; } @keyframes parallax { to { transform: translateY(-100px); } } } ``` ## Accessibility Requirements Every animation must include: **1. Reduced motion support:** ```css @media (prefers-reduced-motion: reduce) { * { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } } ``` **Framer Motion:** ```jsx const reducedMotion = { initial: { opacity: 1 }, animate: { opacity: 1 }, transition: { duration: 0 } }; <motion.div initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: useReducedMotion() ? 0 : 0.2 }} /> ``` **2. Focus management:** ```javascript // Trap focus in modal during animation useEffect(() => { if (isOpen) { const focusableElements = modal.querySelectorAll( 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' ); focusableElements[0]?.focus(); } }, [isOpen]); ``` **3. Meaningful timing:** - Duration: 150–300ms for utility, 300–500ms for expressive - Never exceed 500ms for critical path interactions - Match duration to distance traveled ## Anti-AI-Slop Checklist The audit mode flags these AI-generated motion patterns: ### 1. Pulsing Indicators ```css /* ❌ AI slop if used everywhere */ @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } .loading { animation: pulse 2s infinite; } ``` **Heuristic:** Flag if >3 pulsing elements in viewport. ### 2. Hover-Scale-On-Everything ```css /* ❌ AI slop if on non-pressable elements */ .card:hover { transform: scale(1.05); } ``` **Heuristic:** Flag if >50% of interactive elements have hover scale. ### 3. Stagger-Spam ```jsx /* ❌ AI slop if stagger > 50ms or >10 items */ transition: { staggerChildren: 0.1 } ``` **Heuristic:** Flag if stagger used on >2 lists per page. ### 4. Blur-Everywhere Entrances ```css /* ❌ AI slop pattern */ filter: blur(10px); transition: filter 500ms; ``` **Heuristic:** Flag if blur used on >1 element. ### 5. Bouncy Springs on Utility ```javascript /* ❌ AI slop for delete buttons, form submissions */ spring: { damping: 10, stiffness: 400 } ``` **Heuristic:** Flag if bounce used on destructive or utility actions. ### 6. Motion-on-Mount for Static Content ```jsx /* ❌ AI slop: animating static header */ <motion.header initial={{ y: -100 }} animate={{ y: 0 }} /> ``` **Heuristic:** Flag if page-level static elements animate. ## Performance Best Practices **1. Animate only transform and opacity:** ```css /* ✅ GPU-accelerated */ .fast { transition: transform 200ms, opacity 200ms; } /* ❌ Causes reflow */ .slow { transition: width 200ms, height 200ms; } ``` **2. Use will-change sparingly:** ```css .modal[data-state="opening"] { will-change: transform, opacity; } .modal[data-state="open"] { will-change: auto; /* Remove after animation */ } ``` **3. Avoid layout thrashing:** ```javascript // ❌ Bad: Read then write in loop items.forEach(item => { const height = item.offsetHeight; // Read item.style.height = height + 10 + 'px'; // Write }); // ✅ Good: Batch reads, then batch writes const heights = items.map(item => item.offsetHeight); items.forEach((item, i) => { item.style.height = heights[i] + 10 + 'px'; }); ``` **4. Debounce resize/scroll handlers:** ```javascript let rafId; window.addEventListener('scroll', () => { if (rafId) return; rafId = requestAnimationFrame(() => { // Animation logic rafId = null; }); }); ``` ## Common Patterns by Framework ### React + Framer Motion **Modal:** ```jsx import { motion, AnimatePresence } from 'framer-motion'; import { useEffect } from 'react'; export function Modal({ isOpen, onClose, children }) { useEffect(() => { if (!isOpen) return; const handleEscape = (e) => { if (e.key === 'Escape') onClose(); }; document.addEventListener('keydown', handleEscape); return () => document.removeEventListener('keydown', handleEscape); }, [isOpen, onClose]);
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub