Every cover here is CSS
Every entry on this site has a small moving picture beside it. None of them is an image. Each is a single <div> with two class names, a recipe and a palette, and the browser paints the rest. Hover over one on the homepage and it holds still.
Ten palettes, named in Hindi
Each palette is four colours, --c1 to --c4. They follow one naming rule: a single Hindi word for something in the world that already has those colours. A pigment, a spice, a material, a sky, a time of day.
geru गेरू
Red ochre, the earth pigment of the first cave paintings.
#e8893a--c1#a8391b--c2#1f2a55--c3#0e1330--c4
Used by: Before History
godhuli गोधूलि
The cow-dust hour: dusk, when cattle walking home raise dust into the low sun.
#eaf4fc--c1#f09199--c2#1e50a2--c3#895b8a--c4
Used by: Jev eval · √2
neel नील
Indigo, the dye.
#c9d6ee--c1#3a5ba0--c2#0f1c3f--c3#1b2437--c4
Used by: Latch
laksha लाक्षा
Lac, the resin behind sealing wax and bangles.
#f2e3cf--c1#c8553d--c2#7a1f1f--c3#3b1d1d--c4
Used by: NDA clause model
haldi हल्दी
Turmeric.
#fff3c4--c1#e3a018--c2#2f6f5e--c3#c9791a--c4
Used by: Interactive lessons · Monty Hall
maidan मैदान
The open ground where the neighbourhood plays cricket.
#d9e4b5--c1#6f9a4b--c2#1d4a2f--c3#2e6b3f--c4
Used by: ALTXI · Simpson’s paradox
lajvard लाजवर्द
Lapis lazuli.
#eaf4fc--c1#7aa0c8--c2#1e50a2--c3#2b3a4f--c4
Used by: Blind spreadsheet benchmark
kagaz काग़ज़
Paper, with its ink and the gold of an old account book.
#fbf7ea--c1#c9a54a--c2#3a3a38--c3#8a7a58--c4
Used by: Brief
nabh नभ
Sky.
#f4f8fb--c1#9cc7e8--c2#2f6fb5--c3#16345c--c4
Used by: The best AI strategy is sometimes no AI
kajal काजल
Kohl, the lamp-black eyeliner (and here, a green terminal).
#d8f5d0--c1#58c27d--c2#1f6b4a--c3#111614--c4
Used by: A typing animation with zero JavaScript
godhuli's four colours aren't mine. They're the "Iridescent cloud" preset from the Gradient Builder (Moon White, Peach Pink, Lapis and Ancient Purple), which is where all of this started.
Eight recipes
A palette says which colours. A recipe says what to do with them.
- Mesh. Three soft
radial-gradientfields over a base colour, blurred. The oldest recipe here, and the one the others grew from. - Aurora. Two elliptical bands of light, cut into rays by two repeating stripe patterns multiplied together with
mask-composite: intersect, so the rays vary in brightness like real curtains. Then blurred, and blended withscreen. - Bars. Six
linear-gradientlayers on one element, each with its ownbackground-size, rising left to right. - Prism. One radial glow, masked into columns of alternating brightness.
- Forms. One circle gradient with a firm edge and a soft halo, set low so only the arc shows.
- Sky. A vertical wash with three white radial clouds.
- Watercolour. A gradient masked by fractal noise: an SVG
feTurbulencefilter embedded as adata:image, turned into soft blotches by a colour matrix. It's a still picture, so it costs nothing to keep on screen. - Swirl. A
conic-gradient, blurred until the seams disappear.
The tricks they share
The recipe draws on an oversized ::before layer, not on the cover itself. Here is the sky, whole:
.cover::before { content: ""; position: absolute; inset: -15%; }
.c-sky::before { inset: -15% -35%; animation: cover-clouds 10s ease-in-out infinite alternate; }
@keyframes cover-clouds { from { transform: translateX(-18%); } to { transform: translateX(18%); } }
- Motion is transform only. Moving a layer, rather than redrawing a gradient, lets the compositor run the animation without repainting. The layer is bigger than the cover so its edge never shows: a layer inset by m can travel about m ÷ (1 + 2*m*) of its own size.
- Sizes scale with the cover. Each cover is a size container (
container-type: inline-size), so blurs and stripes are measured incqiand look the same at 100 pixels wide as at 400. - Colours mix in OKLab.
radial-gradient(… in oklab, …)blends through the colours in between, not through grey. - Grain is one tiny SVG. About 400 bytes of
feTurbulence, laid over every cover withmix-blend-mode: overlay. - Stillness when asked. Hover holds a cover still, and
prefers-reduced-motionstops them all. - No two alike. The build refuses two cards with the same recipe and palette, and says which two.
What didn't work
- The first aurora was a thin striped ribbon along the bottom. It took a much taller band, and two stripe patterns multiplied together, before it read as curtains.
- The first watercolour used the palette's darkest ink and came out as grey camouflage. Pigment wants the lighter colours.
- The first motion was too polite: a few percent over twenty seconds, lost under the blur. It now moves about twice as far in half the time.
- CSS can't warp colour the way a shader does, so Flow, the Gradient Builder's signature look, isn't here. Swirl is the nearest I got.
Credits
- The recipes are inspired by the Gradient Builder at feralui.dev, by Sarthak Navalekar. godhuli's colours are its "Iridescent cloud" preset.
- The CSS, the palettes and this page were made with Claude Opus 5.5 in Claude Code, directed by me.