Space tourism is a category that, in 2026, has maybe three real buyers and ten waiting lists. The websites are worse than the market. Most are NASA fan art or worse — a brochure that looks like it was made by a chemical engineering firm that wandered into UX. The orbital experience itself is the most cinematic product humans have ever sold and the marketing reads like an aerospace insurance disclosure.
Horizon is the seventh template in the marketplace I'm shipping. The brief: a booking site for orbital and lunar tourism that earns the visitor's adrenal response.
Stack
Single-page static HTML (HORIZON.html / index.html). React 18 UMD. In-browser Babel. Hand-written CSS (no Tailwind on this one — styles.css is ~44 KB). Google Fonts: a serif display for the headline, a quiet sans for body.
Why hand-written CSS instead of Tailwind? Horizon leans on a small set of bespoke gradients, scroll-driven background-color transitions, and a circular destination gallery that's awkward to express in utility classes. Sometimes a real stylesheet costs less to maintain than a thousand class strings.
The hero
A full-bleed Gemini Veo plate of the Earth's limb from low orbit — black sky above, sunrise-tinted atmosphere along the bottom. Transcoded down to 1280-wide H.264 at CRF 26 (8.8 MB raw → 641 KB shipped), Veo sparkle removed with the standard delogo pass.
Layered on top:
- Horizon wordmark + copyright glyph
- A pill nav: "Book a voyage" (primary) + a hamburger
- Serif headline: "Venture past our sky" in white display weight
- Subtitle: "Private passage to orbit and the Moon. Engineered comfort at the edge of the world."
- A pill CTA: "Reserve a seat"
- Two stat tiles: 34.5 MIN TO ORBIT + 2.8B KM MAPPED
- A right-side rail of section dots (SKY, ORBIT, MOON, etc.) — scroll progress
A second hero video (VID_ALT, a deep nebula field) sits behind the destination gallery as a parallax layer. A third (VID_ORBIS, drifting past the planetary edge) plays under the membership band lower on the page.
Six destinations
The flagship is the DESTINATIONS array. Six tiers of orbital experience, each with:
- name (Low Orbit, Lunar Gateway, Aurora Station, Deep Field, Halo Ring, Solar Drift)
- coordinate band (LEO · 420 KM, L2 · 384,400 KM, ...)
- price ($280,000 → $6,200,000)
- duration, altitude, gravity, seat count
- a one-sentence cinematic description
The gallery is a curved circular array — destination cards orbit a central glow at the center of the section. Drift the gallery with the cursor, the cards rotate through. Click a card, the dossier expands below with full spec.
The scroll-driven background tint
The most expensive feature is the cheapest line of code. sections.jsx watches scroll position and lerps document.body.style.backgroundColor between hard-coded RGB stops as the visitor moves down the page:
document.body.style.backgroundColor = `rgb(${r},${g},${b})`;
Black at the hero (deep sky). Warm beige at the membership band (lunar dawn). Slate at the Flight Log (ISS shadow side). The visitor's brain registers the journey before they read a single word.
The function lives in initSectionGlow. Same idea as a scroll-linked theme but with a hard-coded color ramp instead of a CSS variable system. Twenty lines of JS. No motion library.
What I cut
- No booking calendar widget (this is a brochure, not Stripe Checkout)
- No newsletter modal (Horizon's actual buyer signs up via "Book a voyage" → email)
- No "Backed by [investor logos]" trust strip (the visitor either has the money or doesn't)
What I would change
The scroll-driven background tint reads beautifully on a 144Hz desktop monitor. On a low-end Android with throttled scroll events, the color jumps in steps instead of lerping smoothly. A future pass would debounce the color update to the same RAF the section observer uses — at the moment it runs on every scroll event.
Live
horizon-template-07.netlify.app — scroll slowly. Watch the page color change beneath the destinations.
