Motion.
Per-character clipped slide-up. Count-up numerics. Snappy press. The brand is precise — never bouncy, never decorative.
Each glyph slides 100% of its own height inside an overflow:hidden box. Stagger 30ms per character. Easing: cubic-bezier(0.16, 1, 0.3, 1). 600ms total.
Numbers animate from 0 to target on first render and on slide change. 700ms ease-out cubic. Tabular figures throughout.
Every button — and only buttons — press to scale(0.97). 100ms. Small, snappy.
Tap or click to feel it.
Default for entries — slow ease-out, signature feel
Exits — fast accelerating
Most things — symmetric ease-in-out
| Token | Value | Role |
|---|---|---|
| --dur-instant | 50ms | Hover state changes, micro-interactions |
| --dur-fast | 150ms | Standard — buttons, links, focus rings |
| --dur-normal | 300ms | Sheets, dialogs, route transitions |
| --dur-slow | 500ms | Reserved — only when 300ms feels rushed |
Use the per-character clipped slide-up for hero headings — it is the brand's signature motion.
Animate numerics with count-up (700ms ease-out cubic) on first render and on slide change.
Use scale(0.97) on every button press. Small, snappy, 100ms.
Don't use spring or bouncy easing anywhere. The brand is precise — never wobbly.
Don't animate individual letters with rotation, scale, or color. Slide-up only.
Don't exceed 500ms unless it's a deliberate gradient drift on a marketing surface.
Named interaction recipes added across the portal chrome and landing page. Same three easings, same four durations — no new motion primitives.
| Recipe | Duration | Easing | Role |
|---|---|---|---|
| reveal-on-scroll | 300ms (--dur-normal) | --easing-out | Fade + 8px rise, once, on first viewport entry. `.db-reveal` + `use:reveal` action. |
| view transition | 90ms out · 150ms in | --easing-in / --easing-out | Cross-fade + 4px rise between routes via `document.startViewTransition`. |
| copy-confirm | 150ms (--dur-fast) | --easing-out | Icon swaps to a check with a fade, label flips to "copied", reverts after ~1.2s. |
| hover lift | 150ms (--dur-fast) | --easing-default | Card/tile border + shadow-md on hover — no transform, just weight. |
| nav indicator | 150ms (--dur-fast) | --easing-out | Underline or left-rail mark scales in from 0 on the active item. |
Sections fade in + rise 8px once, the first time they cross 15% of the viewport. Reduced motion: sections render fully visible, no animation.
Copy actions swap their icon to a check with a short fade and add a 'copied' label, then revert after ~1.2s.