NODAL guide

How it was made

Sound, drawn in sand

Nodal is a fictional study bench — Chladni plate no.7 — that renders a thing you normally only hear. A steel plate is driven from beneath at a chosen pitch; sand scattered on top flees the shaking antinodes and piles onto the nodal lines that stand perfectly still, drawing the shape of the standing wave. Its single job: let a visitor see a pitch and watch the figure re-form when they change it.

The signature: pitch you can see

The plate is a full-canvas square driven from its centre. Roughly thirteen thousand sand grains live in normalised plate coordinates. Each frame, every grain samples the local amplitude of the plate's standing wave and hops a random step in proportion to how hard that spot is shaking. Where the amplitude falls to zero — the nodal lines — the grains simply stop, because there is nothing left to throw them. Thousands of grains running out of anywhere to fall is the figure.

The wave itself is the classic square-plate model, the antisymmetric combination cos(nπx)cos(mπy) − cos(mπx)cos(nπy). A frequency dial picks the driving pitch; the nearest resonant mode (m, n) sets the field. Cross a resonance and the plate locks; between resonances a rising agitation floor keeps every grain bouncing, so the sand scatters into static — honestly, only certain notes hold a figure. Change the pitch and the old nodes become antinodes: the sand is flung loose and a new drawing settles out of the noise. A short excitation burst on every change makes the leap visible.

Live: the plate cycling m1·n3 → m3·n4 → m3·n7, the sand re-forming each time.

Palette — argued from steel and sand

A dark instrument bench, one warm material, one cool signal. Nothing decorative: the bright accent is reserved for the node glow and marks, and body text runs on a derived light steel-ink that clears 4.5:1 on the graphite ground.

Plate graphite
#14161A
The cold-rolled steel seen top-down under low light. The ground everything sits on.
Sand · line / mark
#D9C9A3
Fine dry sand. Used for grains, wordmark accents and rules — not for small body copy.
Node glow
#7CC8D6
The cool sheen along the still nodal lines and the centre driver. Accent and glow only.
Steel-ink · body
#C2CAD4
Derived light steel for copy — ≈10.5:1 on the graphite ground. The legible voice.

Type

Fraunces
Nodal — sound, drawn in sand
Display. A high-contrast serif with a soft optical warmth; the italic carries the romance of a 1787 physics demonstration without tipping into cream-and-terracotta cliché.
IBM Plex Mono
418 Hz · G♯4 · mode m3·n4 · LOCKED
Readouts and body. The instrument voice — the plate is a lab bench, so every number is monospaced and reads like a meter.

Techniques

Iteration log

Pass 1 · Craft

Density, crispness, and a broken mobile header

The first settled figure read thin — nodal lines were faint and a little fuzzy. Raised the grain count to ~13k, lowered the base jitter and strengthened the uphill-move rejection so settled grains stay put and the lines sharpen. At 375px the top nav overflowed to 399px (the four links plus the wordmark ran off-edge — exactly the LEARNINGS masking trap). Fixed by hiding the two in-page anchor links below 640px and dropping the wordmark suffix below 400px. Tightened hero spacing and shrank the plate to 60vh so more of the figure clears the fold.

Pass 2 · Depth

Node glow, a nearest-note readout, and strike-to-reset

Pushed the additive node-glow up so the still lines carry a faint cool sheen — the sand on the nodes now looks lit, which is the whole point. Added a nearest-note field to the readout (418 Hz → G♯4): the second-read detail that ties pitch to what you'd hear. Added a micro-interaction — clicking the plate strikes it, re-scattering the sand so it re-settles, the way tapping a real plate does.

Pass 3 · Hardening

Reduced motion, focus, and driving the signature under test

Confirmed the reduced-motion path: JS runs ~620 pre-settle steps, paints one static figure and never starts the loop — a settled plate, not a blank one — verified by two identical frames 1.4s apart. Capped DPR at 2, sized to container, re-derived pixel positions on resize (grains live in normalised coordinates, so resize needs no reset), and paused the rAF loop on document.hidden. Every pass drove the real signature in headless Chrome: programmatically sweeping 418 → 968 Hz and asserting the screenshot hash changed as the sand migrated to the new mode's nodal lines. Zero console errors; 375 / 768 / 1440 clean.

← Back to the plate  ·  All of the Generative Assets collection