Almanac

How it's made

Every mark on the page is measured, not painted.

Concept

ALMANAC is built on a single wager: that real numbers, drawn honestly, are more beautiful than decoration standing in for them. The mood is a nineteenth-century atlas plate — double-rule borders, corner rosettes, figure numbers, footnote asterisks — but every chart underneath is live data-viz, not an engraving of one. Nothing is a photograph or a stock illustration; the entire surface is inline SVG, one canvas element, and CSS.

The orrery

The hero is six nested <g> carriers, each holding one planet at its orbital radius, rotated every frame via element.style.transform = 'rotate(...)' inside a single requestAnimationFrame loop. The angles are not arbitrary: each planet's period is its true ratio to Earth's (Mercury 0.2408 yr, Saturn 29.457 yr), all multiplied by one shared constant so Mercury completes a lap every four seconds — visibly quick — while Saturn barely creeps, exactly as the sky actually behaves, just compressed roughly two million times. The multiplier is printed under the diagram so the compression is never hidden.

Stars, moons, eclipses, light

Figure I plots the twenty brightest stars from a hand-entered table of real apparent magnitudes and distances; a small integer hash of each star's name generates deterministic scatter jitter, so the layout is reproducible rather than random, while dot size and height both encode magnitude. A hand-built tooltip follows pointermove/focus events and repositions with getBoundingClientRect() — no library.

Figure II counts real satellite totals (Jupiter 95, Saturn 146, Uranus 28, Neptune 16) with an IntersectionObserver that, on first appearance, both animates a staggered field of dots (via a CSS custom property --i feeding animation-delay) and drives a requestAnimationFrame counter eased with a cubic ease-out, so the numeral and the dots finish together.

Figure III maps fourteen real long-range eclipse dates onto a year axis with plain arithmetic — (date − 2026) / (2040.6 − 2026) — then draws a “now” hairline at the visitor's own Date.now(), with a caption that computes real days-to-next-eclipse on every page load. Figure IV repeats the trick in reverse: five concentric rings at hand-tuned radii, a photon dot travelling outward on a seven-second loop, each ring flipping to a lit state as the pulse's progress crosses that ring's assigned fraction of the loop.

Atlas details & discipline

Corner rosettes are one inline <symbol> reused four times per plate via <use>. Double rules are a bordered .plate with an inset ::before pseudo-border. An ambient canvas starfield twinkles at low cost — one <canvas>, a seeded pseudo-random generator so the field is stable across reloads, and a sine per star rather than per-element DOM animation. Everything respects prefers-reduced-motion: the orrery holds a composed static pose, dots and stars appear at rest, and the eclipse sweep stops shimmering — the page stays legible and intentional either way. Device pixel ratio is capped at 2, and every loop checks document.hidden before requesting its next frame.

Passes

The build ran in three passes. The first laid the full page and its five figures against real data, favouring accuracy over convenient round numbers wherever a source disagreed with the brief. The second pass was a screenshot audit at 1440×900 and 390×844: dot-strip rows were regrouped to wrap cleanly on narrow widths, the eclipse band was moved into its own horizontally-scrolling track so the page itself never scrolls sideways, and contrast on midnight sections was re-checked so accent colours never carried small body text alone. The third pass tuned motion — easing curves, twinkle timing, the photon's ring-crossing choreography — until the page reads as continuously alive rather than merely animated.