VOIDLINE
← Back to the film

Design guide

How this site was designed and built — the concept, the palette, the shader that draws every frame, and the three passes that shaped it.

01 — Concept & art direction

VOIDLINE is a promo site for a fictional sci-fi epic set beyond the heliopause — the real boundary, about 121 AU out, where the solar wind stops and interstellar space begins. The page is structured as a descent: three acts at increasing distances from the sun, measured by a live AU counter in the HUD, ending in a credits sequence.

The rule that shaped everything: no photography. Every visual on the page — the nebula, the ember, the drifting dust — is computed live by a custom GLSL shader. Dread and awe, drawn by math.

02 — Palette & type

Void black#04060A
Dying-star ember#C1502E
Pale plasma#A7D8DF
Bone white#E9E4D8

Black carries the page; plasma cyan marks the sun’s side of the line, ember marks what lies past it. The HUD signal readout flips from plasma to ember exactly at 121.7 AU.

Syncopate — the last light

Display. Ultra-wide caps with title-sequence DNA — tracked out to 0.3em it reads like the opening titles of a 70mm print.

Instrument Sans — the heliopause is not a wall. It is a held breath.

Body. A quiet grotesk that stays out of the shader’s way and keeps long prose legible on pure black.

IBM Plex Mono — 121.7 AU · carrier lost

Telemetry. Every number, label and log entry on the page speaks in the ship’s instrument voice.

03 — The signature: a scroll-deepened nebula

One fixed WebGL canvas sits behind the whole page. A fullscreen quad runs a fragment shader built on double domain-warped fbm noise — noise fed through itself twice, which turns flat clouds into folded gas:

// gas, not a starfield: warp the noise field with itself, twice
vec2 q = vec2(fbm(p + t), fbm(p + vec2(5.2, 1.3) - t * 0.7));
vec2 r = vec2(fbm(p + 2.2 * q + vec2(1.7, 9.2) + t * 0.4),
              fbm(p + 2.4 * q + vec2(8.3, 2.8) - t * 0.3));
float f = fbm(p + 2.6 * r);

Scroll position is fed in as a uniform, eased in JavaScript so the descent feels like mass, not a scrollbar. Depth does real work in the shader: filaments thin, the ember wakes, the gas red-shifts, the vignette closes in, the stars fade behind you.

// scroll drives the descent
uniforms.uScroll.value += (scrollTarget - uniforms.uScroll.value) * 0.06;

// …and in GLSL, depth rewrites the scene
float fil   = smoothstep(0.40, 0.80, f) * (0.55 - 0.33 * depth);
float ember = exp(-d * d * 5.5) * (0.34 + 0.95 * depth);
col = mix(col, redShift(col), depth * 0.34);

A second draw call renders 420 additive dust points in clip space; they drift with time, sink with scroll, and tint from plasma to ember as the depth uniform climbs. The pointer is lerped at 4% per frame into a parallax offset — the void notices you, slowly.

With reduced motion enabled, the loop never starts: the shader renders one still frame and re-renders only on scroll, so the page stays calm but never goes blank.

04 — Three passes

  1. Correctness & composition. The 390px viewport had horizontal overflow: the tracked-out title spilled past both edges, so the mobile type scale got its own tuning (1.85rem, 0.22em tracking). Fixed a swallowed sentence space in the tagline, rebalanced the hero’s mono metadata, and hardened the scroll reveals so copy shows the moment a section approaches.
  2. Elevate. Gave the shader its thesis: past ~50% depth a razor-thin horizon — the voidline itself — surfaces across the nebula and heats from plasma to ember. Tightened the ember’s falloff so it burns instead of washing the frame. Added the micro-interaction: the recovered flight log types itself out with an uneven, instrument-like cadence when it enters the viewport.
  3. Taste. Chanel rule on mobile: the giant ghost numerals crowded the prose on phones, so below 560px the rail ticks alone carry the depth. Re-anchored those ticks so the marker sits exactly on the rail with its label reading right. Re-verified reduced motion (a still frame that answers only to scroll) and zero console errors on both pages.

05 — Do this yourself

  1. Give Claude a subject with a real physical structure — here, distance from the sun — and ask for a page whose scroll is that structure, not just sections in a row.
  2. Ban the easy asset. “No photography, no stock, no images — draw everything in a shader” forces a signature instead of a hero image.
  3. Fix a four-color palette and name the colors after things in the subject’s world (void, ember, plasma, bone). Named colors get used with intent.
  4. Pick one display face that carries the whole personality — then use it rarely: title, act titles, credits. Let a quiet grotesk do the reading.
  5. Ask for one uniform that does real work: pipe scroll progress into the shader and have it change at least four things (density, color, vignette, particles).
  6. Make the chrome diegetic. The HUD counter, the carrier status, the flight log — every interface element should belong to the fiction.
  7. Iterate in three passes with screenshots: fix composition first, then complexify the signature, then remove one accessory and test mobile + reduced motion.

Voidline — a design study · drawn in real time · no photographs were taken