Skip to content

Motion System

Human’s motion system applies Pixar’s 12 principles of animation to UI interactions. Every animation has purpose — it guides attention, confirms actions, and creates spatial coherence.

TokenValueCSS VariableUsage
duration.instant100ms--hu-duration-instantHovers, state toggles
duration.fast150ms--hu-duration-fastButton presses, small reveals
duration.normal250ms--hu-duration-normalPanel transitions, fades
duration.slow400ms--hu-duration-slowModal entrances, page transitions
duration.slower600ms--hu-duration-slowerComplex orchestrated sequences
TokenValueCSS VariableCharacter
ease.defaultcubic-bezier(0.4, 0, 0.2, 1)--hu-ease-defaultNatural deceleration
ease.incubic-bezier(0.4, 0, 1, 1)--hu-ease-inAccelerating exit
ease.outcubic-bezier(0, 0, 0.2, 1)--hu-ease-outDecelerating entrance
ease.in-outcubic-bezier(0.4, 0, 0.2, 1)--hu-ease-in-outSymmetric motion
ease.springcubic-bezier(0.175, 0.885, 0.32, 1.275)--hu-ease-springBouncy overshoot
ease.bouncecubic-bezier(0.34, 1.56, 0.64, 1)--hu-ease-bouncePlayful bounce

These presets encode Pixar animation principles as token-driven CSS keyframes.

When pressed, buttons compress slightly (squash), then spring back with overshoot (stretch).

TokenValuePrinciple
micro-physics.button-press.scale0.96Squash on press
micro-physics.button-press.duration80msFast physical response
micro-physics.button-release.scale1.02Stretch on release
micro-physics.button-release.duration200msSlower recovery
.btn:active {
transform: scale(var(--hu-physics-button-press-scale));
transition: transform var(--hu-physics-button-press-duration)
var(--hu-ease-spring);
}

Before appearing, modals briefly scale down (anticipation), then spring to full size.

TokenValuePrinciple
micro-physics.modal-anticipation.scale0.95Preparatory pullback
micro-physics.modal-anticipation.duration120msBrief setup

Cards lift slightly with a springy overshoot on hover, settling to final position.

TokenValuePrinciple
micro-physics.card-hover.translate-y-2pxSubtle lift
micro-physics.card-hover.duration300msGentle float

Dropdowns compress before expanding, giving a sense of stored energy.

TokenValuePrinciple
micro-physics.dropdown-anticipation.scale-y0.95Vertical compression
micro-physics.dropdown-anticipation.duration100msQuick wind-up

Toggle switches squash horizontally during state change.

TokenValuePrinciple
micro-physics.toggle-squash.scale-x0.9Horizontal squash
micro-physics.toggle-squash.duration150msSnappy

Applies button press squash/stretch on any interactive element:

<button class="hu-physics-press">Click me</button>

Applies card hover lift with follow-through:

<div class="hu-physics-hover">Hoverable card</div>

Applies anticipation entrance animation on mount:

<dialog class="hu-anticipate-enter">Modal content</dialog>

All animations respect prefers-reduced-motion: reduce. When active:

  • Durations are set to 0ms
  • Transforms are removed
  • Only opacity transitions remain (they don’t cause motion sickness)
@media (prefers-reduced-motion: reduce) {
.hu-physics-press:active,
.hu-physics-hover:hover {
transform: none !important;
transition: none !important;
}
}
ScenarioDurationEasingPrinciple
Button feedbackinstantspringSquash & stretch
Card hovernormalspringFollow-through
Modal entranceslowbounceAnticipation
Page transitionslowease-outStaging
Toast appearancefastease-outTiming
Loading spinnerslowerlinearSecondary action
  • Scrolling content into view (use CSS scroll-behavior: smooth instead)
  • Color theme transitions (instant swap, no fade)
  • Error state changes (immediate, no delay)
  • Content that hasn’t changed (don’t re-animate)