Skip to main content

Motion & Animation

Guidelines for animations and transitions to create smooth, purposeful motion.


Timing

Fast (150ms)
Micro-interactions, hovers
Normal (200ms)
Buttons, inputs, small changes
Medium (300ms)
Modals, dropdowns, panels
Slow (500ms)
Page transitions, complex animations

Easing Functions

EasingUse CaseTailwind
ease-outElements enteringease-out
ease-inElements exitingease-in
ease-in-outMoving/morphingease-in-out
linearLoading spinnersease-linear
// Tailwind transition classes
<button className="transition-colors duration-200 ease-out">
Hover me
</button>

<div className="transition-all duration-300 ease-in-out">
Animated panel
</div>

Common Animations

Hover Effects

bg-orange-500 → bg-orange-600
translateY(-2px) + shadow
scale(1.05)

Card Hover

Activity Card
Hover state: lifted with enhanced shadow
<div className="
transition-all duration-300 ease-out
hover:shadow-lg hover:-translate-y-1
">
Card content
</div>

Entrance Animations

Fade In

Content fades in from opacity 0 → 1

Slide Up

Content slides up from below

// Tailwind animation classes
<div className="animate-fadeIn">Fade in</div>
<div className="animate-slideUp">Slide up</div>

// Custom animations in tailwind.config.js
animation: {
'fadeIn': 'fadeIn 0.5s ease-out',
'slideUp': 'slideUp 0.3s ease-out',
}

Backdrop
Fade in 200ms
Modal
Scale + Fade
Scale 0.95→1, 300ms
// Modal animation
const modalVariants = {
hidden: { opacity: 0, scale: 0.95 },
visible: { opacity: 1, scale: 1 },
};

// CSS
.modal-enter {
opacity: 0;
transform: scale(0.95);
}
.modal-enter-active {
opacity: 1;
transform: scale(1);
transition: all 300ms ease-out;
}

Loading Animation

Spinner
Dots
Progress

Best Practices

  1. Be purposeful - Animation should guide attention, not distract
  2. Keep it fast - Most interactions should be under 300ms
  3. Respect preferences - Honor prefers-reduced-motion
  4. Consistent timing - Use the same duration for similar animations
  5. Ease appropriately - ease-out for entrances, ease-in for exits
// Respect reduced motion preference
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}

// Tailwind: motion-safe and motion-reduce
<div className="motion-safe:animate-fadeIn motion-reduce:opacity-100">
Content
</div>

Animation Tokens

TokenDurationUse Case
duration-150150msHover states, micro-interactions
duration-200200msButton clicks, input focus
duration-300300msModals, panels, dropdowns
duration-500500msPage transitions

Animations should enhance UX, not slow it down. When in doubt, keep it subtle.