Lodestone

A field of hairlines that lines up like iron filings around your call to action. The button is a bar magnet, the pointer a second pole that bends the field toward it, the headline a stone the field flows around, and a success state swings every line to north in one wave.

  • Background
  • Interaction
  • Canvas

Uses motion, clsx, tailwind-merge

Open in ChatGPTOpen in Claude
Private beta · 2,480 teams waiting

Agents that pull in one direction

Meridian lines up every agent in your stack behind one goal, one plan and one log you can read.

Installation

Add the component on its own with the CLI, or copy the file in by hand.

The CLI writes components/ui/lodestone.tsx and installs motion, clsx and tailwind-merge. It needs the @keyframeui registry in components.json; add it once per project.

npx shadcn@latest add @keyframeui/lodestone

Examples

Finished sections built with Lodestone. Each one installs whole, with the component included.

Studio CTA

A studio's closing card in stone and orange. The button is a single pole (`poles="center"`), so the field fans into it from across the card, and the serif headline and the small print are both quiet zones.

Booking Q1 · 2 slots left

Have something you want people to feel?

Brand, product and motion for teams
shipping their first big thing.

Two Paths

A hero with a primary and a secondary call to action. The field rests on the primary; lean toward the other and its `strength` takes over, so the field swings across in a wave from that button.

Your first agent ships this afternoon

Start from a template on your own, or walk through your stack with an engineer.

Props

childrenRequired

TypeReact.ReactNode

The section. Wrap the call to action in LodestoneTarget and the headline in LodestoneQuiet.

aligned

TypebooleanDefaultfalse

Swings every hairline to north in one wave from the strongest target, with a ring. Use it for a success state: a waitlist joined, a form sent.

cursor

TypenumberDefault0.8

Strength of the pointer's own pole, relative to a target. It fades out while a target is hovered. 0 turns it off.

reach

TypenumberDefault1.3

How far the targets' fields carry across the backdrop.

spacing

TypenumberDefault24

Distance between hairlines, in px.

length

TypenumberDefault0.6

Length of a hairline in a strong field, as a share of spacing. In a weak field they shrink toward a quarter of that.

thickness

TypenumberDefault1

Line width, in px.

intro

TypebooleanDefaulttrue

Scatter the hairlines and let them snap into line, in a ring from the target, the first time the field scrolls into view.

marks

TypebooleanDefaulttrue

Draw a faint static + every six cells, like engineering paper.

fade

TypebooleanDefaulttrue

Fade the field out toward the edges.

fieldClassName

TypestringDefault"text-zinc-900 dark:text-zinc-100"

A text-* color for the hairlines. The canvas reads it, so dark: variants work; opacity comes from the field's strength.

accentClassName

TypestringDefault"text-indigo-500 dark:text-indigo-400"

A text-* color that gathers around a hovered target and rides the shockwave.

canvasClassName

Typestring

Classes for the canvas, e.g. opacity-60 to quiet the whole field.

className

Typestring

Classes for the section. Give it a background: the field draws behind the content, on top of it.

target.strength

TypenumberDefault1

LodestoneTarget: how strongly this target pulls. Change it and the field hands over in a wave that starts at this target.

target.poles

Type"ends" | "center"Default"ends"

LodestoneTarget: ends makes it a bar magnet whose field arcs from one end to the other; center is a single pole the field points into.

target.className

Typestring

LodestoneTarget: classes for the wrapper, an inline-flex div. Hovering or keyboard-focusing it charges the target up; pressing it sends a shockwave.

quiet.className

Typestring

LodestoneQuiet: classes for the wrapper. The field parts around it on a rounded outline and draws nothing under it, so text stays readable.