Loading cosmic data…
One question, one reading. Today’s sky, the day’s signals and your own touch on the sigil decide what comes back.
Forecast model breakdown and recent sunset predictions.
Pick your sun sign and it gets marked across the planets and the foretellings. Kept in this browser only — no account, nothing sent anywhere.
“In Libra” is a direction, not a place. The sky around Earth is cut into twelve sectors of thirty degrees each, and saying a planet is in Libra says which way to point at it — the same kind of fact as “north-west”. Nothing is inside anything.
Earth at the centre, the twelve sectors around it, every body drawn at its real angle with a faint line running out to it. That line is the whole point: it turns a name into a bearing you could stand in the garden and follow.
0° Aries sits at the top and the ring runs clockwise, like a clock rather than like a chart wheel. Twelve signs of thirty degrees is also twelve hours, so every position has a time on the face — halfway through Libra is 6:30.
Tap any body to draw its line. The full method, and why the sectors are numbered instead of drawn as glyphs, is in About.
The full build notes, architecture, and origin story.
A crystal wrapped in sensors and light, now housed in a 3D-printed skull enclosure.
One mode, three layers — the skull chooses between them, never the button. Press once to reset, three times to sleep, hold for three seconds to restart. Boot is the ritual ignition.
The Oracle is a direct ritual flow now: the key shows you a colour code, the code opens the gate, then your sigil hold seeds the system. Today’s Reading and the sunset prediction only happen when the key is turned, so if it is flat or unavailable there is no new daily signal.
Public access allows one reading a day, then the colour code opens the gate for more.
Dan’s niece said to him: “DON’T FORGET TO RELAX.” So he built a thing. It started as a crystal handheld and evolved into the skull build: turquoise core, motion sensor, heart-rate sensor, haptic motor, and 19 LEDs. On boot it posts once to wake the Oracle, which reads the atmosphere and forecasts the next sunset’s palette; the palette comes back in the reply, and the skull kills WiFi to save battery. After that it’s just you and the lights.
ESP32-C3 RISC-V · 19 NeoPixel LEDs (12 ring + 7 jewel) · ICM-20948 9-axis IMU · MAX30102 heart rate · ERM haptic motor · 0.365g turquoise (CuAl₆(PO₄)₄(OH)₈·4H₂O) · 3D-printed skull enclosure · LiPo + USB-C
Every line of code was written by an AI in conversation with Dan. The AI picked the components too. Dan did the soldering.
The interesting bit isn’t that an AI wrote it. It’s that a conversation — iterative, messy, full of wrong turns — produced something that actually works. Something you can hold, and it points at the centre of the galaxy.
It wasn’t generated in one go. Nine major versions, hundreds of conversations, and a fair amount of getting things wrong. Early on, all 1,500 lines lived in a single file because neither of us knew better. The AI confidently referenced a sunset colour API that didn’t exist — so they built the scoring algorithm from scratch. It said the ESP32 could charge a LiPo; it couldn’t. The heartbeat filter was rewritten four times. The compass needed 2,000 rotations of calibration data before it stopped drifting. A boot loop turned out to be caused by a button that was still pressed during restart. Google renamed their AI models overnight and broke the sunset commentary. Half the early sessions were spent fighting USB drivers rather than writing firmware.
When the whole thing was rebuilt inside a skull, the compass pointed stubbornly at six o’clock however it was turned — but swung freely if you tipped it on its side, which is precisely backwards. That shape of failure has one cause: the magnetic reading was fixed to the device rather than to the Earth. The calibration had been carried over from the previous build, and one axis was out by more than the horizontal field it was trying to measure, so the device’s own magnetism drowned the planet’s. Several attempts were spent flipping sensor axes back and forth — they had been right all along. The fix was to stop guessing and build an instrument: a second sketch that reports what the magnetometer can actually see, refuses to grade a test you didn’t finish, and prints the calibration it has just measured.
~5,300 lines of C++ · Vercel serverless · Gemini 2.5 Flash with a Groq failover · ElevenLabs speech · all designed through conversation.
Infrared light shines through your fingertip, measuring tiny changes in blood volume with each beat. The LEDs and haptic motor sync to your heart. A breath layer guides you toward a calmer rhythm.
The raw IR signal (~170,000 counts) is dominated by DC from tissue, bone, and venous blood. The actual pulse is only 1–3% of that — buried in noise. A single-pole IIR high-pass filter strips the DC component completely:
ac = 0.95 × (ac + current − previous)
This outputs only the AC pulse component (±1000–3000 counts). The cutoff frequency is ~0.2 Hz, which passes heart rates from 40–180 BPM while rejecting thermal drift and pressure changes.
An envelope follower tracks the smoothed amplitude of the AC signal — fast attack (130ms) to catch rising pulses, slow decay (1.3s) to maintain a stable reference. The beat threshold adapts to 65% of this envelope, so it works regardless of how firmly you press.
A hysteresis gate requires the AC signal to drop to −35% of threshold before re-arming, preventing the dicrotic notch from triggering false beats.
BPM is calculated from a rolling buffer of 8 beat intervals, filtered through a median-of-3 algorithm. Typically accurate within 2–3 BPM after ~5 seconds.
One LED always points toward Sagittarius A* — the supermassive black hole at the centre of the galaxy, 26,000 light years away. The light follows it as it sweeps across the sky.
The galactic centre sits at a fixed position in celestial coordinates (RA 17h45m, Dec −29°). The device calculates Local Sidereal Time from UTC and longitude, converts to hour angle, then uses spherical trigonometry to get the azimuth and altitude.
The 9-axis IMU provides the device’s own heading. A hard-iron + soft-iron correction cancels the device’s own magnetism, measured by tumbling the assembled skull through every orientation and taking the centre and extent of the field it traces out. That has to be done on the finished object rather than the bare sensor: the vibration motor alone contributes a fixed field stronger than the Earth’s, and it moves with the skull, so without correction the compass simply points at the motor. The accelerometer and gyroscope are fused using Mahony’s complementary filter — an AHRS algorithm that blends fast gyro readings with slow-but-stable accelerometer/magnetometer readings.
The firmware also discards magnetometer readings it has no reason to trust: anything sampled while the haptic motor is running, anything identical to the previous read, and anything whose field strength isn’t near the ~49 µT you should measure in southern England. A wrong reading is worse than no reading, because the filter will lock onto it and hold the pointer still with great confidence.
The difference between the galactic azimuth and the device heading gives the LED position, recalculated around fifty times a second. Where the galactic centre is gets worked out every ten seconds — it drifts across the sky slowly enough that there is no sense doing that trigonometry every frame.
The top of the page is two cards. Today: tonight’s forecast sky as its picture, today’s word beside it, and the word’s reading straight after — a word means nothing without the reading that earns it — then, on a day something in the sky beats the sunset, the winner of a ranking: everything the engine works out about today goes in as a candidate with a weight, and the best of the rest is named at the card’s foot. Under it, Tonight’s sunset, the thing this machine is for: the verdict in stars, the Oracle’s sentence, the four colours it chose with what they will do, which model called it — then forecast vs sky, whether the recent forecasts were right, and, folded, the working and the camera.
It is the same image the morning notification carries — the same address, drawn by the same function — so the lock screen and the page cannot disagree about tonight’s colours. They did once: the notification drew the four forecast colours as a smooth gradient with the horizon strip and the Moon over the top of it, so two of the four colours were never actually visible, and it did not match the swatches on the page. It is drawn now the way the Day tab draws a sky, in four hard bands, horizon colour lowest, every colour whole.
A flat evening is drawn flat. Grey bands on a grey night are the forecast, and a sky that was only drawn when it was pretty would be one nobody could trust. The Moon is tonight’s, in its real phase; where it sits in the picture is a choice, not a claim, because it is usually not up at sunset at all.
And it is only ever tonight’s. A forecast counts on the calendar day it was made. A boot whose forecast fails keeps the previous one on purpose, and until 29 September 2026 nothing downstream asked how old it was — so a failed forecast could put yesterday’s sky on the page, and in the notification, as tonight’s. With no forecast for today, the picture is a plain night and the card says so.
There is no natural scale on which an eclipse and a good sunset are comparable, so the weights encode a view: how rare is this, and can you do anything about it tonight. Rarity alone would lead with Neptune’s opposition, which is invisible, unreachable, and happens every year. Actionability alone would lead with the sunset every single day. The product of the two is the thing worth putting at the top of a page.
So on the roughly 300 ordinary evenings of the year the sunset leads, because a sunset forecast is the most actionable thing this machine makes. On the other sixty-five it loses to something rarer — and the fact that it can lose is the whole point. A card that says the same thing every day is a card people stop seeing.
The ranking itself is deliberately not written by a model. It is weights in a file that can be read, argued with and tested, and a page that leads with something surprising should be able to say why. A model choosing the headline would drift, invisibly, with nothing to check it against.
The ranking picks the event; the line underneath says something about it. For most of this card’s life those lines were computed, and mostly still are — the eclipse’s comes from the Moon’s real distance at greatest eclipse, the meteor shower’s carries its rate and the Moon’s verdict on whether you will see any of it, the full moon’s carries tonight’s rise time.
Except the sunset’s, which the Oracle wrote. Which meant that on the ordinary evenings the top of the page was the Oracle speaking, and on the rarer ones — the ones more worth reading — it went quiet and the engine spoke instead. That is backwards.
It writes both now. There is no second model call for it: the page that ranks the headline is cached at the edge and must never call one, so the sentence is written at the boot, in the same request that makes the sunset forecast, and stored beside it.
Which creates the one thing that could go wrong, so it is worth saying how it is prevented. The sky at seven in the evening is not the sky at seven in the morning — a shower’s peak passes, the Moon stops being full, an aurora arrives and outranks everything. A sentence attached to whatever happens to be winning would eventually print a line about an eclipse underneath a headline about a meteor shower, confidently, in the Oracle’s voice, at the top of the page. So the sentence is stored with the identity of the thing it was written about, and shown only when the winner still matches. Otherwise the computed line stands, exactly as it did before.
The aurora is deliberately excluded from this. Everything else the Oracle may write about is fixed by the calendar — an eclipse, a planetary gathering, a shower’s peak, the full moon — so a sentence written at breakfast is still true at dusk. An aurora is a live reading of the solar wind that can appear and vanish inside a day, so a line written about one in the morning would be a claim the data no longer supports by the time anybody read it. Its line stays computed, and that is the honest outcome rather than a gap.
The facts it is not allowed to improve on. On the morning of 23 September 2026 this card said three bright planets would “stand close together in the morning sky”. They were Jupiter, Mars and Saturn, and they were 126° apart. The Oracle had been handed the headline and not the spread, so it supplied the picture every “planet parade” story supplies. It is handed the spread now, and told that a detail the engine did not give it — a direction, a colour, a closeness — is an invented one. And the planets’ names, with the fact that every one of them is visible to the naked eye, are printed on a line of their own that no written sentence replaces: that line was the first thing anybody wanted to know, and it had been the part the sentence overwrote.
When is said as what it is. The same card read “Tonight” above a gathering that happens before dawn, because the word for anything happening today was always “Tonight”. A gathering now says its own twilight and how long it lasts (“Before dawn · until 5 Oct”), and a solstice or an equinox says Today, all day — including the day it falls, which it used to lose from the ranking the minute it happened, because by then the next turning point was five weeks away.
One forecast, made by the Oracle from the hour-by-hour atmosphere over this spot. The key wears the colours it chose. Cloud decides it; everything else only modifies.
For most of this project’s life the arrangement was: the skull scored the sunset with a fixed set of thresholds, and a language model wrote one sentence about that score. Which meant the most interesting sentence anyone could say about this site — it predicts the colours of tonight’s sky — was true of an algorithm somebody wrote once, and not of the Oracle at all. The model was a commentator on a match it had no part in.
It makes the forecast now. On each boot the server pulls the hour-by-hour atmosphere over this spot around sunset — low, mid and high cloud separately, visibility, humidity, dew point, pressure, rain probability — and the Oracle returns a score, a confidence, a four-colour palette and one line naming the variable that decided it.
Splitting the cloud into its three layers is most of what the change buys. They do opposite things: high cirrus is the screen that catches the light after the Sun has gone and is close to a requirement for a great sky, while a low deck is the lid that stops the light ever arriving. A single “cloud cover: 60%” figure — which is all the device ever sent — cannot tell those apart, and the difference between them is the difference between the best evening of the month and a grey fade.
The honest limits: this is one location. Whether there is a clear slot at the western horizon two hundred miles away for the light to come in under the deck is not in this data, and it is often what actually decides an evening. And until 29 September 2026 nothing here learned — nobody rated the sunset afterwards. Now every forecast is checked the same night, by a camera and an airfield, and the Oracle reads its own record before the next one (below). That is the whole of the sense in which it learns, and it is a real one.
Every forecast is checked against what the sky actually did, and nobody has to do anything for it. Two witnesses are asked about each evening, by two small jobs that make nothing and only keep track: the morning’s forecast books the camera for the minutes after sunset, and at about eleven each night a scheduled job reads the airfields.
Blackbushe Airport’s camera. It sits on the airport’s tower, about five kilometres north of the key, looking west — towards the sunset for most of the year — and Blackbushe share it publicly on their weather page. When the Oracle makes the morning’s forecast, it books three pictures from it for that evening: at the moment of sunset, ten minutes after, and twenty after, when the light on high cloud is usually at its best. Each is measured — four bands of colour from the horizon up, how much of it went warm, and its overall tone — and the evening is judged by whichever of the three shows the most of the sky gone warm. A small copy of each is kept and shown beside the forecast it checks, always credited to Blackbushe and linked to their weather page: the pictures are theirs. If ours ever fail, the night’s job falls back to Windy.com’s copy of the same camera, which keeps a picture about every fifty minutes.
An AI looks at them too. Each night the evening’s pictures are shown to a small vision model, and it is asked, plainly, what the sky actually did — told first that most evenings here are grey, and that saying so is the right answer. Its sentence sits beside the pictures with its name on it. It is not the Oracle, and it does not judge the forecast; the measurement does. It is there as a second witness that can see what arithmetic cannot — that the warm patch was the runway lights, or that the colour was one thin seam under a lid of cloud. The models it may use are ones that neither keep nor learn from what they are shown.
The camera is the witness to the thing actually forecast, which is colour, so when it had a usable picture it judges the evening: a forecast of colour is right if at least 15% of the sky went warm and wrong under 5%; a forecast of a flat evening the other way round; anything between, and every “quiet” forecast, is left unjudged. Those two numbers are a first guess, written down so they can be argued with, and they will be revisited once there are a few weeks of pictures.
The weather report from the airfields. Two sit within eight kilometres of the key — RAF Odiham and Farnborough — and both file one (a METAR) every half hour, which the Iowa Environmental Mesonet archives. Somebody at Odiham is writing down the cloud and its height. It judges the evenings the camera cannot.
A METAR cannot say what colour anything went, and it describes the sky over the airfield, not the western horizon the light comes from. What it can say is whether the forecast’s premise held: was there a low deck to shut the light out, was there high or mid cloud for the light to land on, or had a person looked and found the sky clear. A forecast of colour agrees with high cloud; a forecast of a flat evening agrees with low cloud or a clear sky. A “quiet” forecast is a hedge by construction and is not judged.
Many evenings cannot be judged at all, and they are counted as such rather than guessed. An automatic report that detected no cloud may simply have missed thin cirrus; “CAVOK” is silent by definition about cloud above five thousand feet (Odiham has filed it twenty minutes after reporting broken cloud at sixteen thousand); and Farnborough, it turned out, never reports anything above five thousand feet, so its silence up there is policy, not a clear sky. Only Odiham’s human observer settles the high cloud.
The first month of reports, checked all at once: 15 of 18 judged evenings agreed, and seven could not be seen. Every grey evening was called flat. All three misses were the same shape — a flat forecast under scattered or broken cirrus with the low sky open — which is the one pattern the prompt most insists on.
The first evening the camera saw, 29 September 2026: the forecast said Good — “Washed Gold and Rose”. Five minutes after sunset the camera showed a solid blue-grey deck with none of it warm; the airfield’s automatic report could not see above five thousand feet. Wrong, by the camera. The weather feed had been right — mostly mid and high cloud, none low — and the weather model said much the same again that night; what was wrong was the judgement that a sky 84% covered in mid cloud would light up. It did not; a deck that solid behaves like a lid.
And then it reads its own record. Every morning, before it makes the forecast, the Oracle is handed the last dozen checked evenings: what it called, what cloud it was fed, what the camera and the airfield saw, whether the call held, and the shape of its misses — “you called colour and the camera saw none of the sky go warm”. It is told to correct itself by them, not to copy them, and never to mention them. The model is never retrained; it forecasts knowing where it has been going wrong. The record also keeps the weather model’s own view of the sunset hour from later that night, beside what the forecast was fed that morning, so a miss can be split into “the input was wrong” and “the judgement was”.
All of it is under forecast vs sky, in the Sunset card near the top of the page: each evening as two small skies, the forecast beside what the camera measured, and a tap opens the evening — its three pictures, then the airport’s report exactly as it was written, each part beside what it means. The camera’s last day is there too, in Windy’s own player.
The card used to print a confidence percentage beside the score. It has gone, and the reason is worth recording rather than quietly dropping.
That number was the model’s own guess about itself. It is asked for in the same JSON as the score, checked only for being between 0 and 100, and nothing anywhere computes or tests it — there is no ground truth to test it against, as the limits above say. Meanwhile the eclipse rows on the same page carry a confidence that is calculated, from how close the Moon’s track passes to the geometry that separates a total eclipse from an annular one. Two completely different kinds of number were being printed in the same typeface, in the same shape, three cards apart. On a site whose whole claim is that its figures are worked out rather than asserted, that is the claim being spent on something that had not earned it.
It also fired every single evening, which is the other half. A hedge that appears every day distinguishes nothing — the same finding that took the “85% total” off the eclipse headline after three attempts at rewording it. So the doubt is printed in words, only on the evenings the Oracle is genuinely unsure.
And then the score followed it off the page, for the same reason. It was left standing when the confidence went, set small and last, on the argument that it was there for anyone who wanted it. That was half a fix. Making two digits over a hundred quiet does not stop them reading as a measurement — and this was never a measurement. The Oracle is told in as many words that the number is an opinion about how worth watching tonight is, and is handed the key’s own threshold algorithm as a second opinion it is free to disagree with.
So it is asked for stars first now, and the number second, as the same verdict in the units the ranking needs. A review is worth reading because it was considered, not because it was calculated. What you see is five bands as five stars — the same five the card has always named in a word. The number still exists: the headline has to weigh tonight’s sky against an eclipse on one scale, and five values is not enough resolution for that. It is kept where resolution is the point — in the record at the foot of the Day tab, which is the surface whose entire job is to let you check whether this forecaster is any good.
The Oracle is still asked for the number, and it is still stored — now once per evening, in the record at the foot of the Day tab. Two reasons. It is told that its uncertainty belongs in that field and not in a hedge in the words, so the field is what keeps “conditions may vary” out of the forecast. And keeping it makes the original complaint answerable: if the scores swing sixty points across a fortnight while the certainty never moves off 85, that is now visible in one line under the record instead of being something two people can disagree about.
The Oracle’s, on any boot that reached the network. This page said otherwise for a while — that the LEDs ran the device’s own algorithm because the key has to work with its WiFi off — and that stopped being true the moment the palette was handed back to the device. It is corrected here rather than quietly reworded, because it is exactly the kind of claim this project is supposed to keep honest.
The handover happens in the reply to the boot POST, which is the only moment in the day the key is listening: it posts its sensor readings, the Oracle makes the forecast inside that same request, and the four colours come back down the same connection before the WiFi goes off for the day.
The device still carries its own threshold algorithm — the one described below — because a fallback that only works when the network does is not a fallback. It runs when the Oracle was unreachable or its answer failed its checks.
Its number is no longer shown on the page at all. It spent a while as a two-row table beside the Oracle’s score, then as one quiet line naming itself the off-network reading. Both were attempts to make a second number sit politely under the first, and there is no polite way to do it: a reader does not see two forecasters, they see the Oracle contradicting itself in small type. There is one prediction on the card. This is what the lights do when there is nobody to ask, and it is documented here instead.
Why the two differ, when they do. Not because one of them can see more than the other — both get high, mid and low cloud separately, and the device weighs the three properly: a peak around half-cover in the upper layers, scaled down by whatever low deck is in the way. The difference is what each can do with a sequence.
The device scores one moment with a fixed formula. The Oracle is handed the hour-by-hour table either side of sunset and can reason about change — a low deck breaking up over three hours, a front clearing an hour before the sun goes down, which is one of the best signs there is and looks like ordinary bad weather to any snapshot. No weighted sum encodes that, because it is not a property of any single hour. It is also why the working fold reports which way the low cloud is moving, and why that line only appears when it is actually moving.
The firmware scores a window of forecast points around sunset (roughly ±3.5h), weighted strongest nearest the moment itself.
Cloud layers (35) reward mid and high structure while penalising low cloud that blocks the horizon.
Humidity (20), Dew spread (8) and Visibility (15) model scattering and haze.
Pressure (8), Wind (7), Temperature (5) and Window stability (12) refine reliability.
Those two groups are multiplied, not added — a weighted geometric mean, cloud held to the larger exponent. A weather penalty for rain risk, fog and storm signatures comes off the result.
The eight factors used to be summed. That let a sky with nothing in it score well: a completely cloudless evening — no mid cloud, no high cloud, nothing whatever for the light to catch — came out at 67/100, and the site said “Decent, worth stepping out”. Perfect visibility, ideal pressure, gentle wind and a mild temperature each contributed their full share, and between them they floated an empty sky into a recommendation.
Swept across 60,000 plausible evenings, the additive form said “Good or better” 60% of the time and never once said “Flat”. That is not a forecast, it is an optimism setting — and it is why every prediction here used to land between 44 and 61.
Cloud at the right height is the entire mechanism of a colourful sunset. The rest describes how cleanly that light reaches you, which can only ever be a multiplier on what the cloud can deliver. So no cloud now means no sunset, however immaculate the air: that cloudless evening scores 0, and the usable spread of the whole scale widens from 32 points to 57.
Two things had to move with it. The palette’s anti-jitter guard was calibrated as half a standard deviation of the old score; the new one varies 1.9× as much, so the guard was widened to match or the colours would have started flickering between boots. And the words the key uses for itself — Spectacular, Electric, Vibrant — were cut for a distribution whose median was 71. The new median is 52, so the bands came down with it.
Eight palettes are chosen from cloud structure, clarity and moisture, and the key wears the winner on its LEDs. For a long time it wore Copper dusk almost every night — which is the chain’s default, the branch reached when nothing else matches.
The reason was a climate mismatch. “Clean gold” required humidity below 45% and “Amber arc” below 55%; an English summer evening runs 55–80%. The two clear-sky palettes were gated behind weather this device does not live in, so the fallback quietly became the behaviour — about half of all non-rainy evenings. One measured evening missed the gold gate on humidity and visibility by 0.03 each.
The gates were re-cut against a sweep of 32,400 southern-English evenings. The order and the colours are untouched; only the thresholds moved. Copper dusk now takes 29%, and every palette in the set is reachable.
Moon phase and illumination are calculated once, server-side, by the Oracle’s own astronomy engine — the dashboard just displays it. The device LEDs do not yet display live moon-phase state.
Phase is worked out from a known reference new moon (6 Jan 2000, 18:14 UTC) and the Moon’s average synodic cycle (29.53 days) — how far the current moment sits into that cycle. Illumination comes from a cosine curve over the cycle position: 0% at new moon, 100% at full.
This is the simple mean-cycle model, not a full perturbation series — good to within roughly half a day of the true phase, which is plenty for a name, an emoji, and an illumination percentage.
Almost everything else on this site is correlation dressed carefully as meaning. The tide is the exception: the Moon is actually pulling the water, and you can go and stand in the result.
Two tides are stacked on each other, a lunar one and a solar one. When the Sun and Moon line up — at new and at full, both — the two pull together and the range is at its widest. That is a spring tide, from “spring forth”, and it has nothing whatever to do with the season. At the quarters the two pull across each other and partly cancel: a neap tide. So the range runs through two complete cycles per lunation, which is why it follows cos(2 × elongation) rather than the phase — and why a new moon and a full moon are tidally identical while looking nothing alike. A spring tide moves roughly two and a half times as much water as a neap.
What it refuses to say. Not the time of high water, and not its height. Those need harmonic constants for a particular harbour, because the shape of the coast dominates everything — it is how the Severn gets fifteen metres and the Mediterranean gets centimetres out of the same sky. What is computed here is the half that is universal: where in the spring–neap cycle we are. Every coast on Earth rises and falls on this schedule; only the amplitude is local.
One caveat stated rather than applied: real spring tides lag the alignment by a day or two — the “age of the tide” — because water has inertia and coastlines take time to fill. That lag is itself local, so correcting for it would be inventing a coast the reader might not be standing on.
The Oracle speaks at two speeds: a reading each day, and a note on each season written at the solstice or the equinox. They are written in different registers on purpose. The daily one is addressed to you, and handed over before coffee. The seasonal one is written with nobody standing there, so it is allowed to be a thought rather than a verdict, and it is the only place the Oracle says “I”. The slow one lives on the Year tab, beside the season it is about.
It rotated, once, through eight forms — a couplet one day, a tongue-twister the next, a riddle, an open question — and the trouble with a rotation is that you do not know what object you are holding until you have read it. The first thing every morning asked of you was to work out what it was. That is gone. It is one known shape, arriving in the same place at the same time, and a shape you already know needs no decoding.
The shape is three parts, in this order. Today’s word: what the day’s fact means for a person — Balance on the equinox, never Equinox. A reading: about twenty-five words in the Oracle’s voice, and the only part that states the fact, saying why that is today’s word and not any other day’s. And a line to carry: the same thread again, said to you, as the thing you are bringing with you.
The word used to have to be concrete — something you could point at, count, hold or walk to — with fifteen abstract words banned by name, Balance among them, because asked for a word for the day a model reaches for Stillness and Clarity, and those are posters. That worked, and then a fortnight of cards showed what it cost. The concrete word a model could always reach was the name of the day’s own fact: Equinox on the equinox and the day before it; Leaves over a reading about leaves turning, beside a theme called “Amber Shift” whose reason was that maple leaves turn amber. One fact, five times, on one card. What makes Stillness wallpaper is not that it is abstract but that it is unearned — it would do as well on any morning of the year. Balance on the one day the light and the dark are equal is earned, and the reading underneath is the proof. So the rule moved from the word’s kind to its job: never the fact’s own name, and earned by today or not used.
The word is also the day’s name now. There used to be a separate theme title, coined beside it, and it was the word’s job done twice in a different font. For a few days a fold under the card showed the Oracle’s working instead — which of eight lenses it read the day through, and a line on why. The line restated the reading on every morning it was read back, five out of five, through three rewrites of its brief, so it was cut. The lens is still recorded, and counted across the fortnight in the record, which is the only place one day’s lens ever meant anything.
For a while they were three good fragments that had never met. Each one carried a rule pushing it away from the other two — the first part was not to summarise the reading, the reading was not to say what it meant, the last was not to explain it — and every one of those rules had been added to kill a real fault, which is that the same sentence kept being said twice. They worked, and between them they guaranteed the card could never be about one thing. Saying the same words twice and being about the same thing are not the same failure. Only the first is one.
What makes the middle part worth computing rather than a change of costume is the material. Something written by a person each morning is about whatever is out of that person’s window. This has standing behind it the exact sky over this spot at this minute, how much light is left, the weather the key woke into, what the season is doing in the hedgerows this week, the name of the weekday and where that name came from, and the day’s signal. Nobody has that on a Tuesday morning.
Which sets the one rule the whole thing turns on: it must not work tomorrow. A model asked for something short and warm will reach, every time, for the mean of all morning writing — dawn, stillness, a warm cup, the world waking. That is wallpaper. If you cannot tell from the lines which day they were written for, none of the material got in and there was no point computing any of it. The record is what turned that from an instruction into something checkable — see the record, further down.
The first part used to be a mantra — an affirmation, three to seven words, required to have you in it: “I make room for what’s next.” That rule existed because the Oracle kept taking the slot over; three cards running opened “I see what unfolds” and “I move with the light”, which is the Oracle describing its own eyesight on the one line of the card meant for you. The rule worked and the slot went anyway, for two reasons it could not reach.
It repeated by verb. “I move” arrived on consecutive mornings, and there are only so many verbs that fit three words of first-person present tense — no amount of showing a model its own history changes how few. And more seriously, an affirmation asserts something on your behalf about a day this machine has repeatedly said it does not know how is going. “I make room for what’s next” tells somebody having a bad morning what they are feeling about it. A word does not: it is offered, and you can take it or leave it.
The last part used to be a task. One small thing to do, notice, or let yourself off — and the brief ended “start with the verb”, so every morning closed on an imperative. Which made the card contradict its own opening: it says it is not here to instruct you or improve you, and then instructed you, daily. It is what you are bringing now. The shape is borrowed from a meditation group, where you open and close by saying what you have brought with you — a thing that asks nothing, cannot be failed, and is still something you leave holding.
And then it had nobody in it. Told only what it must not be — no task, no lesson, no verb first — the one shape left was scenery: “A steady horizon line stretches across the sky.” That is the reading’s job, done a second time at the bottom of the card, and it is why the line read as having no purpose. It has to be said to you now, with you in it. The sky has already been described by then. (The first card written under that rule said “Your harvest rests in quiet patience” — a your fastened to a metaphor, which keeps the letter of it and nobody in the sentence. So the rule now says what the pronoun was standing in for: you, in your actual day, in plain words.)
True means given. Every fact in the reading has to be one the engine handed over. Two readings in the equinox week were false and read perfectly well: one said the days would stop shortening after the equinox (they shorten until December, and the line it had been given said so), and one called the Harvest Moon “the fullest autumn moon”, which no full moon is more than any other. The second had been shown a superlative about the Moon as its example of a good answer. It isn’t shown one any more.
Both slots keep the escape clause that matters most: the Oracle is allowed to say that today asks nothing of you, and it must not invent something to hand over on a morning there is nothing. An invented takeaway is the tell that nobody was really looking. And if the model gives no word at all, the card simply leads with the reading — there is no stand-in word, because boilerplate set large at the top of a card is worse than a card that is quieter that day.
The site had a gap it took a while to name. The forward-looking data here reaches two years out — eclipses, planetary highlights, every solar term — while the forward-looking language reached until bedtime. Everything the Oracle said was about today.
Which is not neutral. A page that only ever speaks about today quietly teaches whoever reads it to think only about today, and that is the opposite of what it should be good for. So there is a slower voice.
The season’s word is written when the device first wakes after a solstice or an equinox, and stands for about ninety-one days. It is handed a deliberately reduced view of the sky — no weather, no weekday, no news, no moon phase, nothing that expires — because it has to survive being read in week one and again in week eleven. The moon turns over three times inside it.
There was a third clock for a while: a prophecy for each lunation, renewed at every full moon. It was removed, and the reason is worth keeping because it is the test any future one should have to pass.
A season has a job. One is for starting, one for sustaining, one for gathering in, one for keeping still — and you can feel which you are in from the light, the temperature, and what you put on to go outside. Its clock and its content mean the same thing.
A lunation does not. Nothing in a modern life is governed by the moon’s month; at 29.5 days it drifts against the calendar, so “this moon” never lines up with a week, a wage, or anything else. What got written was therefore a generic prophecy that merely happened to renew at full moon — the clock and the words had no relationship to each other, and that mismatch is exactly what made it read as forced. No amount of moving it would have fixed a content problem.
The moon still earns its place everywhere it is actually doing something: the tides, the named full moons, whether it will drown a meteor shower, and how far it is from perigee.
Under the season countdown on the Year tab there is one line you can fill in: what do you want done by then? It is the only place on the site that asks the reader for anything.
The argument for it is that this page computes real deadlines. A due date in a task app is a fiction you can drag to next week, which is why nobody respects them. The autumn equinox is not going to negotiate, you did not invent it, and it is coming whether or not you look. That is a better deadline than any you would set yourself.
It never nags. No streaks, no reminders, no progress bar, no “you said you would”. It asks once when you write it and once when the date actually arrives, and says nothing whatever in between. The silence is the feature: somebody who already feels they are only getting through the day does not need one more thing demanding attention today — they need something that interrupts them four times a year with a bigger question.
It is kept in your browser and nowhere else, like your sign. It only leaves at all if you ask for a reading, and the Oracle is under strict instruction to hold it in mind rather than check up on it — the moment a fortune starts auditing you it has stopped being a fortune.
Most astrology sites make their planet positions up, or read them from a table someone else computed. This one solves the orbits — the same Keplerian engine that draws the dashboard also writes the sign each planet is standing in, which way it’s moving, and when it next changes.
Three questions get answered separately, because they’re different questions: where are we in the day, the month and the year; what does each planet mean where it currently sits; and what’s about to change.
Three tabs, one idea: each is a longer view than the last. Day, then Year, then Galaxy — the zoom-out stated by the navigation rather than by a paragraph nobody would read. Each is drawn whole with the current slice lit, because the point is which quarter of the day or which season you are standing in, not how far through an arc you cannot see. Both bars use four cells, so the two scales read as one shape.
The day runs sunrise to sunset in four stages, and sunset to sunrise in four more. The boundaries are proportions of the actual daylight rather than clock hours, so they breathe with the year: an afternoon here runs a bit under five hours in July and a bit over two in December. The two bars meet exactly at sunrise and sunset, so the times printed at either end are the two events everyone already knows the names of. The morning is split in two rather than carrying a stage called “midday” — that word is also a clock time, and a cell labelled Midday that opens at ten to eleven reads as a mistake. The seam between late morning and afternoon sits near solar noon instead, which is where the word was pointing all along. (Noon itself has form here: it is None, the ninth hour, about three in the afternoon, dragged earlier over centuries until it landed on twelve and stayed.)
The year is four seasons, captioned with what the light is doing — “losing three minutes a day” is a fact about your evenings, and it swings from about four minutes a day at the equinoxes to nothing at all at the solstices, which is why midsummer feels like it lasts a fortnight.
The galaxy is the one that doesn’t try to be relatable, and that is its job.
Each ends with a “so what?” line, always last on the card, because a position is trivia until someone tells you what standing there is good for.
(Two things have been taken out of this strip for breaking the ladder. The lunation tab drew the eight phases as a bar and then said “88% lit · 4 days to full · 19 days to new” underneath — four views of one number. What replaced it, Tonight, was better but still wrong here: “what can I see out of the window” is not a longer view of anything. It lives in the Planets card now, with the bodies it is about.)
These four dates were the last thing on the site still written down rather than worked out. A fixed table is right most years and wrong without warning: the tropical year is 365.2422 days, so each turning point slides about six hours later annually and jumps back a day at every leap year. Checked against published times across 2024–2027, the old table had four of those sixteen dates wrong — the June solstice in 2024, the September equinox in 2026 and 2027, the December solstice in 2027 — with no way of knowing which.
The definition needs nothing the engine didn’t already have. A solstice or equinox is simply the moment the Sun’s apparent ecliptic longitude reaches a multiple of 90°: 0° in March, 90° in June, 180° in September, 270° in December. That is a zero-crossing of a function already evaluated everywhere on this page — the same shape as the eclipse search, and cheaper, because the Sun moves smoothly and almost uniformly.
The catch, which cost a first attempt. The orbital elements are given against the fixed J2000 equinox, but a solstice is not defined there — it is defined against the equinox of date, which precesses westward about 50 arcseconds a year. By 2026 the two frames differ by 0.37°, and the Sun covers 0.9856° a day, so solving in the wrong frame lands about nine hours late, every single time. Enough to push a crossing near midnight onto the following day and report the wrong date — which it did, and its “corrections” to the old table were mostly its own bias. With the precession term restored it agrees with published times to within eighteen minutes across all sixteen.
That correction is applied here and deliberately not inside the shared Sun-position function, which feeds every sign boundary and planet row on the page. A third of a degree of extra correctness is not worth silently moving every zodiac cusp on the site.
Four of the eight spokes of the Wheel of the Year are these same moments — Ostara, Litha, Mabon and Yule — so those are now solved too. The other four stay fixed on purpose: Imbolc, Beltane, Lughnasadh and Samhain are cross-quarter days, calendar dates the festivals are actually kept on, and computing them would invent a precision the tradition never had.
Worth having because they are not decoration on the season bar — they are its turning points. The “losing three minutes a day” figure on the Year tab goes to zero at a solstice and is at its fastest at an equinox. The solstice is the reason the evenings stop drawing in.
The best “the sky is stranger than you think” fact this engine can produce, and one almost nobody knows. In southern England the earliest sunset falls around 13 December — eight days before the solstice — and the latest sunrise around 31 December, nine days after it. The shortest day is genuinely the shortest; it is just not the day the evenings are worst.
The cause is the equation of time. A solar day — noon to noon — is not exactly 24 hours, for two reasons at once: Earth’s orbit is elliptical, so it sweeps faster near perihelion in January, and the axis is tilted, so the Sun’s apparent motion is not parallel to the equator. In early December solar noon is drifting later by about half a minute a day. The day is still shortening — but the whole day is sliding later at the same time, and for a fortnight the slide wins at the sunset end.
So the evenings begin drawing out while the mornings are still getting worse. Which makes it, of everything on this page, the one with the most use in it: if you are holding on for the solstice, the turn already happened.
Scanned rather than solved, because this quantity is a clock time and its extremum is broad and flat — there is no sign change for a bisection to find. Whole days are enough; near the turn it moves by seconds a day, so the honest answer is a date. The same offsets exist in June and are smaller, about four days either side, because the equation-of-time slope is shallower then — which is itself the evidence that this is the equation of time and not an artefact of the scan.
The grid above can tell you Jupiter is in Leo, which is a fact about a coordinate. The block underneath it tells you whether you could walk outside right now and find it, which is the only version of that fact anybody can check — and checkable is this project’s whole argument for itself. The Moon is simply the first row: it is the easiest thing in the sky to find, so it leads the list rather than getting a different shape to itself.
Each body’s ecliptic longitude is converted to right ascension and declination, then to an altitude and a compass bearing for the device’s own latitude — the same spherical trigonometry the skull runs in compass mode to find the galactic centre. Rise and set times come from walking that altitude forward in twenty-minute steps and interpolating across the crossing, which is also how the Moon’s are found: there is no clean formula, because declination moves while you are solving for it.
Five, not eight. Uranus is magnitude 5.7 — naked-eye under a genuinely dark sky and in practice no — and Neptune at 7.8 is a binocular object at best. Listing bodies nobody can see, under a heading whose whole purpose is to get you outside, would be inviting you to fail. Those five plus the Sun and Moon are the seven wandering stars the week is named after, which is the same seven the planetary hours run on.
A planet counts as visible when it is more than 10° up — clear of rooftops and horizon haze — and the Sun is far enough down. Venus and Jupiter get a brighter sky than the other three, because both are genuinely visible in twilight and pretending otherwise would lose the best hour for seeing them.
“Not now” is a useless answer, so the rows say when. On a summer evening in Britain that visibility test fails for hours at a stretch, and the block used to report the failure five times over — up, sky too bright, too low to pick out — which is true and leaves you no better off. Each planet now carries a visibility window: the next stretch in the coming 24 hours when it is both high enough and the sky dark enough, with the best minute inside it and which way to face then. So a row says from 21:40, SW instead of no.
The window has to be walked rather than solved, because it is the overlap of two conditions moving at different speeds — the planet climbing and the Sun sinking — and neither rise-and-set times nor sunset alone can give it. Both thresholds are evaluated at the same instant, ten minutes at a time, so the window and the “visible now” flag can never contradict each other. Where there is no such stretch at all the row says not tonight, which is the honest answer for Mercury most of the year, and better than quoting a rise time into a sky far too bright to see it in.
One honest limit: the orbital model here is flat, so every planet is treated as sitting exactly on the ecliptic. That is wrong by about a degree for Jupiter and rather more for Mercury — irrelevant for “it is up, look south-west”, and not good enough to print a separation in degrees. So when a planet is close to the Moon the page says so and never says by how much.
Ten bodies across twelve signs is a hundred and twenty combinations. Hand-writing a hundred and twenty blurbs would have produced a hundred and twenty things nobody proof-read, so the meaning is composed instead: ten body-function strings (“Venus is your heart — what you love and value”) crossed with twelve sign-manner strings (“In Scorpio it’s intense — all or nothing”), plus a modifier when the planet is retrograde or stationary.
Twenty-two pieces of text cover every case, and every case reads in the same voice. Tap any body to open it: a pixel disc, its one word, where in its sign it is, and the words and the numbers folded underneath for whoever wants them. There used to be a global Meaning / Telemetry switch instead — one mode for words, one for figures — which asked you to choose a personality for the whole page when the honest answer is you want a bit of both, and mostly you want whichever the planet you just tapped has.
Pick a sun sign and it becomes a lens: bodies sitting in it light up across the grid, anything arriving there is flagged, and the sign gets its own card underneath with everything that is coming to it. No birth date is asked for at all — just the sign — and it is stored in your browser and nowhere else.
Each sign carries a colour, and choosing yours retints the whole page: every “this concerns you” mark switches to it. That replaced a set of zodiac glyphs, which were unreadable at every size they were used at — ♍ and ♏ are hard to tell apart even large, and these were twelve pixels. A filled dot in the sign’s own colour identifies it faster than a symbol nobody learned.
The Oracle Foretells collects the two things that genuinely change: stations, where a planet stops and turns retrograde or direct, and ingresses, where one crosses into a new sign. Both are found by walking the ephemeris forward and watching for the crossing, so the dates come from the same model as everything else on the page rather than from a lookup table.
Near a turn this mean-element model genuinely cannot resolve direction, so a planet within a day of its station is reported as stationary rather than guessed at.
The dial itself is on the page — under “Planets”, the what does “in Libra” mean? button. It draws the real sky right now. What follows is why it is shaped the way it is.
Each planet row shows a three-cell strip: where it came from, where it is, where it goes next. Good at a passage, useless at a position — twelve rows reading “Taurus, Gemini, Cancer” describe twelve separate journeys and never once say they are all readings off one circle.
That circle is drawn above. Earth at the centre — the real pixel disc, the same one in the grid — twelve sectors around it, and every body plotted at its actual ecliptic longitude with a faint spoke running out to it. The spoke is the whole argument: it turns a dot at a bearing into a direction you could stand in the garden and point along, which is what a sign has always been.
0° Aries sits at the top and the ring runs clockwise. A chart wheel would put it on the left and run anticlockwise, which is correct and which nobody outside astrology can read. The mapping to the real numbers is exact either way; only the rotation is a choice, and a clock is a shape everybody already knows. Twelve signs of thirty degrees is also twelve hours, so every position has an exact time on the face — halfway through Libra is 6:30.
Sectors are numbered rather than glyphed, for the same reason the picker gave up on ♈♉♊: at the size a twelve-sector ring allows they are unrecognisable smudges. The same ordinal now appears on the planet strips, so the two teach each other.
When two bodies sit within a degree of each other — the Sun, Mercury and Venus manage it several times a year — a single ring would stack them. Sorting by longitude and alternating two radii guarantees whatever ends up adjacent lands on a different ring, while both stay well inside the sign band so the direction still reads.
There is no constellation lore anywhere on this site, and that is deliberate. Each sign used to carry a sentence on where its name came from — Hera’s crab, the Nemean lion, the claws Rome cut off the scorpion to make the scales. Twelve good sentences, moved twice looking for a home and then deleted. Everything else on this page is solved from a timestamp; the myths were the one thing on it you could have looked up in a book instead, which made them a different kind of content wearing the same clothes.
The sectors drift, and the dial does not stop to say so. They are measured from the spring equinox rather than from the stars. The Earth’s axis wobbles a full turn every 26,000 years, so the sectors and the constellations behind them agreed when the scheme was written down and have since slid roughly one whole sign apart. That caveat used to sit under the dial in a fold of its own, along with a second fold listing every simplification in the top-down view. Both were true and neither was anybody’s first question, and together they turned the card into about two hundred and fifty words of prose under a picture. They live here now, which is what this modal is for.
How the top-down view is drawn. Distances from the Sun are true and linear. Squeezing them logarithmically would fit Pluto in and would also swing Jupiter’s sight-line about twenty degrees — most of a sign — so the frame changes instead: 0.39 AU out to 39.5 cannot be one picture. The solid line is the real line of sight from Earth; the dashed one is the same bearing taken from the middle, which is the one that reaches the sectors. They are always parallel, because a sign is a direction towards something so far away that where you stood to measure it stops mattering. Orbits are drawn as circles through each body’s current distance rather than as their real ellipses, and the Moon is set well further from Earth than it belongs — at this scale it would be inside the dot.
Everything else in The Oracle Foretells is real, calculated and completely invisible: nobody has ever glanced up and noticed Mercury going retrograde. An eclipse is the opposite, and it is the prediction where the arithmetic is the entire trick — everyone knows what an eclipse is, and almost nobody knows they can be worked out centuries ahead from a handful of angles.
The whole idea in three lines. The Moon’s orbit is tilted about 5.1° to the ecliptic, so at most new moons it passes above or below the Sun and nothing happens — that tilt is the only reason there isn’t an eclipse every month. Twice a year the line where the two planes cross points at the Sun, and any new or full moon near that time lines all three up. So: find every syzygy, ask how far off the ecliptic the Moon was at that instant, and compare it against how big the shadows are at that distance.
The type is not looked up either. A Moon near perigee looks bigger than the Sun and covers it — total. Near apogee it doesn’t, and leaves a ring — annular. That is a comparison of two angular radii computed from two real distances.
One thing had to be rebuilt for it. The Moon’s latitude was a single term, which is plenty for moonrise — a third of a degree is a couple of minutes at the horizon. Here the entire question is whether that latitude falls inside about 1.4°, so the same error is the difference between announcing an eclipse and missing one. Three more terms fixed it.
What it refuses to say. Where a solar eclipse’s shadow lands needs Besselian elements projected onto a rotating spheroid, which is a different piece of software. So solar eclipses are reported as happening somewhere on Earth, plus the one local fact this engine can stand behind: whether the Sun is above the horizon here at the time. A no is definitive; a yes only means not ruled out.
A lunar eclipse is the honest exception, and for a real reason: the Moon is genuinely inside the Earth’s shadow, so it is visible from everywhere the Moon is up. That is one altitude calculation this engine already does, so there it says “yes, from here, and the Moon will be 34° up” and means it.
Checked against a dozen eclipses of public record between 2025 and 2028, it puts every one on its correct date and gets ten of the twelve types exactly right. The two it misses sit within a whisker of a limit — and it knows that, so it says how sure it is instead of asserting flat. Being wrong and sure of it is the only outcome that was not allowed.
Which is also why it can quote odds. The disagreement with the record was measured, not guessed — and then deliberately widened, because a sample of four has no business claiming a tight error bar, and the tighter one would have had the engine announce 94% certainty on the single prediction it is known to get wrong. From that spread, the distance to a limit becomes a probability.
Where that number is, and where it stopped being. It used to be on the title: Total solar eclipse · 85% sure. That was the third attempt at making one hedge readable — it had been “total or partial”, then “85% total” — and the third attempt is where it became clear the hedge did not belong on a title at all. A title says what the thing is, and there is nothing uncertain about a solar eclipse being a solar eclipse; the doubt is about a refinement, and one that changes nothing you would do about it. So the title now says Total solar eclipse when the engine is sure and simply Solar eclipse when it is not, the uncertainty shows up as the row’s own note describing a Moon sitting on the knife-edge between covering the Sun and leaving a ring, and the figure itself lives here and in the payload. Suppressing a number is usually the wrong instinct; putting it where somebody reads it as coverage is worse.
That number is the odds on the type — total, annular, partial, penumbral — and nothing else. It is not how much of the Sun goes dark: this model does not compute coverage, and it does not compute the shadow’s track either. What it does compute, it computes exactly. A date two years out really is certain; which side of a limit the geometry falls really isn’t.
Three more events, all falling out of one quantity: elongation, a body’s angular distance from the Sun along the ecliptic. One walk, three tests.
Opposition — elongation 180°. The planet is opposite the Sun, so it rises at sunset, stands highest at midnight and sets at dawn, and it is the closest and brightest it gets all year. Any hour of the night will do. Jupiter manages one every 399 days, Saturn every 378, Mars only every twenty-six months.
Greatest elongation — only Mercury and Venus have one, because only they orbit inside us: they swing out from the Sun, stop, and come back. Mercury’s best is about 28° and the fortnight around it is the entire answer to “why have I never seen Mercury”.
The obvious question is whether “furthest from the Sun” means near us, and the answer is no — but the geometry that explains why is the good part. At greatest elongation the line of sight from Earth is tangent to the planet’s orbit, which makes the Sun–planet–Earth angle exactly 90°. Two things fall out of that right angle, and you can check both: the planet is exactly half-lit, the same geometry as a first-quarter moon; and it is as far from the Sun in the sky as it will get, so it stays up longest after sunset. Two things do not fall out of it. Venus is nearest at inferior conjunction, passing between us and the Sun at about 0.28 AU — and invisible in the glare, which is the joke. And it is brightest about five weeks either side of greatest elongation, where a fatter crescent and a shorter distance multiply out to more light than either extreme. At greatest elongation itself it sits around 0.69 AU away: roughly mid-swing, and the best view you will get of it.
Two planets passing — flagged, and never measured. The orbital model here is flat, so it knows the two longitudes agree and genuinely does not know how wide the gap will look, because that part is latitude. Same rule the naked-eye card follows for a planet near the Moon. A pairing is only reported when both planets are more than 15° from the Sun, because the geometry being real is no use if the sight is lost in the glare.
The page knew both halves of this for a long time and never put them together: it printed “Perseids, peak in 7d” in one place and the Moon’s illumination in another, and never once said whether you would actually see anything. Which is the difference between an almanac and advice — the same shower under a new moon is the best night of the year, and under a full one is a wasted hour in a cold field.
Two numbers decide it. The rate is the zenithal hourly rate: what one observer would count under a perfect dark sky with the radiant overhead. Nobody ever gets that, but the ratios are honest, and they are the gap between an alarm worth setting and a glance on the way to the car — the Perseids and Geminids run around 100 and 120 an hour, the Leonids 15, which is one every four minutes.
The Moon is the half that needed care. Illumination alone gets it wrong in both directions: a 97% Moon that has already set leaves the whole best stretch dark, and a modest 40% Moon riding high all night does more damage than the figure suggests. So the sky is sampled at two in the morning on peak night — meteor watching is a post-midnight business, once the radiant has climbed and the Earth’s leading side has turned into the stream — and a Moon below the horizon is treated as no Moon at all, whatever its phase.
The oldest recorded omen there is. Babylonian scribes kept tablets of Venus’s risings and settings in the seventeenth century BC, and plenty of cultures took the morning and the evening apparition for two separate objects — Phosphorus the light-bringer and Hesperus the evening one, which is why philosophers still reach for them as the example of two names for one thing.
It is also the least mystical thing on this list, because it is pure geometry and you can check it tonight. Venus orbits inside us, so it never strays more than about 47° from the Sun. East of the Sun it sets after it — the evening star, low in the west after sunset. West of the Sun it rises before it — the morning star, low in the east before dawn. The sign of the elongation is the entire test, and the elongation was already being computed for Mercury and Venus’s greatest elongations.
The switch happens at conjunction, and the two are not the same event. At inferior conjunction Venus passes between us and the Sun and changes from evening to morning star in a couple of weeks. At superior conjunction it goes round the far side, which takes months and is barely an event at all. Both are zero-crossings of the same signed number, told apart by which way the sign is travelling.
The geomagnetic index has been fetched for a long time and printed as a number in a fold, which is the wrong shape for it entirely. Kp 2 and Kp 7 are not two values of one statistic — they are “nothing is happening” and “go outside now”. It is the only genuinely rare, genuinely visible thing on this page that can arrive with no notice and be gone by morning, and it was filed as telemetry.
Whether you can see it is a question about your latitude, which the raw number never carried. The auroral oval’s equatorward edge sits near 67° geomagnetic latitude when quiet and pushes south roughly two degrees per Kp step. Southern England is about 54° geomagnetic — a few degrees north of its geographic latitude, because the magnetic pole is over Canada — so the oval only reaches here in a serious storm. Aurora can also be seen from several degrees further south than the oval itself gets, low on the northern horizon, and that allowance is built into the bands.
It says a chance and never a promise: the geomagnetic conditions are the only half it knows. Whether the sky is clear, and whether it is even dark yet, are things the page knows elsewhere and this calculation deliberately does not claim.
Not a phase. A supermoon is a full moon that happens to fall near perigee, the near end of an orbit that swings roughly ±21,000 km either side of 385,000. It earns its name honestly: at perigee the disc is about 11% wider and 14% brighter than a full moon at the far end, which is the difference between one you notice crossing the car park and one you don’t.
The distance was already being computed — it is what decides whether a solar eclipse is total or annular, since a Moon near perigee covers the Sun and one near apogee leaves a ring. It simply was never used for the thing it is famous for.
The usual threshold is “within 90% of perigee”, and here that is measured as a fraction of the model’s own range rather than against a published figure in kilometres — a single-term distance series has no business being compared to a threshold finer than its error. Only full moons are labelled. A new moon near perigee is a real geometric fact and a completely invisible event, and announcing it would be trivia in an omen’s coat.
Drawn as a ring with Earth in the middle, that diagram quietly answers a question nobody asked it: it looks like the planets go round us. It is a compass rose wearing the clothes of an orrery, and a central body with things circling it is a shape everyone already knows how to misread. So there is a second view of the same instant, and switching between them is the point.
The reason a flat ring of twelve sectors works at all is that the solar system is flat. Every planet orbits within a few degrees of the same plane, so from here they are always seen against the same narrow band of sky — and that band is the zodiac. Were the orbits randomly tilted, the planets would wander the whole sphere of stars and there would be no twelve signs to cycle through.
Distances in the top-down view are true and linear, which cost something. Squeezing them logarithmically is the obvious way to fit a hundredfold range into one picture, and it was tried: it swings Neptune’s sight-line 22.6° out of true. A sign is 30° wide, so the diagram would have contradicted the one beside it. Instead the frame changes — one out to Mars, one out to Pluto — and at the wider setting the entire inner solar system, us included, is a speck you could cover with a fingernail.
A body you tap draws two lines. The solid one is the real line of sight from where Earth actually is, and it runs dead through the planet because the distances are honest. The dashed one is the same bearing taken from the centre of the ring, and it is the one that reaches a sector. They are always parallel — that is the whole argument. A sign is a direction towards something so far away that the spot you stood in to measure it stops mattering, which is exactly why a geocentric diagram gets the signs right while getting the solar system wrong. In the first view the two lines lie on top of one another, because that view puts Earth at the centre.
It also makes retrograde visible rather than asserted. An outer planet appears to slide backwards because we overtake it on the inside lane; Mercury and Venus do it because they overtake us. Both are one glance at the picture once the planets are in the right places.
The remaining fudges are stated on the card rather than hidden: orbits are drawn as circles through each body’s current distance rather than as their true ellipses, and the Moon is set much further from Earth than it belongs, because at this scale it would be inside the dot.
Every body on the page is drawn pixel by pixel onto a canvas at render time — eleven discs, no image files, nothing downloaded. The whole set is about two hundred lines of maths.
Each body is a tiny grid — often just 14×14 — scaled up with smoothing switched off, so the pixels stay square instead of turning to mush. For every cell inside the circle, the surface normal is worked out from its position on the disc, dotted with a fixed light direction, and the result quantised into a four-step colour ramp. Four steps, not a gradient: that hard banding is what makes it read as pixel art rather than a blurry ball.
On top of that each body gets one feature its silhouette can’t carry — Jupiter’s bands and red spot, Mars’s polar cap, Pluto’s heart, the Moon’s maria. Saturn’s rings are the awkward one: they are a squashed ellipse drawn in two passes, once before the planet and once after, so the far side passes behind the disc and the near side crosses in front. Nothing is composited or masked; the draw order does the occlusion.
The Moon is the only one told the truth about itself. It takes the real phase from the same lunar model the rest of the page uses, so its terminator matches the sky — lit on the right waxing, the left waning — with the dark limb left faintly visible, which is what earthshine actually looks like.
Not to scale, on purpose. A true-scale Pluto beside a true-scale Jupiter would be a smudge next to a dinner plate. But the bodies everyone knows are small were coming out the same size as the giants, which reads as a bug rather than a simplification — so Pluto and the Moon are drawn a little smaller, and Saturn a little larger, because its disc has to shrink to make room for the rings and it was ending up the runt of the set.
Almost nothing, and that’s deliberate. There is no account, no login, and no database of people.
Your reading is private by default — “keep this between us” is ticked before you type. A private reading leaves only a contentless marker so the daily allowance still counts it; the question, the answer and the audio are never written down.
Your sign and which tab you last had open are localStorage in your own browser. They are never sent to the server, so the personalisation works without the site knowing who you are.
Your location is never asked for. Everything is anchored to where the device is, not where you are — the whole point is that you are looking out from where it sits.
What is stored is the device’s own output: the sunset predictions, the daily readings, the colour code, and the record described below. All of it in a handful of JSON blobs, none of it about a visitor.
Everything else on this site is a single slot that gets overwritten. Today’s sunset forecast replaces yesterday’s; the season’s word replaces the last one; the reading history keeps twenty entries of any kind and the prediction history keeps forty-eight hours. So until recently the site could not answer the simplest question anybody asks of it: has it been saying the same thing all week?
Three separate complaints turned out to be that one hole. The daily theme repeated, and nothing was able to notice. The trend chart drew several boots of one evening as though they were separate evenings, which made a forecast firming up over an afternoon look like a forecaster changing its mind. And nobody working on this had ever seen a week of output at once, so every judgement about whether the Oracle was any good came from a single screenshot.
One row per day, written when the key is turned: the lens the day was read through — named by the Oracle itself — what the reading was built on, the day’s word (which is also its name), the line to carry, and the rating and palette it called that evening. Rows from before the word took over the day’s name also carry the title the Oracle used to coin beside it. It is an upsert rather than an append, so the reading and the sunset can be written by two different requests in either order and still complete one row. On a day nobody turns the key there is no row — and that gap is the truth about that day, which is what you want from a record whose only job is to be honest.
It is fed back, and sameness turns out to happen at four separate levels that need four separate fixes. The last fortnight of lenses costs a theme points for having been used lately, so a genuine signal still wins and a marginal repeat does not — deliberately a bias and not a rotation, because if the world really is on one subject for a fortnight the honest reading says so. The last fortnight of words is handed over with instructions not to reuse them: a lens repeats because the news repeats, and a word repeats because models reach for the same words. (That rule once named the title, the mantra and the closing line — and not the word, which is how Equinox came up two mornings running. It was still true the second day. The word was spent anyway.)
Neither of those could see the third, which is the one anybody actually notices. Three mornings running were read through three different lenses, titled three different things, and all three were about the light going back four minutes a day — because nothing recorded what a reading was about. Near an equinox that really is the strongest fact available on the only test the reading has to pass, so every model converges on it honestly. The subject is now read back off the finished text — light, moon, weather, season, the day’s name, the hour, a planet, or something nearer to hand — and the last two are ruled out. Two days, not the whole fortnight: enough to break a run, short enough that the light comes back round inside a week.
All of that is now shown as a fortnight rather than as four lists. For a while the Oracle was handed four parallel columns — the titles it had used, the subjects it had built on, the closing lines, the mantras — each with its own instruction not to repeat itself. They worked in the narrow sense that each stopped the thing it named, and they were the wrong object twice over. Four columns are one card sorted into bins, and the bins destroy the only structure that mattered: that Monday’s word, Monday’s subject and Monday’s closing line were one card. And a ban says where not to go without saying where to go, so a model lands on the nearest thing not on the list — which is why the titles rule had grown a clause about near-synonyms, a clause that is the mechanism admitting it does not work.
The lens used to be a keyword count, and that is the change worth reading twice. Eight categories, each with a list of words, scored by how many of them appeared in the day’s signal text — plus a nudge to resilience if the weather string mentioned rain, a nudge to momentum on a good sunset, a penalty against lenses used lately, and a hash of the date to break ties. The result was handed to the Oracle as a suggestion, and the prompt said in as many words: use it only if it truly fits, otherwise replace it.
And then the record stored the suggestion. So the lens on the fold, the “lenses across 14 days” line, and the penalty itself were all describing a keyword count’s guess about a reading that may have been written through something else entirely. Every anti-repetition mechanism attached to the lens was pointed at a label that need not have matched the thing it labelled.
The Oracle picks it now, reads the day through it, and names it back — and may decline, because a wrong label is worse than none. The vocabulary stays fixed at eight, deliberately, against the obvious alternative of letting it invent one: the lens’s job is not to be expressive, since the word already does that every day in its own terms. The lens’s job is to be countable, and fourteen invented lenses are always fourteen different lenses. The lens is the category; the word is the day.
So it gets the mornings themselves, dated, oldest first, and is asked to read them as one thread: today is the next thing to say, not merely a thing that has not been said. Two hard rules survive, because judgement does not produce them. It may not reuse a line word for word. And it may not build on either of the last two subjects — a model will write about the light three mornings running and be right each time, because near an equinox that genuinely is the strongest fact available, and showing it more context will not change that.
It may never mention a previous morning out loud. There is no scheduler here, so a day nobody turns the key has no row and the fortnight is full of holes — and even on the days it is not, you see today’s card and nothing else. “As I said on Tuesday” is addressed to somebody who is not in the room. The thread shapes what today is about; it is never referred to.
You can read it yourself — it is the fold at the foot of the Day tab, and it rides on the same public response as everything else on the page.
Turn reminders on and you get at most one notification a day — today’s word, and the one thing in the sky most worth going out for, which on some days is something reaching your sign. On a quiet day the line under the word is the reading’s closing line, the ✶ one: the reading explains the word and waits on the page; the closing line is the one that makes you open it. (The toggle used to promise “roughly one every four or five days, on the days something happens”, written before the daily word existed and never told about it.) The obvious way to build the sign part is to send your sign to the server so it knows who to notify — which would quietly undo the one promise this page makes.
So it doesn’t. The server pushes the same payload to every subscriber: the day’s sky events across all twelve signs, which it already works out for the dashboard anyway. The service worker on your phone reads your sign out of local storage and picks the line that is about you. The personalisation happens on the device; the server never learns which one you are, and the only thing it holds is an anonymous push endpoint.
(A service worker cannot read localStorage at all — that API is synchronous and workers are async-only — so the sign is mirrored into IndexedDB purely so the notification can be written without asking anybody anything.)
One notification a day, carrying everything. Its title is today’s word, said as that — “Today’s word: Balance”, because a bare noun on a lock screen is a riddle. Underneath it, one line and one only, ranked by what you could go outside and check: an eclipse first, then a genuine five-star sunset (the top band only, since the whole point of a five-star night is that it is rare), then anything landing in your sign, then the full or new moon. On a day with none of those the line is the reading — the twenty-five words saying why that is today’s word. It used to be “Today reads through” and the name of a lens, which spent most of a collapsed notification on a label for the reading instead of the reading. It was two lines once; a notification is read on a lock screen in the couple of seconds before the phone goes back in a pocket, and two stacked facts is a list. Sending them as separate pushes was the other alternative, and three notifications on one morning is how you teach somebody to turn notifications off.
The picture is tonight’s sky. The icon beside the text is the Oracle’s four forecast sunset colours, drawn as four bands with the horizon lowest, and tonight’s Moon in its real phase — so it changes with the day for the same reason everything else here does. It is the same picture as the one at the top of the page. (The colours travel in the image’s own address, so drawing it needs no model and no stored file.) The switch that turns reminders on sits directly under that card, because the card is what they send; it used to live beside the sign picker, when the notification was mostly about your sign. The small mark next to the clock is the sigil’s outline. It used to be a solid square: phones draw that mark from the image’s transparency alone, and the old one had none — it was the full site icon, filled edge to edge.
They go out on the boot, like everything else. There is no scheduler: if the key is flat, nobody is told anything, because a notification arriving on a morning the device never woke would be the site claiming to know something it doesn’t. Specifically they go out with the daily reading rather than with the status POST that precedes it — the word does not exist until the reading has been written, so a push sent any earlier in the boot could only have carried yesterday’s.
The cosmic dashboard is backed by analytical orbital mechanics, solved once server-side in the same engine the Oracle itself reads from when it writes a reading — the dashboard doesn’t calculate anything, it just displays what the Oracle already worked out, refreshed every few minutes alongside a serverless weather pipeline that ingests real-time solar weather indicators.
By computing precise heliocentric coordinates, we track how far each planet is from the Sun and Earth, the speed at which they zip through space, and exactly how long it takes for a radio wave to reach them.
We expanded the local astronomical models into fully functional 3D orbital simulations using Kepler’s equations of motion. Six orbital elements (semi-major axis a, eccentricity e, mean longitude, etc.) are solved for Julian centuries since J2000.0. After iterating to find the eccentric anomaly E, the heliocentric distance r is derived:
r = a × (1 − e × cos(E))
But to calculate retrograde, we can't just trace planets from the sun. We have to map a Geocentric Ecliptic Projection. We take the planet's heliocentric Cartesian coordinates and subtract Earth's coordinates, finding precisely where that planet appears relative to observers on Earth. If that longitude is decreasing, the planet is in Retrograde.
The rate is a centred difference — the longitude one day ahead minus the longitude one day behind, halved. Comparing today against yesterday instead gives the average motion across the previous 24 hours rather than the motion right now, which reported every direction change half a day late. And within a day of a turn this mean-element model genuinely cannot resolve the direction, so the planet is reported as stationary rather than guessing at it.
The orbital velocity (V) of each planet has been modeled dynamically using the Vis-viva equation (the conservation of orbital energy) relative to its current heliocentric distance:
speed = 29.78 × sqrt(2/r − 1/a)
We calculate geocentric distance (D) between each planet and Earth using their coordinate plane vectors. Real-time electromagnetic wave propagation delays, or transmission latency, are mapped directly:
latency = D × 499.00478 seconds
This means when you click on a planet in the grid above, you can see exactly how long a broadcast signal takes to arrive — "You can't stop the signal."
The Vercel Serverless function at /api/cosmic hooks directly into the NOAA Space Weather Prediction Center (SWPC) alerts loop. Real-time proton fluxes, solar storms (geomagnetic Kp alerts), and solar flare indices under 48 hours old are parsed, deduplicated, and streamed to the dashboard.
The app continuously monitors and formats alerts dynamically with severity level thresholds (ranging from standard informational alerts up to critical G5/R5 alert levels). When peaceful, it defaults to nominal standby modes.
The system leverages a secure, high-performance, stateless serverless backend to link the physical key with global astronomical intelligence and localized AI systems.
Instead of running a heavy, expensive, vulnerable server or database continually polling, the physical ESP32-C3 acts as a lightweight boot-conduit.
Once powered on, the microcontroller sends one small payload — which device it is, and the colour code it has just drawn — to a Vercel Serverless Function at /api/cosmic, with a shared-secret header. It used to carry twenty-five fields of weather it had fetched itself; the server was fetching its own atmospheric profile regardless, so the skull stopped.
To protect the cloud function against accidental battery drain cycles, infinite boot loops, or rogue hardware faults, a Stateless Boot-Loop Throttle reads the previous status’ timestamp stored as a Vercel Blob and discards requests submitted under 5 minutes from the last update.
How does the public web user prove they physically have the key on them to unlock high-tier “Divine Mode” readings?
1. On boot, the physical ESP32-C3 utilizes the hardware random number generator (esp_random()) to dynamically mix a randomized 3-colour code (drawn from Red, Yellow, Green, Blue, Purple, White — allowing duplicates).
2. The key blinks this code physically on its LEDs while securing it into a private, short-lived Vercel Blob (cosmic-colour-code.json) tagged with a strict 24-hour expiration threshold.
3. When a user inputs their sequence on the frontend, the webapp transmits their picks to the API. The serverless function maps their inputs to the encoded indices. If they match completely, a temporary ticket is issued. At no point in this handshake is the raw sequence ever exposed or leaked to the client’s network tab — it is mathematically zero-knowledge authentication.
Upon receiving a validated device POST, Vercel initiates a non-blocking parallel synthesis pipeline:
• It grabs real-time solar wind data from the SWPC NOAA alerts engine.
• It fetches astronomical details and the day’s coordinates from the same server-side Keplerian engine that powers the dashboard.
• It triggers a Wikipedia-scraping step and three parallel Tavily web search engine crawls: world signals from the past week, historical milestones for the date, and a season-aware phenology query whose terms are chosen by the engine’s own season calculation — blossom and frogspawn in spring, leaf fall and first frost in autumn. Phenology is the one thing here that cannot be computed: an orbit is arithmetic, but the date the blossom breaks is observational, so it is the only question the Oracle has to go and ask.
• Results are filtered on relevance before quality. A snippet must actually be about something in the sky or out of doors — or come from a trusted source — to be eligible at all; only then is it ranked, deduplicated and cut for gossip, violence and institutional filler. There is no fallback tier that takes whatever is left on a quiet day, so a thin day shows a short list rather than a padded one.
• The chosen material is frozen once, as a single read set. That same list is packed into the prompt and rendered in the Today’s Signal folds — at the foot of the dashboard, and under a birthday blessing. Those three used to make their own selections independently, all three under a heading claiming to show what the Oracle read, and no two of them guaranteed to agree. The panel is not a summary of what the Oracle read; it is the bytes it read.
This massive, layered dataset is packed into a high-density system prompt sent to Google Gemini 2.5 Flash, which acts as the cosmic voice, producing tailored sunset commentaries. The result is then forwarded to ElevenLabs AI Speech Synthesis, which runs through a three-tiered fail-safe API keys container to output a cached high-fidelity MP3 stream for direct browser playback.
Model providers deprecate models overnight — it has already broken this build once. So Gemini isn’t the only voice. It is asked on two keys in turn, and if neither answers in time the same prompt falls through to OpenAI’s GPT-5.4 mini through Vercel’s AI Gateway (a route that does not learn from what it is sent), then Groq, then OpenRouter, each tried model by model, and each answer reshaped into Gemini’s format so nothing downstream needs to know which one spoke. The reading says which model did — and when it was not Gemini, pressing and holding that line says why, in the words the failure came back with. That second half is new: for four mornings in September 2026 the card said Groq and nothing anywhere recorded what had happened to Gemini, while the same boot’s sunset forecast had come from Gemini five seconds earlier.
Each boot: wake the server, which reads the forecast, runs the model, makes a prediction and writes the day’s reading; take back tonight’s palette; kill WiFi. One burst of signal, then silence.
It always looks ahead to the next sunset. Boot it after dark and it quietly moves on to tomorrow.
No boot means no new awakening and no new sunset prediction — the device is the conduit.