The colophon, expanded
How this site was made
Everything you just scrolled — the direction, the type, the palette, the 3D, the photograph, the voice, the deploy — was designed and built by Claude (Fable 5) in a single working session, from one written brief. This page is the recipe, so you can do the same.
The brief
The owner of this domain asked for a launch site for Legacy, an iPhone app for recording a loved one’s life story — and for the site itself to be a demonstration of what a frontier model can do with total creative freedom: “high-quality 3D tactics, otherworldly animations, exceptional color, novel type.” The model had access to a terminal, a browser for screenshots, an image/video generation service, a local text-to-speech server, GitHub, and Cloudflare. No human touched a file.
1 · Pick one idea and commit
Generic AI sites happen when nobody decides anything. So the first artifact wasn’t code — it was a sentence:
“The Grooves of a Life: a cinematic descent from parchment daylight into a candlelit family archive, built on concentric rings — tree rings, record grooves, sound waves.”
Every later decision — palette, particle motion, even the pricing section’s tone — had to serve that sentence or get cut. When you replicate this, spend real effort here. One committed idea beats ten tasteful defaults.
2 · A palette with a temperature, not a hue wheel
The site lives between two worlds: parchment (the present) and a warm
near-black archive (memory). Both are tinted toward the same amber hue so
the dissolve between them feels like dusk, not a theme toggle. Tokens are
defined in oklch() so lightness steps are perceptually even —
and contrast stays verifiable.
3 · Type that could not be Inter
Your voice is the heirloom.
Fraunces is a
variable “wonky old-style” serif: at display sizes its optical-size axis
sharpens the contrast, and its hidden WONK axis swaps in
crooked, hand-set letterforms — used sparingly on emotional words.
Body text is Newsreader,
drawn for on-screen editorial reading. Both are self-hosted as variable
woff2 files — four files, every weight and italic, zero
layout shift.
4 · The 3D: 2,400 particles, zero libraries
The animated field behind every section is one <canvas>
and ~150 lines of hand-rolled math. Particles live in polar coordinates;
each “scene” is a small function that maps a particle to a 3D point. The
page’s scroll position blends between scenes, then a shared projection
applies pointer-parallax rotation and a perspective divide:
// rotate about Y by pointer, then perspective-project
const xr = x * cosY + z * sinY;
const zr = -x * sinY + z * cosY;
const s = f / (f + zr); // perspective divide
px = cx + xr * R * s;
py = cy + y * R * s;
Six scenes reuse the same particles: a leaning disc (a record on a turntable), a sagging thread, speaking rings, a live waveform, eight chapter arcs, and rising embers. Because the particles never die — they only re-map — transitions read as one continuous material. That’s the “motion dissolve”: geometry dissolves, the medium persists.
5 · The waveform is real
Press play in the listening room and the Web Audio API drives both the
bar waveform and the background particles: an AnalyserNode
samples the actual audio to 48 log-spaced bins each frame.
const src = actx.createMediaElementSource(audio);
analyser = actx.createAnalyser();
analyser.fftSize = 256;
src.connect(analyser);
analyser.connect(actx.destination);
// each frame: getByteFrequencyData → 48 bins → canvas + particles
6 · The photograph that breathes
“Henry” does not exist. His portrait was generated with Higgsfield’s Soul model (prompted as a 1958 silver-gelatin print, complete with scuffed edges), padded onto a black mat, then handed to Kling 3.0 with a cinemagraph prompt: hold almost perfectly still; blink once; let the light shift; keep the print border frozen. The 5-second loop only loads when you scroll near it, and never plays for visitors who prefer reduced motion.
7 · The voice
Henry’s answer was synthesized with a small local text-to-speech server
(kyutai’s pocket-tts) and converted to AAC with macOS’s built-in
afconvert — no cloud audio API involved. The transcript
brightens word by word, timed against playback.
8 · Restraint is a feature
- Backgrounds never use pure black or white — everything is tinted toward amber.
- Animation touches
transform,opacity, and canvas only; easing is exponential, never bouncy. prefers-reduced-motioncollapses the whole show to a still frame, instantly-visible text, and a poster image.- Text contrast is checked against WCAG 2.2 AA in both worlds.
- No glassmorphism, no gradient text, no icon grids. If a decoration didn’t serve the grooves-of-a-life idea, it didn’t ship.
9 · Three iteration passes
After the first complete build, the model audited its own work three times with a headless browser — screenshotting desktop and mobile at every section, then fixing what it saw: spacing rhythm, contrast failures, orphaned lines, scenes that blended too early. Budget as much time for looking as for building. The gap between “generated” and “designed” is exactly this step.
10 · Ship it
# repo
git init && git add -A && git commit -m "Legacy launch site"
gh repo create legacyrecording-site --public --source=. --push
# deploy (Cloudflare Pages)
npx wrangler pages project create legacyrecording
npx wrangler pages deploy . --project-name=legacyrecording --branch=main
# then attach the custom domain in one API call
Do it yourself
- Write a brief with stakes: audience, tone, and “make it unforgettable.” Grant real creative freedom — and real tools.
- Demand a named design direction in one sentence before any code.
- Have the model generate its own assets: imagery, motion, voice. Everything custom, nothing stock.
- Insist on hand-rolled motion over library defaults — that’s where the signature lives.
- Require iteration passes with screenshots. Three, minimum.
- Let it deploy: GitHub → Cloudflare Pages → custom domain.
Built with Claude Code. Directed by one prompt. Return to the site ↩