Spacing & Motion Tokens
4px baseline grid. Subtle animations. No bouncy transitions.
Spacing Scale
| Token |
Value |
Use |
--space-1 |
2px |
Micro (icon padding) |
--space-2 |
4px |
Tight (badge gaps) |
--space-3 |
8px |
Related elements |
--space-4 |
12px |
Component padding |
--space-5 |
16px |
Card padding |
--space-6 |
24px |
Section gap |
--space-7 |
32px |
Large gap |
--space-8 |
48px |
Page sections |
--space-9 |
64px |
Hero sections |
Border Radius
| Token |
Value |
Use |
--radius-sm |
4px |
Small elements |
--radius-md |
6px |
Default |
--radius-lg |
8px |
Cards |
--radius-xl |
12px |
Large cards |
--radius-full |
9999px |
Pills, avatars |
Motion Philosophy
"Subtle fade + 2-4px Y-translate, 80-120ms, no bouncy transitions"
SageOx motion is calm and purposeful:
- Quick enough to feel responsive
- Subtle enough to not distract
- Consistent across the interface
Duration Tiers
| Token |
Value |
Use |
--duration-instant |
50ms |
State changes (toggle, check) |
--duration-fast |
150ms |
Hover, focus, small transitions |
--duration-normal |
250ms |
Panel reveals, tab switches |
--duration-slow |
350ms |
Modal animations |
--duration-slower |
500ms |
Complex sequences |
Timing Functions
| Token |
Curve |
Use |
--ease-out |
cubic-bezier(0, 0, 0.2, 1) |
Exits, closing |
--ease-in-out |
cubic-bezier(0.4, 0, 0.2, 1) |
Most transitions |
--ease-spring |
cubic-bezier(0.175, 0.885, 0.32, 1.275) |
Moments of delight (rare) |
ease-out: Quick start → gentle landing (exits)
ease-in-out: Gentle → quick → gentle (most things)
ease-spring: Overshoot + settle (special moments)
Animation Patterns
Hover State
.card {
transition: transform 150ms var(--ease-out),
box-shadow 150ms var(--ease-out);
}
.card:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-sm);
}
Click Feedback
.button:active {
transform: translateY(1px);
transition: transform 50ms var(--ease-out);
}
Panel Reveal
.panel {
opacity: 0;
transform: translateY(4px);
}
.panel.open {
opacity: 1;
transform: translateY(0);
transition: opacity 250ms var(--ease-out),
transform 250ms var(--ease-out);
}
Modal Entry
.modal {
opacity: 0;
transform: scale(0.95);
}
.modal.open {
opacity: 1;
transform: scale(1);
transition: opacity 350ms var(--ease-out),
transform 350ms var(--ease-spring);
}
Reduced Motion
All durations set to 0ms when user prefers reduced motion:
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0ms !important;
transition-duration: 0ms !important;
}
}
Shadow System
| Token |
Value |
Use |
--shadow-xs |
0 1px 2px rgba(0,0,0,0.04) |
Hover |
--shadow-sm |
0 2px 4px rgba(0,0,0,0.06) |
Cards |
--shadow-md |
0 4px 8px rgba(0,0,0,0.08) |
Dropdowns |
--shadow-lg |
0 8px 16px rgba(0,0,0,0.1) |
Modals |
--shadow-xl |
0 16px 32px rgba(0,0,0,0.12) |
Popovers |
Dark mode shadows have higher opacity for visibility on dark backgrounds.
Z-Index
| Token |
Value |
Use |
--z-dropdown |
1000 |
Dropdowns |
--z-sticky |
1100 |
Sticky headers |
--z-modal-backdrop |
1300 |
Modal overlay |
--z-modal |
1400 |
Modal content |
--z-tooltip |
1600 |
Tooltips |
--z-toast |
1700 |
Toast notifications |