{"slug": "compline-the-radical-laziness-of-sleep-building-an-offline-gothic-sanctuary-with", "title": "Compline: The Radical Laziness of Sleep — Building an Offline Gothic Sanctuary with Gemma 2, a Real-Time 3D Astrolabe, and Vinyl Crackle", "summary": "Developer Arnav, based in Bengaluru, built Compline, an offline gothic wind-down companion that runs Google's open-weight Gemma 2 model locally through Ollama to generate calming bedtime stories with a \"hypnagogic decrescendo\" prompt structure. The browser-based app pairs the local LLM with a real-time 3D celestial astrolabe that aligns 89 constellations to the user's actual sky via geolocation and sidereal time, plus a Web Audio vinyl-crackle phonograph and a tarot wheel. It was submitted to the Hacktoberfest Open-Source AI Challenge's Week 3 \"Slow and Steady\" prompt.", "body_md": "*This is my submission for the [Hacktoberfest Open-Source AI Challenge, Week 3: Slow and Steady](https://dev.to/challenges/hacktoberfest-week3-2026-10-19).* 🦥\n\nI'm Arnav, from Bengaluru. For Week 1's \"Touch Grass\" challenge, I built *WildTrail* to get people outdoors. For Week 2's \"Side Hustle\", I built *GhostLedger* for sovereign freelancer tax intelligence.\n\nFor Week 3, the prompt honors **International Sloth Day**:\n\n*\"Build something with open-weight models or open-source AI that rewards laziness: a tool for relaxation, an automation for a task you dread, or anything that makes life easier.\"*\n\nOne of the challenge's suggested sparks caught my eye immediately:\n\n*\"A wind-down companion that generates a calming bedtime story or ambient soundscape, running entirely offline.\"*\n\nSo I decided to lean fully into radical laziness and built **Compline**: a candlelit gothic wind-down companion that transforms your nightstand into an ancient, tranquil monastic scriptorium.\n\nFalling asleep in the modern world is an exhausting, high-friction chore:\n\nSloths have it figured out: **move at your own pace, conserve your energy, and let the universe come to you.**\n\nWith **Compline**, going to sleep requires zero cognitive effort:\n\n```\nflowchart TD\n    subgraph Client [\"Gothic Nightstand Sanctuary (Zero Dependencies)\"]\n        Candle[\"🕯️ Cinematic Candle Ritual (Match-Strike / Blackout)\"]\n        Astrolabe[\"🧭 3D Celestial Astrolabe (Real Sky LST Alignment)\"]\n        Phono[\"📻 Abbey Phonograph (The Needle & The Groove)\"]\n        Scribe[\"📜 Scriptorium Tome (Illuminated Ink Stream)\"]\n        Tarot[\"⚙️ Wheel of Fate & Gothic Slumber Tarot\"]\n        Grimoire[\"📖 Scriptorium Grimoire (Local Bookmark Storage)\"]\n    end\n\n    subgraph AudioEngine [\"Web Audio Procedural Engine\"]\n        Needle[\"📍 Needle Drop & Arm Physics\"]\n        Crackle[\"🪵 Vintage Surface Crackle (Pink Noise + Lowpass)\"]\n        Tracks[\"💿 Opus I: Nocturne / Opus II: Vespers\"]\n    end\n\n    subgraph AI [\"Open-Source AI & Hypnagogic Core\"]\n        Gemma[\"🧠 Google Gemma 2 (Local Ollama gemma2:2b / 9b)\"]\n        Offline[\"🕯️ Offline Hypnagogic Decrescendo Generator\"]\n    end\n\n    Candle --> Astrolabe\n    Phono --> AudioEngine\n    Scribe --> AI\n```\n\nThe nightstand sky isn't a generic looping starry wallpaper. It is an interactive 3D celestial sphere rendering 89 classical constellations (*Ursa Major, Cygnus, Orion, Cassiopeia, Lyra, Taurus...*), armillary coordinate rings, and the 7 classical wandering planets.\n\nTapping the dedicated **`[🌌 Tonight's Real Sky]`** header button queries your browser's Geolocation API, calculates the exact Greenwich Sidereal Time (GST) and Local Sidereal Time (LST) for your longitude, and rotates the entire celestial sphere so that the stars above your bed match what is overhead in reality.\n\nA tactile analog player built entirely on the native Web Audio API:\n\nBedtime stories should never have cliffhangers, sudden shocks, or escalating conflict. Compline connects to local **Gemma 2** (via Ollama at `http://localhost:11434`) using structured relaxation prompts designed around **hypnagogic decrescendo**:\n\nAn ornate brass-and-stained-glass mechanical wheel with procedural ratchet audio. Giving it a gentle spin draws from an 8-card Gothic Slumber Tarot deck (*The Hermit of the Bell Tower, The Alchemist's Crucible, The Scribe of Midnight...*) to seed the night's meditation.\n\nSleepers can bookmark chapters directly to their personal Grimoire, stored privately in the browser's local storage with zero cloud accounts.\n\nIn the [DEV community discussion on running local LLMs](https://dev.to/kennedyraju55/the-developers-guide-to-running-llms-locally-ollama-gemma-4-and-why-your-side-projects-dont-54oe), developer Kennedy Raju noted that side projects rarely need an external API key when open-weight models have gotten this good. And as highlighted in [recent local AI benchmarks](https://dev.to/rainytechlab/run-ai-locally-on-your-mac-with-ollama-chat-tools-rag-and-a-custom-model-real-numbers-from-a-4ngf), running smaller models locally achieves real-time streaming speeds with zero network overhead.\n\nCompline only works as a true sleep companion *because* of open-weight models:\n\nJust like my previous challenge submissions, I made a commitment to test every detail and inspect real network and runtime behavior. That uncovered three tricky technical challenges:\n\nAfter deploying a critical UI fix, I visited the live Vercel URL and noticed the changes weren't appearing. Opening terminal and inspecting HTTP response headers with `curl -sI https://complineapp.vercel.app/` revealed the culprit:\n\n```\nHTTP/2 200 \nage: 558\ncache-control: public, max-age=0, must-revalidate\nx-vercel-cache: HIT\n```\n\nEven with `max-age=0`, Vercel edge nodes (like `bom1` in India) cache static assets at the CDN layer unless explicitly told otherwise. The fix was updating `vercel.json` to enforce edge invalidation across all routes:\n\n```\n{\n  \\\"headers\\\": [\n    {\\n      \\\"source\\\": \\\"/(.*)\\\",\\n      \\\"headers\\\": [\\n        {\\n          \\\"key\\\": \\\"Cache-Control\\\",\\n          \\\"value\\\": \\\"no-cache, no-store, must-revalidate, max-age=0, s-maxage=0\\\"\\n        }\\n      ]\\n    }\\n  ]\\n}\n```\n\nSetting `s-maxage=0` forced edge cache misses (`age: 0`, `x-vercel-cache: MISS`) and instant propagation on every new commit!\n\nTranslating GPS coordinates into an accurate 3D celestial sphere required real celestial mechanics. Standard clock time doesn't match star time because the Earth rotates once relative to the stars in 23 hours, 56 minutes, and 4 seconds (one sidereal day).\n\nTo compute the celestial rotation angle, I implemented Greenwich Mean Sidereal Time (GMST) and Local Sidereal Time (LST):\n\n``` js\n// Calculate Julian Date from UTC\nconst jd = 2440587.5 + (date.getTime() / 86400000);\nconst d = jd - 2451545.0; // Days from J2000.0\n\n// Greenwich Mean Sidereal Time in degrees\nlet gmst = (280.46061837 + 360.98564736629 * d) % 360;\nif (gmst < 0) gmst += 360;\n\n// Local Sidereal Time\nlet lst = (gmst + longitude) % 360;\nif (lst < 0) lst += 360;\n\n// Rotate the celestial sphere canvas\nconst lstHours = lst / 15;\nstellarSky.rotationAngle = -(lstHours / 24) * Math.PI * 2;\n```\n\nNow, when you look at Cygnus or Ursa Major in Compline, they are in the exact same orientation as the real night sky outside your window.\n\nDuring development, I got excited and spent hours building a volumetric stained-glass god-ray lighting engine (\\\"Rose Window Prism\\\"). It rendered animated caustic light shafts and chromatic dust motes across the screen.\n\nWhen I actually tested it at bedtime, it felt completely wrong:\n\nSo I ruthlessly deleted all 400+ lines of it. Recognizing when to delete code is just as important as knowing what to write. Stripping away the excess left the sanctuary feeling peaceful, quiet, and effortless.\n\nTo give the Hacktoberfest judges a transparent look into how Compline was planned, built, tested, and polished, here is the complete recorded agent session:\n\nTo run it locally with zero external dependencies (pure Python 3 standard library):\n\n```\ngit clone https://github.com/XiaoArnav/complineapp.git\ncd complineapp\npython3 app/server.py\n```\n\nThen visit `http://localhost:7777`.\n\nConnect local Gemma 2 anytime with `ollama run gemma2:2b`.\n\nMay your nights be restful and peaceful. Channel your inner sloth. 🦥✨", "url": "https://wpnews.pro/news/compline-the-radical-laziness-of-sleep-building-an-offline-gothic-sanctuary-with", "canonical_source": "https://dev.to/polymath_arnav/compline-the-radical-laziness-of-sleep-building-an-offline-gothic-sanctuary-with-gemma-2-a-4mh2", "published_at": "2026-10-21 17:29:47+00:00", "updated_at": "2026-10-21 17:40:02.088631+00:00", "lang": "en", "topics": ["generative-ai", "large-language-models", "ai-tools", "ai-products"], "entities": ["Arnav", "Compline", "Gemma 2", "Ollama", "Google", "Hacktoberfest", "Bengaluru", "Kennedy Raju"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/compline-the-radical-laziness-of-sleep-building-an-offline-gothic-sanctuary-with", "markdown": "https://wpnews.pro/news/compline-the-radical-laziness-of-sleep-building-an-offline-gothic-sanctuary-with.md", "text": "https://wpnews.pro/news/compline-the-radical-laziness-of-sleep-building-an-offline-gothic-sanctuary-with.txt", "jsonld": "https://wpnews.pro/news/compline-the-radical-laziness-of-sleep-building-an-offline-gothic-sanctuary-with.jsonld"}}