Demo 01 · Send Message

AI

How can I help you today?

idle → hover → loading → success / error
Force:

Demo 02 · Generate — Same Motion Language, Ghost Variant

Ghost style, amber accent — same timing, same spring, same slot system.

idle → hover → loading → success / error
Force:

Duration & Easing Notes

Slot swap — 220ms ease-out Outgoing slots fade + translate in 220ms. Fast enough to feel snappy, slow enough for the eye to track the swap without confusion.
Width morph — 350ms ease-in-out The container width eases symmetrically — slower than the content slots so it reads as a settled destination, not a race to catch up.
Check draw — 450ms spring (34,1.56,64,1) A slight overshoot on the stroke draw gives the checkmark a moment of personality — it "lands" rather than just appearing. Under reduced-motion the check is shown instantly; only the animation is removed.
Error shake — 500ms ease-out, once Shake fires once and stops — it's information, not punishment. Under prefers-reduced-motion, the shake is skipped entirely; the red color + error label still communicate the failure.
Hover lift — 150ms ease-out Hover uses translateY(-1px) + glow ring rather than scale, so the button doesn't visually grow into its neighbor. The glow is opacity-only — compositor-friendly.
Interruptibility All state is gated by a lock flag. Spam-clicking during loading or a transition is silently ignored. The lock is always released, even on uncaught errors, via a finally block.