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.