Motion principles
Skill almasumdev/awesome-mobile-design-system-agent-skills/.github/skills/motion/motion-principles
Agent skills for building and maintaining mobile design systems, tokens, and component libraries.
npx -y skills add almasumdev/awesome-mobile-design-system-agent-skills --skill motion-principlesAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Purposeful motion for mobile UIs — easing, duration scales, and reduced-motion. Use this when designing or reviewing animations.
SKILL.md
4.8 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
Motion Principles
Instructions
Motion communicates causality, hierarchy, and feedback. If it does not do one of those three things, it is noise. Every animation in the design system must have an intent, a token-backed duration, and a reduced-motion fallback.
1. Purpose Before Polish
Every motion answers one question:
- Causality — what caused this change? (Sheet rises from the button that opened it.)
- Hierarchy — what is primary vs secondary? (Stagger onboarding items 30ms apart.)
- Feedback — did my input register? (80ms press scale, 200ms state transition.)
If none apply, ship a cut, not a transition.
2. Duration Scale
Small, named scale. No magic milliseconds in component code.
| Token | ms | Use |
|---|---|---|
motion.duration.instant | 0 | Reduced-motion fallback |
motion.duration.xs | 80 | Micro-feedback (press, toggle) |
motion.duration.sm | 150 | Small UI state changes, tooltip |
motion.duration.md | 250 | Surface enter/exit, sheet, drawer |
motion.duration.lg | 400 | Hero / shared element |
motion.duration.xl | 600 | Onboarding, first-run reveal |
Rule: most durations in a mobile app live between 150–300ms. Anything longer than 400ms needs justification.
3. Easing Scale
| Token | Curve | Use |
|---|---|---|
motion.easing.standard | cubic-bezier(0.2, 0.0, 0, 1.0) | Enter + exit balanced |
motion.easing.emphasized | cubic-bezier(0.2, 0.0, 0, 1.0) with longer duration | Emphasize arrival |
motion.easing.accelerate | cubic-bezier(0.3, 0.0, 1, 1) | Exit off-screen |
motion.easing.decelerate | cubic-bezier(0, 0, 0, 1) | Enter from off-screen |
motion.easing.linear | linear | Opacity, crossfades, loading |
Prefer emphasized easing (Material 3) for full-screen transitions; it feels purposeful without being theatrical.
4. Stagger & Choreography
Stagger lists with 20–40ms between items, capped at ~6 visible items (beyond that, reveal the remainder without stagger). Never stagger in a loading state — it implies progress where there is none.
5. Reduced Motion
Honor the system preference always.
- Compose:
LocalAccessibilityManager.currentorSettings.Global.TRANSITION_ANIMATION_SCALE. - SwiftUI:
@Environment(\.accessibilityReduceMotion). - Flutter:
MediaQuery.disableAnimations/MediaQueryData.accessibleNavigation. - React Native:
AccessibilityInfo.isReduceMotionEnabled().
When enabled, motion tokens collapse:
export function resolveMotion(base: Motion, reduce: boolean): Motion {
if (!reduce) return base;
return { ...base, duration: { instant: 0, xs: 0, sm: 0, md: 0, lg: 0, xl: 0 } };
}
Replace translation/scale animations with instant changes; keep opacity crossfades under 150ms for state legibility.
6. Physics vs Tween
- Use tween + easing for state transitions where start and end are known (open/close, show/hide).
- Use spring physics for direct manipulation (drag-to-dismiss, swipe-to-delete, pull-to-refresh). Tokenize stiffness/damping if springs are a system-level choice.
.animation(.spring(response: 0.35, dampingFraction: 0.82), value: isOpen)
7. Don't Animate These
- Keyboard appearance/dismissal (OS owns it).
- Navigation transitions between stacks (platform owns them — iOS push, Android predictive back).
- Incoming network data that can arrive in bursts (use a subtle fade, not a slide).
- Text color during dark-mode switch — crossfade the whole surface instead.
8. Anti-Patterns
Thread.sleep(300)orsetTimeout(300)to coordinate animations — use completion callbacks /withAnimation.- Hardcoded 300ms everywhere — breaks the duration scale.
- Animation without a reduced-motion fallback.
- Staggered loaders.
- "Juicy" bounces on enterprise flows (banking, medical) — erodes trust.
Checklist
- Every animation maps to a documented purpose (causality / hierarchy / feedback).
- Durations and easings are tokens; no raw numbers in components.
- Reduced-motion collapses durations to 0 and retains opacity changes only.
- Spring physics is used for direct manipulation; tweens for state transitions.
- Stagger is capped and absent from loading states.
- Platform-owned transitions (keyboard, nav stack) are not overridden.