Skip to content

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