process notes how this site was made
A page that cools like glass:
from furnace to cold shop.
Vitrea sells two things — vessels to collectors and bench time to students — and both start with fire. So the site is structured as an annealing schedule: it opens white-hot with a molten-gather film and literally cools as you scroll, ending in gallery white. A falling temperature ticker keeps score the whole way down.
Palette — a heat ramp, read top to bottom
The colours aren’t a moodboard; they’re a sequence. Each one is anchored to a real section, measured at load, and painted into one document-length gradient — so wherever you are, the background is somewhere on the cooling curve.
Type — soft terminals, like glass off the pipe
Fraunces, with its variable SOFT axis pushed to 100 and optical size at display maximum. The terminals round off like a gather that hasn’t set — the only typeface on Google Fonts whose letterforms can literally melt. The hero uses a 1.6 KB instanced subset of just the six masthead glyphs.
Archivo carries the body like a shop manual, and Spline Sans Mono does every annotation as a batch ticket — dashed borders, tabular numbers, kiln-log capitals. Structure that encodes how a hot shop actually labels things.
The signature: heat-shimmer over the masthead
The word Vitrea is drawn to an offscreen canvas, uploaded as a WebGL texture, and re-sampled every frame through two octaves of value noise that scroll upward — the same refraction you see across a glory hole’s mouth. Displacement is stronger at the bottom of the frame, where the heat would be. A slight chromatic split on the alpha channel makes the edges bleed like hot glass.
float n1 = noise(vec2(v.x*5., v.y*9. + t*1.7)); // slow rising wave float n2 = noise(vec2(v.x*13., v.y*24. + t*3.4)); // fast flicker float amp = .011 * (1. - v.y*.55); // more heat lower down vec2 d = vec2((n1-.5)*.72 + (n2-.5)*.28, (n2-.5)*.6) * amp; float a = texture2D(uText, v + d).a; // shimmered glyphs
Under prefers-reduced-motion the canvas never starts and a plain HTML <h1> — same face, same glow — stands in. The hero film is a six-second silent loop, graded into the palette with a CSS gradient overlay.
video: Higgsfield Seedance 2.0 · stills: gpt-image-2 · everything else drawn in code
The cooling scroll, the ticker, the breath
Colour stops are anchored to real sections, not magic numbers — each stop is measured from its element at load and on resize, then painted into a single document-length gradient. On scroll, the same stops are re-sampled: the masthead reads the colour under itself, the ticker reads mid-viewport, and each flips to ink independently when its luminance crosses 0.5.
{ sel:'#forms', at:.45, color:'#0e211d', temp:700, stage:'the breath' },
{ sel:'#anneal', at:.06, color:'#d9e8e3', temp:510, stage:'anneal — soak' },
// same stops paint the document gradient AND the falling °C ticker
The three Undertow silhouettes inflate as you pass — each is one SVG path with a data-from (rod) and data-to (vessel) of identical command structure, so a scroll-scrubbed lerp of the 42 coordinates is a breath. The annealing chart is generated from the studio’s actual 96-hour schedule and draws itself with a dash-offset transition, orange fading to aquamarine along its own gradient.
Three passes at the bench
- Pass 1 — correctness & compositionThe cooling was a single scroll-driven background colour, so any tall view showed ink text on dark — replaced it with a document-anchored gradient measured from the sections. Pinned the ticker to 1120 °C at the top, made photo reveals clip-path-only so nothing leaves holes, set the tool glossary to five true columns, and calmed the mobile hero.
- Pass 2 — elevateGave the ticker its own mid-viewport luminance sample so it flips to ink independently of the masthead; turned the anneal curve into a scroll-scrubbed draw with a furnace-orange “now” marker riding the schedule; added the ledger-numeral aqua glow on hover; loaded both photographs eagerly so no capture ever misses them.
- Pass 3 — tasteChanel rule: deleted the scroll cue — the falling ticker already says “descend.” Reduced motion now also pauses the hero film to its poster frame; the guide’s crossing zone was tightened and its dark cards given their own background so the fade can never wash their text.
Do this yourself — the recipe
- Find the subject’s one true physical process and make it the page structure. Glass anneals from 1120 °C to room temperature — so the page does too. Don’t decorate with the metaphor; architect with it.
- Give Claude the physics, ask for choreography. “Anchor colour stops to sections, lerp RGB on scroll, flip themes on computed luminance” gets you a system, not a gradient.
- Let one element carry the fire. Here it’s a WebGL noise-displaced masthead. Ask for a fragment shader with two noise octaves and amplitude shaped by position — 40 lines, no library.
- Bake your display type. If a variable font has a personality axis (Fraunces’ SOFT), request an instanced subset of only the glyphs you need and register it with the FontFace API for canvas use.
- Make annotations structural. Pick the subject’s native paperwork — batch tickets, kiln logs, ledgers — and use it for captions, tables, and metadata instead of generic cards.
- Animate with data, not flourish. The chart is the real annealing schedule; the silhouettes are real vessel profiles interpolated point-by-point. Ask Claude to keep both endpoints of any morph structurally identical.
- Screenshot, critique, repeat — three times. Read your own screenshots at desktop and 390 px like a hostile art director. Each pass must remove something as well as add something.
- Test the calm path. Reduced motion should feel designed: poster frame instead of film, finished forms instead of morphs, the same palette standing still.