For the Touch Grass theme I built something that makes the screen the shortest part of the experience: a stargazing guide for Bengaluru terraces that tells you what's actually above the horizon right now — then sends you outside.
What I built
Terrace Sky Spotter — a web app (vanilla HTML/JS + zero-dependency Python server, stdlib only) in two halves:
- Deterministic astronomy (code, not AI): 16 anchor stars from open catalogs (Yale Bright Star Catalogue / HYG, public domain) + real Julian-date → sidereal-time math computes altitude/azimuth for 12.97°N 77.59°E. No GPS, no network. Tap any constellation for its finder hint.
- Open-weight narration (local Gemma 3 1B via Ollama): a "Narrate my tour" button produces the night's viewing order (setting constellations first), star-hop instructions, myths, and practical tips — plus per-constellation "how do I find it?" answers.
Since the first version I added the three features that make it a real observing tool:
- 🌙 Moon phase + washout filter — a synodic model computes illumination (validated against the Mar 3 2026 lunar eclipse); the naked-eye limit slides from ~mag 5.5 to ~mag 2.3 and faint targets get a 🌕 washed-out badge.
- 🪐 Planets — low-precision orbital math adds Venus, Mars, Jupiter and Saturn (verified by the Venus-elongation invariant). Saturn at 42° in the east is currently the best thing in the evening sky.
🕘 Time picker — plan any evening ahead, not just right now.
Live demo: run
python3 app.py, openhttp://localhost:8002(needs Ollama +gemma3:1b; tour narrates in ~30s on CPU)Code: https://github.com/sank8-2/terrace-sky-spotter (MIT)
Who it's for
My roommate Nagaraj and me — terrace sessions in Bengaluru, phone brightness down, eyes up. I took it outside on a bright moonlit night and gazed for real: the moonlight washed out the faint stuff, exactly as the app's washout filter now predicts — the Pegasus square, Vega and Altair punched through while Pisces vanished. That field night is literally what the 🌕 badge is built from.
Why open matters here
- Works with no signal. The catalog is bundled data and the model runs on-device. A closed-API guide dies the moment the bars disappear — exactly where you need it most: terraces, trails, villages.
- Location stays yours. Stargazing needs your coordinates; here they never leave the laptop.
- Free + swappable. One env var changes the model tomorrow.
The honest part: don't let the model invent the sky
Testing caught the key failure mode: asked about Cassiopeia while it was below the horizon, the model cheerfully described it as visible "high up". So the app never lets Gemma state positions — the deterministic math owns what's up and where, and the model only narrates how to find what code already verified. Below-horizon queries get an explicit "not up right now, here's when to catch it" path. Same architecture as my weekend entry's allergy guardrail: code enforces the safety property, the model supplies the words.
Also entering Best Use of Gemma — narrated end-to-end by open-weight gemma3:1b, running locally.
Top comments (0)