← RETURN TO DESCENT DOC PS-382/G · UNCLASSIFIED

MISSION DOSSIERENGINEERING & ART DIRECTION

HOW THIS
SITE WAS BUILT

Perihelion Station is a scroll-driven film: a research station falling into the sun over six pinned chapters. This dossier documents the concept, the palette, the continuous-zoom technique at its core, the AI asset pipeline, and what changed across three iteration passes. Designed and built end-to-end — brief to deploy — by Claude Fable 5, an AI model.

01CONCEPT & CREATIVE DIRECTION

ONE UNBROKEN FALL

The brief: a research station falls toward the sun, told as a film in six chapters, with the scrollbar as the mission clock — 47 days to perihelion. Most scroll stories are a slideshow with easing. The design goal here was the opposite: the entire site is one shot. From the first frame (the sun as a distant ember) to the last (boiling photosphere filling the screen), the background never cuts. It only approaches.

The interface is NASA-brutalist: Michroma set small and tracked wide, hairline panels, tabular telemetry, a HUD that never leaves the corners. The UI had to feel functional rather than decorative — sparklines that actually stream data, a clock that actually counts, readouts derived from one shared distance model. The emotional register is held back deliberately: terse mission language for five chapters so that the single quiet line at perihelion lands with full weight.

6pinned chapters
47→0days on the clock
6solar plates, one zoom
0hard cuts

02PALETTE & TYPE SPECIMEN

BLACK, GOLD, EMBER

SPACE BLACK
#05060D

PLASMA
#F5F2EC

SOLAR GOLD
#FFB03A

EMBER
#E4572E

MICHROMA — DISPLAY / HUD

CORONA PASSAGE

One weight, engineered like instrument lettering. Used at two extremes only: enormous chapter titles and 8–11px tracked-out HUD labels. Nothing in between.

FAMILJEN GROTESK — BODY

Day 31. Eleven instruments wake in sequence. The coronagraph resolves structures no Earth telescope has seen — loops the height of thirty Earths, rewriting themselves by the hour.

400–700 plus italic. Carries all mission prose at 16px+ with tabular numerals for every readout.

03SIGNATURE TECHNIQUE

SIX PLATES, ONE ZOOM

Six AI solar plates were art-directed as successive zoom stages: ember-in-void → small disk → full disk with prominences → coronal loops at the limb → plasma flood → photosphere texture. A single scalar, depth ∈ [0, 5], drives everything. Each pinned chapter's ScrollTrigger scrubs depth across its assigned range, so six pins read as one continuous approach.

The trick that makes the handoff invisible: every plate's scale is an exponential function of its distance from the current depth — scale = 1.5^(depth−i). When plate i finishes crossfading into plate i+1, both have been growing along the same curve the whole time, so there is no velocity discontinuity at the seam. The GPU only ever composites two plates: a fragment shader crossfades them, displaces UVs with drifting value-noise (the heat shimmer, which intensifies with depth), then applies exposure lift and a vignette.

// sunstage.js — the continuous handoff
const i = Math.min(4, Math.floor(depth))   // outgoing plate
const f = depth - i
const mix    = f * f * (3 - 2 * f)          // eased crossfade
const scaleA = Math.pow(1.5, depth - i)     // both plates grow on the
const scaleB = Math.pow(1.5, depth - i - 1) // same exponential curve —
                                            // no seam at the handoff
// each chapter's pinned ScrollTrigger scrubs its slice of depth:
onUpdate: self => {
  sun.setDepth(lerp(ch.depthStart, ch.depthEnd, self.progress))
  setMissionTime(lerp(ch.tStart, ch.tEnd, self.progress))
}
// sun.frag.glsl — heat shimmer over the pair
vec2 shim = vec2(vnoise(uv*11. + vec2(0., t)),
                 vnoise(uv*11. + vec2(5.23, t+3.17))) - .5;
uv += shim * uShimmer * .016;               // uShimmer rises with depth
vec3 col = mix(texture2D(uTexA, coverUv(uv, uScaleA)).rgb,
               texture2D(uTexB, coverUv(uv, uScaleB)).rgb, uMix);

The mission clock, range and velocity readouts all derive from the same scroll position through one model — r(t) = 0.043 + 0.943·(t/47)^0.65 AU — so the HUD, chapter stats and story stay numerically consistent. If WebGL is unavailable, a DOM image stack reproduces identical math with CSS transforms; with prefers-reduced-motion, the film becomes a sequence of readable stills.

04ASSET PIPELINE — HIGGSFIELD MCP

ART-DIRECTING A STAR

Eleven generations, ~22 credits. Every plate prompt shared one locked style block — "Strict palette: pure black, incandescent solar gold, deep ember orange. No blue, no purple. Cinematic IMAX scientific documentary still, high dynamic range, subtle fine film grain" — with only the zoom stage rewritten per plate. That single constraint is what makes six separate generations read as one camera move. One plate was regenerated after the first attempt came back letterboxed inside its own frame; the fix was prompting "full-bleed edge-to-edge, no border, no letterbox" on every later plate.

ASSETMODELZOOM STAGE / DIRECTION
plate-0nano_banana_pro · 2KSun at 1 AU — ember disk, 95% void, sparse stars
plate-1nano_banana_pro · 2KSharp disk ≈15% of frame, corona hugging the limb (regenerated for full-bleed)
plate-2nano_banana_pro · 2KDisk at 60% — roiling surface, erupting prominences
plate-3nano_banana_pro · 2KLimb across lower frame, colossal coronal loops
plate-4nano_banana_pro · 2KInside the corona — plasma flood, no black remaining
plate-5nano_banana_pro · 2KPhotosphere granulation full-bleed, ember lanes
stationnano_banana_pro · 2KHeat shield forward, rim-lit, small sun beyond
crew ×3soul_2 · 2KID portraits — shared key light, sun reflected in visor glass

Masters stay in assets-src/; only optimized WebP ships (tools/optimg.mjs, 1600/800px). The full 1600px plate set totals ≈570KB — the whole approach weighs less than one hero JPEG on most sites. The OG image is a real frame of chapter 01 captured with Playwright, not a separate generation.

05ITERATION DIARY — THREE PASSES

WHAT THE PASSES CHANGED

PASS 1 — STRUCTURE

The scroll harness caught horizontal overflow at every width (tracked-out Michroma titles), a mission clock stuck on SIGNAL LOST after the tool visited the page bottom (a running scramble interval kept writing after its trigger reversed — fixed by making the effect cancelable), and mobile chapters that couldn't fit a pinned viewport. CH02/CH03 now unpin below 768px and scrub their depth range across natural flow instead. A Playwright geometry probe found the scroll cue positioned against the wrong containing block: the chapter-exit tween's transform on the inner div had captured it.

PASS 2 — CRAFT

The best bug of the build: crew portraits rendered 1000px tall because the img's height attribute silently beats CSS aspect-ratio unless you set height: auto. Also: kickers vanished over bright plates (added scoped text-shadows), the gold-flood inversion fired too late (threshold 0.55 → 0.38, ramp starts at 12% of the pin, so type inverts as it enters), and the epilogue began dimming the stage while the perihelion line was still holding. Chapter label + progress rail now derive from a single scroll-position check instead of trigger-toggle ordering, which survives instant jumps to the page end. Verified the reduced-motion path renders every chapter as a readable still.

PASS 3 — COMPLEXIFY & REFINE

Hostile-critic sweep. What was missing was an instrument that ties the whole fall together: the HUD gained a live trajectory plot — infall arc, gold progress stroke, station marker — driven by the same mission-time model as the clock, fading in only once the descent is underway so it never fights the scroll cue. The epilogue gained its bookend: the CH00 exterior camera returns as "LAST FRAME RECEIVED", the station image degraded under animated static with a signal-tear band and frame metadata. Telemetry panels got a gold hover glow. Weakest-screen check: CH01 held up once the trajectory anchored it; nothing else needed elevating.