Every facts card and the terminal's pane should say where the body is in our sky on the date the scrubber is showing — distance from Earth, elongation, phase, apparent size and brightness — because that is the first thing anyone who owns a telescope wants to know.
Today the card is a static almanac: src/pages/explorer.ts renders body.facts straight from src/bodies.ts, and nothing on it changes when the date does. Fetch /?b=mars&jd=2461200.5 and the Mars card is the same six lines it always is. The terminal already does better — facts() in src/tty.ts prints a live distance from the Sun and a comet's activity — so the web page is behind its own terminal, which AGENTS.md says should not happen.
Acceptance criteria
[ ] A new pure module src/observe.ts takes the positions positionsAt(jd) already returns and gives, for any body seen from Earth: distance from Earth (au, and light-minutes), elongation from the Sun in degrees with east/west, phase angle and illuminated fraction, apparent angular diameter (arcseconds; arcminutes for the Moon and the Sun), and apparent magnitude. Plain data in, plain data out, no DOM.
[ ] Those numbers appear in three places: the web card, the terminal's facts pane, and the first server-rendered response for the date in the URL — so they are there with JavaScript off.
[ ] With the script running they follow the clock: the live block refreshes as time runs, no more than a few times a second, with font-variant-numeric: tabular-nums and a fixed number of rows so the panel never reflows.
[ ] Earth's card says what it can say (distance from the Sun, the Sun's apparent diameter) and does not print an elongation from itself. A comet keeps the activity line src/comets.ts already gives it.
[ ] Tests, in the style of src/ephemeris.test.ts:
- [ ] elongation is within 2° of 180° on the five opposition dates that file already checks
- [ ] sampled every 5 days across a century, Mercury's elongation never exceeds 29° and Venus's never exceeds 48°
- [ ] Jupiter's illuminated fraction stays above 0.98; Venus's runs the whole way from near 0 to near 1
- [ ] the Moon's apparent diameter stays between 29′ and 34′, Jupiter's between 29″ and 51″
- [ ] at opposition Jupiter is brighter than Saturn, Saturn than Uranus, Uranus than Neptune, and Neptune is fainter than magnitude 7
[ ] The magnitude model names its source in a comment, and the README's "what is real, and what is not" says how good these numbers are. A tenth of a magnitude is honest; three decimal places is not.
Files I expect to change
src/observe.ts and src/observe.test.ts (new), src/pages/explorer.ts, src/client/main.ts, src/tty.ts, README.md.
Risks
Magnitude formulae are published fits, not physics: keep the coefficients in one table with a comment saying whose they are, and never print more precision than the fit has. The Moon is on mean elements with no perturbations, so its phase angle can be a few tenths of a degree out near new moon — say so rather than round it away. Rise and set times are deliberately not in scope: they need an observer's latitude and a timezone, which is a different feature.
Who fits
vesper — maths in a small typed module plus a little rendering, tested against numbers, which is the brief.
Every facts card and the terminal's pane should say where the body is in our sky on the date the scrubber is showing — distance from Earth, elongation, phase, apparent size and brightness — because that is the first thing anyone who owns a telescope wants to know.
Today the card is a static almanac:
src/pages/explorer.tsrendersbody.factsstraight fromsrc/bodies.ts, and nothing on it changes when the date does. Fetch/?b=mars&jd=2461200.5and the Mars card is the same six lines it always is. The terminal already does better —facts()insrc/tty.tsprints a live distance from the Sun and a comet's activity — so the web page is behind its own terminal, whichAGENTS.mdsays should not happen.Acceptance criteria
src/observe.tstakes the positionspositionsAt(jd)already returns and gives, for any body seen from Earth: distance from Earth (au, and light-minutes), elongation from the Sun in degrees with east/west, phase angle and illuminated fraction, apparent angular diameter (arcseconds; arcminutes for the Moon and the Sun), and apparent magnitude. Plain data in, plain data out, no DOM.font-variant-numeric: tabular-numsand a fixed number of rows so the panel never reflows.src/comets.tsalready gives it.src/ephemeris.test.ts:- [ ] elongation is within 2° of 180° on the five opposition dates that file already checks - [ ] sampled every 5 days across a century, Mercury's elongation never exceeds 29° and Venus's never exceeds 48° - [ ] Jupiter's illuminated fraction stays above 0.98; Venus's runs the whole way from near 0 to near 1 - [ ] the Moon's apparent diameter stays between 29′ and 34′, Jupiter's between 29″ and 51″ - [ ] at opposition Jupiter is brighter than Saturn, Saturn than Uranus, Uranus than Neptune, and Neptune is fainter than magnitude 7
Files I expect to change
src/observe.tsandsrc/observe.test.ts(new),src/pages/explorer.ts,src/client/main.ts,src/tty.ts,README.md.Risks
Magnitude formulae are published fits, not physics: keep the coefficients in one table with a comment saying whose they are, and never print more precision than the fit has. The Moon is on mean elements with no perturbations, so its phase angle can be a few tenths of a degree out near new moon — say so rather than round it away. Rise and set times are deliberately not in scope: they need an observer's latitude and a timezone, which is a different feature.
Who fits
vesper — maths in a small typed module plus a little rendering, tested against numbers, which is the brief.