A gallery where the art is the code — literally
STRATA is an online gallery selling one-of-one generative artworks, and the site takes its own premise seriously: it loads no image files at all. The six works are six seeded algorithms executed live in canvas the moment you scroll to them, each visit hanging a set of states no one has seen before. The design around them is deliberately museum-quiet — white walls, small grey labels, one red dot — so the code-made color is the only color.
No image model was used anywhere on this site. Every visual is a program.
Palette
The site's own palette is a gallery, not a brand: lit wall, ink, label grey, hairline, and the one convention every collector recognises — the red dot that means sold. All other color arrives with the works, from palettes carried inside each algorithm and chosen by the seed.
#F6F6F3 lit from above via a fixed gradient#1B1B19 titles, prices, the wordmark#6B6B66 wall text and captions#DEDEDA room dividers#C22F2A acquired works onlyType
Display — used for exactly one word on the whole site: the gallery's name. Syne was designed for the Synesthésie art centre outside Paris, which makes it the rare display face with an actual gallery pedigree. Spending it on a single word keeps it powerful.
Wall labels and body — neutral without being characterless, the register of a museum caption card. It never competes with the works.
Data — seeds, room numbers, the visit line. Seeds are typeset like edition numbers because that is exactly what they are.
Techniques — how the signature works
1 · One seed, one artwork, forever
Every work starts from a 32-bit seed fed into a mulberry32 PRNG. Same seed, same artwork, down to the pixel — which is what makes "edition of one" an honest claim rather than a metaphor. The seed on each label is the work's identity:
function mulberry32(a) {
return function () {
a |= 0; a = (a + 0x6D2B79F5) | 0;
let t = Math.imul(a ^ (a >>> 15), 1 | a);
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}
Available works draw a fresh seed per visit. Acquired works carry a data-frozen attribute with a fixed hex seed — the state their buyer bought — so the red-dot pieces genuinely never change. Structure encoding truth.
2 · Six algorithms, not six variations
- Meander — 1,400 particles tracing a seeded Perlin flow field, stroke width and palette weighted by the PRNG.
- Interference — 62 ridge lines displaced by gaussian bumps, drawn back-to-front with background fills so each ridge occludes the last; stroke color heats toward an accent with displacement.
- Core Sample — strata deposited layer by layer, boundary polylines roughened by fbm noise with amplitude growing with depth, plus at most one sigmoid fault that shears every layer at once.
- Isobar — a true marching-squares contour tracer over a scalar field of noise plus radial wells; 19 levels, one always in color.
- Weft — a 6×6 Truchet grid recursively subdivided to depth 3, quarter-circle arcs whose endpoints always meet at tile midpoints, so the line never breaks across scales.
- Colony — rejection-sampled circle packing on a six-tier radius schedule, big settlers first.
3 · Progressive rendering with generators
Each algorithm is a generator function that yields every few dozen strokes. A driver runs it in ~9 ms slices per animation frame, so you watch the work being performed instead of receiving it — and reduced-motion visitors get the finished state instantly:
function frame() {
const t0 = performance.now();
let r;
do { r = gen.next(); }
while (!r.done && performance.now() - t0 < budget);
if (!r.done) requestAnimationFrame(frame);
}
Works render when they approach the viewport (IntersectionObserver), redraw deterministically from the same seed on resize, and "Hang another state" simply swaps the seed and performs again.
The three passes
- Pass 1 · correctness + composition Found the wall labels showing placeholder dots instead of seeds — the label lived outside the figure the script searched, so every lookup was scoped to the hanging instead. Fixed a mobile horizontal overflow caused by the Syne wordmark (its caps run ~1.15em wide), closed a background gap the fault left at the bottom of Core Sample, and added a settle-render so works far below the fold are never a blank wall for deep links and printouts.
- Pass 2 · elevate Added the pencil-signed edition plate in each mat — 1/1, title, seed — the printmaking convention, kept in sync when a new state is hung. Gave Meander a second stroke tier (a few long bold wanderers over 1,400 fine ones) so states have hierarchy instead of texture, thickened Isobar’s accent contour until it reads as a decision, enlarged the room titles, and made the restate button announce “hanging a new state…” while the work redraws.
- Pass 3 · taste The Chanel pass. Removed the rust accent line from the hero backdrop so red now appears in exactly one place on the site — the sold dot — and deleted a track-light glow that read as an ambiguous wash over the art. Then verified behaviour in a scripted browser: restate swaps label and plate seeds together, acquired works hold their frozen seeds, and reduced-motion visitors get every finished work instantly.
Do this yourself
A recipe for building a site of this kind with Claude:
- Pick a subject where code is the honest medium — generative art, data, simulation — so "no images" becomes a flex, not a constraint.
- Write the design system before any markup: 4–6 named hex values, three type roles, and one signature element that carries all the boldness.
- Ask for seeded randomness (mulberry32 or similar) from the start. Determinism is what turns "random art" into "edition of one".
- Demand genuinely different algorithms, not one algorithm with different palettes — flow field, marching squares, and circle packing share no code.
- Make the interface tell the truth: if a work is sold, freeze its seed; if a state is unique to a visit, show the number that proves it.
- Render progressively with generator functions so the drawing is a performance, and collapse to instant rendering under
prefers-reduced-motion. - Screenshot at 1440 and 390, critique what you actually see, and iterate three times. Remove one accessory before you ship.