Most front-end devs stop at the CSS transition.
Four running pieces. Open any of them — nothing here is a recording.
Curl-noise fluid
Dye advected through a divergence-free velocity field, ping-ponged between two framebuffers each frame. Flows like a fluid without ever solving for pressure. WebGL2
Scroll-driven corridor
An infinite raymarched corridor whose camera is your scrollbar. Lenis, the GSAP ticker and the shader all read from one clock. WebGL2 · GSAP
Kinetic typography
Mask reveals clipped by real overflow, characters decoding out of noise, and difference-blend inversion across four panels. No WebGL, no library
Spring particles
Thousands of damped springs anchored to pixels sampled from rendered text, scattered by an inverse-square cursor force. Typed arrays · canvas
Production work, hand-coded, no page builder.
Scroll-driven paint & live recolour
Two Three.js scenes driven off the GSAP ticker rather than their own rAF loop, so they stay in phase with Lenis and ScrollTrigger. Paint floods over the hero as it scrolls away; a real surface recolours live when the visitor picks a colour. Both fall back to the underlying image until a frame draws.
Kinetic loader & fold-behind scroll
Six-page static build. Kinetic-type loading sequence, a hero that pins while the next panel rises to cover it, one shared canvas and nav layer across every page.
Zero-build client site
Live on a custom domain. Canvas hero, booking flow, shipped as a single self-contained document — no build step and no dependency left to rot.