---
name: motion-spring-physics
description: >-
Implement physical, tactile micro-interactions and layout transitions using Spring Physics
(Motion / Framer Motion, FLIP technique via layoutId, CSS @starting-style, View Transitions API)
with strict compliance with prefers-reduced-motion.
---
# Motion & Spring Physics Architecture
Ce skill régit l'animation interactive haute fidélité. Il remplace les animations rigides basées sur des durées fixes (`transition: all 0.3s ease`) par des **ressorts physiques réels** (*Spring Physics*), conférant aux interfaces un toucher organique, réactif et interruptible caractéristique des applications comme Linear, Raycast ou macOS.
---
## 🎯 Déclencheurs d'Activation
Activez ce skill dès que :
1. Vous animez des éléments interactifs (boutons, modales, tiroirs, onglets, menus accordéons).
2. Vous concevez des transitions d'état de liste ou de réorganisation (glisser-déposer, suppression, filtrage).
3. Vous implémentez un indicateur de sélection flottant ou un curseur d'onglets partagé (`layoutId`).
4. Vous créez des micro-interactions au survol ou à la pression tactile (`whileHover`, `whileTap`).
5. Vous devez garantir l'accessibilité des animations face au critère WCAG 2.3.3 (`prefers-reduced-motion`).
---
## 🏎️ 1. Les Principes de la Physique de Ressort (*Springs*)
Contrairement aux courbes de Bézier cubiques (`ease-in-out`) qui forcent un temps fixe indépendamment de la distance parcourue, un ressort physique calcule la trajectoire en temps réel :
- **Stiffness (Raideur)** : Vitesse de rappel du ressort. Une raideur élevée (300–500) rend le contrôle vif et immédiat.
- **Damping (Amortissement)** : Friction qui freine le mouvement. Un amortissement bien réglé (20–30) évite les oscillations oscillatoires excessives (« effet cartoon »).
- **Mass (Masse)** : Inertie de l'élément (0.5 à 1.0 par défaut).
### Les 3 Profils de Ressort Standards
| Profil | Cas d'Usage | Paramètres Recommandés |
| :--- | :--- | :--- |
| **Snappy / Micro-tactile** | Boutons, toggles, badges, chips, icones | `{ type: 'spring', stiffness: 500, damping: 30, mass: 0.5 }` |
| **Smooth / Layout** | Modales, volets latéraux, accordéons, cartes | `{ type: 'spring', stiffness: 350, damping: 28, mass: 0.8 }` |
| **Gentle / Page Transition** | Entrées de page, vues séquentielles | `{ type: 'spring', stiffness: 200, damping: 24, mass: 1.0 }` |
---
## 💫 2. Transitions Partagées avec `layoutId` (Technique FLIP)
Pour un indicateur d'onglet ou un sous-lignage qui glisse d'un bouton à l'autre sans saut visuel :
```tsx
import { motion } from 'framer-motion';
import { useState } from 'react';
const tabs = ['Vue d\'ensemble', 'Analytique', 'Paramètres'];
export const TabNavigation = () => {
const [activeTab, setActiveTab] = useState(tabs[0]);
return (
);
};
```
---
## ♿ 3. Respect Impératif de `prefers-reduced-motion`
Chaque animation doit se désactiver instantanément pour les utilisateurs sensibles au mal des transports ou ayant activé la réduction de mouvement dans leur OS :
```tsx
import { motion, useReducedMotion } from 'framer-motion';
export const AccessibleCard = ({ children }: { children: React.ReactNode }) => {
const shouldReduceMotion = useReducedMotion();
return (
{children}
);
};
```
---
## 🎨 4. Alternatives CSS Modernes (Sans Dépendance JS)
Pour les transitions simples au chargement d'éléments, privilégiez `@starting-style` et la View Transitions API :
```css
/* Entrée fluide pure CSS d'un dialog ou popover */
dialog[open] {
opacity: 1;
transform: scale(1);
transition: opacity 0.2s ease-out, transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), display 0.2s allow-discrete;
}
@starting-style {
dialog[open] {
opacity: 0;
transform: scale(0.96);
}
}
```
---
## 📋 Checklist de Conformité Motion
- [ ] Aucun mouvement décoratif continu en boucle (pas de floating infini qui distrait).
- [ ] Les micro-interactions au clic utilisent `active:scale-[0.98]` ou un ressort réactif.
- [ ] `useReducedMotion()` (ou la media query `@media (prefers-reduced-motion: reduce)`) ramène la durée à 0.
- [ ] Les animations de changement de layout (`layoutId`) ne causent aucun reflow de texte brutal.
- [ ] La performance d'animation cible 60fps/120fps en animant exclusivement `transform` et `opacity`.