Animations
Pre-built animations for common UI patterns: entrance effects, loading indicators, and attention-getters. Each animation is stored as a CSS custom property so you can use it via a utility class or reference it directly in custom CSS. All animations respect prefers-reduced-motion automatically.
Entrance Animations
One-shot animations for elements appearing on screen. Useful for HTMX fragment swaps, modal reveals, and page load sequences. Click any card to replay its animation:
.animate-fade-in
Click to replay
Click to replay
Click to replay
.animate-scale-in
Click to replay
.animate-fade-out
Click to replay
Infinite Animations
Looping animations for loading states and attention-getters:
.animate-spin
.animate-pulse
Usage
<!-- Class-based -->
<div class="animate-fade-in">I fade in on mount</div>
<div class="animate-slide-up">I slide up on mount</div>
<!-- Loading spinner -->
<div class="animate-spin">...</div>
<!-- Skeleton placeholder -->
<div class="animate-pulse i-bg-surface rounded-md h-md"></div>
<!-- Variable in custom CSS -->
.my-modal { animation: var(--animate-scale-in); }
<!-- Disable animation -->
<div class="animate-none">No animation</div>
Reduced Motion
When prefers-reduced-motion: reduce is active, entrance animations collapse to an instant opacity change (no movement), and infinite animations are disabled entirely. This happens automatically through the config layer.
Animation Variables
--animate-fade-in - opacity 0 to 1--animate-fade-out - opacity 1 to 0--animate-slide-up - fade in from below--animate-slide-down - fade in from above--animate-scale-in - fade in with slight scale-up--animate-spin - continuous rotation--animate-pulse - opacity breathing effectEntrance animations use both fill mode so elements stay in their end state. Slide distances use --size-sm from the mathematical scale, not arbitrary pixel values.