KQ-1249 · FERRO/POOL

Ferro Pool

A canvas backdrop of a ferrofluid pool seen at a low angle — glossy near-black at the front, reflecting more of the room toward the back, with a softbox lying on it as a long soft band. The pointer is a magnet: its footprint is found through the same perspective that draws the pool, every site of a jittered hexagonal lattice feels its field, and above a threshold each rises into a spike on its own underdamped spring, so the crown jiggles up, leans along the field lines toward the magnet, stands on a mound that bulges beneath it and sinks back with a wobble when the magnet leaves, every spike shaded by a lit flank, a specular line and a rim on the side the slowly drifting light comes from. A click pulses the field — it surges and a ring runs out across the pool kicking every spike it passes — and the keyboard path is a role="application" surface where focus brings the magnet in, arrow keys move it and Enter or Space pulse.

KQ-1249 · FERRO/POOL

Basinworks field notes

Magnetic fluids, issue 12

Arrow keys move a magnet over the pool, Shift for larger steps; the fluid rises into spikes beneath it. Enter or Space pulses the field.

pool at rest · hover, then click to pulse

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/ferro-pool

Props

strength
number
default 0.6
The magnet, 0 to 1: how far its field reaches across the pool, how tall the spikes grow and how far they lean toward it. On a resting pool a change holds the magnet over the middle for a moment, so the new crown shows.
spikes
number
default 16
Spikes across the pool's front edge, 8 to 32: a few tall cones or a dense bristle. The lattice is seeded, so it is the same pool every time. On a resting pool a change shows itself the same way.
sheen
number
default 0.6
How much the fluid shines, 0 to 1: the lit flanks, specular lines, rims and the softbox's reflection. 0 is matte ink, and a matte pool stops drawing once it is flat.
label
string
default "Ferrofluid pool"
The accessible name of the keyboard surface.
onPulse
() => void
default —
A click, a tap, Enter or Space pulsed the field.
disabled
boolean
default false
Ambient only: the pool ignores the pointer and the keyboard and leaves the tab order.
children
React.ReactNode
default —
What sits over the pool — a hero, a heading — in a layer above it. Presses on its own controls never pulse the field.
className
string
default —
Classes for the root, which fills its container (h-full w-full); set its size and radius here.