Motion
Motion in this system is not decoration — it is Datsuzoku.
Philosophy
Motion in this system is not decoration — it is Datsuzoku, the moment of departure from stillness that makes the stillness meaningful. Every animation must justify its existence: does it orient the user, provide feedback, or reveal structure? If not, it is noise. The site should feel alive the way a garden feels alive — not because everything is moving, but because you sense that movement could happen.
Easing Curves
Three custom curves as CSS custom properties. Click each plot to see the curve animate.
--ease-enter: cubic-bezier(0, 0, 0.38, 0.9); /* ease-out — element appears */
--ease-exit: cubic-bezier(0.2, 0, 1, 0.9); /* ease-in — element departs */
--ease-standard: cubic-bezier(0.2, 0, 0.38, 0.9); /* ease-in-out — element moves */
Curve Comparison
All three curves overlaid. Click to play.
Duration Scale
| Token | Duration | Use |
|---|---|---|
--duration-instant | 100ms | Colour shifts, opacity, hover states |
--duration-fast | 200ms | Button feedback, icon transitions |
--duration-moderate | 300ms | Dropdowns, tooltips, card hover |
--duration-slow | 500ms | Modal / overlay entrance |
--duration-deliberate | 800ms | Page transitions, hero reveals |
Motion Demo
Reduced Motion — Seijaku
When prefers-reduced-motion: reduce is active, strip all positional animation. Replace with opacity crossfade or no animation. Motion is never essential to understanding — the content is complete in stillness.
Normal: slide up + scale in + fade — full spatial animation.
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.001ms !important;
scroll-behavior: auto !important;
}
}
Choreography Rules
- Stagger, don’t synchronise. Multiple entering elements stagger by 50–80ms each — like brushstrokes laid one after another.
- Direction follows reading. Elements enter from the left or bottom. Exit in the reverse direction.
- Hierarchy first. Hero headline animates before body text, which animates before captions.
State Transitions
| State change | Animation | Duration | Easing |
|---|---|---|---|
| Hover (link / button) | Colour shift | 100ms | --ease-standard |
| Hover (card image) | Opacity fade + scale (1.0 → 1.02) | 300ms | --ease-enter |
| Page change | Cross-fade | 500ms | --ease-standard |
| Modal open | Opacity 0→1 + translateY(8px → 0) | 300ms | --ease-enter |
| Modal close | Opacity 1→0 + translateY(0 → 8px) | 200ms | --ease-exit |
| Arrow link hover | Arrow translates 4px right | 200ms | --ease-enter |
| Text link hover | Underline draws left to right | 200ms | --ease-enter |