Communitygithub.com

motion-foundations

Jetons de mouvement, préréglages de ressort, règles de performance, adaptation aux appareils, application de l'accessibilité et sécurité SSR pour React / Next.js avec motion/react. Couche fondamentale — toutes les autres compétences de mouvement en dépendent. À utiliser lors de la configuration des jetons de mouvement, des préréglages de ressort, de la gestion des mouvements réduits ou des animations sécurisées SSR dans React ou Next.js.

Qu'est-ce que motion-foundations ?

Cette compétence établit la couche de base du système d'animation pour React et Next.js utilisant `motion/react`. Elle définit tous les jetons de mouvement (durée, easing, distance, échelle), les préréglages de ressort nommés (`snappy`, `gentle`, `bouncy`, etc.), les règles de performance et d'accessibilité non négociables, ainsi que des mécanismes de sécurité SSR et de détection de matériel bas de gamme. Les composants animés tirent parti d'un système de jetons partagé (`motionTokens`), d'une fonction `shouldAnimate()` pour désactiver les animations non essentielles sur les appareils à faible performance ou lorsque l'utilisateur préfère les mouvements réduits, et d'un hook `useSafeMotion` qui garantit que l'état initial correspond au rendu serveur pour éviter les erreurs d'hydratation. Elle est conçue pour être chargée avant toute autre compétence d'animation (`motion-patterns`, `motion-advanced`) et sert de fondation unique sur laquelle toutes les animations du système sont construites, imposant des contraintes strictes comme l'interdiction des animations sur les propriétés de layout ou l'import depuis `framer-motion`.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/motion-foundations

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Motion Foundations

La couche de base du système d'animation. Définit chaque valeur, contrainte et règle que les compétences downstream (motion-patterns, motion-advanced) héritent. Chargez cette compétence avant tout travail d'animation.

Quand activer

  • Créer un composant animé à partir de zéro
  • Configurer des jetons, préréglages de ressort ou valeurs d'easing
  • Implémenter le support de prefers-reduced-motion
  • Déboguer des erreurs d'hydratation dues aux états initiaux d'animation
  • Évaluer si une animation doit exister ou non

Livrables

Cette compétence produit :

  • Un objet motionTokens partagé (durée, easing, distance, échelle)
  • Une carte de préréglages springs partagée (5 configurations nommées)
  • Une porte shouldAnimate() utilisée par tous les composants
  • Des valeurs par défaut d'animation conformes à l'accessibilité via useReducedMotion
  • Des états initiaux compatibles SSR sans avertissements d'hydratation

Principes

Une animation doit remplir au moins l'une des conditions suivantes, sinon elle doit être supprimée :

  • Guider l'attention
  • Communiquer un état
  • Préserver la continuité spatiale

La réactivité prime toujours sur la fluidité. Une animation à 60 fps qui provoque un délai de saisie est pire qu'aucune animation.

Règles

Ces règles sont non négociables. Elles s'appliquent à chaque composant du système.

  1. Utilisez motion/react uniquement. N'importez jamais depuis framer-motion. Ne mélangez jamais les deux dans le même arbre.
  2. initial doit correspondre à la sortie du serveur. Si le serveur rend opacity: 1, la prop initial doit aussi être opacity: 1. Aucune exception.
  3. Le mouvement réduit écrase tout. Quand useReducedMotion() retourne true ou que prefersReduced est true, toutes les transformations sont désactivées. Les fondus uniquement en opacité d'au maximum 0,2 seconde sont la seule solution de repli autorisée.
  4. N'animez jamais les propriétés de layout. width, height, top, left, margin, padding sont interdits dans animate. Utilisez uniquement transform et opacity.
  5. Toutes les valeurs de jetons proviennent de motionTokens. Les durées et easings codés en dur dans les fichiers de composants sont interdits.
  6. Toutes les configurations de ressort proviennent de la carte springs. Les valeurs stiffness/damping en ligne sont interdites.
  7. "use client" est obligatoire sur chaque fichier qui importe depuis motion/react.
  8. Ne lisez jamais window ou navigator au niveau du module. Protégez toujours avec typeof window !== "undefined".

Guide de décision

Choisir une durée

JetonUtilisation
instantAffichage/masquage d'infobulle, anneau de focus, mise à jour de badge
fastRetour de bouton, changement d'icône, bascule de chip
normalOuverture de modale, expansion de carte, entrée d'élément de page
slowEntrée de héros, transition de page entière
crawlNarration délibérée ; à utiliser avec parcimonie

Choisir un ressort

PréréglageUtilisation
snappyUI par défaut — boutons, chips, éléments de navigation
gentleCartes, modales, panneaux qui atterrissent en douceur
bouncyMoments ludiques — états vides, onboarding
instantInfobulles, popovers, menus déroulants
releaseRelâchement après glisser — sensation physique naturelle

Quand désactiver complètement l'animation

Désactivez (faites en sorte que shouldAnimate() retourne false) quand :

  • prefersReduced est true
  • isLowEnd est true et l'animation n'est pas essentielle
  • L'élément est hors écran et n'entrera jamais dans la zone d'affichage
  • L'animation est purement décorative sans but UX

Concepts fondamentaux

Système de jetons

// 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 },
}

Indicateurs d'exécution

// 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
  },
}

Accessibilité

Ordre de priorité (du plus élevé au plus bas) :

  1. prefers-reduced-motion: reduce — désactive toutes les transformations, limite les transitions d'opacité à ≤ 0,2 s
  2. Détection d'appareil bas de gamme — réduit la durée, supprime les animations non essentielles
  3. Préférence de conception — tout le reste

L'animation doit se dégrader gracieusement. Elle ne doit jamais disparaître brusquement d'une manière qui provoque un changement de layout ou désoriente l'utilisateur.

// 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>

Sécurité SSR / hydratation

Règle : initial doit toujours correspondre à ce que le serveur rend.

// FAUX — le serveur rend opacity:1 mais initial dit 0 → erreur d'hydratation
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} />

// CORRECT — utilisez AnimatePresence ou différez le montage client
"use client"
const [mounted, setMounted] = useState(false)
useEffect(() => setMounted(true), [])

<motion.div
  initial={{ opacity: mounted ? 0 : 1 }}
  animate={{ opacity: 1 }}
/>

Exemples de code

De bout en bout : jetons + ressorts + accessibilité + garde SSR

// 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) {
  // Garde SSR — initial doit correspondre à la sortie du serveur (opacity: 1)
  const [mounted, setMounted] = useState(false)
  useEffect(() => setMounted(true), [])

  // Accessibilité — désactive la transformation quand le mouvement réduit est préféré
  const safeMotion = useSafeMotion(motionTokens.distance.md)

  // Porte matérielle — ignore l'animation sur le matériel bas de gamme
  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>
  )
}

Contraintes / Non-objectifs

Cette compétence ne couvre pas :

  • Les motifs de composants UI (bouton, modale, stagger) → voir motion-patterns
  • Le glisser, les gestes, SVG, les animations de texte, les hooks personnalisés → voir motion-advanced
  • Les animations CSS uniquement ou les classes Tailwind animate-* sans motion/react
  • Les bibliothèques d'animation tierces (GSAP, anime.js, etc.)
  • Les décisions de design d'animation (quand animer, quoi mettre en valeur) — c'est une préoccupation de design, pas une contrainte de code

Anti-patrons

Anti-patronRègle violéeCorrectif
import { motion } from "framer-motion"Règle 1Utilisez motion/react
initial={{ opacity: 0 }} sur un composant SSRRègle 2Ajoutez une garde de montage
Ignorer la vérification useReducedMotionRègle 3Utilisez le hook useSafeMotion
animate={{ width: "100%" }}Règle 4Utilisez la transformation scaleX à la place
transition={{ duration: 0.4 }} en ligneRègle 5Utilisez motionTokens.duration.normal
{ stiffness: 300, damping: 30 } en ligneRègle 6Utilisez springs.snappy
Directive "use client" manquanteRègle 7Ajoutez-la en haut du fichier
navigator.hardwareConcurrency au niveau du moduleRègle 8Enveloppez dans typeof navigator !== "undefined"

Compétences associées

  • motion-patterns — consomme les jetons et ressorts définis ici pour construire des motifs de bouton, modale, stagger, transition de page et défilement. Ne redéfinit aucune valeur.
  • motion-advanced — consomme les jetons et ressorts définis ici pour les motifs de glisser, SVG, texte et gestes. Ajoute des séquences useAnimate et des hooks personnalisés par-dessus cette fondation.

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

Skills associés