BUILD GUIDE · 07 OF 25

HELIOS —
how the sun was built.

A fictional solar weather observatory, pitched between mission control and art installation. The page has one job: hold you in front of a star that never stops moving, then let the instruments explain what you're looking at.

01Concept

HELIOS is a solar weather station at the Sun–Earth L1 point, publishing its feed as a public dashboard. The audience is anyone who has ever refreshed an aurora app: the page must feel live, plausible and slightly obsessive. Every number on it ticks from a small physical model — solar wind and southward Bz push the Kp index around, flares spike the X-ray channel — so the instruments agree with each other the way real ones do.

02Palette

#050507 · voidspace, not "dark mode" — barely blue so the corona reads warm against it
#FFF3D6 · corewhite-gold for the hottest plasma cells and primary readouts
#FFB347 · goldmid-temperature step; chart strokes, hovers, C-class events
#FF6B1A · flarethe single loud accent — flares, storms, focus rings, section numbers
#8B93A7 · instrumentgrey-blue for labels, grids and rules; cool so the sun owns all the warmth

The whole page is a temperature ramp: everything cold is grey-blue, everything hot borrows from the sun. Nothing else is allowed a colour.

03Type

Archivo at 125% width
Archivo condensed caps at 78% for instrument labels
Spline Sans Mono 500 — 487 km/s · C2.4 · Kp 3.7

Archivo is a variable font with a real width axis, so one file plays two roles: stretched to 112–125% it becomes the display voice (the headline, the 5,772 K band); compressed to 78–80% caps with wide tracking it becomes NASA-console labelling. Spline Sans Mono carries every number with tabular-nums so readouts tick without shifting. The typographic bravery moment is the full-bleed temperature band — solid white-gold against a hairline-outlined ghost line.

04Techniques

The signature element is a raw-WebGL fragment shader sun — no three.js, one fullscreen triangle. Screen pixels inside the disc are lifted onto a sphere (z = √(R²−r²)) and slowly rotated. Plasma is domain-warped fBm: three fBm fields feed their output back in as an offset (fbm(p·1.6 + q·1.35)), which produces the curling, convective look a single noise pass never gives. Granulation is two ridged value-noise layers at different frequencies and orientations so no grid alignment survives. A temperature ramp maps that scalar field from ember red through #FF6B1A to white-gold; limb darkening (0.26 + 0.74·μ0.65) curves the disc, and a (1−μ)⁶ chromosphere rim reignites the very edge. Outside the disc, the corona is angular fBm sampled on the unit circle (no atan seam) driving both the falloff rate and brightness of the glow, plus a filament term for magnetic loops that hug the limb.

Everything else is honest instrumentation: canvas-2D strip charts on a 0.3 s cadence with a 220-sample ring buffer; a mean-reverting random-walk model with a flare envelope (fast rise, exponential decay) shared by the shader, the X-ray chart, the readouts and the observation log; CSS-only forecast bars; an SVG reticle. Pressing the disc injects an M-class test flare — the shader surges, the chart spikes, and the log quietly notes "this one was you." If WebGL is unavailable the stage swaps to a layered radial-gradient sun and the page carries on.

05Iteration log

Pass 1 — Craft

  • First render of the disc was blown-out white with heavy black blotches — closer to mould than plasma. Re-weighted the heat field, moved the white-gold stop to the top 24% of the ramp, deepened limb darkening and cut sunspot coverage roughly in half.
  • Granulation showed rectilinear value-noise grid artefacts at high frequency. Replaced the single sample with two ridged layers at 24× and 47× on swizzled axes; the grid disappears.
  • The temperature band was set at 9vw with nowrap and clipped past ~800 px viewports; resized to 5vw so both lines clear 1280 px with padding intact.
  • Chart footer claimed "1-min cadence" while the window is 66 s at 0.3 s per sample — corrected the caption to match the actual instrument.

Pass 2 — Depth

  • Enriched the signature: dual-layer granulation, star-field twinkle keyed per star, corona loops term, and simulation time that runs 1.6× during a flare so the surface visibly seethes harder.
  • Second-read details: the reticle carries the Sun's true limb diameter; the Carrington rotation number is computed from today's real Julian date; every ~90 s the feed status blinks through station housekeeping ("STAR TRACKER LOCKED…").
  • Micro-interaction: metric labels warm to gold on hover; pressing the disc injects a test flare that propagates through shader, readouts, chart and log.
  • Motion timing: reveals use a single crafted cubic-bezier(.2,.7,.2,1); new log rows slide in with a brief flare-orange wash.

Pass 3 — Hardening

  • Caught a genuine cascade bug in the browser: .panel's position:relative silently overrode .hud's position:absolute, dropping both HUD panels out of their orbit around the sun. Fixed with a more specific .hero .hud selector, measured the DOM after.
  • Short-desktop collision: at 800 px tall the HUD panels overlapped the headline, and the headline itself was wrapping to four lines inside its 520 px column. Panels now sit at 43% on viewports under 840 px tall; the display size was re-derived from measured text width (canvas measureText) so both lines clear the column. Mobile moves title and panels into normal flow under a 62svh stage (with vh fallbacks for older Safari).
  • Reduced motion: no rAF loop at all — one still frame of the star, prefilled charts, static readouts; CSS kills pulse, reveals and row animations.
  • Performance: DPR capped at 2 and the sun buffer capped at 1600 px wide; rendering pauses when the tab hides or the hero scrolls away; resize is debounced.
  • Chanel rule: deleted the reticle's 300-second rotation — imperceptible ornament costing a composited layer — plus an unused utility class and dead transition.
  • Verified the extracted script parses clean in Node, the shader compiles (checked via a pixel-for-pixel software port rendered to PNG), and the only external requests are the two Google Fonts.