motion-foundations
Motion tokens, spring presets, performance rules, device adaptation, accessibility enforcement, and SSR safety for React / Next.js using motion/react. Foundation layer — all other motion skills depend on this. Use when setting up motion tokens, spring presets, reduced-motion handling, or SSR-safe an
By affaan-m · 2,949 installs
npx skills add affaan-m/ecc --skill motion-foundations
Source repository · Upstream listing
Motion Foundations
The base layer of the motion system. Defines every value, constraint, and
rule that downstream skills ( motion patterns , motion advanced ) inherit.
Load this skill before any animation work begins.
When to Activate
Starting any animated component from scratch
Setting up tokens, spring presets, or easing values
Implementing prefers reduced motion support
Debugging hydration mismatches from animation initial states
Evaluating whether an animation should exist at all
Outputs
This skill produces:
A shared motionTokens object (duration, easing, distance, scale)
A shared springs preset map (5 named configs)
A shouldAnimate() gate used by all components
Accessibility compliant animation defaults via useReducedMotion
SSR safe initial states with zero hydration warnings
Principles
Motion must do at least one of the following or it must be removed:
Guide attention
Communicate state
Preserve spatial continuity
Responsiveness always outranks smoothness. A 60 fps animation that causes
input delay is worse than no animation.
Rules
These are non negotiable. They apply to every component in the system.
1. Use motion/react only. Never import from framer motion . Never mix the two in the same tree.
2. initial must match server output. If the server renders opacity: 1 , the initial prop must also be opacity: 1 . No exceptions.
3. Reduced motion overrides everything. When useReducedMotion() returns true or prefersReduced is true , all transforms are disabled. Opacity only fades at ≤ 0.2s are the only permitted fallback.
4. Never animate layout properties. width , height , top , left , margin , padding are banned from animate . Use transform and opacity only.
5. All token values come from motionTokens . Hardcoded durations and easings in component files are forbidden.
6. All spring configs come from the springs map. Inline stiffness / damping values are forbidden.
7. "use client" is required on every file that imports from motion/react .
8. Never read window or navigator at module level. Always guard with typeof window !== "undefined" .
Decision Guidance
Choosing a duration
Token Use when
instant Tooltip show/hide, focus ring, badge update
fast Button feedback, icon swap, chip toggle
normal Modal open, card expand, page element enter
slow Hero entrance, full page transition
crawl Deliberate storytelling; use sparingly
Choosing a spring
Preset Use when
snappy Default UI — buttons, chips, nav items
gentle Cards, modals, panels landing softly
bouncy Playful moments — empty states, onboarding
instant Tooltips, popovers, dropdowns
release Drag release — natural physics feel
When to disable animation entirely
Disable (make shouldAnimate() return false ) when:
prefersReduced is true
isLowEnd is true and the animation is non essential
The element is off screen and will never enter the viewport
The animation is purely decorative with no UX purpose
Core Concepts
Token system
Runtime flags
Accessibility
Priority order (highest to lowest):
1. prefers reduced motion: reduce — disables all transforms, limits opacity transitions to ≤ 0.2s
2. Low end device detection — reduces duration, removes non essential animations
3. Design preference — everything else
Motion must degrade gracefully. It must never disappear abruptly in a way
that causes layout shift or confuses orientation.
SSR / hydration safety
Rule: initial must always match what the server renders.
Code Examples
End to end: tokens + springs + accessibility + SSR guard
Constraints / Non Goals
This skill does not cover:
UI component patterns (button, modal, stagger) → see motion patterns
Drag, gestures, SVG, text animations, custom hooks → see motion advanced
CSS only animations or Tailwind animate classes without motion/react
Third party animation libraries (GSAP, anime.js, etc.)
Motion design decisions (when to animate, what to emphasize) — that is a design concern, not a code constraint
Anti Patterns
Anti pattern Rule violated Fix
import { motion } from "framer motion" Rule 1 Use motion/react
initial={{ opacity: 0 }} on SSR component Rule 2 Add mount guard
Skipping useReducedMotion check Rule 3 Use useSafeMotion hook
animate={{ width: "100%" }} Rule 4 Use scaleX transform instead
transition={{ duration: 0.4 }} inline Rule 5 Use motionTokens.duration.normal
{ stiffness: 300, damping: 30 } inline Rule 6 Use springs.snappy
Missing "use client" directive Rule 7 Add to top of file
navigator.hardwareConcurrency at module level Rule 8 Wrap in typeof navigator !== "undefined"
Related Skills
motion patterns — consumes tokens and springs defined here to build button, modal, stagger, page transition, and scroll patterns. Does not redefine any values.
motion advanced — consumes tokens and springs defined here for drag, SVG, text, and gesture patterns. Adds useAnimate sequences and custom hooks on top of this foundation.