Animation System
Motion Guide
Motion should be felt, not seen. All animation variants live in lib/motion.ts - never defined inline in components.
Philosophy
Purposeful
Every animation communicates state change, hierarchy, or direction.
Proportional
Short transitions for small elements, longer for full-page changes.
Respectful
All animations respect prefers-reduced-motion OS setting.
Easing Curves
gridnest-out
cubic-bezier(0.16, 1, 0.3, 1)
gridnest-spring
cubic-bezier(0.34, 1.56, 0.64, 1)
ease-in-out (default)
easeInOut
Timing Scale
Fast
150ms
Tap, hover, icon swaps
Normal
250ms
Menus, popovers, inline feedback
Slow
400ms
Page sections, larger layout reveals
Component Recipes
Variants Gallery
fadeUp
opacity + y translate reveal. Used on headlines and body text.
scaleIn
scale + opacity entrance. Used on cards, modals, and preview panels.
clipReveal
Horizontal clip-path text reveal. Used for editorial headlines.
Do / Don't
Do
- Import variants from lib/motion.ts
- Use staggerContainer for list reveals
- Respect useReducedMotion()
- Keep durations under 500ms for UI
Don't
- Define animation variants inline in components
- Animate on every scroll event
- Use durations > 700ms for UI feedback
- Animate layout-triggering properties (width, height)