← Back to Nebula Voyages

Build guide — Nebula Voyages

How this showpiece was concepted, art-directed and built: the brief, the palette, the actual image prompts, the WebGL and scroll techniques, and what each of the three iteration passes changed.

01 /// CONCEPTThe overview effect as a luxury product

The brief: commercial space tourism sold with the calm confidence of a heritage travel house. Vast, silent, awe — Apple × NASA, never sci-fi kitsch. The voice is quiet, second-person and specific: “You will watch sixteen sunrises before lunch.” Numbers do the persuading — altitudes, sunrise counts, a 214/214 safety record — so the copy never has to shout.

The page is built as a single continuous descent: a fixed WebGL sky sits behind everything, and the content scrolls over it while the sky itself changes mood — hushed at boarding, streaking at ascent, blooming pink at the overview.

Palette

Void · #030014
Deep indigo · #1B1040
Aurora · 7C3AED → 22D3EE → F472B6
Starlight · #F8FAFC

The aurora gradient is rationed: type accents, card borders, one CTA. Everything else stays void-dark so the gradient reads as an event, not a theme.

Type

Unbounded — display, wide & orbital Space Grotesk — body, engineered warmth at 300 weight. 27,580 km/h · 460 km · 112 sunrises — tabular numerals (font-variant-numeric: tabular-nums) for every mission readout, so counters tick without jitter.

02 /// ASSETSGPT Image 2 — actual prompts

All imagery generated with gpt-image-2 at 1536×1024, quality high, exported as .webp. Each was visually inspected and kept only when genuinely awe-inducing.

Generated violet and cyan nebula
nebula-vista.webp — hero fallback + guide texture
Generated spacecraft cabin with Earth through the window
cabin-earth.webp — The Craft
Generated Earth limb at orbital sunrise
earth-limb.webp — Vista section
Generated spaceplane above Earth
craft-exterior.webp — The Craft
nebula-vista · 1536×1024 “Vast interstellar nebula seen from deep space, immense luminous clouds of violet and magenta gas lit from within by newborn blue-white stars, ribbons of cyan ionized hydrogen, deep indigo shadows dissolving into near-black void, thousands of pinprick stars of varying brightness, ultra-deep-field astrophotography in the style of the James Webb Space Telescope, cinematic, awe-inspiring cosmic scale, subtle photographic grain, dominant palette of deep violet, electric cyan and soft pink against near-black, no planets, no text, no watermark”
cabin-earth · 1536×1024 “Interior of an ultra-luxury commercial spacecraft cabin in orbit, minimalist design with cream boucle reclined seats, brushed titanium and matte charcoal surfaces, soft warm indirect cove lighting, one entire wall is a vast panoramic window showing planet Earth from orbit filling the view — deep blue oceans, swirling white clouds, a thin glowing band of atmosphere against pure black space, serene and silent mood, wide-angle architectural photography, Apple-store minimalism meets NASA engineering, photorealistic, no people, no text, no watermark”
earth-limb · 1536×1024 “The curved limb of planet Earth photographed from low orbit at the exact moment of orbital sunrise, a razor-thin electric-blue and amber line of atmosphere glowing along the planet's dark curve, the sun cresting the horizon as a brilliant golden starburst flooding light across moonlit cloud tops, faint stars in the black of space above, photorealistic astronaut photography from the cupola of a space station, breathtaking quiet awe, high dynamic range, no spacecraft parts visible, no text, no watermark”
craft-exterior · 1536×1024 “A sleek white and graphite commercial spaceplane gliding silently in low Earth orbit, elongated elegant fuselage with a row of large panoramic windows glowing warm from inside, subtle violet-cyan iridescent accents on the hull, Earth's blue curve and thin atmosphere below, black star-flecked space above, dramatic rim lighting from the sun, photorealistic aerospace render, Apple x NASA industrial design language, cinematic composition with the craft off-center, no text, no watermark, no logos”

03 /// TECHNIQUESThe signature effects

1 · One fixed WebGL sky behind the whole page

A single Three.js canvas (position: fixed, z-index 0) renders two layers: ~6,200 shader points and a domain-warped fbm nebula on a far plane. All page content scrolls over it, so the sky becomes the connective tissue between sections.

2 · Starfield with wrap-around ascent streaks

Star drift is done in the vertex shader with a modulo wrap, so “ascent” is just a speed uniform — no per-frame buffer writes:

// vertex shader — uScroll accumulates speed × dt each frame
p.y = mod(p.y - uScroll * (0.55 + aRandom * 0.9) + 55.0, 110.0) - 55.0;

Pointer parallax lerps the camera a couple of units; the nebula plane sits at z = −120 so it parallaxes less than the stars — free depth.

3 · Noise-shader nebula with two palettes

vec2 q = vec2(fbm(uv + t), fbm(uv + vec2(5.2, 1.3) - t));
vec2 r = vec2(fbm(uv + (1.6 + uWarp) * q + ...), ...);
float f = fbm(uv + 1.8 * r);           // two-pass domain warp
vec3 col = mix(paletteA(f), paletteB(f), uMix);  // indigo/cyan → violet/pink

uMix, uWarp, intensity and star speed are eased toward stage targets every frame, so mood changes feel like weather, not switches.

4 · The pinned journey

GSAP ScrollTrigger pins the journey panel for 320% of viewport height. Scroll progress drives four things at once: stage copy crossfades, the outlined stage number, tabular-numeral mission readouts (T-clock, altitude to 460 km, velocity to 27,580 km/h), and the WebGL sky state — boarding is hushed, ascent streaks the stars, the overview blooms pink.

ScrollTrigger.create({
  trigger: ".journey", start: "top top", end: "+=320%",
  pin: ".journey__pin", scrub: true,
  onUpdate(self) {
    setJourneyData(self.progress);   // T-clock, alt, vel
    setStage(Math.floor(self.progress * 4));
    applySkyStage(self.progress);    // WebGL mood
  }
});

5 · Holographic ticket cards

A registered CSS custom property makes the conic gradient border rotate on hover — a genuine holo-foil move, 1px thick:

@property --holo-angle { syntax: "<angle>"; initial-value: 120deg; }
.card { padding: 1px; background: conic-gradient(from var(--holo-angle), ...); }
.card:hover { --holo-angle: 480deg; }  /* transitions via @property */

6 · Fallbacks & accessibility

04 /// PROCESSThree iteration passes

Pass 1 — structure & correctness

Full desktop + mobile sweep with console audit. Fixed: GSAP lag-smoothing stalling entrance tweens in throttled tabs; a WebGL canvas that could composite black in background tabs (preserved drawing buffer + hidden-tab render-on-scroll); an orphaned line break in the hero sub; the mobile nav pill wrapping; misaligned voyage-card bottoms; sub-AA contrast on small data labels. Elevated: craft-image hover zoom with cyan border glow, ambient “breathe” on the featured card, aurora gradient hairline on the footer.

Pass 2 — rhythm & texture

Fixed: brand wordmark + CTA overflowing 375 px (wordmark hides, mark stays); craft gallery images with mismatched heights; the reserve headline being consumed by the hero’s load animation instead of its own scroll reveal. Elevated: manifesto converted to a scrubbed staggered fade-rise; aurora dash above every section head; card CTA arrow slide; editorial right-offset for the manifesto meta; oversized aurora quote glyph.

Pass 3 — polish & edge cases

Verified the no-WebGL fallback and added a legibility scrim over the still; re-checked reduced-motion stacking; recompressed all four images (6.8 MB → 0.77 MB total, visually lossless at q82); halved the starfield on small screens; tested the reserve form’s inline confirmation; final desktop + mobile screenshots and a clean console.

05 /// SHIP ITDeploy

Static files, no build step. From the site directory:

npx wrangler pages deploy . --project-name nebula-voyages