§ Explained — A technical diary
How it was made.
Nine acts, one page, nothing but CSS and a little JavaScript for sprinkling stars. Here is what is happening underneath — scene by scene, technique by technique.
§ 01
Becalmed — A warm horizon
A quiet opener before the storm.
The first scene is a cream-on-cream landscape with a single horizon rule and a
boat no wider than a thumbnail. It is built with a linear gradient,
layered radial glows, and a 1 pixel divider drawn as a
pseudo-element. The boat is a small inline SVG anchored to the horizon with
position: absolute.
The slow sway is a sub-pixel translateY keyframe running at
4 seconds, easing in and out. Nothing fancy — the goal is to feel still without
being actually still. Living rooms are never silent.
§ 02
Storm — Rain, lightning, pressure
A registered property drives the sky's darkness.
Storm is where CSS starts earning its rent. The sky is driven by
@property --storm-darkness, a custom property registered with a
typed syntax so it can be animated smoothly. As the value climbs, a stack of
gradients deepens and a second --rain-density property multiplies
the opacity of the rain layer.
Rain itself is a single repeating-linear-gradient translated at
two speeds, creating parallax for free. Lightning is a pair of SVG bolts with a
brief full-screen flash courtesy of mix-blend-mode: screen.
§ 03
Wave — Liquid displacement
SVG filters applied to HTML.
The wave uses an <feTurbulence> and
<feDisplacementMap> pair defined once in a hidden SVG at the
top of the document, then referenced from CSS with
filter: url(#wave-displace). The turbulence animates its
baseFrequency, which is what makes the text crest and fall as if a
slow tide were moving through it.
This is the cheapest liquid effect you can buy. One filter reference, no canvas, no shaders — the browser is doing the math in its compositor.
§ 04
Break — A hidden starfield
Two hundred stars, six constellations, one discovered ship.
The break slide reads as a single line of centered type over empty dark. Scroll past it, though, and the flashlight cursor reveals roughly 220 procedurally placed stars, labelled Ursa, Lyra, Orion, Corvus, Cygnus, and Draco, four cardinal points, a lunar phase row, a sketched clipper ship and a few shooting stars.
The flashlight itself is a radial-gradient mask driven by CSS
variables the cursor writes (--mx, --my). The stars
are DOM elements the script avoids placing over the centered text — an
exclusion zone — so the headline never fights the dots.
§ 05
Figures in space — 3D without a canvas
Pure transform-style: preserve-3d.
Every solid on this slide — the cube, the torus of blades, the double helix, the
trefoil knot, the tunnel — is made of plain <div>s laid out
with transform: rotateX / rotateY / translateZ. The parent carries
perspective and transform-style: preserve-3d, and the
children orbit through @keyframes.
The blades, rungs, and beads are generated at load by
controller.js, which does nothing more than stamp N children with
a calculated transform. The motion is entirely CSS — the script
never runs again after the initial build.
§ 06
Geometry — A grid with memory
Sixty-four tiles, one hover.
A display: grid of 64 tiles, each with a
transition on transform and
background-color. On pointer move, the act writes
--px and --py; each tile computes its distance from
the pointer with calc() and a squared
pow() — no per-tile JS, just math in the style engine.
§ 07
Kinetic — Marching type
Two lines, opposite directions, a seam of light.
The kinetic band is a single line of type duplicated and animated in opposite
directions via translateX. A gradient mask fades the edges so the
seam never reveals itself. The glow across the center is a
background-clip: text trick — a moving linear gradient
painted into the glyphs rather than behind them.
§ 08
Goo — Blobs that know each other
A classic feGaussianBlur + threshold.
The goo filter is an old favourite: blur the group, then clamp the alpha
channel with a steep feColorMatrix. Any two circles close enough
to overlap in the blur will merge. Move them apart and they snap into separate
drops. The circles are divs with border-radius: 50% tumbling on
their own keyframes.
§ 09
Calm — Still water, still space
A mirrored horizon, a breathing moon, rings that never move.
The final act is a reflection. The sky holds a starfield drawn as a stack of
single-pixel radial-gradients; the space shapes — three
concentric rings around the moon, two tilted planetary ellipses, two tiny
planets — are intentionally motionless. Stillness given a shape.
Below the horizon line, a darker gradient carries a vertical column of
moonlight, three horizontal shimmer bands, and six expanding ripples
capped at a modest scale. The headline beneath is duplicated, flipped with
transform: scaleY(-1), blurred, and faded toward its
bottom with mask-image — a live reflection in the
water plane, drifting every six seconds with a sub-degree skew.
§ Notes
A few principles
One page, one cascade. Every scene loads from the same set of
stylesheets. Tokens — colour, type, easing — live in
colors_and_type.css and are consumed everywhere else.
Motion with a brake. Every animated block respects
prefers-reduced-motion. The showcase still reads as a showcase
with animations off — just quieter.
No shortcuts for typography. Fraunces handles the display work with its optical size axis pinned to 144 at hero scale. Inter carries the body. JetBrains Mono marks the edges — section numbers, tags, footers.
Nothing is a screenshot. Every pixel you see is computed. Resize, zoom, swap to dark mode, print it — it composes.