Motion
Motion in Naluma should feel like settling — elements arrive where they belong with the gentle deceleration of something finding its place. This mirrors the brand promise: sound finding its right position. No bouncy animations, no abrupt cuts, no urgency.
Token source: tokens/primitive/transition.json
See the Visual Identity Direction for the motion philosophy and the Brand Personality Spectrum for the Urgent — Still (60% still) position that governs these choices.
Standard ease (250ms)
cubic-bezier(0.4, 0, 0.2, 1) Settle — Naluma (600ms)
cubic-bezier(0.16, 1, 0.3, 1) Hover to animate
Transition Presets
Section titled “Transition Presets”Complete transition shorthand values that can be applied directly to CSS transitions.
| Token | Value | Usage |
|---|---|---|
primitive.transition.fast | 150ms ease | Hover colors, opacity changes |
primitive.transition.normal | 250ms ease | Layout shifts, sidebar transitions |
primitive.transition.slow | 400ms ease | Header scroll, accordion open/close |
primitive.transition.settle | 600ms cubic-bezier(0.16, 1, 0.3, 1) | Core Naluma motion language |
Easing Curves
Section titled “Easing Curves”Named easing functions for use with custom durations or animation frameworks.
| Token | Value | Character |
|---|---|---|
primitive.easing.default | cubic-bezier(0.4, 0, 0.2, 1) | Standard easing curve |
primitive.easing.settle | cubic-bezier(0.16, 1, 0.3, 1) | Settling — slow deceleration, calm arrival |
The “Settle” Motion
Section titled “The “Settle” Motion”The settle curve is Naluma’s signature motion. It is used for:
- Page and view transitions
- Elements entering the viewport
- Modal and sheet presentations
- Any motion that represents “arriving”
The curve has a fast initial phase and a long, gentle deceleration. Visually, the element moves quickly at first and then slowly eases into its final position — the motion equivalent of a sound finding its place.
Settle vs. Standard
Section titled “Settle vs. Standard”Standard (ease) | Settle | |
|---|---|---|
| Duration | 150—400ms | 600ms |
| Curve | cubic-bezier(0.4, 0, 0.2, 1) | cubic-bezier(0.16, 1, 0.3, 1) |
| Character | Functional, responsive | Calm, deliberate, grounded |
| Use for | Micro-interactions (hover, toggle) | Macro-interactions (navigation, content reveal) |
When to use which
Section titled “When to use which”Standard easing (fast, normal, slow) — Use for interactions that should feel responsive and immediate: button hover states, input focus, toggle switches, tooltip appearance.
Settle easing — Use for transitions that should feel intentional and unhurried: page navigation, content cards entering view, session start/end, progress reveals. The 600ms duration is longer than typical app transitions, which is deliberate. The Naluma brand position is “60% toward Still” — the motion language should reinforce that the app is not in a hurry.
Implementation Notes
Section titled “Implementation Notes”CSS usage
Section titled “CSS usage”/* Standard micro-interaction */.button { transition: background var(--primitive-transition-fast);}
/* Settling page transition */.page-enter { transition: opacity 600ms var(--primitive-easing-settle), transform 600ms var(--primitive-easing-settle);}Flutter usage
Section titled “Flutter usage”// Standard curvefinal defaultCurve = Curves.easeInOut;
// Settle curve — map to Cubicfinal settleCurve = Cubic(0.16, 1, 0.3, 1);const settleDuration = Duration(milliseconds: 600);Anti-Patterns
Section titled “Anti-Patterns”- Bouncy / spring animations — Convey playfulness, which conflicts with the 75% Serious personality position
- Instant transitions (0ms) — Feel jarring and clinical
- Looping animations — Create visual noise; the anxious user’s attention is already stretched thin
- Parallax or scroll-linked motion — Adds complexity without serving the content; risks motion sickness
- Loading spinners — Prefer a calm, static waiting state over a spinning indicator; a moment of stillness is not a UX failure in this context