Motion.

Something moves on this site only to show something: a section arriving, a process running, a line being drawn. Every loop pauses off screen, and under reduced motion everything settles to its final frame.

Travelling arrow.

The arrow on a link or button leaves up and to the right and a fresh one arrives from the bottom left, as if the link were already taking you there. It moves only on hover or keyboard focus.

Show code
// Inside any element with `group`: TextLink and Button set it for you.
<TravelArrow className="size-3" />

Drawn linework.

Lines draw the way a pen would: extension lines first, then the dimension, then its arrowheads and value, about 650ms in all on one easing curve.

The dimensioned CTA and the Redliner’s pen circle draw themselves on hover. See them on Button.

Ground.

A slow field of dots behind a closing band or a showcase: texture, never content. It pauses when it scrolls off screen or the tab is hidden, and draws one still frame under reduced motion.

Show code
import { DitherFlow } from "#/ui/dither-flow";

<div className="relative ...">
  <DitherFlow className="absolute inset-0 h-full w-full" />
</div>

Marquee.

A slow band of mono labels. It pauses on hover, so anything in it can be read, and stops under reduced motion. It is background texture, so it runs slowly, and a longer loop is calmer.

Shipped weeklyFree to readUnsubscribe in one clickWritten by engineers
Show code
import { Marquee, MarqueeItem } from "#/ui/site/marquee";

<Marquee seconds={48}>
  <MarqueeItem>Shipped weekly</MarqueeItem>
</Marquee>

Timing.

Feedback, a hover or a state change, is 150 to 200ms. Arrival, a section rising in or a menu settling, is 140 to 700ms, eased out. Drawing, linework writing itself, is around 650ms in sequence. Sections rise in with the reveal class as they scroll into view.

Best practices.

Do

  • Give motion a reason: something arrived, something is working, a line is being drawn.
  • Pause every loop when it is off screen or the tab is hidden.
  • Settle to the final frame under prefers-reduced-motion.
  • Keep feedback under 200ms.

Don't

  • Do not animate text a reader is trying to read.
  • Do not loop anything that carries meaning.
  • Do not run two hover animations on one control.
  • Do not write a new reduced-motion check; use the shared one.