Cosmos Atlas — v2 roadmap¶
For the next session picking up cosmos work cold. Read this top-to-bottom plus v1 shipped. This doc is the running list of what's NOT in v1, what could lift the cosmos further, and what Sush's first eyes-on revealed needs tuning.
The three keywords are still the gauge: lively · highly interactive · bold and ambitious. If any v2 idea doesn't visibly serve all three, push back honestly.
🔴 Read these first¶
- v1 shipped — every artefact + decision in v1. Don't redesign anything in here without a strong reason.
- Cosmos Philosophy — atmosphere autonomy + cosmos law #6 (no paid content via free pathways)
- Plain AI Curriculum philosophy (
~/.copilot/plain-ai-curriculum-philosophy.md) — the 🌱 free forever firewall is non-negotiable - Voice & Tone — Sush's voice fingerprints, brag-allergy
- The live site: cosmos.aguidetocloud.com — load it, click every body, run reduced-motion, run mobile, before drafting any change
✅ V2.3 — SHIPPED (8 May 2026 NZST · deploy 8c547b37)¶
Sush V2.2 verdict: "looks good, now move MCP star with the system + make it more prominent". Plus the 4 V2.2 backlog items shipped same round.
| # | Item | Status |
|---|---|---|
| 1 | MCP star moves with cosmos | ✅ mcp.position (rOrbit + thetaDeg) drives world-space projection. Star pans/zooms/tilts with the system instead of being canvas-anchored. |
| 2 | MCP star more prominent | ✅ Size 32→44, halo multiplier 1.8× → 4.4×, always-on pulse, secondary halo ring r×1.7, MCP starfield cluster now follows the star. Reads as a beacon now. |
| 3 | Horizon bolder at high tilt | ✅ Layer alphas now scale with sinTilt |
| 4 | Body shadows cast AWAY from sun | ✅ Sun→body vector drives offset; physics-correct |
| 5 | Top-down galactic ring backdrop | ✅ Faint multi-stop ring (violet/cyan/violet) around sun |
| 6 | Sun god rays fade with tilt | ✅ tiltMul = 0.45 + 0.55×sinTilt; soft in top-down, full at tilt |
Bundle: ~26 KB JS / ~9 KB gzip. Still tiny.
Files touched (V2.3):
- src/data/atlas.json — mcp.position, anchor.size 32→44, brighter glowCore
- src/scripts/cosmos.ts — McpPosition interface, world-space projection for star, star halo boost, MCP starfield star-relative, tilt-aware horizon, tilt-faded god rays, physics-correct shadows, drawTopdownGalacticRing
- No CSS/markup changes
Reference brief lives at: session-state files/cosmos-v2-review.md (also contains the full V3 backlog for the next session).
✅ V2.2 — SHIPPED (8 May 2026 NZST · deploy 6cc96258)¶
Visual depth pass + dual-mode + list view fix. Sush's V2.1 verdict was "still a black screen with dots in the middle, list view is broken" — this round answers that. Bundle 25.52 KB JS / gzip 8.84 KB (+2.7 KB for 8 features combined). No new dependencies.
| # | Item | Status |
|---|---|---|
| 1 | List view scroll bug | ✅ html.js-ready body { overflow: hidden } was winning specificity; fix uses !important + html-class toggle |
| 2 | Dual mode: cosmos ↔ top-down | ✅ Segmented HUD pill (🌌 Cosmos · 📐 Top-down). Tilt lerps to target. localStorage-persisted (cosmosViewMode.v1). R-key resets to cosmos |
| 3 | Tilt 38° → 30° + scale clamp | ✅ project() clamps [0.5, 1.45] so front bodies don't balloon. Fixes the "Claw looks huge" complaint without abandoning tilt |
| 4 | Galactic horizon band | ✅ 3 stacked stretched-radial gradients (violet halo + cyan core + warm gold near sun) drawn in screen blend. Hidden in top-down. The biggest "we are in space" win |
| 5 | Bigger nebulae | ✅ Sizes 1.6× (720→1280 etc), alphas 2× (0.06→0.14, 0.075→0.18, 0.085→0.20) |
| 6 | Body shadow plates | ✅ Squashed elliptical shadows under each planet/moon (auto-disappears in top-down via cos collapse) |
| 7 | Orbit depth gradient | ✅ Per-segment alpha varies with z; front of orbit ~0.55× brighter than back |
| 8 | Sun god rays | ✅ 14 long soft radial light shafts, additive screen blend, slow rotation, per-ray breathing |
Top-down mode: tilt 0°, uniform body sizes, circular orbits, no body shadows, no horizon band. Parallax stars + nebulae + MCP rays + constellation + sun + god rays stay.
Files touched (V2.2):
- src/data/atlas.json — atmosphere.tilt 38→30, nebula sizes + alphas bumped
- src/scripts/cosmos.ts (~44 KB → ~50 KB) — viewMode state, tilt lerp, scale clamp, drawGalacticHorizon, drawSunGodRays, drawBodyShadows, depth-aware drawOrbits, view toggle wires, R-key includes view reset
- src/styles/cosmos.css — list-view !important fix, view-toggle pill styles
- src/pages/index.astro — segmented .hud-view-toggle with Cosmos/Top-down buttons
Known V2.2 imperfections (V3 backlog): - Galactic horizon could be more colourful at high tilt — current restraint may be too gentle for Sush's taste; easy bump. - Body shadows are a visual cheat (offset below body, not real sun-cast direction). Reads right but won't pass physics scrutiny. - Top-down mode is intentionally austere — could add a subtle galactic ring or gradient backdrop if Sush wants it richer. - Sun god rays show in top-down too — fine, but could fade them with tilt for cleaner overhead diagram.
✅ V2.1 — SHIPPED (8 May 2026 NZST, evening · deploy c031b0cf)¶
Five items stacked on V2.0 the same day to take the cosmos from "lively · interactive" toward "the card is a destination · the cosmos performs". Bundle 22.76 KB JS / gzip 8.04 KB (+3.4 KB for all five features combined). No new dependencies.
| # | Item | Status |
|---|---|---|
| 1 | Card hero portrait | ✅ 220px atmosphere-palette panel + 6 mini parallax stars + slowly-rotating planet body + drop-shadow glow + typewriter "SHIPPED N DAYS AGO" stamp |
| 2 | Freshness pulse | ✅ Subtle pulsing ring on bodies whose lastShippedAt ≤ 14 days. Manual today; sitemap.xml automation parked for V3. |
| 3 | Idle camera drift | ✅ After 30s of no input, gentle Ken-Burns drift (sin/cos phase, ~90×50px, ~6% zoom). Reset on any input. Skipped under reduced-motion. |
| 4 | HUD shortcut row + keyboard 1–6 / 0 | ✅ Mono pill row bottom-right (1–6 · focus, 0 · MCP, ⇧+drag · tilt, wheel · zoom, R · reset). Hidden < 720px. Number keys focus planets in atlas order. |
| 6 | Constellation lines | ✅ On focus, faint 3-stop dashed gradient lines fade in from focused body to each connectsTo[] slug. Earth ↔ Brainbar/PlainAI/Shift, PlainAI ↔ Earth, Agentic ↔ Claw, moons ↔ parents. |
(#5 OG image + favicon deferred this round — top-5 highest-impact items shipped first.)
Atlas data additions:
- lastShippedAt (ISO date) per planet/moon/MCP — manually maintained; bump on each visible ship
- connectsTo[] (slug array) per planet/moon — surfaced as constellation lines on focus
Verification: Playwright screens at session-state files/screens/v21-live/ (desktop, Earth card panel, keyboard "4" → Plain AI focus, mobile, mobile card). All passed.
Reference brief lives at: session-state files/cosmos-v2-review.md.
Known V2.1 imperfections (V3 backlog):
- Idle drift threshold (30s) may be too aggressive on slow readers — easy tune in IDLE_THRESHOLD_MS.
- Constellation lines are subtle at 0.30 alpha — bump if Sush wants them more declarative.
- Plain AI's atmospheric ring still slightly hot (V2.0 imperfection unchanged) — V3 fix is per-planet ring alpha tuned by colour luminance.
- lastShippedAt is hand-maintained — V3: prebuild script that fetches each planet's sitemap.xml and writes generated freshness.json.
Files touched (V2.1):
- src/data/atlas.json — lastShippedAt + connectsTo on 6 planets, 2 moons, MCP star; doc comments
- src/scripts/cosmos.ts (~38 KB → ~44 KB) — freshness map, drawFreshnessPulses, drawConstellationLines with eased fade, idle drift in updateCamera, markInteraction wired through all input handlers, keyboard 0–9 handler, portrait-aware renderCardHtml
- src/styles/cosmos.css — appended ~4.1 KB for .card-portrait*, .card-meta, .hud-shortcuts
- src/pages/index.astro — .hud-shortcuts markup with <kbd> keys
✅ V2.0 P0 + P1 — SHIPPED (8 May 2026 NZST · deploy 3fb973f6)¶
Twelve items shipped to take the cosmos from "calm · clickable · tasteful" toward Sush's locked three-keyword gauge: lively · highly interactive · bold and ambitious. No new dependencies — still vanilla TS + Canvas 2D + Astro 5.18. Bundle 19.35 KB JS (gzip 7.05 KB).
| # | Tier | Item | Status |
|---|---|---|---|
| 1 | P0 | Mobile cosmos doesn't render | ✅ removed deliberate if (innerWidth < 600) toggleList.click() auto-fallback |
| 2 | P0 | Sun too small, no corona | ✅ size 12 → 28 + 4-stop corona + 8 rotating ray spokes during pulse peaks |
| 3 | P0 | MCP star visually orphaned | ✅ animated dashed rays from MCP to every status: "live" endpoint |
| 4 | P1 | Bodies feel flat | ✅ atmospheric ring at r * 1.05 (chose ring over sphere underlay so brand SVGs stay clean) |
| 5 | P1 | Depth falloff too subtle | ✅ FOCAL 900 → 600 desktop, FOCAL 1100 on narrow mobile so inner planets don't crush |
| 6 | P1 | No parallax starfield | ✅ 3 layers, deterministic seeded RNG, 80 + 38 + 14 stars with twinkle and halo |
| 7 | P1 | No volumetric mood | ✅ 3 nebula blobs (purple #3B0764, blue #0C4A6E, warm #7C2D12) with globalCompositeOperation = 'screen' |
| 8 | P1 | No first-load wow moment | ✅ ignition state machine: sun fades in → orbits draw → bodies arrive (~2.5s); persisted via localStorage.cosmosIntroSeen.v1 |
| 9 | P1 | Hover state inelegant | ✅ HUD readout: dark glassy bg, mono uppercase, amber top-rule, ▸ accent prefix |
| 10 | P1 | Camera locked | ✅ wheel zoom (0.55–2.4), drag-pan, Shift+drag tilt rotate (18°–58°), pinch on mobile, r reset |
| 11 | P1 | No cursor magnetism | ✅ 180px range, max 8px pull, stronger on hover, baseScreenX/Y for stable hit-test |
| 12 | P1 | No sonar ping | ✅ ring on mouseenter, expands 5.2× over 1200ms ease-out cubic |
Verification: Playwright captured desktop + hover + MCP card + mobile + reduced-motion at session-state files/screens/v2-live/. All five pass.
Files touched:
- src/data/atlas.json — atmosphere.focal, sun stops + rays, nebulae[]
- src/scripts/cosmos.ts (~28 KB → ~38 KB) — parallax, nebula, sun ignition + rays, MCP rays, atmospheric rings, sonar pings, cursor magnetism, free zoom/pan/tilt, intro state machine, mobile-aware FOCAL
- src/styles/cosmos.css — cosmic HUD readout, mobile chrome tightening, cursor: grab
Known V2.0 imperfections (V3 backlog candidates):
- Plain AI's atmospheric ring reads slightly more prominent than other planets due to lavender on dark — could tune per-planet ring alpha by colour luminance.
Shift+dragfor tilt is undiscoverable. Add HUD hint (SHIFT + DRAG · TILT) or move rotation to right-click-drag in V3.- On narrow mobile the sun visually drifts to upper-right because the camera centres on body average + orbital tilt projection. Acceptable but not ideal. Possible fix:
cameraPullToSunbias on narrow viewports. - Intro
localStoragekey versioned.v1— bump to.v2for any V3 visual intro change to replay for everyone.
Deviations from the original brief:
-
4 sphere underlay → atmospheric ring. The brand SVGs (lotus, AI bubble,
[*],$_) already carry weight; a sphere underlay would have flattened them.¶ -
5 depth crank → mobile-aware. Desktop FOCAL=600 was perfect; mobile crushed inner planets. Solution: narrow viewports get FOCAL=1100.¶
-
10 camera →
Shift+dragfor rotate (not always-on) so plain drag stays as pan.¶
Reference brief lives at: session-state files/cosmos-v2-review.md — full review doc with 24 items, world-class refs (NASA Eyes, igloo.inc, bruno-simon, rauno.me etc.), and what NOT to do.
Eyes-on items from Sush's first browser pass¶
Status: 7 of 8 resolved in v1.1 (commit
98a5f27, 8 May 2026 evening). See v1-shipped.md → v1.1 polish for the full diagnosis + fixes. The bottom line: the perceived crowding was mostly halo bleed, an opaque lotus webp, and tight inner-orbit spacing — NOT the tilt.
| # | Item | v1.1 outcome |
|---|---|---|
| 1 | Tilt feels right at 38°? | ✅ Confirmed correct. Tested at 38° after live eyes-on; the "felt crowded" complaint resolved when halos and orbits were tuned, with tilt unchanged. Don't re-litigate without strong reason. |
| 2 | Orbit speeds | ⏳ Untouched in v1.1. Outer planets (Agentic 245s, Claw 290s) might still feel slow; needs Sush eyes-on after v1.1. |
| 3 | Hit-radius on small moons | ✅ Fixed via .planet-body::before { inset: -12px } invisible hit-zone. Moons (size 22) still look small but are easy to click. |
| 4 | Camera glide easing | ⏳ Untouched in v1.1. Lerp factor 4.5× — needs Sush eyes-on after v1.1. |
| 5 | Halo intensities | ✅ Tightened globally. Body halo multiplier 4.4×/3.0× → 3.2×/2.2×. Sun halo radius 7× → 5×. No more bleed between neighbours. |
| 6 | Plain AI cyan vs MCP amber | ✅ Resolved. MCP star bumped 26→32 + repositioned to corner-most (0.92, 0.10). Plain AI cyan halo no longer eats the quadrant. |
| 7 | Mobile portrait layout | ✅ Auto-fall-back to list view < 600px. The "Cosmos View" HUD button still lets users override and try the canvas anyway. ⚠️ V2.0 update (8 May): auto-fall-back removed — mobile renders the full canvas now. List view still available via header toggle. |
| 8 | Reduced-motion mode | ✅ Verified — orbits frozen at phase, cards still open, twinkles/pulse muted. |
Items 2 + 4 are the only original eyes-on items left for a future session.
High-leverage v2 ideas (ranked by impact × ease)¶
🥇 1. Cosmos atlas brand mark (replace placeholder favicon)¶
Impact: High — placeholder favicon is a brand smell. Effort: Medium — needs a design call.
The current public/favicon.svg is a quick concentric-rings + tiny sun glyph I drew during scaffolding. Per cosmos-philosophy lotus-as-default, framework defaults are a brand violation but my placeholder isn't the lotus either. Phase 4b owns the cosmos-atlas mark — it should:
- Read at 16×16 favicon size
- Distinguish the atlas (meta-layer) from any individual planet
- Reuse Deep Cosmos palette (#02030E + #FFB347)
- Candidates: orbital sweep silhouette · scientific instrument (sextant?) · spiral · star burst
🥈 2. Real OG image (1200×630 cosmos screenshot)¶
Impact: High — social shares + LinkedIn previews land flat with no image.
Effort: Low — Playwright headless screenshot of / then crop.
Plan:
1. Add playwright as a devDep
2. Write scripts/og.mjs that:
- Launches headless Chromium
- Loads cosmos.aguidetocloud.com
- Waits 2s for fonts + layout
- Screenshots viewport at 1200×630
- Saves to public/og.png
3. Add npm run og script
4. Run pre-deploy
5. CDN cache invalidates automatically on next deploy
🥉 3. Atlas joins planets.toml mirror set (cosmos-audit guard #4)¶
Impact: Medium — atlas should appear in every other planet's cosmos rail. Effort: Medium — 5-file mirror commit across 5 OTHER repos.
Per cosmos-audit § GUARDRAIL rule #4, every planet joins planets.toml. The atlas hasn't yet — it's not in:
- aguidetocloud-revamp/data/planets.toml
- aguidetocloud-revamp/brainbar/data/planets.toml
- guided/src/data/planets.json
- shift/src/data/planets.json
- plainai/content/planets.json
A NEW SESSION (not this one) should add cosmos-atlas to all 5 mirrors in the same commit. Slug cosmos, name "Cosmos Atlas", url https://cosmos.aguidetocloud.com/, tagline "the cosmos, mapped". Update typed unions in 2 Astro PlanetIcon components if a new icon slug is added.
This is deferred per locked decision #12 (atlas writes nothing other sessions own) until parallel voice/logo/nav/parity work lands.
4. Phase 12 — cross-link from each planet's footer to atlas¶
Impact: Medium — discoverability. Effort: Medium — 6 repos, footer edit each.
A single small link in each planet's footer: "part of the Cosmos Atlas". Per locked decision #12, deferred until parallel voice/logo/nav/parity sessions settle.
5. Sound — opt-in ambient pad¶
Impact: Medium — adds a sensory layer for the visitors who turn it on. Effort: High — licensing, opt-in UX, fade logic, perf.
Direction (from vision §3): Brian Eno's Apollo: Atmospheres and Soundtracks as the reference. Reality: Eno's actual album is copyrighted; royalty-free pad music is the only legal path. Or commission a custom 60-second loop.
UX:
- Default OFF (autoplay rules + perf + a11y)
- HUD toggle button (volume icon)
- Fade in over 800ms when toggled on
- Persist preference in localStorage
- Crossfade if toggled off mid-track
Skip in v2 unless Sush specifically wants it — most visitors never enable optional audio.
6. Per-planet "what's been updated" pulse¶
Impact: Medium — gives the cosmos a heartbeat (alive, not static).
Effort: Medium — needs each planet to expose a last_updated timestamp.
If a planet has shipped content in the last 14 days, its body pulses with a subtle ring (like the MCP star starfield). Source the timestamp from each planet's RSS feed or sitemap.xml <lastmod>.
This requires:
- A small last-updated.json cache in atlas (fetched on build or daily)
- Each planet must expose RSS or lastmod (Earth + Shift + Plain AI already do; CMD + Guided + Agentic + Claw need verifying)
- Cosmos.ts adds a pulsing ring on bodies whose last_updated is within 14 days
7. Per-planet MCP endpoint live status¶
Impact: Low — currently hardcoded as live or planned in atlas.json.
Effort: Low — ping each MCP endpoint at build time.
For each MCP endpoint listed in atlas.json → mcp.endpoints, ping it during build. If 200, mark live. If 404/timeout, mark planned. This keeps the MCP card honest without manual updates.
8. Deep-link to a planet¶
Impact: Low — share-friendly URLs. Effort: Low.
/?planet=earth opens the atlas with Earth's card already open. Lets Sush share cosmos.aguidetocloud.com/?planet=plainai in tweets. Already roughly possible — atlas just needs to read the query string on mount and call openSlug().
9. Webp/AVIF lotus alongside webp¶
Impact: Tiny. Effort: Tiny.
Earth lotus is currently webp 11.6KB. AVIF would shave ~30%. Not urgent but easy.
10. Self-hosted fontsource → variable fonts¶
Impact: Tiny — saves ~30KB. Effort: Low.
@fontsource-variable/space-grotesk is a single file with all weights. Same for JetBrains Mono. Drop from 4 weights × 2 fonts = 8 woff2 files (~94KB) to 2 woff2 files (~60KB).
11. Better Lighthouse profile — loading="eager" on lotus¶
Impact: Low — visible LCP improvement. Effort: Tiny.
Currently loading="eager" is set on the static-shell lotus. The canvas overlay also references it but later. One small CSS preload in Base.astro could push LCP down a bit.
Deferred-permanently items¶
These were considered and rejected in v1. Don't re-litigate without explicit Sush sign-off.
| Item | Why rejected |
|---|---|
| 3-question router quiz | The cosmos IS the navigation. Adding a quiz on top says "we don't trust the metaphor". |
| Voices block | Atlas is spatial orientation across the cosmos. Voice testimonials are Earth-cert-shaped — would feel cargo-culted here. |
Open Laboratory journal-public.json |
Another data contract. Skip until a real "what changed?" use case emerges. |
| AGTC lotus at the cosmic centre | Earth orbits the Sun; the lotus belongs on Earth's body, not at the gravitational anchor. |
| GSAP for camera/card animation | Vanilla CSS transitions + rAF loops handle it. Saves ~50KB. |
| Three.js full 3D | Canvas 2D + 38° tilt does the job for 7 bodies + 2 moons. Three.js is overkill until we want flythrough. |
Known v1 imperfections (file as v2 backlog)¶
Updated 8 May 2026 evening after v1.1 polish.
- MCP star is fixed-screen-position — doesn't move with camera glide. Per vision §4 this is by design (star = "fixed coordinates"). v1.1 made the star bigger + brighter and pushed it to the corner-most position, so it reads as deliberate now.
- Planet body intrinsic sizes are tuned by guess (Earth 36, smaller planets 28-34, moons 22, MCP 32 in v1.1). Sush eyes-on may want adjustments after v1.1.
- Orbit eccentricity + tilt — v1.1 tightened eccentricities (0.04-0.10 → 0.04-0.06) for cleaner circles. Per-orbit
tiltstill hardcoded in atlas.json; visual rhythm may want tuning. - No analytics yet — no CF Web Analytics, no Plausible, no GA. Could add CF Web Analytics in 2 lines of head config (it's free, privacy-first, no cookies).
- No 404 page — Astro doesn't generate one by default for static. CF Pages will serve a generic one. Could add
src/pages/404.astro. - Self-hosted font weights are 4 (Space Grotesk 400/500/600/700) + 2 (JetBrains Mono 400/500). Could trim to 3 + 2 if 600 is unused.
- The hud-hint pulses on idle. Some users find pulsing distracting. Consider toggling off after first interaction.
- List-view auto-fallback triggers on
window.innerWidth < 600at mount. Doesn't react to viewport changes — if user resizes browser from desktop to mobile width, canvas keeps trying to render. Could listen toresizeand re-engage list-view, but adds complexity.
Inputs the next session must NOT touch¶
- Atmosphere palette — Deep Cosmos is locked. Don't change
#02030E/#F2EDE3/#FFB347without Sush's explicit sign-off. - Sun representation — invisible glow is locked. Don't add a glyph or label.
- 3-question router — permanently skipped per Phase 0 call.
- Plain AI 🌱 free forever firewall — non-negotiable; must stay at TOP of Plain AI + Curriculum cards.
- Forbidden words list — cosmos-wide enforcement.
- Card body ≤100 words — vision §6 word budget.
- Brand voice — Sush's voice fingerprints, never analyst voice.
Pickup pattern for the next session¶
- Open the live URL in a browser. Click every body. Try mobile. Try reduced-motion.
- Ask Sush: "What's the first thing you'd change?"
- Read v1-shipped.md (especially the v1.1 polish section at the bottom) to understand what's already been tuned.
- If touching
cosmos.ts: 3D math is inproject()andupdateCamera(). Hover/click in the body event listeners. Time progression is split intosimT(orbital, pauses on hover) andgetRealT()(twinkles + pulse, never pauses) — keep that distinction. - If touching cards: layout is in
cosmos.css.card-hero,.card-stats, etc. Content is inatlas.json. - If adding new content: voice-pass through 4 tests + forbidden-words list before commit.
- Before push:
npm run buildthen screenshot via Playwright at 1440 + 1920 + 820 + 390 + reduced-motion before deploy — Sush's session 8 May evening proved this is essential. Visuals catch what code reviews miss. - Deploy:
npm run deploy. After deploy: smoke-test the live URL. - If a brand asset (lotus, etc.) has a baked-in background, use the chroma-key pattern from
~/.copilot/session-state/061c101c-.../files/chroma-key.mjsrather than CSS workarounds —mix-blend-mode: screenis silently isolated byfilteron ancestors. - Update v2-roadmap.md if any v2 idea is shipped (mark done, add new ones).
Voice gate for any new card content¶
Run every new sentence through these:
- Mum test — would my mum understand this on first read?
- Dinner-table test — would I say this without sounding like a robot?
- 12-year-old test — could a bright 12-year-old follow it?
- Honesty test — am I trying to please a vendor, or serve the reader?
Fail any → rewrite. No exceptions.