How this site was made
A guide to the stack, the techniques, and the deployment — so you can build your own dark room.
Atelier Umbra is a single HTML file. No framework, no build step, no bundler. Everything — markup, styles, shader, cursor — travels together, which is fitting for a studio that only makes one print.
The key light
The hero is a full-screen WebGL fragment shader drawn on one triangle. The
wall is five octaves of value-noise FBM composited at three scales (plaster, texture, tooth).
The light that follows your cursor is a Gaussian falloff exp(-d²·3.2) tinted warm
(≈2800K), with drifting dust motes hashed per grid cell and only visible inside the beam.
Cursor position is eased with p += (target−p)·0.055 so the lamp has weight.
The headline is lit by the same lamp: a duplicate layer of the title is masked with a CSS
radial-gradient whose center is driven by the same eased coordinates via custom
properties (--lx, --ly). One light source, two rendering systems.
The light-meter cursor
On fine pointers, the native cursor is replaced by a dot and a trailing ring that reads like
a light meter: each section carries a data-f aperture value, and the ring's label
updates as you cross into it — wide open at the dark hero (f/1.4), stopped down by the footer
(f/11). On touch devices the cursor vanishes and the key light drifts on a slow Lissajous path
instead.
Typography & palette
- Italiana for display — an engraver's roman with hairline stress, set huge and lit like an object.
- Figtree (300–500) for text — quiet, warm, and invisible on purpose.
- Palette: carbon
#0A0908, bone#E8E2D6, brass#A98E63, and one drop of oxblood#6E1423kept for the darkest corners.
Image slots
Every portrait is a real <img> with a stable, descriptive filename
(assets/noir-portrait-01.jpg …). The files currently hold rendered gradient
stand-ins — layered radial glows, vignette and grain — so the design reads correctly today and
the real photography can be dropped in later without touching a line of code. Portraits rest at
brightness(0.52) and are lit to full only under your hover, like prints under a
viewing lamp.
Access & restraint
prefers-reduced-motion stills the reveals, the scroll cue, and slows the light
to a candle's pace. The shader pauses entirely when the hero leaves the viewport. The whole
site ships under 40 KB of code plus seven placeholder frames.
Deployment
Deployed to Cloudflare Pages as a static folder — no build configuration at all:
npx wrangler pages deploy set1-a --project-name=set1-a
Wrangler creates the project on first deploy and returns the live URL. Three
self-critique passes (desktop and mobile screenshots at five scroll depths) were run before
shipping; the changes are logged in the repository's NOTES.md.
Designed and built end-to-end by Claude Fable 5.