Development
#react
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 animation in React or Next.js.
DeepseekModel
Curated skill
Quality Excellent · 90
v1.0.0
Get
https://deepseekmodel.com/api/download.php?id=affaan-m-ecc-skills-motion-foundations-skill-md&format=skill
Download .skill
Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name motion-foundations description 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 animation in React or Next.js. tags ["motion","animation","performance","accessibility"] category frontend author jeff metadata {"version":"1.0.0"} 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. Use motion/react only. Never import from framer-motion . Never mix the two in the same tree. initial must match server output. If the server renders opacity: 1 , the initial prop must also be opacity: 1 . No exceptions. 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. Never animate layout properties. width , height , top , left , margin , padding are banned from animate . Use transform and opacity only. All token values come from motionTokens . Hardcoded durations and easings in component files are forbidden. All spring configs come from the springs map. Inline stiffness / damping values are forbidden. "use client" is required on every file that imports from motion/react . 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 // lib/motion-tokens.ts export const motionTokens = { duration : { instant : 0.08 , fast : 0.18 , normal : 0.35 , slow : 0.6 , crawl : 1.0 , }, easing : { smooth : [ 0.22 , 1 , 0.36 , 1 ], sharp : [ 0.4 , 0 , 0.2 , 1 ], bounce : [ 0.34 , 1.56 , 0.64 , 1 ], linear : [ 0 , 0 , 1 , 1 ], }, distance : { xs : 4 , sm : 8 , md : 16 , lg : 24 , xl : 48 , }, scale : { subtle : 0.98 , press : 0.95 , pop : 1.04 , }, } export const springs = { snappy : { type : "spring" , stiffness : 300 , damping : 30 }, gentle : { type : "spring" , stiffness : 120 , damping : 14 }, bouncy : { type : "spring" , stiffness : 400 , damping : 10 }, instant : { type : "spring" , stiffness : 600 , damping : 35 }, release : { type : "spring" , stiffness : 200 , damping : 20 , restDelta : 0.001 }, } Runtime flags // lib/motion-config.ts export const motionConfig = { isLowEnd ( ) { return ( typeof navigator !== "undefined" && navigator. hardwareConcurrency <= 4 ) }, prefersReduced ( ) { return ( typeof window !== "undefined" && window . matchMedia ( "(prefers-reduced-motion: reduce)" ). matches ) }, shouldAnimate ( { essential = false } = {} ) { if ( this . prefersReduced ()) return false if (!essential && this . isLowEnd ()) return false return true }, duration ( ) { return this . isLowEnd () || this . prefersReduced () ? motionTokens. duration . instant : motionTokens. duration . normal }, } Accessibility Priority order (highest to lowest): prefers-reduced-motion: reduce — disables all transforms, limits opacity transitions to ≤ 0.2s Low-end device detection — reduces duration, removes non-essential animations Design preference — everything else Motion must degrade gracefully. It must never disappear abruptly in a way that causes layout shift or confuses orientation. // hooks/use-reduced-motion.tsx "use client" import { useReducedMotion } from "motion/react" export function useSafeMotion ( fullY : number = 16 ) { const reduce = useReducedMotion () return { initial : { opacity : 0 , y : reduce ? 0 : fullY }, animate : { opacity : 1 , y : 0 }, exit : { opacity : 0 , y : reduce ? 0 : -fullY }, } } /* globals.css */ @media ( prefers-reduced-motion : reduce) { .motion-safe-transition { transition : opacity 0.15s ; } .motion-reduce-transform { transform : none !important ; } } <!-- Tailwind --> < div class = "motion-safe:animate-fade motion-reduce:opacity-100" > </ div > SSR / hydration safety Rule: initial must always match what the server renders. // WRONG — server renders opacity:1 but initial says 0 → hydration mismatch <motion. div initial={{ opacity : 0 }} animate={{ opacity : 1 }} /> // CORRECT — use AnimatePresence or defer to client mount "use client" const [mounted, setMounted] = useState ( false ) useEffect ( () => setMounted ( true ), []) <motion. div initial={{ opacity : mounted ? 0 : 1 }} animate={{ opacity : 1 }} /> Code Examples End-to-end: tokens + springs + accessibility + SSR guard // components/fade-in-card.tsx "use client" import { useState, useEffect } from "react" import { motion } from "motion/react" import { motionTokens, springs } from "@/lib/motion-tokens" import { useSafeMotion } from "@/hooks/use-reduced-motion" import { motionConfig } from "@/lib/motion-config" interface FadeInCardProps { children : React . ReactNode delay ?: number } export function FadeInCard ( { children, delay = 0 }: FadeInCardProps ) { // SSR guard — initial must match server output (opacity: 1) const [mounted, setMounted] = useState ( false ) useEffect ( () => setMounted ( true ), []) // Accessibility — disables transform when reduced motion is preferred const safeMotion = useSafeMotion (motionTokens. distance . md ) // Device gate — skip animation on low-end hardware if (!motionConfig. shouldAnimate () || !mounted) { return < div > {children} </ div > } return ( < motion.div initial = {safeMotion.initial} animate = {safeMotion.animate} exit = {safeMotion.exit} transition = {{ ...springs.gentle , delay , }} whileHover = {{ scale: motionTokens.scale.pop }} whileTap = {{ scale: motionTokens.scale.press }} > {children} </ motion.div > ) } 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.
Keywords that activate this skill. Click one to copy it.
This skill does not provide trigger words.
The downloaded .skill package contains the following fields.
| Field | Description |
|---|---|
| format | Format tag (skill/v1) |
| skill_id | Unique skill ID |
| name | Skill name |
| version | Version |
| description | Description |
| category | Categories (array) |
| trigger_words | Trigger words |
| tags | Tags |
| source | Source |
| source_url | Source URL (this page) |
| exported_at | Exported at (set per download) |
| system_prompt | System prompt body |
| model_config | Model config: provider / model / temperature / max_tokens / top_p |
| examples | Examples |
| install_guide | Import guide for Coze / Dify / Claude / custom frameworks |
The same skill can be exported in different platform formats.