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