“The Ascent” is a single continuous WebGL climb from a dawn cloudscape to the Kármán line, built with no framework, no build step, and only one dependency (Three.js). This page is the reproducible recipe: every technique on the site, in the order you'd rebuild it.
Altior is Latin for higher; the brand line is “We Elevate.”
So the site doesn't illustrate elevation — it performs it. The page is a vertical
journey through real atmospheric layers (Troposphere → Exosphere), the scrollbar is an altimeter,
and every visual system — colour, particles, type, copy — is driven by one number:
progress ∈ [0,1], your altitude. When one scalar drives everything, the piece feels
inevitable rather than decorated. That is the whole trick.
The entire background — dawn gradient, sun, sea of clouds, noctilucent wisps, aurora, star field,
and the Earth's limb at the top — is a single fullscreen ShaderMaterial.
Each phenomenon is a small block gated by an altitude window, all blended by the same
uProgress uniform:
float meso = smoothstep(0.45, 0.62, pr) * (1.0 - smoothstep(0.72, 0.95, pr));
float aur = smoothstep(0.62, 0.80, pr) * (1.0 - smoothstep(0.88, 1.0, pr));
float limb = smoothstep(0.80, 1.00, pr);
fbm(q + fbm(q) * 0.9))
inside a Gaussian vertical band whose centre sinks as you climb, so the cloud sea falls away below you.±0.006 hash dither. Dark gradients band badly on
cheap panels; one line of noise fixes it.
The updraft is a single THREE.Points with three attributes: a seed, a size, and a
y-position. Everything else happens in the vertex shader: particles rise forever via
mod(y + t·speed, H), sway with layered sines, and sit inside a radius envelope that is a
tight cone (a mountain silhouette) at ground level and relaxes into a wide open veil
at altitude. Colour lerps from ember to glacier with the same uProgress.
Additive blending, no depth-write, DPR clamped at 2 — it runs full-frame on integrated graphics.
Native scrolling is kept (accessibility, momentum, keyboard), but the page you see is a
position: fixed main element translated by a lerped copy of scrollY
(cur += (target − cur) × 0.085). That one exponential gives the whole site its
inertial, “heavy” feel. The same smoothed value drives the WebGL camera's rise, the altimeter,
and the marquee's velocity — so DOM and canvas can never drift out of sync.
Reveal triggers use getBoundingClientRect() in the rAF loop rather than
IntersectionObserver, so they respect the transform.
Display type is Fraunces, a variable serif with optical-size, softness and — genuinely —
a WONK axis that swaps in crooked, hand-drawn alternates. Headlines run at
opsz 144, WONK 1 for maximum character; on hover the principles soften live
(SOFT 0 → 70) — animation inside the letterforms themselves, no extra assets.
Labels are Space Grotesk, letter-spaced like instrument markings, with tabular numerals in the HUD.
Both are self-hosted variable WOFF2s: three files, ~290 KB, the entire type system.
Two temperatures, one journey: ember (dawn, ground, effort) cooling into glacier (space, clarity) as you rise, over an ink base that is never pure black — it leans violet so the ember reads warm against it. Text is bone, not white; at 90 % of white the glow of the shader still reads as light behind the page. Accents stay under ~10 % of any viewport, which is what keeps it feeling engineered instead of decorated.
uNacreous from how much of the section is on screen — the honest
phenomenon for 20–30 km, where earlier versions flew a (physically misplaced)
orbital ring. The section itself scrolls normally; an earlier design pinned it,
and the pin was retired in favour of an uninterrupted climb.data-alt value, displayed with a spring-lerped counter and a needle on a tick rail.
A scrollbar that tells you your altitude.feTurbulence tile stepped through 4
positions at 0.9 s. Kills the “too clean” digital look for ~0 cost.offsetTop after document.fonts.ready, then masked and slid up
with per-line delays. Splitting before fonts load is the classic bug — lines re-wrap and the
masks are wrong.
Everything above could still look like a tech demo. What stops it: one typeface pair, one accent
hue per temperature, hairline borders at 14 % opacity, generous dead space, copy written in the
client's actual constitutional language (“research, analyse, learn, iterate”), and
prefers-reduced-motion honoured throughout — reveals settle instantly and the inertial
scroll steps aside. A flagship is a system with taste, not a pile of effects.
index.html, one CSS file, two JS modules, a vendored
three.module.min.js, three WOFF2s. No bundler.progress means, then make every
system read it.vercel deploy . --prod. The included vercel.json adds
immutable caching for fonts and vendor files.