KQ-1439 · IRON/SAND

Iron Sand

A background of iron sand on a plate with magnets hidden under it: the grains are laid along the field and each is a short needle on its own angular spring that turns to the field wherever it is strong enough to beat friction, so the sand lines up in flowing lines between the poles and stands up into small tufts of spikes at each one while the magnets wander slowly. The pointer carries a pole (position on the springs.glide constants, presence on springs.drift) and the sand streams after it; a press taps the plate, so every grain hops, lets go of friction and snaps to the field on the springs.recoil constants. Keyboard focus on a control inside carries the pole there and taps from it.

KQ-1439 · IRON/SAND

Fieldline Magnetics

See the field you cannot feel

two poles · 3,500 grains · graphite

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/iron-sand

Props

children
React.ReactNode
default —
The content on top of the plate: a hero line, a heading, a call to action.
grains
number
default 3500
How many grains on a wide card, 300 to 8000; smaller boxes get fewer so the dusting stays even.
strength
number
default 0.6
How strong the field is, 0 to 1: how much of the plate it lines up and how hard the poles pull.
color
"graphite" | "rust" | "cobalt" | string
default "graphite"
The sand's colour: a named one, or any CSS colour.
poles
number
default 2
Magnets under the plate, 0 to 4: one, a dipole, a triangle, a quadrupole.
grainLength
number
default 5
A grain's length, px.
drift
number
default 0.35
How far the hidden magnets wander on their slow paths, 0 (still) to 1.
surface
string
default the page, lifted a breath toward the ink
The plate under the sand.
interactive
boolean
default true
The pointer and keyboard focus carry a pole, and a press taps the plate.
pointerStrength
number
default 0.8
How strong the carried pole is, 0 to 1.
tap
boolean
default true
A press on the plate taps it: the grains hop and settle into cleaner lines.
paused
boolean
default false
Hold the magnets still; the sand still answers the pointer.
seed
number
default 1
Seeds where the magnets sit and how the sand was scattered.
dpr
number
default 2
Cap on the canvas's device pixel ratio, at most 2.
onActiveChange
(active: boolean) => void
default —
Fires when the pointer or keyboard focus picks up (true) or drops (false) the pole.
className
string
default "h-full w-full"
Sizes and shapes the box.