← Back to the site

How this site was built

One self-contained HTML file. No framework, no animation library, no stock imagery. The background is a real physics simulation you can push around with your cursor.

Design & build: Claude (Opus 5) · Commissioned by Zayaneflow

The background is a simulation, not a video

Most "particle backgrounds" are a looping video or a few hundred CPU-animated dots. This is neither. Particle position and velocity live in floating-point textures on the GPU. Every frame, a simulation shader reads the current state, applies forces, and writes the next state to a second texture — then the two swap. That technique is called ping-pong framebuffering, and it is what makes tens of thousands of independently-simulated particles affordable at 60fps.

A separate render pass draws each texel of that texture as a point. The particles you see are the literal contents of GPU memory, one frame old.

Three forces act on every particle

Move the cursor quickly and a fourth term kicks in: particles are dragged along your direction of travel. That term is gated on pointer speed, so a resting cursor only repels — an early version pulled particles toward the pointer whenever it stopped, which looked like a bug because it was one.

Why no imagery

An earlier version of this site used AI-generated photographic backdrops. They were beautiful individually and wrong together — you could see the seams between them, because they were separate photographs stitched into one page. Everything here is drawn instead: the particle field, the hairline rules, the timeline beam. One coherent world, no joins.

Restraint as the brief

The palette is deliberately narrow: near-black ground, warm off-white text, and a single cold blue accent used sparingly. Type is Inter for text with Instrument Serif italic carrying the emphasis — the contrast between a neutral grotesque and a high-contrast serif does the expressive work, so nothing else has to shout.

The particles are tuned to near-invisibility at rest. They brighten only where they are moving. The field should read as a material the page sits on, not as a light show.

Performance, measured rather than assumed

CheckResult
Lighthouse, 4× throttled mobile100 / 100 / 100 / 100, 45 passed, 0 failed
Page weight94 KB
External dependencies0
Languages, all inline4

Particle density is derived from viewport area rather than fixed, so a phone gets far fewer particles than a desktop and the perceived density stays constant. A fixed count packed into a narrow screen turned atmosphere into noise.

What happens when things are unavailable

Native scroll is never hijacked, so keyboard navigation, anchor links and find-in-page all behave normally.

Four languages, and the detail most sites miss

English, French, Spanish and German ship in the same file. Number formatting follows the locale: $23,045 becomes 23 045 $ in French and 23.045 $ in German — separator and symbol placement both change. $1.8B keeps its symbol leading everywhere, because the magnitude letter has to stay attached to the digits.

A note on the numbers. $23,045 is revenue from Zayaneflow's own e-commerce brand. $1.8B is Holtzbrinck's scale as a publishing group — not money produced for them. 101K is a creator's audience size, not a result. Those distinctions are encoded in the content layer so they cannot drift as the copy changes.

Built with Claude Code · hand-written GLSL · no libraries · back to the site