STRATA
Guide · how this site was built

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.

Wall#F6F6F3 lit from above via a fixed gradient
Ink#1B1B19 titles, prices, the wordmark
Label grey#6B6B66 wall text and captions
Hairline#DEDEDA room dividers
Red dot#C22F2A acquired works only

Type

Syne 800

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.

Instrument Sans

Wall labels and body — neutral without being characterless, the register of a museum caption card. It never competes with the works.

Spline Sans Mono · State 7F3A-19C2

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

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

  1. 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.
  2. 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.
  3. 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:

  1. Pick a subject where code is the honest medium — generative art, data, simulation — so "no images" becomes a flex, not a constraint.
  2. Write the design system before any markup: 4–6 named hex values, three type roles, and one signature element that carries all the boldness.
  3. Ask for seeded randomness (mulberry32 or similar) from the start. Determinism is what turns "random art" into "edition of one".
  4. Demand genuinely different algorithms, not one algorithm with different palettes — flow field, marching squares, and circle packing share no code.
  5. 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.
  6. Render progressively with generator functions so the drawing is a performance, and collapse to instant rendering under prefers-reduced-motion.
  7. Screenshot at 1440 and 390, critique what you actually see, and iterate three times. Remove one accessory before you ship.