The Brief
The Night Office is an almanac for the hours nobody claims, published by a fictional periodical and computed by a real browser. Nothing on the front page is canned. The moon on the masthead is drawn from tonight's illuminated fraction. The paper darkens with the actual twilight band. The ephemeris, the planet verdicts, the sentence under the masthead: all of it falls out of the clock and the coordinates in use, recomputed live as you drag the instrument through the night.
The point being proved: a page can be truthfully different every hour, and computation can carry an editorial voice instead of a dashboard.
The Arithmetic
Everything runs client side, from compact series of the kind collected in Jean Meeus's Astronomical Algorithms. No sky API, no library, about three hundred lines. The sun's ecliptic longitude comes from its mean longitude and the equation of center:
const L0 = norm360(280.46646 + 36000.76983 * T + 0.0003032 * T * T);
const M = norm360(357.52911 + 35999.05029 * T - 0.0001537 * T * T);
const C = (1.914602 - 0.004817 * T - 0.000014 * T * T) * Math.sin(Mr)
+ (0.019993 - 0.000101 * T) * Math.sin(2 * Mr)
+ 0.000289 * Math.sin(3 * Mr);
// apparent longitude, nutation approximated by the 0.00478 sin(omega) term
const lambda = norm360(L0 + C - 0.00569 - 0.00478 * Math.sin(omega));
js/astro.js · sunEcliptic
Twilight is then a matter of definition: civil while the sun is less than 6 degrees down, nautical to 12, astronomical to 18, true night beyond. Rise, set and each dusk are found by scanning the altitude curve and closing in on every crossing by bisection, which stays honest at any latitude; when a threshold is never reached, the almanac says so rather than inventing a time.
The moon uses the principal terms of the lunar theory, sixteen for longitude, eight for latitude, fourteen for distance, with a topocentric parallax correction of nearly a degree, which matters this close to home. Its phase is not looked up; it is the geometry of the moment, and the drawing follows it:
// The lit limb is the true circle; the terminator is a half-ellipse
// whose minor axis is r|2k-1|, k the illuminated fraction.
export function moonLitPath(k, litRight, r = 50, cx = 60, cy = 60) {
const rx = r * Math.abs(2 * k - 1);
const N = `${cx} ${cy - r}`, S = `${cx} ${cy + r}`;
if (litRight) {
return `M ${N} A ${r} ${r} 0 0 1 ${S} A ${rx} ${r} 0 0 ${k > 0.5 ? 1 : 0} ${N} Z`;
}
return `M ${N} A ${r} ${r} 0 0 0 ${S} A ${rx} ${r} 0 0 ${k > 0.5 ? 0 : 1} ${N} Z`;
}
js/moon.js · moonLitPath
The five naked-eye planets come from the Standish mean orbital elements, the JPL approximation valid from 1800 to 2050. Each body is placed by solving Kepler's equation and rotating into the ecliptic; the Earth is carried the same way, and the difference of the two vectors is where the planet stands in our sky:
function keplerE(Mdeg, e) {
const M = norm360(Mdeg) * RAD;
let E = M + e * Math.sin(M);
for (let i = 0; i < 8; i++) {
E = E + (M - (E - e * Math.sin(E))) / (1 - e * Math.cos(E));
}
return E;
}
js/astro.js · keplerE
The core was checked against published worked examples before any typesetting began: the sun for 1992 October 13, the moon for 1992 April 12, sidereal time for 1987 April 10, and the Washington altitude of Venus from the same chapter. All pass within the tolerances claimed below; the harness lives beside the site's QA shots.
What We Claim, and No More
Almanac precision, not observatory precision. Stated plainly:
| Quantity | Method | Good to |
|---|---|---|
| Sun position | Meeus low-precision series | 0.01° |
| Sunrise, sunset, twilights | altitude scan + bisection, refraction 34′ | about 2 min |
| Moon position | principal lunar terms, topocentric | 0.3° |
| Moonrise, moonset | same scan, upper limb | about 10 min |
| Moon illumination | true phase angle geometry | 1 point |
| Planet places | Standish elements, 1800 to 2050 | 1° |
| Planet magnitudes | classical phase formulas | 0.3 mag |
| Star places | J2000 catalog, precession unapplied | 0.4° |
Saturn's listed magnitude ignores its rings, which can brighten it by most of a magnitude when open. The difference between terrestrial and universal time, about a minute in this era, is absorbed by the stated tolerances. Phase names switch inside a day of the exact quarter; the drawn disc, not the name, is the precise statement.
The Hour Link
The almanac can be opened at any minute of tonight by link. Add ?t=03:00 to the address, or ?t=9:30pm if you keep civilian hours, and the instrument arrives already set, with every figure computed for that minute. Send a correspondent the almanac at the hour you mean, not the hour they open it.
Without the parameter the office runs live: the cursor rides the present minute, and anything you drag can be surrendered back with return to now. Before sunset the cursor waits at the night's edge, which is the office suggesting the evening ahead.
A Month of Moons
The same drawing function, run for the next thirty nights from the moment you loaded this page. One function, thirty different moons; the age in days is printed under each.
The Controls
Drag anywhere on the instrument, mouse or thumb.
Arrow keys step five minutes; shift makes it thirty; page up and down step an hour; home and end reach the night's edges.
The slider reports itself to assistive tech as the time and band, for instance "2:40 AM, astronomical twilight."
Reduced motion is honored: the paper changes band instantly and nothing on the page moves on its own.
Location is asked for once, politely, by a single button, and the answer never leaves your browser; declined, the office computes Portland and says so in the colophon.
Provenance
Every image is drawn at load time: the masthead moon and its age dial, the brass instrument, the sky-brightness band, the star field behind the page, the bearing rose beside the moon figure, and the Prospect panorama with its dotted ecliptic. There are no image files, no icon set, no chart library, no build step. The only outside requests are the two typefaces, EB Garamond and IBM Plex Mono, from Google Fonts. The periodical is fictional; the arithmetic is not.
What the Passes Caught
Pass one confirmed the sky against published worked examples and then caught the print shop's own errors: a dropped cap landing on the FILED line instead of the essay, the masthead overrunning its measure at both 1440 and 390, and the moon table reporting the previous afternoon's moonset as tonight's. The essay columns also ran long below the figures, so the night's queue now spreads full measure beneath the sheet.
Pass two added the Prospect panorama and, in doing so, caught the build's best bug: the month figure above rendered its full moons dark. The phase angle's denominator carried the wrong sign, quietly inverting every illuminated fraction while leaving the phase names correct, so a quarter moon read 55 percent instead of 45 and nobody could tell by eye. One drawn diagnostic exposed it in a second; the check suite now locks full bright and new dark forever. This page is partly an apology to that figure.
Pass three set the countdown standfirst in words under the instrument, drew the rise and set bearings on a small compass beside the moon figure, and swept the final shots at three hours and two widths for widows, contrast and console silence.