Motion
Spring-based motion tokens, short state transitions, and a hard requirement to respect reduced motion.
Motion in Tanrei explains a change and then gets out of the way. Most of it is a state layer fading in over 200 to 250 milliseconds.
Motion tokens are organised as springs along two axes:
- Spatial springs move or resize things. They may overshoot slightly, the way a physical object settles.
- Effects springs change color and opacity. They never overshoot, because a color that bounces looks like a glitch.
Each kind comes in fast, default and slow. Platforms with real spring animation use the stiffness and damping values; CSS uses the duration and the cubic-bezier approximation stored alongside them.
There are two schemes. Standard is the default and is nearly critically damped. Expressive is an additive layer with more bounce for products that want it.
Fixed durations and easing curves are provided for transitions that are not springs.
| Kind of change | Guideline |
|---|---|
| State change (hover, press, selection) | 200–250ms |
| An element entering | 300–400ms, longer for a larger surface |
| A large reveal | up to 800ms, with items staggered 100ms apart |
| Anything leaving | faster than it entered |
| Token | Value | Curve |
|---|---|---|
--tanrei-sys-motion-easing-emphasized-accelerate | cubic-bezier(0.3, 0, 0.8, 0.15) | |
--tanrei-sys-motion-easing-emphasized-decelerate | cubic-bezier(0.05, 0.7, 0.1, 1) | |
--tanrei-sys-motion-easing-enter | cubic-bezier(0.2, 0, 0, 1) | |
--tanrei-sys-motion-easing-exit | cubic-bezier(0.3, 0, 1, 1) | |
--tanrei-sys-motion-easing-linear | cubic-bezier(0, 0, 1, 1) | |
--tanrei-sys-motion-easing-spatial | cubic-bezier(0.2, 0, 0, 1) | |
--tanrei-sys-motion-easing-standard | cubic-bezier(0.2, 0, 0, 1) | |
--tanrei-sys-motion-easing-standard-accelerate | cubic-bezier(0.3, 0, 1, 1) | |
--tanrei-sys-motion-easing-standard-decelerate | cubic-bezier(0, 0, 0, 1) | |
--tanrei-sys-motion-easing-state | cubic-bezier(0.2, 0, 0, 1) |
Generated from design/tokens/tanrei.light.tokens.json, tokens/sys/motion.tokens.json
- The focus ring appears instantly. Keyboard users need to see where they are without waiting for an animation.
- No ripple by default. Press feedback is the state layer; ripple is a theme-level option, not a baseline.
Every implementation must honour the platform’s reduced-motion setting. Under it, spatial movement is removed or replaced by a short cross-fade, and nothing loops. This is part of each component’s definition of done, not an enhancement.
All values are listed in the motion token reference.