Export
The CSS dialect
Plain @keyframes and an animation shorthand. Springs are turned into a linear() easing, so there's nothing to install. It's just CSS.
- Your component comes back with its class
- Every rule hangs off one class on your component’s root, like
.card > :nth-child(2). The export gives you your markup back with that class already on the root, next to the stylesheet, and a split heading comes with its letters written in. Paste the stylesheet, paste the markup over yours, and that’s it. A pasted module comes back whole, and raw HTML comes back as HTML. - Where one paste stops
- You don’t get the markup back if the root’s class is computed at runtime (
cn(…), or a template literal with a${}in it), if the root has a spread, or if there’s more than one root. The stylesheet tells you which class to add instead. A split heading in a raw HTML paste still comes as its own block. - Springs become linear()
- CSS has no spring easing, so the spring’s curve is sampled into a
linear()easing with enough stops to stay within tolerance. It’s longer to read than a spring config and matches the preview closely. - One declaration per group
- Transform properties share one
transformdeclaration and filters share onefilter, so the export merges them. That’s why their composition order matters. - More stops where the curve bends
- The stops aren’t evenly spaced. They’re added wherever fewer would drift out of tolerance, so a spring’s first bounce gets more than a straight run does. There’s also one just before each keyframe, because a spring that’s cut short leaves a near-vertical edge there.
- Interrupting starts it over
- A CSS animation doesn’t know its current velocity, so re-triggering one mid-flight starts it again from the first keyframe. Motion redirects instead. The export says so in a comment.
Worst case across the parity fixtures: 0.30%, against a 0.6% tolerance. That’s the total error of the sampled CSS against the engine, measured in a real browser.