Make a change easier to follow.
Try real component transitions. Keep motion brief, purposeful, and optional. All examples use local browser animation with no external service.
System preference is respected automatically.
Introduce a component
Fade or move a component into place without changing its meaning.
Expand the details
What happens in older browsers?
The content opens immediately. Supporting browsers smoothly animate its natural height. Native keyboard and screen-reader behavior stay intact.
Use the same transition with Accordion. No extra runtime is needed.
Open a focused task
Dialogs fade and scale. Drawers rise from the bottom; sheets enter from the side. All share Lumen timing, a fading backdrop, and Escape with focus restoration.
Loading to success
This is a simulated save. No data is sent.
Ready to preview.
Follow an item entering or leaving
Insertion and removal are optional. The application owns the list and moves focus before an item exits.
1 example item.
Use the shared foundation
Presence animates a mounted DOM reference in Astro, React, or Web Components. Keep it on a wrapper when a component already owns its transform or animation. Abort stale requests on unmount; cancelled exits must not remove a newly reopened item.
import { animateLumenPresence } from '@santi020k/lumen-core'
// Mount with your framework first, then animate its DOM ref.
await animateLumenPresence(element, { preset: 'slide-up' })
// Move focus out before disabling interaction and exiting.
element.inert = true
const result = await animateLumenPresence(element, { phase: 'exit' })
if (result !== 'cancelled') element.remove()
else element.inert = false<ScrollReveal animation="slide-up" duration="slow">
<Card>A single entrance</Card>
</ScrollReveal>
<RevealGroup stagger={80}>
<Card>Plan</Card>
<Card>Build</Card>
<Card>Ship</Card>
</RevealGroup>