Noctuary

Design guide · site 11 of 25

How Noctuary was made

A field journal of the night sky, kept by a fictional observer in the Western Australian wheatbelt. The page has one job: make you feel the patience of looking up, then teach you the sky is legible.

The concept

Noctuary is an amateur astronomer's diary set at 31.9° south — a deliberately southern-hemisphere sky, so Orion does a handstand and the moon waxes from the left. The audience is anyone who has stood in a paddock at night; the single job is to convert scrolling into the feeling of dark-adapted eyes finding a constellation.

Everything on the page is procedural: a canvas starfield with parallax and twinkle, SVG star charts that draw themselves, and a moon whose phase is computed from the real date — not an illustration of the moon, but the moon.

Palette

Zenith#0B1026 — the darkest ink-blue, straight overhead. Never pure black: real night sky isn't.
Horizon#1B2745 — the page brightens toward the bottom the way sky brightens toward the ground.
Starlight#EAF2FF — blue-white, used for stars, headings, and the lit moon. Warm white would read as lamplight.
Annotation gold#C8A24B — the colour of a brass telescope and a pencil-gilded chart label. All lines, labels, dials.

Two darks, one light, one accent. The gold is only ever an annotation — the human hand on the sky — so it never fills a surface, only strokes and small type.

Type

Cormorant Italic — the observer's hand

Display, entry titles, labels on the charts. The italic is handwriting-adjacent without being a script face: elegant, slightly antique, right for a journal that quotes itself. Weight 500–600 only; light weights vanish against the starfield.

Source Sans 3 — the legible instrument

Body copy and data. A quiet humanist sans at 17px/1.72 that stays readable on a dark ground, with letterspaced small caps reserved for eyebrows, datelines, and conditions labels.

The typographic bravery moment is the dictionary entry — noc·tu·ar·y set at display scale with gold middots — which stakes the site's claim on a nearly extinct word.

Techniques

  • Self-drawing constellations — the signatureEach journal entry carries an inline SVG star chart. Stars pop in brightest-first (sorted by core radius, the way dark-adapted eyes actually find them), then each connecting line draws point-to-point using stroke-dasharray/dashoffset with per-segment durations proportional to line length, sequenced by accumulated transition delays. An IntersectionObserver fires the whole choreography once per entry; after it completes, the stagger delays are cleared so hover states respond instantly.
  • Real moon-phase mathMoon age = days since the new moon of 6 January 2000, 18:14 UT, modulo the mean synodic month (29.530588853 days). Illumination is (1 − cos 2πf)/2. The lit area is one SVG path: a half-disc along the bright limb plus a half-ellipse terminator whose x-radius is r·|cos 2πf|, mirrored for southern-hemisphere viewing. Validated against the 8 April 2024 eclipse (computes to a new moon) and July 2026's actual new/full dates.
  • Canvas starfieldThree parallax layers (~290 stars, density scaled to viewport) with per-star twinkle phase, diffraction spikes on the brightest, a pre-rendered Milky Way haze band on an offscreen canvas, and meteors on an irregular 7–16 s timer with gradient trails. DPR capped at 2, rAF paused when the tab hides.
  • Second-read detailsEvery dateline shows the computed moon phase for that historical night — same arithmetic as the live widget. Hovering any star names it. A gold dial around the moon marks progress through the lunation. A quiet counter in the footer logs the meteors that fell while you read.

The terminator is a half-ellipse with x-radius r·|cos 2πf| — zero at the quarters, full radius at new and full. One path handles all eight phases; a south flag mirrors it below the equator.

Iteration log

Pass 1 · Craft

Spacing, type, honesty of detail

  • The dictionary entry had an italic gold "ar" syllable — a flourish with no argument for it. Recast: roman word, gold middots only.
  • Conditions lines were full sentences in letterspaced all-caps — unreadable past four words. Now a small-caps gold label with sentence-case content.
  • Meteors moved a fixed 16.7 ms per frame, so they flew double speed on 120 Hz displays. Switched to real delta-time.
  • The Milky Way haze parallax used a modulo that snapped the band every ~1,300 px of scroll. Rebuilt the offscreen canvas 260 px taller and clamped the offset instead.

Pass 2 · Depth

Enrich the signature, reward the second visit

  • Stars now appear brightest-first — sorted by rendered magnitude, not DOM order — which the intro copy had promised all along.
  • Added the Jewel Box cluster as a gold four-point sparkle beside Mimosa in the Crux chart, because the entry text mentions it and readers check.
  • Gave the moon a lunation dial: a gold arc around the disc showing how far through the 29.53-day cycle tonight sits, with a marker dot.
  • Hovering a chart warms its lines and labels; the stagger delays are cleared after drawing so the hover answers immediately instead of seconds later (a bug the first version of this pass introduced, then fixed).

Pass 3 · Hardening

375 px, reduced motion, the Chanel rule

  • Verified the single-column collapse at 375 px: charts centre at max 26rem, the nav drops to three links, the moon panel stacks.
  • Reduced motion now has three layers: the CSS media query kills transitions, the JS skips the rAF loop and draws one static frame, and a live matchMedia listener stops or restarts the sky if the setting changes mid-visit.
  • Resize regenerates the starfield only when width changes or height jumps ≥140 px — the mobile URL-bar bounce no longer reshuffles the sky. Resize itself is debounced 120 ms.
  • Chanel rule: removed the bobbing animation on the scroll hint's arrow. The page already has a sky full of motion; the arrow can sit still.