Motion
Short, purposeful motion that explains where things come from and where they go. Durations and curves are tokens; springs work in pure CSS.
Motion in prfct has one job: to explain change. A menu grows out of the button that opened it; a dialog rises into place; a switch thumb springs across its track. Nothing moves just to be seen moving.
Build finished
Enters in 220ms with ease-enter, leaves in 100ms with ease-exit.
Principles
Responsive. Feedback starts within 100ms of input. Hover and press states are near-instant; the interface never waits for an animation to finish before responding.
Directional. Elements enter from their origin — the trigger's side, the screen edge — and leave the way they came. Popups scale from --transform-origin, which Base UI sets to the anchor.
Asymmetric. Things leave faster than they arrive. Exits use shorter durations and accelerating curves, so dismissal never feels sticky.
Optional. Motion is decoration on top of a working interface. With reduced motion enabled, everything still works — instantly.
Durations
Easing
prfct ships four cubic-bézier curves and two springs. The springs are simulated from physical parameters (stiffness and damping) and encoded as CSS linear() functions — real spring motion in CSS transitions, with no animation library and no JavaScript on the main thread.
Each dot travels the same distance in its token’s duration.
Default for elements that change in place.
Elements entering the screen. Fast start, long settle.
Elements leaving. Accelerates away; pair with shorter durations.
Elements moving from one place to another on screen.
Physical, responsive feedback: switches, drag release, popovers.
Playful emphasis: success confirmations, badges appearing.
// A switch thumb that settles like a physical toggle
<span className="transition-transform duration-spring ease-spring" />Choreography utilities
Components share their motion through three utilities, so every overlay in the system moves the same way:
They are driven by Base UI's data-starting-style and data-ending-style attributes, so animations are interruptible: closing a menu halfway through opening reverses smoothly from where it is.
Reduced motion
When the operating system asks for reduced motion, prfct collapses every transition and animation to an instant. Skeleton sweeps and spinner rotation stop; state still changes, so nothing is lost. Because prfct never uses motion to convey meaning, this is always safe.