Constellation
A photo treasure hunt that only runs once
Next.js · Convex · Convex Auth · Framer Motion

The problem
A treasure hunt is a piece of software with no second attempt. It runs once, outdoors, on a phone, on a specific day — and every ordinary failure mode becomes unrecoverable. No signal in a basement. A GPS fix that lands thirty metres off. A dead battery. Anything that blocks progress doesn't degrade the experience, it ends it.
Why it exists
I wanted to build something where correctness meant something more than passing tests, and where the constraints were real rather than imagined. Designing for one person on one day turns out to impose more discipline than designing for many: there is no retry, no support channel, and no version two of that afternoon.
How I solved it
Nothing can permanently block progress. Each stop escalates — geofence, then a manual override after two failures, then a host force-unlock from a second device, then a numeric code. Clues cache to localStorage and photos queue in IndexedDB, so a dead zone delays the record rather than the hunt. The guest client never receives a stop's coordinates or an unearned reveal; state is sanitised server-side so the answer can't be read out of the network tab. Content lives in git and is seeded into the database, so if the backend is unreachable the clues still exist in two other places. Version two generalises it so other people can build their own — which inverts four decisions that were correct at two users and wrong at many, starting with the fact that every backend function was public.