In-Their-Face Motions

Good UI motion is invisible: fast enough to feel instant, slow enough to track. Animate only transform and opacity, ease out, stay under 300ms; everything else is noise.1

Match behavior and timing in production, not this markup. Each section pairs a live demo with handoff recipes (Changes, Duration, Ease, …). Token values live in Global tokens; rules at the bottom of that card.

Global Tokens

Copy :root values into production recipes.

Durations

--dur-fast
100ms

Press · dropdown · uncheck · variant ring

--dur-slow
160ms

Hover · check-in · tooltip · toast exit · forms · alias --dur-local

--dur-toggle
160ms

Knob + chevron · track calc(var(--dur-toggle) × 1.625)

--dur-content
~213ms

Accordion open · tabs · toast enter · slow × 4/3

Eases

--ease-ui
cubic-bezier(0.25, 0.46, 0.45, 0.94)

Default everywhere unless emphatic is called for

--ease-ui-emphatic
cubic-bezier(0.32, 0.72, 0, 1)

Toggle knob + accordion chevron only

Offsets
--tooltip-delay · 200ms · --acc-close-delay · 50ms
Always
ease-out · UI <300ms · transform + opacity · keyboard skips decorative motion
Never
ease-in · transition: all · scale(0) enter · table row transitions

Actions

Buttons must feel like they're listening.
All button variants share one hover and press path.

Action button · hover

Changes
resthover: border, fill, label color +1 tier
Duration
160ms · --dur-local
Ease
--ease-ui
Avoid
Disabled: frozen at rest, no feedback

Action button · press

Changes
rest/hoverpressed: scale(0.98)
Duration
Instant on press · 100ms on release
Ease
--ease-ui on release only
A11y
Skip press scale when disabled or prefers-reduced-motion

Overlays

Skip delay on subsequent hovers; the group feels faster for it.
Dropdown enter/exit and tooltip group timing.

SLA
SLS
Tough 2000

Dropdown · open / close

Changes
closedopen: opacity, translateY(-6px), scale(0.98→1), backdrop-filter: blur(4px) (optional)
Duration
100ms · --dur-fast
Ease
--ease-ui
Notes
Close holds visibility until exit finishes · focus hop = instant

Tooltip · cold entry / exit

Changes
Enter: hiddenvisible: opacity + scale(0.94→1) · Exit: opacity only
Duration
Enter: 200ms delay then 160ms · Exit: 100ms, no delay
Ease
--ease-ui

Tooltip · warm hop

Changes
Tooltip A → B within group: instant swap
Duration
0ms
Ease
instant
A11y
Reduced motion: opacity-only or instant show

Toggles

Start from scale(0.95), never from zero.
Switch knob leads; checkboxes draw the mark; radios scale the dot.

Switch · off → on

Changes
Knob slides first · track fill/border follows
Duration
Knob 160ms · track 260ms (--dur-toggle × 1.625)
Ease
Knob --ease-ui-emphatic · track --ease-ui
Static
Track size
A11y
Space toggles · reduced motion: instant position + color

Checkbox · check

Changes
uncheckedchecked: brand fill + stroke-dashoffset draw-in
Duration
100ms · --dur-fast
Ease
--ease-ui
Static
Box size
A11y
Space same draw · reduced motion: skip stroke-dash

Checkbox · uncheck

Changes
checkedunchecked: mark undraws, fill clears
Duration
50ms (faster than check)
Ease
--ease-ui
A11y
Space same undraw · reduced motion: instant clear

Radio · select

Changes
unselectedselected: inner dot scale(0→1)
Duration
160ms
Ease
--ease-ui
Static
Outer ring size
A11y
Arrow keys · reduced motion: instant dot

Forms

Details nobody notices. That's the point.
Fields validate on blur; error and success feedback fade inside a reserved slot so siblings never shift.

Text field · focus

Changes
restfocused: border color step only
Duration
160ms
Ease
--ease-ui
Static
Height, padding, label position
A11y
:focus-visible matches pointer · reduced motion: color at 0.01ms

Text field · validate

Changes
neutralvalid/invalid: border, status icon, message opacity
Duration
In ~160ms · out 70ms opacity-only
Trigger
On blur only, not per keystroke
Static
Reserved message slot height; never animate height
A11y
Validate on blur for keyboard too

Select · open

Changes
closedopen: dropdown enter recipe; trigger border → brand instantly
Duration
Menu 100ms · trigger border 0ms
Ease
--ease-ui on menu
Static
Field width
A11y
Opens on pointerdown · instant hop when keyboard-navigating options
Notes
Closed + focused keeps border step until blur

Error message · swap

Changes
Message A → B: opacity out 70ms, new message fades in ~160ms
Duration
Out 70ms · in ~160ms
Ease
--ease-ui
Static
Slot dimensions fixed
Avoid
Height animation · error icon stroke draw on exit (opacity-only)

Cards & Rows

Most details users never consciously notice. That is the goal.
Variant ring selection and product row hover share the unified card language.

Form 4 · SLA Printer

Engineering-grade resin · 25µm layers

In stock

Card · hover

Changes
resthover: 2% fill tint + border +1 step
Duration
160ms
Ease
--ease-ui
Static
Size, padding, content layout
A11y
:focus-within matches hover · reduced motion: color/border only

Variant · select

Changes
unselectedselected: inset brand ring opacity 0→1 on ::after + title text → brand orange
Duration
100ms on ring + text color
Ease
--ease-ui
Static
Fixed 2px inset ring; never animate spread or real border width
A11y
Enter/Space · reduced motion: instant ring swap

Product row · hover

Changes
resthover: shadow lift only
Duration
160ms
Ease
--ease-ui
Static
Layout · no press scale
A11y
Reduced motion: shadow or opacity (no transform)

Never animate

Box-shadow spread · border 1px→2px · selected background tint · press scale on cards

Accordion

Exit fast: the system is responding, not deliberating.
Close orchestrates copy fade before panel collapse; chevron uses emphatic ease.

What materials are supported?

Over 40 engineering-grade resins across SLA, SLS, and FDM platforms. Each material ships with validated print settings in PreForm or Dashboard.

Is PreForm free to use?

Yes. PreForm is free to download and use for print preparation across all Formlabs printers, with no license fee or subscription required.

Does the Form 4 require a subscription?

No subscription required. All software and firmware updates are included at no additional cost for the lifetime of the printer.

Trigger · hover / open

Changes
resthover/open: label color darkens; no background fill
Duration
160ms
Ease
--ease-ui
Static
Row height, dividers
A11y
Enter/Space toggles · reduced motion: color only

Chevron · open

Changes
closedopen: rotate(180deg)
Duration
~213ms · --dur-content
Ease
--ease-ui-emphatic
Static
Icon box
A11y
Reduced motion: instant rotation or opacity swap

Panel · open / close

Changes
collapsedexpanded: height/grid reveal + copy fade · close: copy first, then panel after --acc-close-delay
Duration
Open panel ~213ms · close copy ~160ms then panel ~160ms
Ease
--ease-ui
A11y
Reduced motion: instant expand/collapse

Never animate

Trigger background · divider position · per-row box shadows · height animation is accordion-only

Tabs

Transitions, not keyframes: stay interruptible.
Pill glides always; content crossfades on pointer; keyboard snaps content instantly.

Form 4

Next-generation SLA with LFS™ technology. 25µm resolution, sub-day turnaround, and 40+ engineering-grade materials.

Print accuracy

145 × 145 × 185mm build volume. ±0.2% dimensional accuracy. Layer thickness 25–300µm across all materials.

40+ resins

Engineering, dental, and prototyping resins. All ship with validated print settings; no calibration required.

PreForm + Dashboard

Free print preparation software. Fleet management, remote monitoring, and usage analytics via Dashboard.

Tab pill · move

Changes
Active tab A → B: pill translate + width morph
Duration
~149ms · calc(var(--dur-content) × 0.7)
Ease
--ease-ui
A11y
Always runs; keyboard and reduced-motion only snap content, pill still animates

Text panel · pointer switch

Changes
Panel A → B: outgoing stays opaque; inner copy opacity + translateY(6px→0)
Duration
~213ms · --dur-content
Ease
--ease-ui
Static
Grid stack, no layout shift
A11y
Keyboard: instant swap · rapid clicks <250ms: instant content

Image panel · pointer switch

Changes
Image A → B: opacity crossfade + mask-size wipe 150%→0% (gradient mask L→R)
Duration
~213ms
Ease
--ease-ui
A11y
Keyboard/reduced motion: instant swap, no wipe

Never animate

Outgoing panel fade-out · layout reflow between panels · press scale on tabs

Tiles

Every animation must answer: why does this animate?
Poster/video swap on hover; chevron uses Links recipe.

Rigid
Tough
General purpose
Elastic

Tile · hover

Changes
resthover: ring, scrim, chevron; poster ↔ video (instant after first frame). Leave: ring 100ms out, video pauses
Duration
Ring/scrim/chevron 160ms in · video swap instant after paint
Ease
--ease-ui
Static
Tile size, crop, hairline border
A11y
:focus-within matches hover · reduced motion: skip chevron transform

Never animate

Poster ↔ video opacity crossfade · layout reflow · hairline border color · video = play/pause not CSS tween