Nakshatra: Stargazing in Total Darkness (Because Phone Screens Blind Your Eyes) A developer built Nakshatra, a browser-based astronomical radar that guides users to real stars using acoustic cues and a near-black OLED display rather than a virtual sky map. The system uses a dual-oscillator sonar hum and whispered voice prompts to align the phone with celestial bodies, keeping the screen at 0.000 nits with deep-red telemetry above 650nm to preserve retinal rhodopsin, and runs a local Google Gemma model to narrate star lore. It splits targeting into a chest-level azimuth sweep and a chin-level altitude tilt to avoid arm fatigue. This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass https://dev.to/challenges/hacktoberfest-week1-2026-10-05 Most software designed to help people disconnect from screens makes a contradictory mistake: it asks you to walk outside, pull out a glass rectangle, and look down at a screen to photograph leaves. It replaces desk-screen time with outdoor-screen time. I wanted something different. I wanted to step onto an urban rooftop at midnight, walk away from terminal windows, and look up at the actual sky. When you look at a smartphone in the dark, you encounter an immediate biological barrier. The human retina contains roughly 120 million rod photoreceptors that govern nocturnal night vision. These rods rely on a photopigment called rhodopsin. A single 500-millisecond glance at an illuminated smartphone screen bleaches over 80 percent of your retinal rhodopsin. Your pupils constrict from seven millimeters down to two. Rebuilding that dark adaptation requires 20 to 30 continuous minutes in total darkness. Every mainstream astronomy app forces you to stare down at a digital simulation of stars rendered in glowing pixels. You stand under real celestial bodies while staring at a backlit slab. I built Nakshatra the Sanskrit word for constellation or star sector . Nakshatra is an eyes-up astronomical radar that runs inside the mobile browser. It does not display a virtual sky map. Its display is kept at 0.000 nits solid 000000 on OLED panels with low-intensity deep-red telemetry $\lambda 650\text{ nm}$ that preserves retinal rhodopsin. You hold the phone flat against your chest. A dual-oscillator acoustic radar hums in your earbuds, rising in pitch as your torso turns toward an invisible celestial body. When you align with the star, a chime sounds, and a whispered voice directs you to bring the phone to your chin. You tilt your head back, look directly into the night sky, and listen as local Google Gemma whispers the lore of the star into your ears. Your eyes never leave the sky. Figure 1: Nakshatra running in pitch darkness. On OLED panels, unused subpixels turn off completely 0.000 nits . Red elements use wavelengths above 650nm to protect rod photoreceptors. npm start --prefix client Runs at http://localhost:3000 Figure 2: The two-phase posture: holding the phone flat at chest height to sweep the horizon, then raising it to the chin to gaze directly upward. npm test --prefix client . Building for an idealized browser simulator is straightforward. Deploying that same software on a physical smartphone standing on a cold concrete roof reveals immediate hardware hurdles. Here is how the system is engineered from the ground up. Holding a smartphone upward at arm's length for two minutes causes rapid muscle fatigue and tremors. Nakshatra decouples horizontal azimuth alignment from vertical altitude targeting into two physical postures: graph LR subgraph Phase 1 "Phase 1: Chest-Level Sweep" direction TB P1 Action "Phone flat in palm at chest pitch <= 25° " P1 Sound "Acoustic sonar hums 220Hz-440Hz" P1 Lock "Dwell within 6° for 1000ms locks heading" P1 Voice "Whisper: 'Bring phone to your chin'" P1 Action -- P1 Sound -- P1 Lock -- P1 Voice end subgraph Phase 2 "Phase 2: Chin-Level Tilt" direction TB P2 Action "Phone raised to chin pitch 25° " P2 Cue "Whisper: 'Tilt your head up slightly'" P2 Lock "Pitch matches altitude within 3°" P2 Voice "Lock chime: 'Stop right there'" P2 Action -- P2 Cue -- P2 Lock -- P2 Voice end subgraph Phase 3 "Phase 3: Dark Observation" direction TB P3 Screen "Screen solid black 0.000 nits " P3 Gemma "Local Gemma whispers celestial lore" P3 Screen -- P3 Gemma end P1 Voice -- P2 Action P2 Voice -- P3 Screen On mobile Chromium on mid-tier Android devices, calling event.acceleration returns {x: 0, y: 0, z: 0} without throwing an error. The API appears active, but reports zero motion. Any code relying on linear acceleration to track physical movement fails silently. To detect when a user is walking versus standing still, I read event.accelerationIncludingGravity , calculate the raw Euclidean magnitude, and strip Earth's gravitational acceleration: js handleMotion event { if event return; let dynamicMag = 0; let hasLinearAcc = false; if event.acceleration && typeof event.acceleration.x === 'number' && event.acceleration.x == null { const ax = Number event.acceleration.x || 0; const ay = Number event.acceleration.y || 0; const az = Number event.acceleration.z || 0; const mag = Math.sqrt ax ax + ay ay + az az ; if mag 0.05 { dynamicMag = mag; hasLinearAcc = true; } } if hasLinearAcc && event.accelerationIncludingGravity { const ax = Number event.accelerationIncludingGravity.x || 0; const ay = Number event.accelerationIncludingGravity.y || 0; const az = Number event.accelerationIncludingGravity.z || 0; const rawMag = Math.sqrt ax ax + ay ay + az az ; dynamicMag = Math.abs rawMag - 9.81 ; } const now = Date.now ; if dynamicMag 0.50 && now - this. lastStepTime 300 { this. lastStepTime = now; this.stepsDetected += 1; this.displacementMeters += 0.65; } } This filter detects real footsteps and resets tracking if the user walks away from their observation point. Smartphone magnetometers experience continuous jitter between eight and twelve degrees caused by rooftop rebar and sensor noise. If you instruct an application to guide a user toward an exact single-degree coordinate, the audio radar chatters constantly. Furthermore, celestial targets between zero and fifteen degrees altitude are almost always obstructed by apartment buildings, power lines, or streetlights. I resolved both issues in quadrant selector.js : selectTargetForHeading currentHeadingAz, allVisibleTargets { if allVisibleTargets || allVisibleTargets.length === 0 { return null; } const currentQuad = this.getQuadrant currentHeadingAz ; if this.latchedTarget && this.activeQuadrant === currentQuad && this.isTargetCooledDown this.latchedTarget.name { return this.latchedTarget; } const inQuadrant = allVisibleTargets.filter t = { if typeof t.azimuth == 'number' || typeof t.altitude == 'number' { return false; } if t.altitude < this.minAltitudeDeg { return false; } return this.getQuadrant t.azimuth === currentQuad; } ; if inQuadrant.length === 0 { return null; } const uncooled = inQuadrant.filter t = this.isTargetCooledDown t.name ; const candidatePool = uncooled.length 0 ? uncooled : inQuadrant; const chosen = this. pickWeightedCandidate candidatePool ; this.latchedTarget = chosen; this.activeQuadrant = currentQuad; return chosen; } My initial prototype used a strict 15-degree heading margin between the chest sweep and the chin tilt phase. In outdoor testing, this caused nine out of ten attempts to abort. When a human raises their hands from chest level to their chin, the elbow hinge naturally rotates the wrist. This mechanical arc swings the internal phone compass by 25 to 35 degrees during transit. I relaxed the heading abort tolerance to 45 degrees during the lift motion and implemented a 1.2-second post-lift gyroscopic stabilization dampener. The software now conforms to human anatomy instead of treating the user like an industrial robotic arm. A core requirement of Nakshatra was to eliminate robotic coordinate readouts. Hearing a synthesized voice say "Azimuth 214 degrees, pitch 42 degrees, Right Ascension 18 hours" pulls the user out of contemplation and back into analytical tension. graph TD subgraph Tier 1 "1. Mobile Sensor Hardening 50Hz " S Orient "DeviceOrientation Compass & Pitch " -- S Filter "Low-Pass Filter alpha = 0.15 " S Motion "DeviceMotion Raw Accelerometer " -- S Gravity "Gravity Decomposition Filter" S Filter -- S Fusion "Calibrated Pose & Motion Vectors" S Gravity -- S Fusion end subgraph Tier 2 "2. Astronomical Ephemeris Engine" E Catalog "80+ Celestial Body Catalog" -- E Math "Sidereal & Topocentric Math" S Fusion -- E Math E Math -- E Quad "4-Quadrant Selector 18° Skyline Floor " E Quad -- E Latch "Target Latching & 30-Minute Cooldown" end subgraph Tier 3 "3. Intelligence & Audio Synthesis" E Latch -- A Radar "Web Audio Radar 220Hz-440Hz " E Latch -- W Gemma "On-Device Gemma 3 WebGPU Worker " W Gemma -- |Memory limits| W Lore "Deterministic Lore Database" W Gemma -- A Speech "Sub-15ms Whispered Speech Synthesizer" W Lore -- A Speech A Radar -- A Speech end Nakshatra uses a dual-engine architecture to generate body-relative celestial phrasing: gemma-3-270m-it-ONNX via Web Worker or Chrome's native Prompt API . All weight loading, token caching, and generation run off the main JavaScript thread, ensuring the audio oscillators never stutter. All model outputs pass through a deterministic validation filter that checks for forbidden technical terms: js const FORBIDDEN JARGON REGEX = /\b azimuth|altitude|right\s+ascension|declination|degree s ?|arcminute s ?|arcsecond s ?|bearing|southeast|northeast|southwest|northwest|fist s ?|clenched \b/i; Unit tests in an IDE pass easily. Real hardware outdoors fails in unexpected ways. Testing under real skies caught three critical edge-case bugs: sensors.js using shortest-angle modulo wrapping: js shortestAngleDiff target, source { let diff = target - source + 180 % 360 - 180; if diff < -180 diff += 360; return diff; } The 81 automated tests in npm test execute in 1.3 seconds via Node's native test runner, ensuring these mathematical edge cases remain guarded against regression. Open Innovation Matter? Open-source and open-weight AI models are vital for tools designed for the physical outdoors. When you stand in a dark-sky preserve, on a mountain ridgeline, or on a remote trail, cellular towers do not reach you. A proprietary cloud application that depends on remote inference servers fails the moment connectivity drops. Google Gemma models running locally on client hardware fundamentally change outdoor software: