dorkhub_ design

// motion

Motion

Every duration and easing below is a live var() from globals.css, not a copy-pasted number — read docs/motion.md for the full policy this page demonstrates.

01 · tokens

Duration & easing

Hover a card to replay it. No component is allowed to invent its own timing or curve — everything ships from these four durations and two easings.

150ms

--motion-fast · hover, press, color

200ms

--motion-base · tooltips, dropdowns, modal enter/exit

300ms

--motion-slow · larger reveals, sheet exit

500ms

--motion-enter · sheet open only

ease-quiet · cubic-bezier(.16, 1, .3, 1) — strong ease-out, every enter/exit

ease-quiet-in-out · cubic-bezier(.65, 0, .35, 1) — on-screen moves

// hover this card to replay both at once

02 · reduced motion

The kill switch

Decorative motion is skipped entirely under prefers-reduced-motion, never just played shorter — functional loading indicators (the spinner) are the one carve-out.

click ++ with the switch off, then on — the pop and micro-burst should disappear entirely, not just play shorter.

03 · adopted transitions

Every shipped motion, in one place

The six overlay primitives below are adapted from transitions.dev's free-tier catalog — re-implemented on our own tokens and class names, never vendored (their terms forbid redistributing the library). Everything past the overlays is original to this system.

dialog

200ms · ease-quiet · centered, scale .95→1 + fade

dropdown-menu

200ms · ease-quiet · scales from trigger origin

tooltip

200ms · ease-quiet · scales from trigger origin

select

200ms · ease-quiet · scales from trigger origin

hover-card

200ms · ease-quiet · scales from trigger origin

sheet

500ms in / 300ms out · ease-quiet

collapsible

300ms · ease-quiet · grid-rows 0fr→1fr

#hardware#raspberry-pi#e-ink#plants#iot#sensors#dashboard

Never tweens height directly — a grid track sized 0fr/1fr does the reveal, so it's transform/layout-cheap.

stat-button like-pop

150ms ease-quiet pop · 400ms ease-quiet burst

Scale 1→1.15→1, and only on the ++ (like) action going active — never on save, never on un-liking. The 5-particle burst is primary-tinted and restrained on purpose.

copy-button

200ms ease-quiet · icon crossfade + stroke-draw

git clone github.com/mollybuilds/tinysynth

theme-toggle

150ms ease-quiet · label crossfade (scale + blur)

avatar-stack

150ms ease-quiet in · 200ms overshoot out

@mollybuilds@gremlinworks@rosiehux@kevbot

The overshoot return uses an explicitly-approved custom back-ease (cubic-bezier(.34,1.56,.64,1)) — the one place this system allows a curve outside the two named tokens.

skeleton-card shimmer

1.6s linear, infinite — respects the kill switch

number pop-in

200ms ease-quiet · RepoStatsRow + ProjectCard counts

TypeScript21412 forksMIT

switch

150ms ease-quiet-in-out · thumb + track color

project-card hover

150ms ease-quiet · border sharpen + lift 1px

Retuned from a hardcoded ease-out to the token — same behavior, correct curve.

command palette

no animation — ever

Command Palette

Search for a command to run...

⌘K is opened 100+ times a day by the people who use it most. Per docs/motion.md that frequency gets zero animation, full stop — contrast this against every other entry above.

04 · rejected

Considered, not shipped

Every one of these was a real idea before it wasn't — the reason is the point.

  • card stack hoverno surface to stack — ProjectCard doesn't layer.
  • 3D tiltcontradicts the locked hover treatment (sharpen + lift 1px).
  • literal confettibg-bloom pulse instead — same celebratory beat, on-brand.
  • Pro gradient textno gradient type in this system; also Pro-gated on source.

search

search projects, people, and tags