Personal Project · Not Client Work Creative Coding · WebGL Designer · Builder

Tidepool: your listening history as a living organism.

I wanted to turn my listening history into somewhere I could go, not another report to scroll. The picture in my head was a living organism shaped like a galaxy: every artist you’ve ever played as a liquid-chrome blob you can fly through and dive into, grouped by the stretch of life you played them in, with the numbers behind it one tab away.

RoleDesign direction, product thinking, builder
Built withClaude Code · Claude
StackVite · React · TypeScript · raw WebGL · Web Worker
StatusIn progress · running prototype
Open the live site ↗
tidepool · live demo
Live and interactive · drag to pan, scroll to zoom, click a blob to dive in
§01What it is

A galaxy you dive into, not a slideshow you watch.

Tidepool is a cluster of connected, liquid-chrome blobs. Each blob holds the artists you played around the same time, and they’re joined by liquid bridges into one living organism. Scroll or pinch into a blob and it turns to glass: its top artists surface with generous spacing, and more appear as you lean in. Songs orbit inside each artist. Tap one and it plays.

The moves are simple: pick a blob, pick an artist, then tap a song. That last tap pops open a card with the song’s play and skip counts and a Spotify embed, so you can hear a preview right there without leaving the galaxy. Everything else is just scrolling and zooming through your own history.

The shape of it is your data.

How many blobs there are, where they sit, how big they are, and the colors running through them all come from one person’s listening. Nobody else’s Tidepool looks like yours, because nobody else listened the way you did.

The same organism, on your phone.

The layout reflows for touch: the detail card sits along the bottom edge, and when you tap a song the Spotify-style player slides in over it, so one thumb can move through the whole thing.

Everything is the same engine and the same data, just a narrower frame deciding how much surfaces at once.

Live · mobile layout, running the same demo
§02The idea

It started as a picture in my head: a living organism, shaped like a galaxy, made of my music.

I kept imagining something you could fly through and explore, the way you move through a world in a game or across a map of a galaxy, except every star is an artist you actually listened to. Not a set of stats to read once, but a place that felt alive and specific to you, that you could wander back into any time.

Time, without a timeline.

Artists are grouped by when you played them, so the stuff from the same chapter of your life sits together and 2015 isn’t next to 2026. But it’s deliberately not a rigid year-by-year timeline or a scrubber. Time quietly decides placement; it never becomes the interface.

§03How it’s built

I set the direction and made the calls; the implementation was done with Claude Code.

I made every design, product, and interaction decision, set the aesthetic, and signed off on every change; the code itself was written with Claude Code. That’s how I work across this whole site, which I go into on my AI & this site page. I’m a designer who can read and reason about code, not a frontend engineer, and that split is exactly what let me ship something this ambitious while keeping full control over how it looks and feels.

Pipeline All in the browser

The Spotify export is parsed in a Web Worker with interned ids and typed arrays, so a 334,000-play, 6,300-artist history processes in a couple of seconds. Nothing is uploaded.

Layout Grouped, then placed

Weighted k-means clusters artists by a time centroid into blobs, a low-discrepancy sequence plus a relaxation pass places them so nothing ever overlaps, and nearby blobs are joined with liquid bridges.

Rendering One chrome shader

A single full-screen WebGL metaball shader does the liquid-chrome look; a points pass draws the crowd. Progressive reveal shows about one artist per 85×85px, so thousands never clutter the screen.

§04Design decisions

A handful of choices that kept it feeling like one thing.

Chrome only.

Every blob, every bridge between them, and every droplet inside is the same material: liquid chrome with thin-film iridescence. No flat cards, no dashboard chrome, no alternate “styles.” Because the blobs all share one surface, the galaxy reads as a single living organism instead of a UI.

Blobs, not eras.

Early versions labeled chapters as named “eras,” and it always felt forced and generic. The blobs are the eras now, identified by the music actually inside them, not by a made-up label.

Reveal by zooming.

You see a blob’s headliners first; the rest surface as you move closer. Dumping six thousand dots on screen at once would be noise, so the view only ever shows what you can actually read.

It’s always moving.

The surface breathes, blobs drift, bridges pulse. A static version felt dead; motion is what makes it feel alive, with a reduced-motion setting for anyone who wants it still.

§05The Insights page

The numbers behind the blobs, drawn to feel native, not like analytics.

A second view trades the galaxy for the data, but refuses to look like a dashboard. Every chart borrows from the blob world: a centered streamgraph of hours per blob, your day drawn as one bright radial blob, three glass vials for how you listen, and your top artists packed as chrome droplets. The frame below is the real page, scroll inside it.

tidepool · insights
Live · the real Insights page, scroll inside the frame to explore it
§06Reflection & next steps

Setting the direction and letting AI handle the mechanics.

Most of the hard work on Tidepool wasn’t writing the code, it was the judgment calls: what the thing should feel like, when something looked cheap or generic, how much to show, when to stop. Building it with Claude Code let me move fast on the mechanics and spend my time on the part that’s genuinely hard to automate, taste.

It’s still in progress, and that’s the honest state of it. But it already does the thing I set out to make: turn a decade of listening into something you can actually fall into, that feels like yours.

What’s next: naming the blobs from the data itself.

The piece I most want to crack is giving each blob a custom, unique name generated from your own listening, not a template with your numbers dropped in. The plan is a small LLM step that reads what’s actually inside a blob, the artists, the songs, how the taste shifts across that stretch, how heavily it leans on one sound, and writes a short, personal title just for it. Something that could land as “2016 road trip favorites” for one person and a gentle roast like “this much Drake???” for another. The hard requirement is that it stays bespoke: every blob named for what it holds, so no two people, and no two blobs, ever read the same.

Explore Tidepool live ↗